def update(self, dt, events): super().update(dt, events) if self.velocity == [0, 0]: angle = random.random()*math.pi*2 self.velocity[0] = math.sin(angle) * self.speed self.velocity[1] = math.cos(angle) * self.speed mag = c.mag(*self.velocity) if mag < self.speed: self.velocity[0] *= self.speed/mag self.velocity[1] *= self.speed/mag
def bump_tile(self, x, y): dx = x - self.x dy = y - self.y if math.sqrt(dx**2 + dy**2) > 1.5 * c.TILE_SIZE + self.radius: return False else: did_something = False decel = 0.2 if hasattr(self, "bounces"): decel = 1.0 if type(self) is BounceEnemy: decel = 1 if -c.TILE_SIZE//2 < dx < c.TILE_SIZE//2: if 0 < dy < self.radius + c.TILE_SIZE//2: self.y = y - c.TILE_SIZE//2 - self.radius - 1 self.velocity[1] *= -decel did_something = True if 0 > dy > -self.radius - c.TILE_SIZE//2: self.y = y + c.TILE_SIZE//2 + self.radius + 1 self.velocity[1] *= -decel did_something = True if -c.TILE_SIZE//2 < dy < c.TILE_SIZE//2: if 0 < dx < self.radius + c.TILE_SIZE//2: self.x = x - c.TILE_SIZE//2 - self.radius - 1 self.velocity[0] *= -decel did_something = True if 0 > dx > -self.radius - c.TILE_SIZE//2: self.x = x + c.TILE_SIZE//2 + self.radius + 1 self.velocity[0] *= -decel did_something = True if did_something: if hasattr(self, "bounces"): self.bounces += 1 return True for corner in [(-1, -1), (1, -1), (-1, 1), (1, 1)]: cx = x + corner[0] * c.TILE_SIZE//2 cy = y + corner[1] * c.TILE_SIZE//2 if math.sqrt((self.x - cx)**2 + (self.y - cy)**2) < self.radius: dcx = cx - self.x dcy = cy - self.y unit_mag = c.mag(dcx, dcy) if not unit_mag: continue self.x = cx - (self.radius+1) * dcx/unit_mag self.y = cy - (self.radius+1) * dcy/unit_mag if abs(dcy) < abs(dcx): self.velocity[0] *= -decel else: self.velocity[1] *= -decel if hasattr(self, "bounces"): self.bounces += 1 return True return False
def check_tile_collisions(self): if self.game.room is None: return else: x, y = self.game.room.world_to_cell(self.x, self.y, discrete=True) for cell_x in [x - 1, x, x + 1]: for cell_y in [y - 1, y, y + 1]: if self.game.room.cell_is_blocking(cell_x, cell_y): real_x, real_y = self.game.room.cell_to_world( cell_x, cell_y) if self.bump_tile(real_x, real_y): if c.mag(*self.velocity) > 5: self.game.bounce_noise.play() return
def bump_tile(self, x, y): dx = x - self.x dy = y - self.y if math.sqrt(dx**2 + dy**2) > 1.5 * c.TILE_SIZE + self.radius: return False else: did_something = False decel = 0.4 if self.has_powerup(c.SLIPPERY_SOCKS): decel = 0.7 if -c.TILE_SIZE // 2 < dx < c.TILE_SIZE // 2: if 0 < dy < self.radius + c.TILE_SIZE // 2: self.y = y - c.TILE_SIZE // 2 - self.radius self.velocity[1] *= -decel did_something = True if 0 > dy > -self.radius - c.TILE_SIZE // 2: self.y = y + c.TILE_SIZE // 2 + self.radius self.velocity[1] *= -decel did_something = True if -c.TILE_SIZE // 2 < dy < c.TILE_SIZE // 2: if 0 < dx < self.radius + c.TILE_SIZE // 2: self.x = x - c.TILE_SIZE // 2 - self.radius self.velocity[0] *= -decel did_something = True if 0 > dx > -self.radius - c.TILE_SIZE // 2: self.x = x + c.TILE_SIZE // 2 + self.radius self.velocity[0] *= -decel did_something = True if did_something: return True for corner in [(-1, -1), (1, -1), (-1, 1), (1, 1)]: cx = x + corner[0] * c.TILE_SIZE // 2 cy = y + corner[1] * c.TILE_SIZE // 2 if math.sqrt((self.x - cx)**2 + (self.y - cy)**2) < self.radius: dcx = cx - self.x dcy = cy - self.y unit_mag = c.mag(dcx, dcy) if not unit_mag: continue self.x = cx - self.radius * dcx / unit_mag self.y = cy - self.radius * dcy / unit_mag if abs(dcy) < abs(dcx): self.velocity[0] *= -decel else: self.velocity[1] *= -decel return True return False
def update(self, dt, events): x, y, w, h = self.game.room.get_rect() if self.x > x + w or self.y > y + h or self.x < x or self.y < y: self.x, self.y = c.WINDOW_WIDTH // 2, c.WINDOW_HEIGHT // 2 pygame.display.set_caption( "Spinnerets (definitely not riddled with bugs)") for effect in self.effects[::-1]: effect.update(dt, events) self.since_damage += dt self.controller.update(dt, events) self.since_fire += dt if self.since_fire >= self.temp_sail_time: self.sailing = False if self.controller.is_pressed(): self.down() if self.controller.is_released(): self.up() self.check_bullet_collisions() self.check_player_collisions() mag = c.mag(self.velocity[0], self.velocity[1]) if not self.sailing and mag and not self.has_powerup(c.SLIPPERY_SOCKS): self.velocity[0] = self.velocity[0] * 0.002**dt self.velocity[1] = self.velocity[1] * 0.002**dt if self.has_powerup(c.SLIPPERY_SOCKS): max_speed = 400 if mag > max_speed: self.velocity[0] *= max_speed / mag self.velocity[1] *= max_speed / mag self.x += self.velocity[0] * dt self.y += self.velocity[1] * dt self.angle += self.get_spin_velocity() * dt if self.charging: speed = 1 / self.get(CHARGE_TIME) self.charged += speed * dt if self.charged > 1: self.charged = 1 if self.dead: self.props[SPIN_SPEED] *= 0.2**dt self.check_tile_collisions()
def check_player_collisions(self): for player in self.game.current_scene.players: if player is self: continue else: dx = player.x - self.x dy = player.y - self.y mag = c.mag(dx, dy) if mag < self.radius + player.radius - 2: if not mag: continue bump_amt = 200 x = dx / mag * bump_amt y = dy / mag * bump_amt self.bump_vel(-x, -y) player.bump_vel(x, y) self.x = player.x - (self.radius + player.radius) * dx / mag self.y = player.y - (self.radius + player.radius) * dy / mag
def check_collisions(self): for player in self.game.current_scene.players: if c.mag(player.x - self.x, player.y - self.y) < player.radius + self.radius and self.landed: self.collected_by(player) break