def __init__(self, center, bound, pwm, controller: PlayerController, player_turret: Turret, missile_turret: Turret, life_turret: Turret): super().__init__(center, bound, pwm) ''' INIT PLAYER ''' self.player_turret = player_turret self.player = Player(bound, bound, pwm, player_turret, controller) self.player.laser.on() ''' INIT MISSILE ''' self.missile_turret = missile_turret self.missile = NPC(pwm, missile_turret) self.missile.laser.on() ''' INIT LIFE COUNTER ''' self.life_turret = life_turret self.life_counter = NPC(pwm, life_turret) self.life_pos = int(center + bound / 2) # Put life counter out of bounds self.life_counter.set_servo( int(center - bound / 2) - 10, int(center + bound / 2)) self.life_counter.laser.on() self.life_distance = int(bound / self.lives)
def win(self): """ "We're in the endgame now" - Wizard guy. :return: """ # Free up the GPIO pin del self.player.laser del self.missile.laser del self.life_counter.laser npc1 = NPC(self.pwm, self.player_turret) npc2 = NPC(self.pwm, self.missile_turret) npc3 = NPC(self.pwm, self.life_turret) radius = 20 rate = 0.1 circle1 = Circle(415, 375, radius, 0, rate) circle2 = Circle(375, 375, radius, 0, rate) circle3 = Circle(335, 375, radius, 0, rate, clockwise=False) data1 = npc1.follow_path(circle1.data()) data1.__next__() data1.__next__() npc1.laser.on() data2 = npc2.follow_path(circle2.data()) data2.__next__() data2.__next__() npc2.laser.on() data3 = npc3.follow_path(circle3.data()) data3.__next__() data3.__next__() npc3.laser.on() for _ in range(0, 400): if _ % 100 == 0: circle3.clockwise = False data1.__next__() data2.__next__() data3.__next__()
def win(self): # Free up the GPIO pin del self.player.laser npc = NPC(self.pwm, self.player_turret) radius = 20 rate = 0.1 circle = Circle(375, 375, radius, 0, rate) data = npc.follow_path(circle.data()) data.__next__() data.__next__() npc.laser.on() for _ in range(0, 600): if _ % 100 == 0: circle.clockwise = False data.__next__()
def make_missile(self, rate=1, npc: NPC = None) -> Generator: """ Creates a new random missile :param rate: :param npc: :return: """ y_low = int(self.center - self.bound / 2) y_high = int(self.center + self.bound / 2) x_start = random.randint(y_low, y_high) # Since the controllers can't reach the corners, restrict them x_end = random.randint(y_low + 15, y_high - 15) if self.num_missiles > 5: path = Line(x_start, y_high, x_end, y_low, rate) else: # Last five missiles get cray-cray path = Corkscrew(x_start, y_high, x_end, y_low, 10, 0, 1, rate) if npc is None: missile = self.missile.follow_path(path.data()) else: missile = npc.follow_path(path.data()) # Let the servos get into position. Yield once for init, yield again to move servos missile.__next__() missile.__next__() return missile
def lose(self): """ "Did we just lose?" - Sun-Count. :return: """ # Free up the GPIO pin del self.player.laser del self.missile.laser del self.life_counter.laser npc1 = NPC(self.pwm, self.player_turret) npc2 = NPC(self.pwm, self.missile_turret) npc3 = NPC(self.pwm, self.life_turret) npc1.laser.on() npc2.laser.on() npc3.laser.on() rate = 2 m1 = self.make_missile(rate, npc1) m2 = self.make_missile(rate, npc2) m3 = self.make_missile(rate, npc3) prev_time = 0 num_losers = 15 while True: if num_losers == 0: break self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: prev_time = self.curr_time try: m1.__next__() except StopIteration: m1 = self.make_missile(rate, npc1) num_losers -= 1 try: m2.__next__() except StopIteration: m2 = self.make_missile(rate, npc2) num_losers -= 1 try: m3.__next__() except StopIteration: m3 = self.make_missile(rate, npc3) num_losers -= 1
def __init__(self, center, bound, pwm, player_1_controller, player_2_controller, player_1_turret, player_2_turret, npc_turret): super().__init__(center, bound, pwm) self.player_1 = Player(bound, bound, pwm, player_1_turret, player_1_controller, no_x=True, fixed_x=int(center + bound / 2)) self.player_2 = Player(bound, bound, pwm, player_2_turret, player_2_controller, no_x=True, fixed_x=int(center - bound / 2)) self.ball = NPC(pwm, npc_turret) self.bounce = None
def win(self, player): if player == 1: del self.player_1.laser center = int(self.center + self.bound / 2) npc = NPC(self.pwm, self.player_1_turret) else: del self.player_2.laser center = int(self.center - self.bound / 2) npc = NPC(self.pwm, self.player_2_turret) circle = Circle(center, 375, 25, 0, 2) data = npc.follow_path(circle.data()) data.__next__() data.__next__() npc.laser.on() spin_spin = 0 prev_time = 0 while self.playing: self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate * 3: prev_time = self.curr_time data.__next__() spin_spin += 1 if spin_spin == 100: self.playing = False
class Pong(Game): """ Two players swat a ball back and forth. """ ''' PLAYER INFO ''' paddle_length = 15 ''' BALL INFO ''' ball_rate = 2 resetting = False skip_frame = False laser_blink = False reset_time = 0 reset_rate = 1 ''' GAME INFO ''' win_points = 10 def __init__(self, center, bound, pwm, player_1_controller, player_2_controller, player_1_turret, player_2_turret, npc_turret): super().__init__(center, bound, pwm) self.player_1_turret = player_1_turret self.player_2_turret = player_2_turret self.npc_turret = npc_turret self.player_1 = Player(bound, bound, pwm, player_1_turret, player_1_controller, no_x=True, fixed_x=int(center + bound / 2)) self.player_2 = Player(bound, bound, pwm, player_2_turret, player_2_controller, no_x=True, fixed_x=int(center - bound / 2)) self.ball = NPC(pwm, npc_turret) self.bounce = None def play_on(self): player_1_points = 0 player_2_points = 0 self.playing = True self.ball.laser.on() self.player_1.laser.on() self.player_2.laser.on() # vertical_hit = False # horizontal_hit = False while self.playing: if player_1_points == self.win_points: self.win(1) elif player_2_points == self.win_points: self.win(2) # pi/2 cone facing either player if random.randint(0, 1): angle = random.uniform(-0.785, 0.785) else: angle = random.uniform(2.355, 3.925) ball = self.make_ball(rate=self.ball_rate, angle=angle) prev_time = 0 while self.playing: self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: if not self.resetting: xs, ys = ball.__next__() else: xs = self.center ys = self.center prev_time = self.curr_time x_1, y_1 = self.player_1.set_servo() x_2, y_2 = self.player_2.set_servo() x_1_hit = xs > 415 x_2_hit = xs < 320 y_1_hit = fabs(y_1 - ys) <= self.paddle_length y_2_hit = fabs(y_2 - ys) <= self.paddle_length # Player 1 or 2 lose if not y_1_hit and x_1_hit: player_2_points += 1 self.resetting = True self.reset_time = time.time() break elif not y_2_hit and x_2_hit: player_1_points += 1 self.resetting = True self.reset_time = time.time() break else: top_hit = ys >= (self.center + self.bound / 2) bottom_hit = ys <= (self.center - self.bound / 2) # Player hit if (y_1_hit and x_1_hit) or (y_2_hit and x_2_hit): self.bounce.vertical_hit(random_bounce=True) self.bounce.rate += 0.1 # Top or bottom wall hit elif top_hit or bottom_hit: self.bounce.horizontal_hit() self.handle_ball_resetting() def handle_ball_resetting(self): """ Handles all player info after firing, such as laser blinking :return: """ if self.resetting: if not self.skip_frame: self.skip_frame = True if self.laser_blink: self.ball.laser.on() else: self.ball.laser.off() self.laser_blink = not self.laser_blink else: self.skip_frame = False if self.curr_time - self.reset_time > self.reset_rate: self.resetting = False self.ball.laser.on() def make_ball(self, angle=2, rate=2): self.bounce = Bounce(self.center, self.center, angle, rate) ball_servo = self.ball.follow_path(self.bounce.data()) # Let the servos get into position. Yes, yield twice ball_servo.__next__() ball_servo.__next__() return ball_servo def win(self, player): if player == 1: del self.player_1.laser center = int(self.center + self.bound / 2) npc = NPC(self.pwm, self.player_1_turret) else: del self.player_2.laser center = int(self.center - self.bound / 2) npc = NPC(self.pwm, self.player_2_turret) circle = Circle(center, 375, 25, 0, 2) data = npc.follow_path(circle.data()) data.__next__() data.__next__() npc.laser.on() spin_spin = 0 prev_time = 0 while self.playing: self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate * 3: prev_time = self.curr_time data.__next__() spin_spin += 1 if spin_spin == 100: self.playing = False
class MissileDefense(Game): """ The player must aim and shoot at missile raining down on a peaceful city. """ ''' GAME INFO ''' curr_time = 0 num_missiles = 20 ''' PLAYER INFO ''' # Delay until the player can fire again player_attack_rate = 1 # Size of player attack bomb_radius = 15 player_fired = False fire_time = 0 skip_frame = False laser_blink = False ''' MISSILE INFO ''' # How long to delay until the missile comes alive missile_delay = 1 # How much to increase the missile speed per success rate_increase = 0.1 ''' LIVES INFO ''' lives = 10 life_pos = 0 def __init__(self, center, bound, pwm, controller: PlayerController, player_turret: Turret, missile_turret: Turret, life_turret: Turret): super().__init__(center, bound, pwm) ''' INIT PLAYER ''' self.player_turret = player_turret self.player = Player(bound, bound, pwm, player_turret, controller) self.player.laser.on() ''' INIT MISSILE ''' self.missile_turret = missile_turret self.missile = NPC(pwm, missile_turret) self.missile.laser.on() ''' INIT LIFE COUNTER ''' self.life_turret = life_turret self.life_counter = NPC(pwm, life_turret) self.life_pos = int(center + bound / 2) # Put life counter out of bounds self.life_counter.set_servo( int(center - bound / 2) - 10, int(center + bound / 2)) self.life_counter.laser.on() self.life_distance = int(bound / self.lives) def play_on(self): self.playing = True hit = False lose = False prev_time = 0 missile_rate = 1 missile = self.make_missile() missile_respawn = False respawn_time = time.time() while self.playing: if hit: missile_rate += self.rate_increase elif lose: self.lives -= 1 self.life_pos -= self.life_distance self.life_counter.set_servo( int(self.center - self.bound / 2) - 10, self.life_pos) if hit or lose: self.num_missiles -= 1 hit = False lose = False self.missile.laser.off() missile = self.make_missile(missile_rate) missile_respawn = True respawn_time = time.time() # Win/lose conditions. Check lose first in case of lives=missiles=0 if self.lives == 0: self.lose() break elif self.num_missiles == 0: self.win() break self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: prev_time = self.curr_time p_x, p_y = self.player.set_servo() if not missile_respawn: try: m_x, m_y = missile.__next__() except StopIteration: lose = True else: if not self.player_fired and self.player.firing(): self.player_fired = True self.fire_time = time.time() dist_2_bomb = sqrt((m_y - p_y)**2 + (m_x - p_x)**2) if dist_2_bomb <= self.bomb_radius: hit = True else: if self.curr_time - respawn_time > self.missile_delay: missile_respawn = False self.missile.laser.on() self.handle_player_firing() def handle_player_firing(self): """ Handles all player info after firing, such as laser blinking :return: """ if self.player_fired: if not self.skip_frame: self.skip_frame = True if self.laser_blink: self.player.laser.on() else: self.player.laser.off() self.laser_blink = not self.laser_blink else: self.skip_frame = False if self.curr_time - self.fire_time > self.player_attack_rate: self.player_fired = False self.player.laser.on() def make_missile(self, rate=1, npc: NPC = None) -> Generator: """ Creates a new random missile :param rate: :param npc: :return: """ y_low = int(self.center - self.bound / 2) y_high = int(self.center + self.bound / 2) x_start = random.randint(y_low, y_high) # Since the controllers can't reach the corners, restrict them x_end = random.randint(y_low + 15, y_high - 15) if self.num_missiles > 5: path = Line(x_start, y_high, x_end, y_low, rate) else: # Last five missiles get cray-cray path = Corkscrew(x_start, y_high, x_end, y_low, 10, 0, 1, rate) if npc is None: missile = self.missile.follow_path(path.data()) else: missile = npc.follow_path(path.data()) # Let the servos get into position. Yield once for init, yield again to move servos missile.__next__() missile.__next__() return missile def win(self): """ "We're in the endgame now" - Wizard guy. :return: """ # Free up the GPIO pin del self.player.laser del self.missile.laser del self.life_counter.laser npc1 = NPC(self.pwm, self.player_turret) npc2 = NPC(self.pwm, self.missile_turret) npc3 = NPC(self.pwm, self.life_turret) radius = 20 rate = 0.1 circle1 = Circle(415, 375, radius, 0, rate) circle2 = Circle(375, 375, radius, 0, rate) circle3 = Circle(335, 375, radius, 0, rate, clockwise=False) data1 = npc1.follow_path(circle1.data()) data1.__next__() data1.__next__() npc1.laser.on() data2 = npc2.follow_path(circle2.data()) data2.__next__() data2.__next__() npc2.laser.on() data3 = npc3.follow_path(circle3.data()) data3.__next__() data3.__next__() npc3.laser.on() for _ in range(0, 400): if _ % 100 == 0: circle3.clockwise = False data1.__next__() data2.__next__() data3.__next__() def lose(self): """ "Did we just lose?" - Sun-Count. :return: """ # Free up the GPIO pin del self.player.laser del self.missile.laser del self.life_counter.laser npc1 = NPC(self.pwm, self.player_turret) npc2 = NPC(self.pwm, self.missile_turret) npc3 = NPC(self.pwm, self.life_turret) npc1.laser.on() npc2.laser.on() npc3.laser.on() rate = 2 m1 = self.make_missile(rate, npc1) m2 = self.make_missile(rate, npc2) m3 = self.make_missile(rate, npc3) prev_time = 0 num_losers = 15 while True: if num_losers == 0: break self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: prev_time = self.curr_time try: m1.__next__() except StopIteration: m1 = self.make_missile(rate, npc1) num_losers -= 1 try: m2.__next__() except StopIteration: m2 = self.make_missile(rate, npc2) num_losers -= 1 try: m3.__next__() except StopIteration: m3 = self.make_missile(rate, npc3) num_losers -= 1
class Pong(Game): """ Two players swat a ball back and forth. """ ''' PLAYER INFO ''' paddle_length = 10 x_hit = 0 ''' BALL INFO ''' ball_rate = 2 resetting = False skip_frame = False laser_blink = False reset_time = 0 reset_rate = 1 def __init__(self, center, bound, pwm, player_1_controller, player_2_controller, player_1_turret, player_2_turret, npc_turret): super().__init__(center, bound, pwm) self.player_1 = Player(bound, bound, pwm, player_1_turret, player_1_controller, no_x=True, fixed_x=int(center + bound / 2)) self.player_2 = Player(bound, bound, pwm, player_2_turret, player_2_controller, no_x=True, fixed_x=int(center - bound / 2)) self.ball = NPC(pwm, npc_turret) self.bounce = None def play_on(self): player_1_points = 0 player_2_points = 0 self.playing = True self.ball.laser.on() self.player_1.laser.on() self.player_2.laser.on() # vertical_hit = False # horizontal_hit = False while self.playing: ball = self.make_ball(self.ball_rate) prev_time = 0 # xs, ys = ball.send((horizontal_hit, vertical_hit)) while self.playing: self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: if not self.resetting: # xs, ys = ball.send((horizontal_hit, vertical_hit)) xs, ys = ball.__next__() else: xs = self.center ys = self.center prev_time = self.curr_time x_1, y_1 = self.player_1.set_servo() x_2, y_2 = self.player_2.set_servo() x_1_hit = fabs(x_1 - xs) <= self.x_hit x_2_hit = fabs(x_2 - xs) <= self.x_hit y_1_hit = fabs(y_1 - ys) <= self.paddle_length y_2_hit = fabs(y_2 - ys) <= self.paddle_length # Player 1 or 2 lose if not y_1_hit and x_1_hit: player_2_points += 1 self.resetting = True self.reset_time = time.time() break elif not y_2_hit and x_2_hit: player_1_points += 1 self.resetting = True self.reset_time = time.time() break else: top_hit = ys >= (self.center + self.bound / 2) bottom_hit = ys <= (self.center - self.bound / 2) # Player hit if (y_1_hit and x_1_hit) or (y_2_hit and x_2_hit): # vertical_hit = True self.bounce.vertical_hit() # horizontal_hit = False self.bounce.rate += 0.1 # Top or bottom wall hit elif top_hit or bottom_hit: # vertical_hit = False # horizontal_hit = True self.bounce.horizontal_hit() # else: # vertical_hit = False # horizontal_hit = False # if not self.resetting: # xs, ys = ball.send((horizontal_hit, # vertical_hit)) self.handle_ball_resetting() def handle_ball_resetting(self): """ Handles all player info after firing, such as laser blinking :return: """ if self.resetting: if not self.skip_frame: self.skip_frame = True if self.laser_blink: self.ball.laser.on() else: self.ball.laser.off() self.laser_blink = not self.laser_blink else: self.skip_frame = False if self.curr_time - self.reset_time > self.reset_rate: self.resetting = False self.ball.laser.on() def make_ball(self, angle=2, rate=2): self.bounce = Bounce(self.center, self.center, angle, rate) ball_servo = self.ball.follow_path(self.bounce.data()) # Let the servos get into position. Yes, yield twice ball_servo.__next__() ball_servo.send((False, False)) return ball_servo
import time import Adafruit_PCA9685 from src import NPC from src.TURRETS import TURRET_1 from paths.math import Hypotrochoid pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(60) h = Hypotrochoid(375, 1 / 240, 70, 50, 20) d = h.data() npc = NPC(pwm, TURRET_1) npc.laser.on() graph = npc.follow_path(d) curr_time = time.time() while True: if time.time() - curr_time > 1 / 60: graph.__next__()
class MissileDefense(Game): """ The player must aim and shoot at missile raining down on a peaceful city. """ ''' GAME INFO ''' curr_time = 0 ''' PLAYER INFO ''' # Delay until the player can fire again player_attack_rate = 1 # Size of player attack bomb_radius = 10 player_fired = False fire_time = 0 skip_frame = False laser_blink = False ''' MISSILE INFO ''' # How long to delay until the missile comes alive missile_delay = 1 # How much to increase the missile speed per success rate_increase = 0.1 ''' LIVES INFO ''' lives = 10 life_pos = 0 def __init__(self, center, bound, pwm, controller: PlayerController, player_turret: Turret, missile_turret: Turret, life_turret: Turret): super().__init__(center, bound, pwm) ''' INIT PLAYER ''' self.player = Player(bound, bound, pwm, player_turret, controller) self.player.laser.on() ''' INIT MISSILE ''' self.missile = NPC(pwm, missile_turret) self.missile.laser.on() ''' INIT LIFE COUNTER ''' self.life_counter = NPC(pwm, life_turret) self.life_pos = int(center + bound / 2) # Put life counter out of bounds self.life_counter.set_servo( int(center - bound / 2) - 10, int(center + bound / 2)) self.life_counter.laser.on() self.life_distance = int(bound / self.lives) def play_on(self): self.playing = True hit = False lose = False prev_time = 0 player_score = 0 missile_rate = 1 missile = self.make_missile() missile_respawn = False respawn_time = time.time() while self.playing: if hit: player_score += 1 missile_rate += self.rate_increase if lose: self.lives -= 1 self.life_pos -= self.life_distance self.life_counter.set_servo( int(self.center - self.bound / 2) - 10, self.life_pos) if hit or lose: hit = False lose = False self.missile.laser.off() missile = self.make_missile(missile_rate) missile_respawn = True respawn_time = time.time() # Win/lose conditions if player_score == 10: pass elif self.lives == 0: pass self.curr_time = time.time() if self.curr_time - prev_time >= self.time_rate: prev_time = self.curr_time p_x, p_y = self.player.set_servo() if not missile_respawn: try: m_x, m_y = missile.__next__() except StopIteration: lose = True else: if not self.player_fired and self.player.firing(): self.player_fired = True self.fire_time = time.time() dist_2_bomb = sqrt((m_y - p_y)**2 + (m_x - p_x)**2) if dist_2_bomb <= self.bomb_radius: hit = True else: if self.curr_time - respawn_time > self.missile_delay: missile_respawn = False self.missile.laser.on() self.handle_player_firing() def handle_player_firing(self): """ Handles all player info after firing, such as laser blinking :return: """ if self.player_fired: if not self.skip_frame: self.skip_frame = True if self.laser_blink: self.player.laser.on() else: self.player.laser.off() self.laser_blink = not self.laser_blink else: self.skip_frame = False if self.curr_time - self.fire_time > self.player_attack_rate: self.player_fired = False self.player.laser.on() def make_missile(self, rate=1) -> Generator: """ Creates a new random missile :param rate: :return: """ y_low = int(self.center - self.bound / 2) y_high = int(self.center + self.bound / 2) x_start = random.randint(y_low, y_high) # Since the controllers can't reach the corners, restrict them x_end = random.randint(y_low + 20, y_high - 20) path = Line(x_start, y_high, x_end, y_low, rate) missile = self.missile.follow_path(path.data()) # Let the servos get into position. Yield once for init, yield again to move servos missile.__next__() missile.__next__() return missile