def _generate_frame(self, border = False): radius = self.size + 8 padding = 8 cx,cy = radius + padding, radius + padding self._width = radius * 2 + padding * 2 self._height = radius * 2 + padding * 2 frame = pygame.Surface((self._width, self._height), pygame.SRCALPHA) border_radius = 2 if border else 1 color = self.owning_civ.color if self.owning_civ else PICO_YELLOW # Border pygame.draw.circle(frame, color, (cx,cy), radius + border_radius) for building in self.buildings: offset = V2.from_angle(building['angle'] + self.base_angle) * radius + V2(cx, cy) building['building'].draw_outline(frame, color, offset, building['angle'] + self.base_angle,expand=border) # Foreground #pygame.draw.circle(frame, PICO_GREYPURPLE, (cx,cy), radius) rotated = pygame.transform.rotate(self.art, 0) frame.blit(rotated, (cx - rotated.get_width() // 2, cy - rotated.get_height() // 2)) for building in self.buildings: offset = V2.from_angle(building['angle'] + self.base_angle) * radius + V2(cx, cy) building['building'].draw_foreground(frame, offset, building['angle'] + self.base_angle) return frame
def sphere_get(offset, planet_pos): spherize = 0.25 + pow(planet_pos.magnitude(), 1.75) / 40.0 dist, angle = planet_pos.to_polar() angle += wavy_angle p2 = offset + V2.from_angle(angle) * dist * spherize color = wavy.get_at((int(p2.x), int(p2.y))) return color
def update(self, planet, dt): self.fire_time += dt threats = planet.get_threats() if self.fire_time > self.FIRE_RATE and threats: self.fire_time = 0 for i in range(planet.population): angle = random.random() * 6.2818 b = Bullet(planet.pos + V2.from_angle(angle) * planet.get_radius(), random.choice(threats), planet, vel=V2.from_angle(angle) * 20, mods={ 'homing': True, "damage_debuff": 0.5 }) planet.scene.game_group.add(b)
def travel_to_target(self, dt): ### Directional Forces ### target_vector = V2(0, 0) # Towards target if self.orbits: orbital_pos = (self.pos - self.target.pos).normalized() * ( self.target.size + 20) + self.target.pos towards_angle = (orbital_pos - self.pos).to_polar()[1] else: towards_angle = (self.target.pos - self.pos).to_polar()[1] towards_angle += math.sin(self.speed_t) / 4 target_vector += V2.from_angle(towards_angle) * TARGET_POWER target_vector += self.get_fleet_target_vector() # Now turn towards that target vector target_vector = target_vector.normalized() self.turn_towards(target_vector, dt) self.speed_t += dt speed = math.sin(self.speed_t) * 2 + self.base_speed speed *= self.owning_civ.upgrade_stats['move_speed'] + 1 self.velocity = V2.from_angle(self._angle) * speed self.try_warp(dt) self.pos += (self.velocity + self.push_velocity) * dt if self.velocity.sqr_magnitude() > 0: self.thrust_particle_time += dt if self.thrust_particle_time > THRUST_PARTICLE_RATE: pvel = V2(random.random() - 0.5, random.random() - 0.5) * 5 pvel += -self.velocity / 2 p = particle.Particle( "assets/thrustparticle.png", 1, self.pos + -self.velocity.normalized() * self.size, 1, pvel) self.scene.game_group.add(p) self.thrust_particle_time -= THRUST_PARTICLE_RATE
def turn_towards(self, vector, dt): facing = V2.from_angle(self._angle) cp = facing.cross(vector) try: ao = math.acos(facing.dot(vector)) except ValueError: ao = 0 if ao < 0.25: self._angle = math.atan2(vector.y, vector.x) else: if cp > 0: self._angle += 3 * dt else: self._angle -= 3 * dt return cp
def draw_shape(self, surface, shape, color, offset, angle, expand=False): center = offset for pt in shape: center += pt * (1 / len(shape)) final_pts = [] for pt in shape: dist, ang = pt.to_polar() ang += angle new_pt = V2.from_angle(ang) * dist + offset if expand: new_pt += (new_pt - center).normalized() * .75 final_pts.append(new_pt) pygame.draw.polygon(surface, color, [pt.tuple() for pt in final_pts], 0)
def push_from_planets(self, dt): for planet in self.scene.get_planets(): dist = (planet.pos - self.pos).sqr_magnitude() if dist < (planet.get_radius() + 5)**2: delta = (self.pos - planet.pos) dir = delta.normalized() mag = abs((planet.get_radius() + 5) - delta.magnitude()) fwd = V2.from_angle(self._angle) self.push_velocity = dir * mag w = fwd.cross(dir) if w > 0: self._angle += 5 * dt self.push_velocity += V2(dir.y, -dir.x) * 2 else: self._angle -= 5 * dt self.push_velocity -= V2(dir.y, -dir.x) * 2 self.push_velocity *= 0.9
def homing(self, dt): towards = (self.target.pos - self.pos).normalized() speed, angle = self.vel.to_polar() facing = self.vel.normalized() cp = facing.cross(towards) try: ao = math.acos(facing.dot(towards)) except ValueError: ao = 0 if ao < 0.25: angle = math.atan2(towards.y, towards.x) else: if cp > 0: angle += 3 * dt else: angle -= 3 * dt self.vel = V2.from_angle(angle) * speed self._generate_image()
def dogfight(self, threats, dt): if self.current_dogfight_target == None or self.current_dogfight_target.health <= 0: self.current_dogfight_target = random.choice(threats) dist = (self.current_dogfight_target.pos - self.pos).sqr_magnitude() if dist < RANGE ** 2: self.assault(self.current_dogfight_target, dt) else: towards = (self.current_dogfight_target.pos - self.pos).normalized() target_vector = towards target_vector += self.get_fleet_target_vector() target_vector = target_vector.normalized() self.turn_towards(target_vector, dt) self.speed_t += dt speed = math.sin(self.speed_t) * 2 + self.base_speed speed *= self.owning_civ.upgrade_stats['move_speed'] + 1 self.velocity = V2.from_angle(self._angle) * speed self.thrust_particle_time += dt if self.thrust_particle_time > THRUST_PARTICLE_RATE: pvel = V2(random.random() - 0.5, random.random() - 0.5) * 5 pvel += -self.velocity / 2 p = Particle("assets/thrustparticle.png",1,self.pos,1,pvel) self.scene.game_group.add(p) self.thrust_particle_time -= THRUST_PARTICLE_RATE
def update(self, dt): self._status = [] my_planets = self.scene.get_civ_planets(self.civ) general_rate = min(0.75 + (len(my_planets) / 6), 2) if my_planets: if not self.homeworld: self.homeworld = my_planets[0] self.homeworld.health = self.homeworld.get_max_health() self._status.append("planets: " + ", ".join([str(p.pos) for p in my_planets])) self.building_time += dt * general_rate if self.building_time > BUILDING_TIME: self.building_time = 0 if random.random() > 0.25: p = random.choice(my_planets) if len(p.buildings) < 5: p.add_building( random.choice(["mining_rate", "regen", "armory"])) else: self.civ.upgrade_stats['fire_rate'] += 0.1 self._status.append(str(dict(self.civ.upgrade_stats))) self._status.append("%.2f" % self.add_fighter_timer) self.add_fighter_timer += dt * general_rate if self.add_fighter_timer > ADD_FIGHTER_TIME: p = random.choice(my_planets) p.add_ship('alien-fighter') self.add_fighter_timer = 0 self._status.append("%.2f" % self.invade_timer) self.invade_timer += dt * general_rate near_planets = self.scene.get_planets() near_planets.sort( key=lambda x: (x.pos - self.homeworld.pos).sqr_magnitude()) near_unclaimed = [ p for p in near_planets if p.owning_civ != self.civ ][0:3] self._status.append("near unclaimed: " + ", ".join([str(p.pos) for p in near_unclaimed])) if self.invade_timer > max(INVADE_TIME - self.battleship_wave, 4): target = random.choice(near_unclaimed) my_planets_with_fighters = [ p for p in my_planets if p.ships['alien-fighter'] > 0 ] if my_planets_with_fighters: p = random.choice(my_planets_with_fighters) for _ in range(random.randint(1, p.ships['alien-fighter'])): p.emit_ship('alien-fighter', {'to': target}) if p.ships['alien-battleship']: for _ in range( random.randint(1, p.ships['alien-battleship'])): p.emit_ship('alien-battleship', {'to': target}) if p.population > 1: pop = random.randint(1, p.population - 1) p.emit_ship('alien-colonist', { 'to': target, 'num': pop }) self.invade_timer = 0 p.needs_panel_update = True self.battleship_timer += dt * general_rate if self.battleship_timer > max( BATTLESHIP_TIME / (1 + self.battleship_wave / 4), 20): self.battleship_timer = 0 self.battleship_wave += 1 near_planets = [ p for p in self.scene.get_planets() if (p.pos - self.homeworld.pos).sqr_magnitude() < ( self.battleship_wave * 100)**2 ] planet = random.choice(near_planets) bsp = planet.pos + V2.from_angle(random.random() * 6.2818) * 40 ww = WarpWarning(planet, self.scene, bsp) self.scene.game_group.add(ww)