Skip to content

Instantly share code, notes, and snippets.

@horstjens
Last active October 21, 2024 16:54
Show Gist options
  • Save horstjens/8fbb7dc3b4c94dc1084e3774d32db811 to your computer and use it in GitHub Desktop.
Save horstjens/8fbb7dc3b4c94dc1084e3774d32db811 to your computer and use it in GitHub Desktop.
asteroid16
import pygame
import random
import os.path
W, H = 1280, 720
class TextSprite(pygame.sprite.DirtySprite):
def __init__(self, pos, color, textsize, text, age_max, anchor="center" ):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 9
self.anchor = anchor
pygame.sprite.DirtySprite.__init__(self, Game.uigroup, Game.allgroup)
self.pos = pygame.Vector2(pos[0],pos[1])
self.color = color
self.textsize = textsize
self.text = text
self.age = 0
self.age_max = age_max
self.change_color = False
self.move = pygame.Vector2(0, 0)
self.bounce = False
self.create_text(self.text)
def create_text(self, text):
font = pygame.font.SysFont("System", self.textsize)
if self.change_color:
r,g,b = self.color
new_colors = []
for old_color in r,g,b:
new_color = old_color + random.randint(-100,100)
new_color = max(10, new_color)
new_color = min(255, new_color)
new_colors.append(new_color)
else:
new_colors = self.color
self.image = font.render(text, True, new_colors)
self.rect = self.image.get_rect()
self.image.set_colorkey((0,0,0))
self.image = self.image.convert_alpha()
self.rect.center = self.pos
def update(self, dt):
self.age += dt
if self.age_max is not None:
if self.age > self.age_max:
self.kill()
self.pos += self.move * dt
if self.change_color:
self.create_text(self.text)
if self.bounce:
if self.pos.x < 0:
self.pos.x = 0
self.move.x *= -1
if self.pos.x > W:
self.pos.x = W
self.move.x *= -1
if self.pos.y < 0:
self.pos.y = 0
self.move.y *= -1
if self.pos.y > H:
self.pos.y = H
self.move.y *= -1
if self.anchor == "center":
self.rect.center = self.pos
elif self.anchor == "topleft":
self.rect.topleft = self.pos
class Rocket(pygame.sprite.DirtySprite):
def __init__(self, shooter ):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer=6
pygame.sprite.DirtySprite.__init__(self, Game.rocketgroup, Game.allgroup, Game.scrollgroup)
self.pos = pygame.Vector2(shooter.pos.x, shooter.pos.y)
try:
self.victim = random.choice(Game.playergroup.sprites())
except IndexError:
self.kill()
self.hitpoints = 20
self.age = 0
self.age_max = 20
self.speed = 100
self.speed_max = 200
self.image = pygame.surface.Surface((100, 20))
pygame.draw.polygon(self.image, (64,255,0),
((0,0), (10,5),(50,5),(50,0),(55,5),
(80,5),(90,10),
(80,15),
(55,15),(50,20),(50,15),(10,15),(0,20),
(5,10))
)
self.image.set_colorkey((0,0,0))
self.image= pygame.transform.scale(self.image, (50,10))
self.image = self.image.convert_alpha()
self.image0 = self.image.copy()
self.rect = self.image.get_rect()
self.rect.center = self.pos
self.move = pygame.Vector2(0,0)
def update(self, dt):
if self.hitpoints <= 0:
self.kill()
self.age += dt
if self.age > self.age_max:
self.kill()
if self.victim not in Game.playergroup:
self.kill()
# rotate toward victim
m = self.victim.pos - self.pos
m.normalize_ip()
winkel = m.angle_to(pygame.Vector2(1,0))
self.image = pygame.transform.rotate(self.image0, winkel)
self.rect = self.image.get_rect()
self.rect.center = self.pos
#if self.speed < self.speed_max:
# self.speed *= 1.01
# self.speed = min(self.speed_max, self.speed)
# verfolgung
m = pygame.math.Vector2(self.speed, 0)
m.rotate_ip(-winkel)
self.move += m * dt
self.pos += self.move * dt
self.rect.center = self.pos
if random.random() < 0.5:
v = pygame.Vector2(-25,0)
v.rotate_ip(-winkel)
Bubble(self.pos+v,
v*5,
acc = 0.99,
color_start=(64,255,0),
color_end=(0,64,0),
age_max=1,
radius_start=1,
radius_end=6,
)
class Ufo(pygame.sprite.DirtySprite):
def __init__(self):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 4
pygame.sprite.DirtySprite.__init__(self, Game.aliengroup, Game.allgroup, Game.scrollgroup)
self.hitpoints = 10
self.image = pygame.surface.Surface((100,100))
#pygame.draw.polygon(self.image, (64,64,64), ((30,20),(50,60), (70,40),(110,40),(160,90),(160,100),
# (150,110),(110,110),(110,120),(160,160),(110,120),(110,110),
# (70,110),(70,120),(20,160),(70,120),(70,110),(30,110),(20,100),
# (20,90),(50,60)))
pygame.draw.polygon(self.image, (0,128,0), ((10,50), (30,20), (70,20), (90,50), (80,65), (20,65))) # fill
pygame.draw.polygon(self.image, (0, 172, 0), ((10, 50), (30, 20), (70, 20), (90, 50), (80, 65), (20, 65)), 4) # line
pygame.draw.line(self.image, (0,172,0), (10,50),(90,50),5)
for x in (30,50,70):
#pygame.draw.circle(self.image, (0,0,0), (x, 40), 6)
pygame.draw.polygon(self.image,
(0,0,0),
[(x,30),(x-10, 40),(x+10,40)])
self.image.set_colorkey((0,0,0))
self.image = self.image.convert_alpha()
self.rect = self.image.get_rect()
self.w, self.h = self.rect.width, self.rect.height
ok = False
while not ok:
self.pos = pygame.Vector2(random.randint(0,W),
random.randint(0,H))
# too close to player?
ok = True
for player in Game.playergroup:
distance = self.pos - player.pos
if distance.length() < 200:
ok = False
break
self.rect.center = self.pos
self.move = pygame.Vector2(random.uniform(50,100))
self.move.rotate_ip(random.uniform(0,360))
def update(self, dt):
if random.random() < 1/120:
Rocket(self)
if self.hitpoints <= 0:
for _ in range(250):
m = pygame.Vector2(random.uniform(300, 350), 0)
m.rotate_ip(random.random() * 360)
p = pygame.Vector2(self.pos.x, self.pos.y)
Bubble(p, m, color_start=(0,64,0),
color_end=(0,255,0),
age_max=4,
radius_start=5,
radius_end=20,
acc=0.995)
Game.sounds["ufokill"].play()
self.kill()
self.pos += self.move * dt
if random.random() < 0.01:
# change direction
self.move = pygame.Vector2(random.uniform(50, 200))
self.move.rotate_ip(random.uniform(0, 360))
# wrap at screen edge
# wrap
#if self.pos.x > W + self.w:
# self.pos.x = -self.w
#if self.pos.x < -self.w:
# self.pos.x = W + self.w#
#if self.pos.y > H + self.w:
# self.pos.y = -self.w
#if self.pos.y < -self.w:
# self.pos.y = H + self.w
# center
self.rect.center = self.pos
class Rock(pygame.sprite.DirtySprite):
def __init__(self, pos, size=1):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 4
pygame.sprite.DirtySprite.__init__(self, Game.rockgroup, Game.allgroup, Game.scrollgroup)
self.alpha = 255
self.pos = pos
self.size = size
self.winkel = 0
self.image = self.create_image()
self.image0 = self.image.copy()
self.rect = self.image.get_rect()
self.rect.center = self.pos
self.rotation_speed = random.uniform(1,100) * random.choice((1,-1))
match size:
case 1:
self.hitpoints = 100
self.hitpointsfull = 100
low, high = 25,50
case 2:
self.hitpoints = 50
self.hitpointsfull = 50
low, high = 55,100
case 3:
self.hitpoints = 10
self.hitpointsfull = 10
low, high = 105,150
case 4:
self.hitpoints = 5
self.hitpointsfull = 5
low, high = 155, 175
if size == 1:
m = pygame.Vector2(W/2, H/2)
self.move = m - self.pos
self.move.normalize_ip()
self.move *= random.uniform(low, high)
else:
self.move = pygame.Vector2(random.uniform(low, high), 0)
self.move.rotate_ip(random.randint(0, 360))
def create_image(self):
match self.size:
case 1:
self.w = 128
case 2:
self.w = 64
case 3:
self.w = 32
case 4:
self.w = 16
img = pygame.surface.Surface((self.w, self.w))
points = []
for winkel in range(0, 360, 360//12):
v = pygame.Vector2(random.uniform(0.6, 0.95),0)
v *= self.w // 2
v.rotate_ip(winkel)
v += pygame.Vector2(self.w //2, self.w//2)
points.append((v.x, v.y))
#points.append(points[0])
farbe = (random.randint(170,210),
random.randint(120,160),
0)
pygame.draw.polygon(img,farbe, points)
img.set_colorkey((0,0,0))
img = img.convert_alpha()
return img
def explode(self):
if self.size < 4:
for _ in range(3):
pos = self.pos.copy()
Rock(pos,self.size +1)
Game.sounds["rockkill"].play()
self.kill()
def update(self, dt):
# rotate
self.winkel += self.rotation_speed * dt
self.image = pygame.transform.rotate(self.image0, self.winkel)
self.rect = self.image.get_rect()
self.pos += self.move * dt
# wrap at screen edge
# wrap
#if self.pos.x > W + self.w:
# self.pos.x = -self.w
##if self.pos.x < -self.w:
# self.pos.x = W + self.w#
#if self.pos.y > H + self.w:
# self.pos.y = -self.w
#if self.pos.y < -self.w:
# self.pos.y = H + self.w
# center
#self.rect.center = self.pos
#print(self.rect.center)
class Bullet(pygame.sprite.DirtySprite):
def __init__(self, shooter):
Game.sounds["laser1"].play()
self.dirty = True
self.visible = True
self.blendmode = 0
pygame.sprite.DirtySprite.__init__(self, Game.bulletgroup, Game.allgroup, Game.scrollgroup)
self.v0 = 300
self.damage = 1
self.shooter = shooter
self.pos = self.shooter.pos + shooter.nose
self.image = pygame.Surface((15,3))
#self.image.fill((255,0,0)) # red
pygame.draw.line(self.image, (255,0,0), (0,1), (15,1),1)
self.image = pygame.transform.rotate(self.image, shooter.direction)
self.image.set_colorkey((0,0,0)) # make black transparent
self.image = self.image.convert_alpha() # no alpha necessary
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect.center = self.pos
self.age = 0
self.age_max = 4
self.move = pygame.Vector2(self.v0, 0 )
self.move.rotate_ip(-self.shooter.direction)
self.move += self.shooter.move.copy()
#print("bullet created")
def update(self, dt):
self.age += dt
if self.age > self.age_max:
self.kill()
self.pos += self.move * dt
# wrap at screen edge
# wrap
#if self.pos.x > W + 32:
# self.pos.x = -32
#if self.pos.x < -32:
# self.pos.x = W + 32#
#if self.pos.y > H + 32:
# self.pos.y = -32
#if self.pos.y < -32:
# self.pos.y = H + 32
# center
self.rect.center = self.pos
#print(self.rect.center)
class Star(pygame.sprite.DirtySprite):
def __init__(self):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 4
pygame.sprite.DirtySprite.__init__(self,
Game.allgroup, Game.stargroup)
x = random.random() * W * 2
y = random.random() * H * 2
z = random.random() # 0...1
self.pos = pygame.Vector3(x, y, z)
self.create_image()
def create_image(self):
size = int(self.pos.z * 5) + 1
self.image = pygame.Surface((size,size))
if size <= 2:
self.image.fill((255,255,255))
else:
pygame.draw.circle(self.image,
(255,255,255),
(size/2, size/2),
size/2)
self.image.set_colorkey((0,0,0))
self.image = self.image.convert_alpha()
self.rect = self.image.get_rect()
class Bubble(pygame.sprite.DirtySprite):
def __init__(self,
pos,
move=pygame.Vector2(0,0),
radius_start = 1,
radius_end = 10,
radius_plusminus = 3,
color_start=(0,0,200),
color_end=(0,0,200),
#colordelta=30,
acc=1.0,
age_min = 2.0,
age_max = 4.0,
age_max_plusminus = 1.0,
alpha_start=255,
alpha_end=0,
):
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 2
pygame.sprite.DirtySprite.__init__(self, Game.allgroup, Game.scrollgroup)
self.pos = pygame.Vector2(pos[0],pos[1])
self.move = pygame.Vector2(move[0], move[1])
self.image = pygame.Surface((radius_end*2, radius_end*2))
self.radius = radius_start
self.radius_start = radius_start
self.radius_end = radius_end + random.randint(-radius_plusminus, radius_plusminus)
self.color = [color_start[0], color_start[1], color_start[2]]
self.color_start = color_start
self.color_end = color_end
self.alpha = alpha_start
self.alpha_start = alpha_start
self.alpha_end = alpha_end
self.acc = acc
#self.age_max_plusminus = age_max_plusminus
self.age_max = age_max + random.uniform(-age_max_plusminus, age_max_plusminus)
self.age = 0
self.draw_image()
self.rect = self.image.get_rect()
self.rect.center = self.pos
def draw_image(self):
pygame.draw.circle(self.image, # surface
self.color, # color
(self.radius_end, self.radius_end), # pos
self.radius, # radius
)
self.image.set_colorkey((0, 0, 0)) # black is transparent
self.image.set_alpha(self.alpha)
self.image = self.image.convert_alpha()
def update(self, dt):
self.age += dt
if self.age > self.age_max:
self.kill()
self.pos += self.move * dt
self.move *= self.acc
# kill on screen edge
if self.pos.x < 0 or self.pos.y < 0 or self.pos.x > W or self.pos.y > H:
self.kill()
self.age_percent = self.age / self.age_max
#self.color = [0,0,0]
for i in (0,1,2):
self.color[i] = int(self.color_start[i] + self.age_percent * (self.color_end[i] - self.color_start[i]))
self.color[i] = max(0, self.color[i])
self.color[i] = min(255, self.color[i])
#print(i, self.color[i])
#print(self.age_percent, self.color)
# alpha: 0 is fully transparent, 255 is fully opaque
self.alpha = self.alpha_start + (self.alpha_end - self.alpha_start) * self.age_percent
self.image.fill((0,0,0)) # black
self.radius = self.radius_start + self.age_percent * (self.radius_end - self.radius_start)
self.draw_image()
self.rect.center = self.pos
class Player(pygame.sprite.DirtySprite):
def __init__(self, pos=pygame.Vector2(W/2,H/2)):
self.age = 0
self.energy = 500
self.energy_max = 500
self.generator = 50 # energy per second
self.energy_per_shot = 10
self.energy_per_shield = 100 # for each second with shield
self.energy_per_forward = 10
self.energy_per_rotate = 5
self.lives = 4
self.dirty = True
self.visible = True
self.blendmode = 0
self._layer = 5
pygame.sprite.DirtySprite.__init__(self, Game.playergroup, Game.allgroup)
self.score = 0
self.hitpoints = 100
self.grace = 10.0
self.unverwundbar = self.grace
self.number = len(Game.playergroup) + 1
self.image = pygame.Surface((100,100))
points = ((25, 25), (80, 50), (25, 75), (35, 50)) # looking to right
pygame.draw.polygon(self.image, "#ffffff", points, 0)
self.image.set_colorkey("#000000")
self.image = self.image.convert_alpha()
self.image0 = self.image.copy()
self.image1 = self.image.copy()
self.rect = self.image.get_rect()
self.move = pygame.Vector2(0,0)
self.rotation_speed = 180 # grad/second
self.speed_limit = 400 # pixel/second
self.moving_speed = 50
self.direction = 0
self.mass = 1000
#self.pos = pygame.Vector2(W / 2, H / 2)
self.pos = pos
self.vec_nose = pygame.Vector2(32,0) # from center
self.vec_upper_engine = pygame.Vector2(-25,-25) # from center
self.vec_lower_engine = pygame.Vector2(-25,25) # from center
self.nose = self.vec_nose.copy()
self.upper_engine = self.vec_upper_engine.copy()
self.lower_engine = self.vec_lower_engine.copy()
self.schutzschild()
self.timeout_bullet = 0.1
self.time_since_last_bullet = 0
def forward(self, dt, power=2.8):
if self.energy < self.energy_per_forward * dt:
return
self.energy -= self.energy_per_forward * dt
new_move = pygame.Vector2(self.moving_speed, 0) * dt * power
# new_move += pygame.Vector2(player_moving_speed, 0) * dt
new_move.rotate_ip(-self.direction)
self.move += new_move
if random.random() < 0.3:
bubblemove = pygame.Vector2(2, 0)
bubblemove.rotate_ip(-self.direction)
bubblemove *= (1 + self.move.length())
bubblemove *= 0
Bubble(self.pos + self.upper_engine, -bubblemove, color_start=(255,255,0), color_end=(255,0,0), age_max=2)
Bubble(self.pos + self.lower_engine, -bubblemove, color_start=(255,255,0), color_end=(255,0,0), age_max=2 )
def rotate(self, dt, clockwise=True, power=1.5):
if self.energy < self.energy_per_rotate * dt:
return
self.energy -= self.energy_per_rotate * dt
if clockwise:
sign = -1
else:
sign = 1
self.direction += self.rotation_speed * dt * sign * power
self.image1 = pygame.transform.rotate(self.image0, self.direction)
self.rect = self.image1.get_rect()
self.rect.center = self.pos
# player1.rect = player1.image.get_rect()
self.nose = self.vec_nose.rotate(-self.direction)
self.upper_engine = self.vec_upper_engine.rotate(-self.direction)
self.lower_engine = self.vec_lower_engine.rotate(-self.direction)
# make bubbles
if random.random() < 0.4:
bubblemove = pygame.Vector2(110, 0)
bubblemove.rotate_ip(-self.direction + 90)
# HIER WEITERMACHEN!
Bubble(self.pos + self.upper_engine, -bubblemove, color_start=(255,255,0), color_end=(255,0,0), age_max=1, radius_start=1, radius_end=4 )
Bubble(self.pos + self.lower_engine, -bubblemove, color_start=(255,255,0), color_end=(255,0,0), age_max=1, radius_start=1, radius_end=4)
bubblemove = pygame.Vector2(110, 0)
bubblemove.rotate_ip(-self.direction - 90)
Bubble(self.pos + self.nose, -bubblemove, color_start=(255,255,0), color_end=(255,0,0), age_max=1, radius_start=1, radius_end=4)
def schutzschild(self):
self.schild = pygame.Surface((100, 100))
pygame.draw.circle(self.schild,
(0,0,255), # blau
(50,50), # center
40 # radius
)
self.schild.set_colorkey((0,0,0)) # schwarz
if self.unverwundbar > self.age:
#if self.unverwundbar < self.grace:
p = (self.unverwundbar-self.age) / self.grace
self.schild.set_alpha(p * 250)
self.schild = self.schild.convert_alpha()
def shoot(self):
if self.time_since_last_bullet > self.timeout_bullet:
if self.energy < self.energy_per_shot:
return
self.energy -= self.energy_per_shot
self.time_since_last_bullet = 0
Bullet(self)
def activate_shield(self):
if self.energy < self.energy_per_shield :
return
if self.unverwundbar > self.age:
return
self.unverwundbar = self.age + 1 # shield for 1 second
self.unverwundbar = min(self.grace, self.unverwundbar)
def update(self, dt ):
self.age += dt
self.energy += self.generator * dt
self.time_since_last_bullet += dt
# friction
if self.unverwundbar <= self.age:
self.image = self.image1.copy()
else:
self.energy -= self.energy_per_shield * dt
if self.energy <= 0:
self.unverwundbar = 0
self.unverwundbar -= dt
if self.unverwundbar < 0:
self.unverwundbar = 0
#self.unverwundbar = max(self.unverwundbar, 0)
self.image = self.image1.copy()
x = self.rect.width // 2
y = self.rect.height // 2
self.schutzschild()
self.image.blit(self.schild,
(x-self.schild.get_width()//2,
y-self.schild.get_height()//2))
self.move *= 0.95
# speed limit
if self.move.length() > self.speed_limit:
self.move = self.move.normalize() * self.speed_limit
self.pos += self.move * dt
Game.screenpos = pygame.Vector2(self.pos.x - W/2, self.pos.y - H/2)
# wrap
#if self.pos.x > W + 32:
# self.pos.x = -32
#if self.pos.x < -32:
# self.pos.x = W + 32#
#if self.pos.y > H + 32:
# self.pos.y = -32
#if self.pos.y < -32:
# self.pos.y = H + 32
# pos
#self.rect.center = self.pos
self.rect.center = (W//2, H//2)
#self.draw()
class Game:
background = None
screen = None
player1 = None
player2 = None
clock = None
sounds = {}
joysticks = {}
scoretext1 = ""
scoretext2 = ""
ufo_timeout = 30
FPS = 60
# sprite groups
playergroup = pygame.sprite.Group()
aliengroup = pygame.sprite.Group()
bulletgroup = pygame.sprite.Group()
rocketgroup = pygame.sprite.Group()
rockgroup = pygame.sprite.Group()
uigroup = pygame.sprite.Group()
# allgroup = pygame.sprite.RenderUpdates()
scrollgroup = pygame.sprite.Group()
stargroup = pygame.sprite.Group()
allgroup = pygame.sprite.LayeredDirty()
screenpos = (0,0)
def create_background():
Game.background = pygame.Surface((W * 2, H *2))
for _ in range(200):
Star()
#light = random.randint(64, 172)
#radius_max = 5
#pygame.draw.circle(Game.background, (light, light, light), (random.randint(0, W), random.randint(0, H)),
# random.randint(1, radius_max))
# big Asteroids font on center of background
font = pygame.font.SysFont("System", 256)
textsurface = font.render("Asteroids", # text
True, # antialias
(32, 32, 32), # color
)
w, h = textsurface.get_rect().size
Game.background.blit(textsurface, (W / 2 - w / 2, H / 2 - h / 2))
# little "created by" font on right bottom corner of background
font = pygame.font.SysFont("System", 32)
textsurface = font.render("created 2024 by spielend-programmieren.at", # text
True, # antialias
(64, 64, 0), # color
)
w, h = textsurface.get_rect().size
Game.background.blit(textsurface, (W - w - 10, H - h - 5))
def create_ui_layer():
# left top corner
# a lot of Textsprites
#layer = pygame.Surface((W,H))
TextSprite(pos=(0,0), color=(255,255,255), textsize=32, text="Player One", age_max=None, anchor="topleft")
Game.text_lives_1 = TextSprite(pos=(0,25), color=(255,255,255), textsize=24, text="Lives:", age_max=None, anchor="topleft")
Game.text_shield_1 = TextSprite(pos=(0,50), color=(0,0,255), textsize=24, text="Shield:", age_max=None, anchor="topleft" )
Game.text_energy_1 = TextSprite(pos=(0,75), color=(255,255,0), textsize=24, text="Energy:", age_max=None, anchor="topleft")
Game.text_score_1 = TextSprite(pos=(0,100), color=(255,255,255), textsize=24, text="Score:", age_max=None, anchor="topleft")
#font = pygame.font.SysFont("System", 32)
#text = font.render("Player One",
# True,
# (255, 255, 255))
#layer.blit(text, (0, 0))
#text = font.render("Lives:", True, (255,255,255))
#layer.blit(text,(0, 25))
#text = font.render("Shield:", True, (0,255,0))
#layer.blit(text,(0, 50))
#text = font.render("Energy:", True, (255,255,0))
#layer.blit(text,(0,75))
#text = font.render("Score:", True, (255,255,255))
#layer.blit(text,(0,100))
#layer.set_colorkey((0,0,0))
#layer.convert_alpha()
#Game.ui_layer = layer
def new_wave():
Rock(pygame.Vector2(0, 0), 1, )
Rock(pygame.Vector2(W, 0), 1, )
Rock(pygame.Vector2(W, H), 1, )
Rock(pygame.Vector2(0, H), 1, )
def load_assets(): # (os.path.join("Sounds", "laser1.wav")
Game.sounds["laser1"] = pygame.mixer.Sound("soundeffect_laser1.wav")
Game.sounds["impact1"] = pygame.mixer.Sound("soundeffect_impact1.wav")
Game.sounds["ufo"] = pygame.mixer.Sound("soundeffect_ufohit.wav")
Game.sounds["ufokill"] = pygame.mixer.Sound("soundeffect_ufokill.wav")
Game.sounds["rockkill"] = pygame.mixer.Sound("soundeffect_rockkill.wav")
def setup():
# pygame setup
pygame.init()
#print("joystick:", pygame.joystick.get_init())
#FPS = 60 # frames per seconds that we wish for (reality will be sometimes lower)
Game.screen = pygame.display.set_mode((W, H))
Game.clock = pygame.time.Clock()
running = True
#dt = 0
# sterne malen
create_background()
# sprites
Game.player1 = Player()
create_ui_layer()
#player1 = Player()
#ufo1 = Ufo(aliengroup, allgroup)
score = 0
#time_without_ufo = 0
#ufo_timeout = 10
#Game.scoretext1 = TextSprite((0,0),(0,255,0),32,
# "Score: 0 Shield: 5 s",None)
#w, h = Game.scoretext1.image.get_rect().size
#Game.scoretext1.pos = pygame.Vector2(w/2,h/2)
#new_wave()
#Game.energytext1 = TextSprite((0,40), (255,255,0), 32, f"energy: {int(Game.player1.energy/5000*50)}",None)
#w, h = Game.energytext1.image.get_rect().size
#Game.energytext1.pos = pygame.Vector2(w/2, h/2+20)
def mainloop():
running = True
dt = 0
time_without_ufo = 0
Game.screen.blit(Game.background, (0,0))
pygame.display.flip() # once!
while running:
#Game.scoretext1.create_text(f"Lives: {"@"*Game.player1.lives} Shield: {Game.player1.unverwundbar:.1f} {int(Game.player1.unverwundbar)*'-'} Score: {Game.player1.score}")
#w,h = Game.scoretext1.image.get_rect().width, Game.scoretext1.image.get_rect().height
#Game.scoretext1.pos = (w/2,h/2)
# energy bar (a bit less than half screen):
#Game.energytext1.create_text(f"energy: {Game.player1.energy:.0f} {int(Game.player1.energy / 5000 * 35)*"~"}")
#w, h = Game.energytext1.image.get_rect().size
#Game.energytext1.pos = pygame.Vector2(w / 2, h / 2 + 20)
Game.text_lives_1.create_text(f"Lives: {Game.player1.lives * '@'}")
Game.text_shield_1.create_text(f"Shield: {int(Game.player1.unverwundbar * 6) * '='}")
Game.text_energy_1.create_text(f"Energy: {int(Game.player1.energy/5) * '~'}")
if len(Game.rockgroup) == 0:
new_wave()
# collision detection bullet vs Rocket
for rocket in Game.rocketgroup:
crashgroup = pygame.sprite.spritecollide(rocket, Game.bulletgroup, False)
for b in crashgroup:
impactpoint = pygame.sprite.collide_mask(rocket, b)
if impactpoint is not None:
b.kill()
rocket.hitpoints -= 1
# collision detection player vs Rocket
for player in Game.playergroup:
if player.lives <= 0:
continue
crashgroup = pygame.sprite.spritecollide(player, Game.rocketgroup, False)
for r in crashgroup:
impactpoint = pygame.sprite.collide_mask(player, r)
if impactpoint is not None:
if player.unverwundbar <= 0:
player.hitpoints -= 1
else:
#player.unverwundbar = 0
player.energy = 0
# in any case
r.kill()
# collision detection rocket vs rock
for rock in Game.rockgroup:
crashgroup = pygame.sprite.spritecollide(rock, Game.rocketgroup, False)
for r in crashgroup:
impactpoint = pygame.sprite.collide_mask(rock, r)
if impactpoint is not None:
r.kill()
# collision detection player vs Rock
for player in Game.playergroup:
if player.lives <= 0:
continue
if player.unverwundbar <= 0:
crashgroup = pygame.sprite.spritecollide(player, Game.rockgroup, False)
for c in crashgroup:
impactpoint = pygame.sprite.collide_mask(player, c)
if impactpoint is not None:
player.unverwundbar = 0 + player.grace
player.move = pygame.Vector2(0,0)
player.lives -= 1
# explosion
for _ in range(250):
m = pygame.Vector2(random.uniform(300, 350), 0)
m.rotate_ip(random.random() * 360)
p = pygame.Vector2(player.pos.x, player.pos.y)
Bubble(p, m, color_start=(255, 255, 255),
color_end=(10, 10, 10),
age_max=5,
radius_start=8,
radius_end=25,
acc=0.991)
if player.lives > 0:
player.pos = pygame.Vector2(W/2,H/2)
else:
for _ in range(500):
p = pygame.Vector2(player.pos.x, player.pos.y)
m = pygame.Vector2(random.uniform(50,400),0)
m.rotate_ip(random.random() * 360)
Bubble(p,m,color_start=(0,0,128),color_end=(0,0,255), acc=0.99)
player.kill()
if len(Game.playergroup) == 0:
gosprite = TextSprite((100,100), # pos
(255,0,0), # color
200,
"Game Over",
None,
)
gosprite.change_color = True
gosprite.move = pygame.Vector2(300, 50)
gosprite.bounce = True
# collision between Bullet and Ufo
for ufo in Game.aliengroup:
crashgroup = pygame.sprite.spritecollide(ufo, Game.bulletgroup, False)
for b in crashgroup:
impactpoint = pygame.sprite.collide_mask(ufo, b)
if impactpoint is None:
continue
else:
b.shooter.score += 5
#Game.scoretext1.create_text(f"Score: {b.shooter.score}")
ufo.hitpoints -= 1
Game.sounds["ufo"].play()
b.kill()
# collision detection Bullet vs Rock
for rock in Game.rockgroup:
crashgroup = pygame.sprite.spritecollide(rock, Game.bulletgroup, False)
for b in crashgroup:
impactpoint = pygame.sprite.collide_mask(rock, b)
if impactpoint is None:
continue
else:
# impact bubble
reflection = b.move.copy()
reflection *= -0.75 # invert direction and slow
reflection.rotate_ip(random.gauss(0,20))
Bubble(pos=b.pos.copy(),age_min=0.3, age_max=1.2,
color_start=(random.randint(128,255),0,0), color_end=(random.randint(64,128),0,0),
radius_start=1,radius_end=8,
move=reflection,
acc = 0.6)
b.shooter.score += 1
rock.hitpoints -= b.damage
percent = rock.hitpoints / rock.hitpointsfull
percent = 0.25 + percent * 0.75
rock.image0.set_alpha(int(percent * 255))
# move rock a bit
rock.move += b.move.normalize() * 1
if rock.hitpoints <= 0:
rock.explode()
#Game.player1.score += 1
b.shooter.score += 100
Game.scoretext1.create_text(f"Score: {Game.player1.score}")
b.kill()
Game.sounds["impact1"].play()
# poll for events
# pygame.QUIT event means the user clicked X to close your window
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_LSHIFT:
if Game.player1.energy > 1000:
Game.player1.energy -= 1000
Game.player1.unverwundbar += 1
Game.player1.unverwundbar = min(Game.player1.grace, Game.player1.unverwundbar)
Game.player1.score -= 100
# Handle hotplugging joysticks
if event.type == pygame.JOYDEVICEADDED:
# This event will be generated when the program starts for every
# joystick, filling up the list without needing to create them manually.
joy = pygame.joystick.Joystick(event.device_index)
Game.joysticks[joy.get_instance_id()] = joy
print(f"Joystick {joy.get_instance_id()} connencted")
# handle removing josticks
if event.type == pygame.JOYDEVICEREMOVED:
del Game.joysticks[event.instance_id]
print(f"Joystick {event.instance_id} disconnected")
keys = pygame.key.get_pressed()
if Game.player1.lives > 0:
if keys[pygame.K_SPACE]:
Game.player1.shoot()
if keys[pygame.K_w] or keys[pygame.K_UP]:
Game.player1.forward(dt)
if keys[pygame.K_a] or keys[pygame.K_LEFT]:
Game.player1.rotate(dt, clockwise=False)
if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
Game.player1.rotate(dt, clockwise=True)
if keys[pygame.K_LSHIFT]:
Game.player1.activate_shield()
# For each joystick:
for nr, joystick in enumerate(Game.joysticks.values()):
jid = joystick.get_instance_id()
hats = joystick.get_numhats()
for i in range(hats):
hat = joystick.get_hat(i) # tuple x,y with values -1, 0, 1
buttons = joystick.get_numbuttons()
axes = joystick.get_numaxes()
#print(i, hat)
if nr == 0 and Game.player1.lives > 0: # player1
x,y = hat
if x==-1: # turn left
Game.player1.rotate(dt, clockwise=False)
if x==1: # turn right
Game.player1.rotate(dt, clockwise=True)
if y == 1: # forward
Game.player1.forward(dt)
#for i in range(buttons):
# button = joystick.get_button(i)
# #print(i, button)
if joystick.get_button(0):
# blue button is pressed
#Bullet(Game.player1)
Game.player1.shoot()
# print axes
#for i in range(axes):
# axis = joystick.get_axis(i)
# print(i, axis)
deadzone = 0.1
# rotate
power = joystick.get_axis(0)
if power > deadzone:
Game.player1.rotate(dt, clockwise=True, power=abs(power))
elif power < -deadzone:
Game.player1.rotate(dt, clockwise=False, power=abs(power))
# forward
power = joystick.get_axis(1)
if power < -deadzone:
Game.player1.forward(dt, abs(power))
# move everything in scrollgroup according to player.move
for thing in Game.scrollgroup:
#thing.pos -= Game.player1.move
thing.rect.topleft = thing.pos - Game.screenpos
# stars
for star in Game.stargroup:
star.pos.x += Game.player1.move.x * star.pos.z
star.pos.y += Game.player1.move.y * star.pos.z
star.rect.center = pygame.Vector2(star.pos.x, star.pos.y) - Game.screenpos
# spritegroups
if len(Game.playergroup) > 0: # at least one player is alive
#if keys[pygame.K_0]:
Game.allgroup.clear(Game.screen, Game.background)
Game.allgroup.update(dt)
for s in Game.allgroup:
s.dirty = True
dirty = Game.allgroup.draw(Game.screen)
pygame.display.update(dirty)
##Game.screen.blit(Game.ui_layer, (0,0))
else: # all players are dead -> Game Over mode
Game.allgroup.update(dt)
#for s in allgroup:
# s.dirty = True
#dirty= allgroup.draw(screen)
for s in Game.allgroup:
topleft = s.rect.topleft
Game.screen.blit(s.image, topleft)
#pygame.display.update(dirty)
#allgroup.repaint_rect(screen.get_rect())
##Game.screen.blit(Game.ui_layer, (0, 0))
pygame.display.flip()
#pygame.display.flip()
if len(Game.aliengroup) == 0:
time_without_ufo += dt
if time_without_ufo > Game.ufo_timeout:
time_without_ufo = 0
Ufo()
# limits FPS to 60
# dt is delta time in seconds since last frame, used for framerate-
# independent physics.
dt = Game.clock.tick(Game.FPS) / 1000
pygame.display.set_caption(f"fps: {Game.clock.get_fps():.2f} resolution: {W}x{H} lives: {Game.player1.lives} u:{Game.player1.unverwundbar:.2f}")
if __name__ == "__main__":
setup()
load_assets()
mainloop()
pygame.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment