Jun-06-2024, 07:22 PM
Hello,
I'm currently programming a small game and, apart from 2 topics, I'm almost finished. There is one topic I would like to ask about today. When an enemy is hit by a missile, an explosion animation occurs. I would like the final image of the explosion to collide with other enemies and cause them to explode as well. Unfortunately I haven't been able to fully implement it yet.
In the class Explosion all explosions with the size 1 to 4 are yellow (I use yellow images).
When the rocket Explosion hits some enemies, the enemies shall explode with a red animation. The reason is that you can differentiate the small explosions of the enemies from the big one of the rocket explosion. If they would have all the same color then you perhaps can't notice it.
In the class RocketExplosion I'm trying to check for collisions between the last image of the rocket explosion ("explosion7.png") and the enemies in the update method.
But I think the check for collisions should be in the class Explosion in the for loop (# rocket hits alien). When the rocket hits an alien the big explosion (size 4) is created.
There the picture "explosion7.png" occurs. "explosion7.png" shall be a sprite and at this place the collision detection, should be done.
It would be great, if I could get a hint how this could be done.
Thanks a lot in advance for your help!!
I'm currently programming a small game and, apart from 2 topics, I'm almost finished. There is one topic I would like to ask about today. When an enemy is hit by a missile, an explosion animation occurs. I would like the final image of the explosion to collide with other enemies and cause them to explode as well. Unfortunately I haven't been able to fully implement it yet.
In the class Explosion all explosions with the size 1 to 4 are yellow (I use yellow images).
When the rocket Explosion hits some enemies, the enemies shall explode with a red animation. The reason is that you can differentiate the small explosions of the enemies from the big one of the rocket explosion. If they would have all the same color then you perhaps can't notice it.
In the class RocketExplosion I'm trying to check for collisions between the last image of the rocket explosion ("explosion7.png") and the enemies in the update method.
But I think the check for collisions should be in the class Explosion in the for loop (# rocket hits alien). When the rocket hits an alien the big explosion (size 4) is created.
There the picture "explosion7.png" occurs. "explosion7.png" shall be a sprite and at this place the collision detection, should be done.
It would be great, if I could get a hint how this could be done.
Thanks a lot in advance for your help!!
import pygame from PIL import Image from pygame import mixer from pygame.locals import * import random, math from itertools import product pygame.mixer.pre_init(44100, -16, 2, 512) mixer.init() pygame.init() # define fps clock = pygame.time.Clock() fps = 60 screen_width = 1280 screen_height = 720 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption('Space Invaders') # define fonts font30 = pygame.font.SysFont('Constantia', 30) font40 = pygame.font.SysFont('Constantia', 40) alien_cooldown = 1000 # bullet cooldown in milliseconds last_count = pygame.time.get_ticks() last_alien_shot = pygame.time.get_ticks() # define colours red = (255, 0, 0) green = (0, 255, 0) white = (255, 255, 255) # load image bg = pygame.image.load("bg.png") screen_rect = bg.get_rect() def draw_bg(): screen.blit(bg, (0, 0)) # define function for creating text def draw_text(text, font, text_col, x, y): img = font.render(text, True, text_col) screen.blit(img, (x, y)) ################ space invaders things ############################################################################### # create spaceship class class Spaceship(pygame.sprite.Sprite): def __init__(self, x, y, health): pygame.sprite.Sprite.__init__(self) self.x = x self.y = y self.health_start = health self.health_remaining = health self.image = pygame.image.load("ship.png") self.rect = self.image.get_rect() self.rect.center = x, y self.xmin = self.rect.width // 2 # Compute Spaceship x range. self.xmax = screen_width - self.xmin self.last_shot = pygame.time.get_ticks() def move(self, xpos): self.xpos = xpos self.rect.centerx = max(self.xmin, min(self.xmax, xpos)) def update(self): # set a cooldown variable cooldown = 500 # milliseconds game_over = 0 # record current time time_now = pygame.time.get_ticks() # shoot, get key press key = pygame.key.get_pressed() if key[pygame.K_SPACE] and time_now - self.last_shot > cooldown: # single bullet single_bullet = SingleBullets(self.rect.centerx, self.rect.top) single_bullet_group.add(single_bullet) self.last_shot = time_now # for later use (double bullets) # bullet_1 = Bullets(self.rect.centerx - 43, self.rect.top) # bullet_2 = Bullets(self.rect.centerx + 43, self.rect.top) # update mask self.mask = pygame.mask.from_surface(self.image) # draw health bar pygame.draw.rect(screen, red, (self.rect.x, (self.rect.bottom + 10), self.rect.width, 15)) if self.health_remaining > 0: pygame.draw.rect(screen, green, ( self.rect.x, (self.rect.bottom + 10), int(self.rect.width * (self.health_remaining / self.health_start)), 15)) elif self.health_remaining <= 0: explosion = Explosion(self.rect.centerx, self.rect.centery, 3, "yellow") explosion_group.add(explosion) self.kill() game_over = -1 return game_over # create player spaceship = Spaceship(screen_width / 2, screen_height - 100, 3) # create SingleBullets class class SingleBullets(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.x = x self.y = y weapon_list = ["bullet.png", "flash.png", "rocket.png"] self.chosen = random.choice(weapon_list) self.image = pygame.image.load(self.chosen) self.rect = self.image.get_rect() self.rect.center = x, y def update(self): self.rect.y -= 5 if self.rect.bottom < 0: self.kill() hits = pygame.sprite.spritecollide(self, alien_group, True, pygame.sprite.collide_mask) if hits: self.kill() for alien in hits: x, y = alien.hit() if self.chosen == "rocket.png": explosion = Explosion(x, y, 4, "yellow") else: explosion = Explosion(x, y, 2, "yellow") explosion_group.add(explosion) # create RocketExplosion class # for hits between aliens and rocket explosion class RocketExplosion(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) # this is the last image of the rocket's explosion, it self.image = pygame.image.load("explosion7.png") self.rect = self.image.get_rect() self.rect.center = x, y def update(self): hits_rocket_expl_and_alien_group = pygame.sprite.spritecollide(self, alien_group, True, pygame.sprite.collide_mask) if hits_rocket_expl_and_alien_group: for alien in hits_rocket_expl_and_alien_group: x, y = alien.hit() explosion = Explosion(x, y, 2, "red") alien_red_explosion_group.add(explosion) # create Aliens class class Aliens(pygame.sprite.Sprite): def __init__(self, x, y, move_direction): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("alien" + str(random.randint(1, 6)) + ".png") self.x = x self.y = y self.move_direction = move_direction self.rect = self.image.get_rect() self.rect.center = x, y def hit(self): x = self.rect.centerx y = self.rect.centery self.kill() return x, y def update(self, move_direction): self.rect.x += self.move_direction if self.rect.right >= screen_width or self.rect.left <= 0: self.move_direction = -self.move_direction self.rect.y += 10 # update mask self.mask = pygame.mask.from_surface(self.image) # create Alien Bullets class class Alien_Bullets(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("alien_bullet.png") self.rect = self.image.get_rect() self.rect.center = x, y def update(self): self.rect.y += 2 if self.rect.top > screen_height: self.kill() if pygame.sprite.spritecollide(self, spaceship_group, False, pygame.sprite.collide_mask): self.kill() # explosion2_fx.play() # reduce spaceship health spaceship.health_remaining -= 1 explosion = Explosion(self.rect.centerx, self.rect.centery, 1, "yellow") explosion_group.add(explosion) # create Explosion class class Explosion(pygame.sprite.Sprite): def __init__(self, x, y, size, color): pygame.sprite.Sprite.__init__(self) self.images = [] if color == "yellow": for num in range(1, 8): img = pygame.image.load(f"explosion{num}.png") # ship is hit if size == 1: img = pygame.transform.scale(img, (20, 20)) # alien is hit if size == 2: img = pygame.transform.scale(img, (100, 100)) # ship gameover if size == 3: img = pygame.transform.scale(img, (160, 160)) # rocket hits alien if size == 4: img = pygame.transform.scale(img, (500, 500)) # add the image to the list self.images.append(img) self.index = 0 self.image = self.images[self.index] self.rect = self.image.get_rect() self.rect.center = x, y self.counter = 0 # add the image to the list if color == "red": # rocketExplosion hits alien, it occurs a red explosion for num1 in range(1, 8): img = pygame.image.load(f"explosion2_{num1}.png") img = pygame.transform.scale(img, (100, 100)) # add the image to the list self.images.append(img) self.index = 0 self.image = self.images[self.index] self.rect = self.image.get_rect() self.rect.center = x, y self.counter = 0 def update(self): explosion_speed = 3 # update explosion animation self.counter += 1 if self.counter >= explosion_speed and self.index < len(self.images) - 1: self.counter = 0 self.index += 1 self.image = self.images[self.index] # if the animation is complete, delete explosion if self.index >= len(self.images) - 1 and self.counter >= explosion_speed: self.kill() # create sprite groups spaceship_group = pygame.sprite.Group() spaceship_group.add(spaceship) paddle_group = pygame.sprite.Group() ball_group = pygame.sprite.Group() single_bullet_group = pygame.sprite.Group() flash_group = pygame.sprite.Group() alien_group = pygame.sprite.Group() alien_bullet_group = pygame.sprite.Group() explosion_group = pygame.sprite.Group() rocket_explosion_group = pygame.sprite.Group() # a different red explosion alien_red_explosion_group = pygame.sprite.Group() lives_group = pygame.sprite.Group() def create_aliens(rows, cols, move_direction): # generate aliens for row in range(rows): for item in range(cols): alien = Aliens(100 + item * 100, 100 + row * 100, move_direction) alien_group.add(alien) def play_space_invaders(level, move_direction): game_over = 0 create_aliens(4, 10, move_direction) last_count = pygame.time.get_ticks() last_alien_shot = pygame.time.get_ticks() countdown = 3 run = True while run: clock.tick(fps) # draw background draw_bg() # space invaders single bullets level if countdown == 0: # create random alien bullets # record current time time_now = pygame.time.get_ticks() # shoot if time_now - last_alien_shot > alien_cooldown and len(alien_bullet_group) < 5 and len( alien_group) > 0: attacking_alien = random.choice(alien_group.sprites()) alien_bullet = Alien_Bullets(attacking_alien.rect.centerx, attacking_alien.rect.bottom) alien_bullet_group.add(alien_bullet) last_alien_shot = time_now # check if all the aliens have been killed if len(alien_group) == 0: game_over = 1 level += 1 return level if game_over == 0: # update spaceship game_over = spaceship.update() # update sprite groups single_bullet_group.update() alien_group.update(move_direction) alien_bullet_group.update() explosion_group.update() rocket_explosion_group.update() alien_red_explosion_group.update() else: if game_over == -1: draw_text('GAME OVER!', font40, white, int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if game_over == 1: draw_text('YOU WIN!', font40, white, int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if countdown > 0: draw_text('GET READY!', font40, white, int(screen_width / 2 - 110), int(screen_height / 2 + 50)) draw_text(str(countdown), font40, white, int(screen_width / 2 - 10), int(screen_height / 2 + 100)) count_timer = pygame.time.get_ticks() if count_timer - last_count > 1000: countdown -= 1 last_count = count_timer # update explosion group explosion_group.update() rocket_explosion_group.update() alien_red_explosion_group.update() # draw sprite groups spaceship_group.draw(screen) single_bullet_group.draw(screen) alien_group.draw(screen) alien_bullet_group.draw(screen) explosion_group.draw(screen) rocket_explosion_group.draw(screen) alien_red_explosion_group.draw(screen) # event handlers for event in pygame.event.get(): if event.type == pygame.QUIT: run = False elif event.type == pygame.MOUSEMOTION: # space invaders level spaceship.move(event.pos[0]) pygame.display.flip() pygame.quit()