def is_colliding_with_player(self, player): # can't collide if you're dead if self.dead: return False dist = c.distance_between_points(self.x, self.y, player.x, player.y) dist -= self.radius if dist < player.collision_radius: return True return False # test center of circle inside player if self.x < player.x + player.width//2: if self.x > player.x - player.width//2: if self.y < player.y + player.height//2: if self.y > player.y - player.height//2: return True # test collision in cardinal directions if self.x < player.x + player.width//2 and self.x > player.x - player.width//2: # top if self.y < player.y: if self.y > player.y - player.height//2 - self.radius: return True # bottom if self.y > player.y: if self.y < player.y + player.height//2 + self.radius: return True if self.y < player.y + player.height//2 and self.y > player.y - player.height//2: # left if self.x < player.x: if self.x > player.x - player.width//2 - self.radius: return True # right if self.x > player.x: if self.x < player.x + player.width//2 + self.radius: return True # test collisions with corners c1 = player.x - player.width//2, player.y - player.height//2 c2 = player.x + player.width//2, player.y - player.height//2 c3 = player.x - player.width//2, player.y + player.height//2 c4 = player.x + player.width//2, player.y + player.height//2 corners = (c1, c2, c3, c4) for item in corners: if c.distance_between_points(self.x, self.y, *item) < self.radius: return True return False
def update(self, dt, events): self.age += dt if self.age >= 0.2: if self.door_speed == 0: self.game.door_close.play() self.door_speed -= dt * 10 self.doors_open = min(max(0, self.doors_open + self.door_speed * dt), 1) if self.age >= 3: self.moving = True self.x -= self.game.scroll_speed * dt if self.moving: if c.distance_between_points(*self.shake_target, * self.shake_position) < 5: self.shake_position = [ random.random() * 2 - 1, random.random() * 2 - 1 ] dx = self.shake_target[0] - self.shake_position[0] dy = self.shake_target[1] - self.shake_position[1] self.shake_position[0] += dx * 2 self.shake_position[1] += dy * 2 self.speed += self.accel * dt self.x += self.speed * dt pass
def update_pickups(self, dt, events): for item in self.game.pickups[::-1]: item.update(dt, events) if c.distance_between_points( item.x, item.y, self.player.x, self.player.y) < self.player.width // 2: item.get() self.game.pickups.remove(item)
def check_player_bullets(self): if self.dead: return to_destroy = set() for item in self.game.player.bullets: if c.distance_between_points(item.x, item.y, self.x, self.y) < item.radius + self.radius: self.get_hit_by(item) to_destroy.add(item) self.game.player.bullets -= to_destroy
def update(self, dt, events): if pygame.mouse.get_pressed()[0]: self.shoot() if self.hit_circle_radius < 1000: self.hit_circle_radius += 2500 * dt if self.movement_enabled: self.y_velocity += 2500 * dt self.y += self.y_velocity * dt self.x_velocity *= 0.0005**dt self.x += self.x_velocity * dt self.bullet_cooldown += dt self.since_hit += dt if self.since_hit >= 0.05 and not self.dead: self.sprite.start_animation("Running") self.collide_corridor(self.game.corridor) self.update_movement(dt, events) to_destroy = set() for bullet in self.bullets: bullet.update(dt, events) margin = 30 if bullet.x > c.WINDOW_WIDTH + margin or bullet.y > c.WINDOW_HEIGHT + margin or \ bullet.x < -margin or bullet.y < -margin: to_destroy.add(bullet) self.bullets -= to_destroy self.sprite.update(dt) mindist = 800 for enemy in self.game.enemies: if enemy.dead or self.dead: continue dist = c.distance_between_points(self.x, self.y, enemy.x, enemy.y) dist -= enemy.radius + 32 if dist < mindist: mindist = dist if mindist < 0: mindist = 0 self.game.slowdown = min(0.4 + 0.6 * mindist / 130, 1)
def update(self, dt, events): self.age += dt self.doors_open = min(max(0, self.doors_open + self.door_speed * dt), 1) self.x -= self.game.scroll_speed * dt if self.x <= c.WINDOW_WIDTH: self.game.scroll_speed = min(self.game.scroll_speed, (self.x + 430 - c.WINDOW_WIDTH / 3)) if self.moving: if c.distance_between_points(*self.shake_target, * self.shake_position) < 5: self.shake_position = [ random.random() * 2 - 1, random.random() * 2 - 1 ] dx = self.shake_target[0] - self.shake_position[0] dy = self.shake_target[1] - self.shake_position[1] self.shake_position[0] += dx * 2 self.shake_position[1] += dy * 2 self.speed += self.accel * dt self.x += self.speed * dt
def main(self): self.car_surf = pygame.image.load("images/subway_car_interior.png") clock = pygame.time.Clock() self.age = 0 self.shake_target = [0, 0] self.shake_pos = [1, 0] self.shake_amp = 15 self.shade = pygame.Surface(c.WINDOW_SIZE) self.shade.fill(c.BLACK) self.shade.set_alpha(255) self.shade_alpha = 1.0 self.shade_target_alpha = 0 self.proceed = False self.popup_age = 0 self.popup_visible = True self.title = pygame.image.load("images/title.png") self.title = pygame.transform.scale(self.title, (self.title.get_width()*2, self.title.get_height()*2)) self.frame = pygame.image.load("images/frame.png") self.game.bus_ride.play(-1) self.game.battle_music.fadeout(400) self.since_train = 10 while True: dt = clock.tick(60)/1000 if dt > 1/30: dt = 1/30 events = self.game.update_globals() self.age += dt self.since_train += dt if self.since_train > 5: self.game.muffled_train.play() self.since_train = 0 if self.popup_visible: self.popup_age += dt speed = 2 if self.shade_alpha > self.shade_target_alpha: self.shade_alpha = max(0, self.shade_alpha - speed*dt) elif self.shade_alpha < self.shade_target_alpha: self.shade_alpha = min(1.0, self.shade_alpha + speed*dt) self.shade.set_alpha(self.shade_alpha * 255) dx = self.shake_target[0] - self.shake_pos[0] dy = self.shake_target[1] - self.shake_pos[1] self.shake_pos[0] += dx*dt*4 self.shake_pos[1] += dy*dt*4 if c.distance_between_points(*self.shake_pos, *self.shake_target) < 2: self.shake_target = [random.random()*2 - 1, random.random()*2 - 1] self.game.screen.fill(c.BLACK) self.draw_subway_car(self.game.screen) text = "PRESS ENTER TO BEGIN" if time.time() % 1 < 0.7: surf = self.game.ledger_font.render(text, 0, (c.WHITE)) x = c.WINDOW_WIDTH//2 - surf.get_width()//2 y = c.WINDOW_HEIGHT - 40 self.game.screen.blit(surf, (x, y)) for event in events: if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN: if self.proceed == False: self.proceed = True self.game.press_enter.play() x = c.WINDOW_WIDTH//2 - self.title.get_width()//2 y = 40 self.game.screen.blit(self.title, (x, y)) self.game.screen.blit(self.shade, (0, 0)) pygame.display.flip() if self.proceed: if not self.game.first_play: self.game.bus_ride.fadeout(500) self.game.muffled_train.fadeout(500) self.shade_target_alpha = 1 if self.shade_alpha == 1 and self.shade_target_alpha == 1: self.game.level = 1 self.game.score = 0 break