def __init__(self, location, bounds, shoot_delay, acceleration, max_speed, turn_rate, respawn_func = default_respawn, direction = 0, velocity = (0.0, 0.0), shield_duration = 120, curr_acceleration = (0.0, 0.0)): self.location = location self.bounds = bounds self.shoot_delay = shoot_delay self.delay = 0 self.velocity = velocity self.direction = direction self.rect = pygame.Rect(location[0]-bounds[0], location[1]-bounds[1], bounds[0]*2, bounds[1]*2) self.acceleration = acceleration self.max_speed = max_speed self.turn_rate = turn_rate self.death_timer = 0 self.respawn_func = respawn_func self.respawn_event = Broadcaster() self.moved = False self.shield_duration = self.shield = shield_duration*2 self.shield_obj = None self.curr_acceleration = curr_acceleration self.id = Ship.CUR_ID Ship.CUR_ID+=1
def __init__(self): self.onShipDeath = Broadcaster() self.onBulletDeath = Broadcaster()
def __init__(self): self.current_tick = 0 #event system self.onShipDeath = Broadcaster() self.onShipKill = Broadcaster() self.onBulletDeath = Broadcaster() self.onBulletTimeout = Broadcaster() self.onShipUpdate = Broadcaster() self.onBulletUpdate = Broadcaster() self.onLogicUpdate = Broadcaster() self.onShipReflectWall = Broadcaster() self.onShipReflectShip = Broadcaster() #required data self.bullet_list = [] self.wall_list = [] self.ship_list = [] #scoreboard self.scoreboard = scoreboard() self.onShipDeath+=self.scoreboard.on_ship_death self.onShipKill+=self.scoreboard.on_ship_kill
class Logic: def __init__(self): self.current_tick = 0 #event system self.onShipDeath = Broadcaster() self.onShipKill = Broadcaster() self.onBulletDeath = Broadcaster() self.onBulletTimeout = Broadcaster() self.onShipUpdate = Broadcaster() self.onBulletUpdate = Broadcaster() self.onLogicUpdate = Broadcaster() self.onShipReflectWall = Broadcaster() self.onShipReflectShip = Broadcaster() #required data self.bullet_list = [] self.wall_list = [] self.ship_list = [] #scoreboard self.scoreboard = scoreboard() self.onShipDeath+=self.scoreboard.on_ship_death self.onShipKill+=self.scoreboard.on_ship_kill def add_ship(self, ship): self.ship_list.append(ship) self.scoreboard.add_player(ship) def calculate_reflection(self, rect, location, velocity): normal = Utility.calculate_normal(rect, location, velocity) velo = (-1*velocity[0], -1*velocity[1]) dot_prod = velo[0]*normal[0] + velo[1]*normal[1] rvelo = (2*dot_prod*normal[0] - velo[0], 2*dot_prod*normal[1] - velo[1]) return rvelo def doLogic(self): for ship in self.ship_list: ship.update() self.onShipUpdate.fire(ship) for i in range(len(self.ship_list)): ship1 = self.ship_list[i] if not ship1.isDead(): for j in range(i+1, len(self.ship_list)): ship2 = self.ship_list[j] if not ship2.isDead(): if not ship1.shield_obj and not ship2.shield_obj: if ship1.rect.colliderect(ship2.rect): ship1.kill(DEATH_TIME) self.onShipDeath.fire(ship1) ship2.kill(DEATH_TIME) self.onShipDeath.fire(ship2) elif not ship1.shield_obj and ship2.shield_obj: if ship1.rect.colliderect(ship2.shield_obj): ship1.kill(DEATH_TIME) self.onShipDeath.fire(ship1) self.onShipKill.fire(ship1, ship2) elif ship1.shield_obj and not ship2.shield_obj: if ship1.shield_obj.colliderect(ship2.rect): ship2.kill(DEATH_TIME) self.onShipDeath.fire(ship2) self.onShipKill.fire(ship2, ship1) elif ship1.shield_obj and ship2.shield_obj: if ship1.shield_obj.colliderect(ship2.shield_obj): ship1.velocity = self.calculate_reflection(ship2.shield_obj, ship1.location, ship1.velocity) ship2.velocity = self.calculate_reflection(ship1.shield_obj, ship2.location, ship2.velocity) self.onShipReflectShip.fire(ship1, ship2) for ship in self.ship_list: if ship.shield_obj: for n in self.wall_list: if ship.shield_obj.colliderect(n) and not ship.isDead(): velo = self.calculate_reflection(n, ship.location, ship.velocity) ship.velocity = velo overlap = ship.shield_obj.clip(n) if overlap.w < overlap.h: if ship.location[0] > overlap.centerx: ship.location = (ship.location[0] + overlap.w + velo[0], ship.location[1] + velo[1]) else: ship.location = (ship.location[0] - overlap.w + velo[0], ship.location[1] + velo[1]) else: if ship.location[1] > overlap.centery: ship.location = (ship.location[0] + velo[0], ship.location[1] + overlap.h + velo[1]) else: ship.location = (ship.location[0] + velo[0], ship.location[1] - overlap.h + velo[1]) self.onShipReflectWall.fire(ship, n) for n in self.bullet_list: if ship.shield_obj.colliderect(n) and not ship.isDead() and ship is not n.ship: self.onBulletDeath.fire(n, ship.shield_obj) n.duration = 0 else: for n in self.wall_list: if ship.rect.colliderect(n) and not ship.isDead(): ship.kill(DEATH_TIME) self.onShipDeath.fire(ship) for n in self.bullet_list: if ship.rect.colliderect(n) and not ship.isDead() and ship is not n.ship: ship.kill(DEATH_TIME) self.onShipDeath.fire(ship) self.onShipKill.fire(ship, n.ship) n.duration = 0 i = 0 while i < len(self.bullet_list): bullet = self.bullet_list[i] bullet.update() self.onBulletUpdate.fire(bullet) for n in self.wall_list: if n.colliderect(bullet.rect): bullet.duration = 0 self.onBulletDeath.fire(bullet, n) if bullet.duration>0: i = i+1 else: self.onBulletTimeout.fire(self.bullet_list[i]) self.bullet_list.remove(self.bullet_list[i]) self.onLogicUpdate.fire(self) self.current_tick+=1
class Ship: CUR_ID = 0 def __init__(self, location, bounds, shoot_delay, acceleration, max_speed, turn_rate, respawn_func = default_respawn, direction = 0, velocity = (0.0, 0.0), shield_duration = 120, curr_acceleration = (0.0, 0.0)): self.location = location self.bounds = bounds self.shoot_delay = shoot_delay self.delay = 0 self.velocity = velocity self.direction = direction self.rect = pygame.Rect(location[0]-bounds[0], location[1]-bounds[1], bounds[0]*2, bounds[1]*2) self.acceleration = acceleration self.max_speed = max_speed self.turn_rate = turn_rate self.death_timer = 0 self.respawn_func = respawn_func self.respawn_event = Broadcaster() self.moved = False self.shield_duration = self.shield = shield_duration*2 self.shield_obj = None self.curr_acceleration = curr_acceleration self.id = Ship.CUR_ID Ship.CUR_ID+=1 def update(self): #self.velocity = (self.velocity[0] + self.curr_acceleration[0], self.velocity[1] + self.curr_acceleration[1]) self.location = (self.location[0] + self.velocity[0], self.location[1] + self.velocity[1]) self.rect.center = self.location if self.delay>0: self.delay = self.delay-1 if self.shield < self.shield_duration and not self.shield_obj: self.shield+=1 if self.shield_obj: self.shield-=2 if self.shield<=0: self.shield_obj = None if self.isDead(): self.death_timer -= 1 if not self.isDead(): self.respawn_func(self) self.respawn_event.fire(self) def turn(self, turn_speed): self.direction += turn_speed def turn_left(self): self.turn(-self.turn_rate) def turn_right(self): self.turn(self.turn_rate) def move(self): self.move_from_force_in_direction(self.acceleration, self.direction) def move_from_force(self, acceleration): self.move_from_force_in_direction(acceleration, self.direction) def move_from_force_in_direction(self, acceleration, direction): sinD = math.sin(math.radians(direction)) cosD = math.cos(math.radians(direction)) self.velocity = (self.velocity[0] + acceleration*sinD, self.velocity[1] - acceleration*cosD) mag = math.sqrt(math.pow(self.velocity[0], 2) + math.pow(self.velocity[1], 2)) if mag>self.max_speed: self.velocity = (self.velocity[0]/mag*self.max_speed, self.velocity[1]/mag*self.max_speed) def accelerate(self): sinD = math.sin(math.radians(self.direction)) cosD = math.cos(math.radians(self.direction)) self.curr_acceleration = (self.acceleration*sinD, self.acceleration*cosD) def reset_acceleration(self): self.curr_acceleration = (0.0, 0.0) def kill(self, death_time): self.death_timer = death_time self.velocity = (0, 0) def isDead(self): return self.death_timer > 0 def can_toggle_shield(self, flag): return not flag or self.shield>self.shield_duration/8 def toggle_shield(self, flag): self.is_shielded = flag