def update(self, dt): if self.hover: self.hover_time += dt self.pos = self.initial_pos + ( V2(4, 0) * math.sin(self.hover_time * 1.25) + V2(0, 4) * math.cos(self.hover_time * 1.25)) if random.random() < 0.25: colors = [PICO_WHITE, PICO_BLUE, PICO_BLUE] if random.random() < 0.5: colors = [PICO_WHITE, PICO_YELLOW, PICO_YELLOW] p = Particle(colors, 1, self.pos + V2(41, 11) + helper.random_angle() * 1, 0.25, helper.random_angle() * 20) self.scene.game_group.add(p) if random.random() < 0.25: ep = self.pos + V2(19, 45) def scale_fn(t): return 1 - t e = explosion.Explosion( ep, [PICO_WHITE, PICO_LIGHTGRAY, PICO_WHITE, PICO_LIGHTGRAY], 1, random.randint(3, 6), scale_fn, velocity=V2(0, 9) + helper.random_angle() * 4) e.layer = -1 self.scene.game_group.add(e) else: self.pos = self.initial_pos return super().update(dt)
def update(self, dt): if self.hover: self.hover_time += dt self.pos = self.initial_pos + V2(1, -3) * math.sin( self.hover_time * 6) # Make an explosion for the thruster, with a random chance. if random.random() < 0.25: def scale_fn(t): return 1 - t #return math.sin(t * 3.14159) offset = V2(2, 29) if random.random() > 0.5: offset = V2(12, 32) ep = self.pos + offset + helper.random_angle() * 0 vel = V2(-7, 20) e = explosion.Explosion( ep, [PICO_WHITE, PICO_YELLOW, PICO_ORANGE, PICO_RED], 1, random.randint(2, 3), scale_fn, velocity=vel) self.scene.game_group.add(e) else: self.pos = self.initial_pos return super().update(dt)
def update(self, dt): self.pos = self.attached.pos self.ring.pos = self.attached.pos if self.radius < self.target_radius: self.radius += 1 * dt self._generate_image() self.ring.radius = self.radius + 1.5 self.ring._generate_image() if random.random() > 0.93: pos = helper.random_angle() * random.random( ) * self.radius + self.pos p = Particle([PICO_LIGHTGRAY, PICO_DARKGRAY], 1, pos, 0.25, helper.random_angle() * 3) p._layer = -1 self.scene.game_group.add(p) return super().update(dt)
def wander(self, dt): self.wander_time -= dt if self.wander_time < 0: self.wander_time = 5 self.wander_point = self.wander_center + helper.random_angle( ) * random.random() * 30 delta = self.wander_point - self.pos if delta.length_squared() < 10**2 or self.wander_time < 1: self.brake(dt) else: self.velocity += helper.try_normalize(delta) * ACCEL * dt
def update(self, dt): self.time += dt self.particle_time += dt if self.particle_time > 0.1: for res in self.resources.data.keys(): amt = self.resources.data[res] if amt > 0: pos = helper.from_angle(self.time * 2) * 6 + self.owner.pos p = particle.Particle([RESOURCE_COLORS[res]], 1, pos, amt / 100, helper.random_angle() * 2) self.owner.scene.game_group.add(p) self.particle_time = 0 return super().update(dt)
def state_stunned(self, dt): self.target_velocity = V2(0, 0) self.target_heading = self.angle + dt * 2 if self._timers['stun_time'] > 5: self.set_state(self.post_stun_state) if ((self._timers['stun_time'] + dt) * 20) % 1 < (self._timers['stun_time'] * 20) % 1: ra = helper.random_angle() p = particle.Particle( [PICO_YELLOW, PICO_BLUE, PICO_YELLOW, PICO_BLUE], 1, self.pos + ra * 4, 0.35, ra * 10) self.scene.add_particle(p)
def warp(self, warp_dist): end = self.effective_target.pos offset_dist = self.effective_target.radius + 20 delta = (end - self.pos) delta_length = delta.length() if warp_dist >= (delta_length - offset_dist) or not self.scene.flowfield.has_field( self.effective_target): maxdist = delta_length - offset_dist delta = helper.try_normalize(delta) target_pos = self.pos + delta * min(warp_dist, maxdist) else: target_pos = self.scene.flowfield.walk_field( self.pos, self.effective_target, warp_dist) for color in [PICO_BLUE, PICO_WHITE, PICO_DARKBLUE]: p = LaserParticle(self.pos + helper.random_angle() * 3, target_pos + helper.random_angle() * 3, color, random.random() / 2) self.scene.add_particle(p) self.pos = target_pos self.on_warp()
def _generate_image(self): pad = 4 amt = math.sin( clamp(self.time / self.end_time, 0, 1) * 3.14159) * self.intensity self._width = self._height = self.radius * 2 + pad * 2 self.image = pygame.Surface((self._width, self._height), pygame.SRCALPHA) x = int(self.x) y = int(self.y) src1 = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA) src1.blit(self.scene.game.screen, (0, 0), (x - self.radius, y - self.radius, self.radius * 2, self.radius * 2)) src1.blit(self.mask1, (0, 0), None, pygame.BLEND_RGBA_MULT) offset = V2(pad, pad) + helper.random_angle() * amt self.image.blit(src1, offset) self._recalc_rect()
def update(self, dt): self.new_target_timer += dt if self.new_target_timer > 0.35: self.new_target_timer = 0 self.find_new_target() if self.target: delta = (self.target.pos - self.pos).normalize() lp = LaserParticle(self.pos + delta * 6, V2(self.target.pos), PICO_PINK, 0.25) self.scene.add_particle(lp) b = bullet.Bullet(self.target.pos, self.target, self, mods={'damage_base':3 * self.planet.planet_weapon_mul}) self.scene.game_group.add(b) self.pos += delta * -2 if self.target: delta = helper.from_angle(self.angle) off = delta * 0 vel = delta * -15 + helper.random_angle() * 15 p = Particle([PICO_WHITE, PICO_PINK], 1, self.pos + off, 0.25, vel) self.scene.game_group.add(p) return super().update(dt)
def update(self, dt): if self.constructed: return super().update(dt) else: if not self.updated_color: self.update_color() self.updated_color = True self._timers['construction_particle'] += dt if self._timers['construction_particle'] > 0.4: for i in range(3): x = random.randint(0, self.width - 1) y = random.randint(0, self.height - 1) color = self.image.get_at((x, y)) if color[3] > 128 and color[0:3] != PICO_BLACK: p = Particle([PICO_WHITE, PICO_YELLOW, PICO_BROWN], 1, self.pos + V2(x - 9, y - 9), 1.25, helper.random_angle() * 5) self.scene.add_particle(p) if self.health <= 0: self.kill()
def take_damage(self, damage, origin=None): was_shield = False sa = min(damage, self.shield) if self.shield > 0: was_shield = True self.shield -= sa damage -= sa self.health -= damage if origin: delta = origin.pos - self.pos dn = helper.try_normalize(delta) hitpos = self.pos + dn * self.radius if was_shield: sound.play("shield") for i in range(10): ang = dn.as_polar()[1] ang *= 3.14159 / 180 rad = max(self.radius, 5) + 2 hp = self.pos + rad * helper.from_angle( ang + random.random() - 0.5) p = Particle([ PICO_GREEN, PICO_WHITE, PICO_BLUE, PICO_BLUE, PICO_BLUE, PICO_BLUE, PICO_DARKBLUE ], 1, hp, 0.65 + random.random() * 0.2, dn) self.scene.game_group.add(p) else: sound.play("hit") particles = 10 if self.radius > 6: particles = 4 e = Explosion(hitpos, [PICO_WHITE, PICO_YELLOW, PICO_RED], 0.2, 5, "log", 2) self.scene.game_group.add(e) for i in range(particles): p = Particle([ PICO_WHITE, PICO_YELLOW, PICO_YELLOW, PICO_RED, PICO_LIGHTGRAY ], 1, hitpos, 0.25, helper.random_angle() * 9) self.scene.game_group.add(p)
def apply(self, to): if to.owning_civ.alien.difficulty <= 1: return found_ship = None for ship in to.scene.get_civ_ships(to.owning_civ): if isinstance(ship, Alien2Battleship): found_ship = ship break if found_ship and not found_ship.constructed: found_ship.frame += 1 if found_ship.frame == 2: found_ship.constructed = True target = random.choice( to.scene.get_civ_planets(to.scene.player_civ)) found_ship.set_target(target) else: pos = to.pos + helper.random_angle() * (to.radius + 20) ship = Alien2Battleship(to.scene, pos, to.owning_civ) ship.frame = 0 ship.constructed = False to.scene.game_group.add(ship)
def fire(self, at): if self.get_stat("ship_take_damage_on_fire"): self.health -= self.get_stat("ship_take_damage_on_fire") for j in range(3): towards = helper.try_normalize(self.effective_target.pos - self.pos) b = Bullet(self.pos, self.effective_target, self, vel=helper.random_angle() * 10, mods=self.prepare_bullet_mods()) self.scene.game_group.add(b) for i in range(3): pvel = helper.try_normalize(towards + V2(random.random() * 0.75, random.random() * 0.75)) * 30 * (random.random() + 0.25) p = Particle([PICO_WHITE, PICO_WHITE, PICO_BLUE, PICO_DARKBLUE, PICO_DARKBLUE], 1, self.pos, 0.2 + random.random() * 0.15, pvel) self.scene.add_particle(p) enemies = self.scene.get_enemy_objects(self.owning_civ) threat_range = self.THREAT_RANGE_DEFAULT if self.chosen_target.owning_civ == self.owning_civ: # Target is our own planet (defense) threat_range = self.THREAT_RANGE_DEFENSE threats = [ e for e in enemies if ((e.pos - self.pos).length_squared() < threat_range ** 2 and e.is_alive()) ] if threats: self.effective_target = random.choice(threats)
def take_damage(self, damage, origin): super().take_damage(damage, origin=origin) if self.health <= 0: sound.play_explosion() civ = origin.owning_civ e = Explosion(self.pos, [PICO_YELLOW, PICO_ORANGE, PICO_RED, PICO_BROWN], 0.4, 13, line_width=1) self.scene.game_group.add(e) for i in range(40): v = helper.random_angle() * 4 * random.random() color = random.choice( [PICO_YELLOW, PICO_ORANGE, PICO_ORANGE, PICO_RED]) p = Particle([color], 1, self.pos + v, random.random() + 0.5, v * 3) self.scene.add_particle(p) for r, v in self.resources.data.items(): yield_mul = civ.get_stat("asteroid_yield_mul") + 1 v *= yield_mul civ.earn_resource(r, v, where=self.pos) self.kill()
def update(self, dt): self.time += dt self.health_bar.pos = self.pos + V2(0, -self.height / 2) if self.time > 1.0 and not self.jumped: self.jumped = True bad_location = True i = 0 while bad_location: np = V2( self.scene.game.game_resolution.x * 0.66, self.scene.game.game_resolution.y * 0.4 ) + helper.random_angle() * random.random() * (50 + i * 10) _, dsq = helper.get_nearest(np, self.scene.get_planets()) if dsq > 50**2: bad_location = False i += 1 delta = np - self.pos dn = helper.try_normalize(delta) side = V2(dn.y, -dn.x) for i in range(12): color = random.choice( [PICO_RED, PICO_RED, PICO_ORANGE, PICO_YELLOW, PICO_WHITE]) z = random.randint(-12, 12) l1 = LaserParticle(self.pos + side * z / 2, np - dn * (10 - abs(z)) + side * z, color, random.random()) self.scene.game_group.add(l1) self.pos = np self.frame = int(self.time * 3) % 15 if self.state == self.STATE_CINEMATIC_TRAVELING: self.target_planet, sqdist = helper.get_nearest( self.pos, self.planets_to_revive) if self.target_planet: #delta = self.target_planet.pos - self.pos if sqdist < REVIVING_PLANET_CLOSE_RANGE**2: self.state = self.STATE_CINEMATIC_POPULATING self.emit = ['bosscolonist'] num = 2 if len(self.planets_to_revive) == len(self.ships_on_board): num = 1 if len(self.planets_to_revive) > len(self.ships_on_board): num = 0 for i in range(num): self.emit.append(self.ships_on_board.pop(0)) self.emit_timer = 5.0 if self.target_planet.owning_civ == self.scene.player_civ: possible_evacs = self.scene.get_civ_planets( self.scene.player_civ) possible_evacs.remove(self.target_planet) if possible_evacs: possible_evacs = helper.nearest_order( V2(0, self.scene.game.game_resolution.y // 2), possible_evacs) evac_target = random.choice(possible_evacs[0:3]) for ship, amt in self.target_planet.ships.items(): for i in range(amt): self.target_planet.emit_ship( ship, {"to": evac_target}) if self.target_planet.population: self.target_planet.emit_ship( "colonist", { "to": evac_target, "num": self.target_planet.population }) return towards_planet = self.scene.flowfield.get_vector( self.pos, self.target_planet, 5) self.velocity += towards_planet * dt * ACCEL if self.state == self.STATE_CINEMATIC_POPULATING: self.brake(dt) self.emit_timer -= dt if not self.emit: if self.emit_timer < -3: self.planets_to_revive.remove(self.target_planet) if self.planets_to_revive: self.state = self.STATE_CINEMATIC_TRAVELING else: self.state = self.STATE_GAME_WAITING self.range_indicator = RangeIndicator( self.pos, REINCARNATE_RANGE, PICO_ORANGE, 1, 5) self.scene.ui_group.add(self.range_indicator) else: if self.emit_timer < 0: if self.target_planet.owning_civ == self.scene.player_civ: self.target_planet.change_owner(None) self.emit_timer = 1.0 name = self.emit.pop(0) ctor = SHIPS_BY_NAME[name] ship = ctor(self.scene, self.pos, self.owning_civ) if 'colonist' in name: ship.set_pop(3) ship.set_target(self.target_planet) self.scene.game_group.add(ship) pass if self.state == self.STATE_GAME_WAITING: self.wander(dt) self.wait_time -= dt if self.wait_time < 0: self.state = self.STATE_GAME_TRAVELING self.travel_target = None if self.state == self.STATE_GAME_TRAVELING: if not self.travel_target: # Pick only fleets targeting a neutral or player planet fleets = [ f for f in self.scene.fleet_managers['enemy'].current_fleets if f.target.owning_civ != self.owning_civ and isinstance(f.target, planet.Planet) ] if fleets: self.travel_target = random.choice(fleets).target else: self.state = self.STATE_GAME_WAITING self.wait_time = 5 self.wander_center = V2(self.pos) if self.travel_target: delta = self.travel_target.pos - self.pos if delta.length_squared() > (REINCARNATE_RANGE - 10)**2: accel = self.scene.flowfield.get_vector( self.pos, self.travel_target, 10) * ACCEL self.velocity += accel * dt else: self.state = self.STATE_GAME_WAITING self.wander_center = V2(self.pos) self.wait_time = 30 objs = self.scene.get_planets() + self.scene.get_hazards() nearest, dsq = helper.get_nearest(self.pos, objs) if dsq < 40**2: delta = nearest.pos - self.pos self.velocity += -helper.try_normalize(delta) * ACCEL / 2 * dt if self.velocity.length_squared() > self.max_speed**2: self.velocity = helper.try_normalize( self.velocity) * self.max_speed self.pos += self.velocity * dt if self.range_indicator: self.range_indicator.pos = self.pos if self.state in [self.STATE_GAME_WAITING, self.STATE_GAME_TRAVELING]: self.update_reincarnation() return super().update(dt)