def make_explosion(self, explosions): if self.is_big_bomb: explosions.append( Explosion(self.position, pygame.Color(200, 50, 50, 255), 20, 75.0)) else: explosions.append( Explosion(self.position, pygame.Color(40, 30, 30, 255), 10, 50.0))
def update_movement_and_collision(self, tiled_level, collideable_tiles, players, monsters, time_delta, time_multiplier, new_explosions, explosions): if self.is_ai_bullet: for player in players: if player.test_projectile_collision(self.sprite.rect): self.should_die = True else: for monster in monsters: if monster.test_projectile_collision(self.sprite.rect): self.should_die = True for tile_x in range(tiled_level.zero_tile_x, tiled_level.end_tile_x): for tile_y in range(tiled_level.zero_tile_y, tiled_level.end_tile_y): tile = tiled_level.tile_grid[tile_x][tile_y] if tile.test_projectile_collision(self.sprite.rect): self.should_die = True self.shot_range -= time_delta * time_multiplier * self.bullet_speed self.world_position[0] += (self.current_vector[0] * time_delta * time_multiplier * self.bullet_speed) self.world_position[1] += (self.current_vector[1] * time_delta * time_multiplier * self.bullet_speed) self.world_rect.center = self.world_position self.position[ 0] = self.world_position[0] - tiled_level.position_offset[0] self.position[ 1] = self.world_position[1] - tiled_level.position_offset[1] self.sprite.rect.center = self.position if self.shot_range <= 0.0: self.should_die = True # calc facing angle direction_magnitude = math.sqrt(self.current_vector[0]**2 + self.current_vector[1]**2) unit_dir_vector = [0, 0] if direction_magnitude > 0.0: unit_dir_vector = [ self.current_vector[0] / direction_magnitude, self.current_vector[1] / direction_magnitude ] facing_angle = math.atan2(-unit_dir_vector[0], -unit_dir_vector[1]) * 180 / math.pi bullet_centre_position = self.sprite.rect.center self.image = pygame.transform.rotate(self.original_image, facing_angle) self.sprite.rect = self.image.get_rect() self.sprite.rect.center = bullet_centre_position if self.should_die: new_explosion = Explosion(self.world_position, self.explosions_sprite_sheet, 96, self.damage, DamageType.MISSILE) new_explosions.append(new_explosion) explosions.append(new_explosion)
def update_movement_and_collision(self, monsters, time_delta, new_explosions, explosions): self.shot_range -= time_delta * self.bullet_speed self.shot_distance_acc += time_delta * self.bullet_speed self.position[0] += (self.current_vector[0] * time_delta * self.bullet_speed) self.position[1] += (self.current_vector[1] * time_delta * self.bullet_speed) self.rect.center = (int(self.position[0]), int(self.position[1])) if self.shot_range <= 0.0: self.should_die = True if self.shot_distance_acc >= self.current_puff_gap: new_explosion = Explosion(self.position, self.explosions_sprite_sheet, self.current_puff_radius, self.damage, DamageType.FIRE, self.collision_grid) new_explosions.append(new_explosion) explosions.append(new_explosion) self.current_puff_radius += 3 self.current_puff_gap += self.current_puff_radius - 2
def tick(self): ground = self.gs.height - self.gs.get_height(self.rect.centerx) # if not hit anything, keep going if not self.hit_detect(): acc = GRAVITY + self.gs.wind self.vel += acc # Used numpy objects for easy matrix operations (N dimensionality!) self.pos += self.vel.astype(np.int) self.pos[0] = self.pos[0] % self.gs.width self.rect.center = self.pos # explode on contact else: # To avoid double explosions, we only remove blocks on one game, then # send which blocks to remove to the other. Small overhead for this, only 2 ints of data if self.isEnemy: self.gs.player2.bcount -= 1 else: self.gs.player1.bcount -= 1 if self.gs.isServer: self.gs.remove_blocks( self.pos[0], self.pos[1]) # remove the blocks from the map data = pickle.dumps( self.pos ) # serialize the data (might be overkill here but we wanted to be consistent) self.gs.terrainConnection.transport.write(data) self.gs.gameobjects.append(Explosion( self.gs, self.pos)) # create a new explosion object as a result # If there are too many bullets on the screen this might throw and exception try: self.gs.gameobjects.remove(self) # get rid of the bullet except ValueError: pass
def bullet_shooting_update(self, bullet, bullets, hit_list_tank, hit_list_wall): """ Updates bullets and explosions. Args: bullet: the length of the sprite list bullets: individual bullet objects hit_list_tank: list of tanks that were hit hit_list_wall: list of bullets that hit a wall Contributors: Reed Hunsaker Adrianna Lund Isabel Aranguren Jordan McIntyre """ if len(hit_list_wall) > 0: self.bullet.bullet_bounce(bullet, bullet.angle) if len(hit_list_tank) > 0: for tank in self.tanks.sprite_list: life = tank.get_life() explosion = Explosion(self.explosion_texture_list) # set explosion center to location of first hit in list explosion.center_x = hit_list_tank[0].center_x explosion.center_y = hit_list_tank[0].center_y # update explosion (sets first image) explosion.update() self.explosions_list.append(explosion) # if bullet leaves screen, kill it elif bullet.bottom > constants.SCREEN_HEIGHT or bullet.top < 0 or bullet.right < 0 or bullet.left > constants.SCREEN_WIDTH: bullet.kill() bullets -= 1 # play sound and kill bullet from hit lists for tank in hit_list_tank: tank.set_life(-25) arcade.play_sound(self.tank_explode, .5) bullet.kill() bullets -= 1
def create_explosion(self, position, size=32): self.explosions.append( Explosion(position, size, self.explosions_sprite_sheet, self.all_explosion_sprites))
def createExplosion( self, name, pos, animationSpeed ): self.loadUnit( name ) someExplosion = Explosion( name, pos, animationSpeed ) someExplosion.maxAnimationScenes = self.myImgMngr.getMaxAnimationScenes( name, 'a' ) self.addEntity( someExplosion ) return someExplosion
def on_update(self, delta_time: float): """ Updates the game screen. Args: self (Gameview): instance of Gameview delta_time: essential for updates to run Contributors: Reed Hunsaker Adrianna Lund Isabel Aranguren Jordan McIntyre """ # if game is ending - update the last explosion, then go to the game over view if self.game_ending: self.explosions_list.update() if not self.explosions_list: self.switch_game_over_view(self.name) return self.physics_engine.update() self.physics_engine2.update() self.physics_engine3.update() self.explosions_list.update() # handle bullet collisions bullets = len(self.bullet.bullet_sprite_list) if bullets > 0: for bullet in self.bullet.bullet_sprite_list: hit_list_wall = arcade.check_for_collision_with_list( bullet, self.ground.ground_sprite_list) hit_list_tank = arcade.check_for_collision_with_list( bullet, self.tanks.sprite_list) self.bullet_shooting_update(bullet, bullets, hit_list_tank, hit_list_wall) # powerups powers = len(self.power.sprite_list) if powers > 0: for power in self.power.sprite_list: hit_list_wall = arcade.check_for_collision_with_list( power, self.ground.ground_sprite_list) hit_list_tank = arcade.check_for_collision_with_list( power, self.tanks.sprite_list) hit_list_bullet = arcade.check_for_collision_with_list( power, self.bullet.bullet_sprite_list) if len(hit_list_wall) > 0: power.kill() powers -= 1 self.power = SpawnRandom() # Paired with checker above in bullet collision checks. should destroy/block bullet if len(hit_list_bullet) > 0: if self.power.sprite_list[-1].get_value() == 2: for angle in range(0, 360, 60): self.bullet.shoot_bullet( self.power.sprite_list[-1]._get_center_x(), self.power.sprite_list[-1]._get_center_y(), angle) power.kill() powers -= 1 self.power = SpawnRandom() for tank in hit_list_tank: if self.power.sprite_list[-1].get_value() == 0: tank.set_life(-25) arcade.play_sound(self.powerdown_sound, .8) elif self.power.sprite_list[-1].get_value() == 1: tank.set_life(50) arcade.play_sound(self.powerup_sound) elif self.power.sprite_list[-1].get_value() == 2: for angle in range(0, 360, 60): bullets += 1 self.bullet.shoot_bullet(tank._get_center_x(), tank._get_center_y(), (tank.angle + angle)) power.kill() powers -= 1 self.power = SpawnRandom() # check tank health & set final explosion for tank in self.tanks.sprite_list: alive = tank.is_alive() if alive == False: self.game_ending = True self.count = 50 self.explosion_texture_list = arcade.load_spritesheet( self.file_name, self.sprite_width, self.sprite_height, self.columns, self.count) explosion = Explosion(self.explosion_texture_list) # set explosion center to location of first hit in list explosion.center_x = tank.center_x explosion.center_y = tank.center_y # update explosion (sets first image) explosion.update() self.explosions_list.append(explosion) self.name = tank.name tank.kill()
def update_movement_and_collision(self, monsters, time_delta, new_explosions, explosions): if self.homing_time_acc < self.homing_time: self.homing_time_acc += time_delta else: self.time_to_home_in = True if self.time_to_home_in: self.homing_time_acc = 0.0 self.time_to_home_in = False if self.current_target is None or self.current_target.should_die: self.current_target, self.target_distance = self.get_closest_monster_in_radius( monsters) if self.current_target is not None: self.target_distance = self.calc_distance_to_target( self.current_target) self.target_vector = self.calculate_aiming_vector( self.current_target, self.target_distance) relative_angle = self.rotate_current_angle_to_target(time_delta) self.shot_range -= time_delta * self.projectile_speed self.position[0] += (self.current_vector[0] * time_delta * self.projectile_speed) self.position[1] += (self.current_vector[1] * time_delta * self.projectile_speed) self.rect.center = (int(self.position[0]), int(self.position[1])) self.collision_shape.set_position(self.position) if self.shot_range <= 0.0: self.should_die = True if relative_angle != 0.0: direction_magnitude = math.sqrt(self.current_vector[0]**2 + self.current_vector[1]**2) unit_dir_vector = [0, 0] if direction_magnitude > 0.0: unit_dir_vector = [ self.current_vector[0] / direction_magnitude, self.current_vector[1] / direction_magnitude ] facing_angle = math.atan2(-unit_dir_vector[0], -unit_dir_vector[1]) * 180 / math.pi bullet_centre_position = self.rect.center self.image = pygame.transform.rotate(self.original_image, facing_angle) self.rect = self.image.get_rect() self.rect.center = bullet_centre_position self.collision_shape.set_rotation( math.atan2(-unit_dir_vector[0], -unit_dir_vector[1])) if self.should_die: self.collision_grid.remove_shape_from_grid(self.collision_shape) # explode at front of missile explosion_pos = [0.0, 0.0] explosion_pos[0] = self.position[0] + (self.current_vector[0] * 7.0) explosion_pos[1] = self.position[1] + (self.current_vector[1] * 7.0) new_explosion = Explosion(self.position, self.explosions_sprite_sheet, 12, self.damage, DamageType.MISSILE, self.collision_grid) new_explosions.append(new_explosion) explosions.append(new_explosion)
def main(): pygame.init() os.environ[ 'SDL_VIDEO_CENTERED'] = '1' # center the window in the middle of the screen pygame.key.set_repeat() x_screen_size = 1024 y_screen_size = 600 pygame.display.set_caption('Artillery duel') screen = pygame.display.set_mode((x_screen_size, y_screen_size)) background = pygame.image.load("images/background.png").convert() stats_base_image = pygame.image.load( "images/stats_back.png").convert_alpha() all_sprites = pygame.sprite.OrderedUpdates() all_explosion_sprites = pygame.sprite.Group() all_bullet_sprites = pygame.sprite.Group() wall_sprites = pygame.sprite.Group() font = pygame.font.Font(None, 16) large_font = pygame.font.Font(None, 64) explosions_sprite_sheet = pygame.image.load( "images/explosions.png").convert_alpha() wind = Wind(-20, 20) wind_gauge = WindGauge( [x_screen_size / 2, y_screen_size - y_screen_size * 0.10], wind.min, wind.max) bullets = [] lives_board = [] walls = [] explosions = [] ground_rect = pygame.Rect(-2000, (y_screen_size - (y_screen_size * 0.20) + 10), 3024, (y_screen_size * 0.20) + 10) # move up by floor height and half wall height walls.append( Wall([x_screen_size / 2, y_screen_size - 118 - y_screen_size * 0.20])) for wall in walls: wall_sprites.add(wall) player_lives = 10 players_to_respawn = [] players = [] start_location1 = StartLocation(int(x_screen_size * 0.05), int(x_screen_size * 0.40), (y_screen_size - y_screen_size * 0.20)) start_location2 = StartLocation(int(x_screen_size - x_screen_size * 0.40), int(x_screen_size - x_screen_size * 0.05), (y_screen_size - y_screen_size * 0.20)) player_1_id = "Player 1" player_1_lives = PlayerLives(player_1_id, player_lives, (int(x_screen_size / 2) - 100, (y_screen_size - y_screen_size * 0.13))) lives_board.append(player_1_lives) player_2_id = "Player 2" player_2_lives = PlayerLives(player_2_id, player_lives, (int(x_screen_size / 2) + 100, (y_screen_size - y_screen_size * 0.13))) lives_board.append(player_2_lives) power_gauge_1_pos = [ int(x_screen_size * 0.02), int(y_screen_size - y_screen_size * 0.13) ] power_gauge_2_pos = [ int(x_screen_size - x_screen_size * 0.02) - 300, int(y_screen_size - y_screen_size * 0.13) ] power_gauge_1 = PowerGauge(power_gauge_1_pos, 250, 18) power_gauge_2 = PowerGauge(power_gauge_2_pos, 250, 18) player_control_scheme_1 = Scheme() player_control_scheme_1.fire = K_LSHIFT player_control_scheme_1.detonate = K_LCTRL player_control_scheme_1.left = K_a player_control_scheme_1.right = K_d player_control_scheme_2 = Scheme() players.append( Player(player_1_id, start_location1, player_control_scheme_1, power_gauge_1, player_lives, PowerUps())) players.append( Player(player_2_id, start_location2, player_control_scheme_2, power_gauge_2, player_lives, PowerUps())) clock = pygame.time.Clock() running = True is_game_over = False restart_game = False win_message = "" while running: frame_time = clock.tick(60) time_delta = frame_time / 1000.0 all_sprites.empty() all_bullet_sprites.empty() all_explosion_sprites.empty() # handle UI and inout events for event in pygame.event.get(): if event.type == QUIT: running = False for player in players: player.process_event(event) if is_game_over: if event.type == KEYDOWN: if event.key == K_y: restart_game = True if restart_game: restart_game = False spawn_players(players, bullets, explosions, player_1_id, start_location1, player_control_scheme_1, power_gauge_1, player_2_id, start_location2, player_control_scheme_2, power_gauge_2, player_lives) is_game_over = False if is_game_over: for explosion in explosions: all_explosion_sprites = explosion.update_sprite( all_explosion_sprites, time_delta) explosions[:] = [ explosion for explosion in explosions if not explosion.should_die ] all_explosion_sprites.update() else: # handle re-spawning players after dying for respawning_player in players_to_respawn: if respawning_player.time_to_spawn: new_player = Player(respawning_player.player_id, respawning_player.start_location, respawning_player.control_scheme, respawning_player.power_gauge, respawning_player.current_lives, respawning_player.power_ups) new_player.activate_random_power_up() players.append(new_player) respawning_player.has_respawned = True else: respawning_player.update(frame_time) players_to_respawn[:] = [ r for r in players_to_respawn if not r.has_respawned ] # update wind wind.update(time_delta) wind_gauge.update_wind_direction_and_strength(wind.current_value) # update players and bullets for player in players: bullets = player.create_fired_bullets(bullets) player.update_movement_and_collision(bullets, lives_board, time_delta, explosions) all_sprites = player.update_sprite(all_sprites) if player.should_die: if player.current_lives > 1: players_to_respawn.append(RespawnPlayer(player)) else: for lives in lives_board: if lives.player_id == player.player_id: lives.lives = 0 is_game_over = True if player.player_id == "Player 1": win_message = "Player 2 wins!" else: win_message = "Player 1 wins!" players[:] = [ player for player in players if not player.should_die ] for bullet in bullets: bullet.update_movement_and_collision(walls, ground_rect, time_delta, wind.current_value) all_bullet_sprites = bullet.update_sprite(all_bullet_sprites) if bullet.should_die: explosions.append( Explosion(bullet.position, explosions_sprite_sheet, bullet.player_power_ups)) bullets[:] = [ bullet for bullet in bullets if not bullet.should_die ] for explosion in explosions: all_explosion_sprites = explosion.update_sprite( all_explosion_sprites, time_delta) explosions[:] = [ explosion for explosion in explosions if not explosion.should_die ] all_sprites.update() all_bullet_sprites.update() all_explosion_sprites.update() screen.blit(background, (0, 0)) # draw the background wall_sprites.draw(screen) all_sprites.draw(screen) # draw all our moving sprites all_bullet_sprites.draw(screen) # draw all our moving sprites all_explosion_sprites.draw(screen) # draw all our moving sprites power_gauge_1.draw(screen) power_gauge_2.draw(screen) wind_gauge.draw(screen, font) if is_game_over: win_message_text_render = large_font.render( win_message, True, pygame.Color("#FFFFFF")) win_message_text_render_rect = win_message_text_render.get_rect( centerx=x_screen_size / 2, centery=(y_screen_size / 2) - 128) play_again_text_render = font.render( "Play Again? Press 'Y' to restart", True, pygame.Color("#FFFFFF")) play_again_text_render_rect = play_again_text_render.get_rect( centerx=x_screen_size / 2, centery=(y_screen_size / 2) - 90) screen.blit(win_message_text_render, win_message_text_render_rect) screen.blit(play_again_text_render, play_again_text_render_rect) for lives in lives_board: screen.blit( stats_base_image, [lives.screen_position[0] - 50, lives.screen_position[1] - 18]) score_string = "Lives: " + "{:,}".format(lives.lives) score_text_render = font.render(score_string, True, pygame.Color("#FFFFFF")) score_text_render_rect = score_text_render.get_rect( centerx=lives.screen_position[0], centery=lives.screen_position[1]) screen.blit(score_text_render, score_text_render_rect) shots_value_str = "Shots: " + str(lives.shots) shots_text_render = font.render(shots_value_str, True, pygame.Color("#FFFFFF")) shots_text_render_rect = shots_text_render.get_rect( centerx=lives.screen_position[0], centery=lives.screen_position[1] + 18) screen.blit(shots_text_render, shots_text_render_rect) clusters_value_str = "Clusters: " + str(lives.clusters) clusters_text_render = font.render(clusters_value_str, True, pygame.Color("#FFFFFF")) clusters_text_render_rect = clusters_text_render.get_rect( centerx=lives.screen_position[0], centery=lives.screen_position[1] + 36) screen.blit(clusters_text_render, clusters_text_render_rect) clusters_value_str = "Blast size: " + str(lives.explosion_power) clusters_text_render = font.render(clusters_value_str, True, pygame.Color("#FFFFFF")) clusters_text_render_rect = clusters_text_render.get_rect( centerx=lives.screen_position[0], centery=lives.screen_position[1] + 54) screen.blit(clusters_text_render, clusters_text_render_rect) pygame.display.flip() # flip all our drawn stuff onto the screen pygame.quit() # exited game loop so quit pygame