Last active
October 7, 2024 16:42
-
-
Save horstjens/86f66f300fa8137d3a24b3440e2d895d to your computer and use it in GitHub Desktop.
asteroids14
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
import random | |
import os.path | |
# done: ufo more pretty, triangular windows | |
# done: ufo change colors | |
# TODO: impact on asteroid changes speed of asteroid | |
# TODO: asteroid shall change color to indicate loosing hitpoints | |
W, H = 1280, 720 | |
class TextSprite(pygame.sprite.DirtySprite): | |
def __init__(self, pos, color, textsize, text, age_max ): | |
self.dirty = True | |
self.visible = True | |
self.blendmode = 0 | |
self._layer = 9 | |
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 | |
self.rect.center = 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) | |
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) | |
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) | |
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) | |
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) | |
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) | |
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 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) | |
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.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 = 5.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): | |
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()) | |
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 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.grace: | |
p = self.unverwundbar / 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: | |
self.time_since_last_bullet = 0 | |
Bullet(self) | |
def update(self, dt ): | |
self.time_since_last_bullet += dt | |
# friction | |
if self.unverwundbar <= 0: | |
self.image = self.image1.copy() | |
else: | |
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.999 | |
# speed limit | |
self.pos += self.move * dt | |
if self.move.length() > self.speed_limit: | |
self.move = self.move.normalize() * self.speed_limit | |
# 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.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() | |
allgroup = pygame.sprite.LayeredDirty() | |
def create_background(): | |
Game.background = pygame.Surface((W, H)) | |
for _ in range(200): | |
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 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") | |
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() | |
#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",None) | |
w,h = Game.scoretext1.image.get_rect().size | |
Game.scoretext1.pos = pygame.Vector2(w/2,h/2) | |
#new_wave() | |
def mainloop(): | |
running = True | |
dt = 0 | |
time_without_ufo = 0 | |
Game.screen.blit(Game.background, (0,0)) | |
pygame.display.flip() # once! | |
while running: | |
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 | |
if player.unverwundbar <= 0: | |
crashgroup = pygame.sprite.spritecollide(player, Game.rocketgroup, False) | |
for r in crashgroup: | |
impactpoint = pygame.sprite.collide_mask(player, r) | |
if impactpoint is not None: | |
player.hitpoints -= 1 | |
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 | |
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 += 1 | |
Game.scoretext1.create_text(f"Score: {b.shooter.score}") | |
ufo.hitpoints -= 1 | |
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: | |
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 | |
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 | |
# 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) | |
# 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)) | |
# 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) | |
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()) | |
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