def main(): """ Main Program """ pygame.mixer.pre_init(44100, -16, 2, 2048) pygame.init() # Initialize gameplay game = Gameplay() # Start game clock clock = pygame.time.Clock() # End loop condition loop = True # ======== Main Game Loop ======== while loop: for event in pygame.event.get(): if event.type == QUIT: loop = False # Check for level change game.change_level() # Limit to 60 FPS game.set_fps(FPS, clock) # Checks for input based on player type (ship vs hero) game.get_input() # Update each sprite groups in current level game.update() # Render level game.render_level(clock.get_fps()) # Update screen pygame.display.flip()
class FourElementsRunWindow(arcade.Window): def __init__(self, width, height, window_title): super().__init__(width, height, window_title) self.stage = MENU self.all_check_cover() self.howto_page = 1 self.gameplay = Gameplay() self.sound_fx = Sound() def all_check_cover(self): self.start_cover = False self.how_cover = False self.howto_left = False self.howto_right = False self.game_over_cover = False self.sound_onoff_cover = False self.howto_gui_cover() def howto_gui_cover(self): self.player = False self.range = False self.melee = False self.hp = False self.power = False self.floor = False self.score = False self.platform = False self.monster = False def all_howto_interface(self, x, y): self.howto_interface_player(x, y) self.howto_interface_range(x, y) self.howto_interface_melee(x, y) self.howto_interface_hp(x, y) self.howto_interface_power(x, y) self.howto_interface_floor(x, y) self.howto_interface_score(x, y) self.howto_interface_platform(x, y) self.howto_interface_monster(x, y) def howto_interface_player(self, x, y): if x in range(127, 178) and y in range(121, 187): self.player = True else: self.player = False def howto_interface_range(self, x, y): if x in range(206, 323) and y in range(159, 208): self.range = True else: self.range = False def howto_interface_melee(self, x, y): if x in range(206, 271) and y in range(102, 150): self.melee = True else: self.melee = False def howto_interface_hp(self, x, y): if x in range(166, 367) and y in range(462, 483): self.hp = True else: self.hp = False def howto_interface_power(self, x, y): if x in range(166, 347) and y in range(451, 461): self.power = True else: self.power = False def howto_interface_floor(self, x, y): if x in range(581, 640) and y in range(466, 483): self.floor = True else: self.floor = False def howto_interface_score(self, x, y): if x in range(581, 640) and y in range(448, 465): self.score = True else: self.score = False def howto_interface_platform(self, x, y): if x in range(501, 680) and y in range(332, 349): self.platform = True else: self.platform = False def howto_interface_monster(self, x, y): if x in range(561, 620) and y in range(192, 242): self.monster = True else: self.monster = False def menu_hover(self, x, y): self.game_over_cover = False if x in range(274, 526) and y in range(151, 204): self.start_cover = True else: self.start_cover = False if x in range(382, 418) and y in range(87, 124): self.how_cover = True else: self.how_cover = False if x in range(750, 785) and y in range(15, 50): self.sound_onoff_cover = True else: self.sound_onoff_cover = False def menu_press(self, x, y): if x in range(274, 526) and y in range(151, 204): self.stage = GAMEPLAY self.gameplay.set_up() elif x in range(382, 418) and y in range(87, 124): self.stage = HOWTOPLAY elif x in range(750, 785) and y in range(15, 50): self.gameplay.enable_sound = not self.gameplay.enable_sound def game_over_press(self, x, y): if self.gameplay.world.player.is_dead: if x in range(312, 489) and y in range(50, 100): self.stage = MENU def game_over_hover(self, x, y): if self.gameplay.world.player.is_dead: if x in range(312, 489) and y in range(50, 100): self.game_over_cover = True else: self.game_over_cover = False def howto_press(self, x, y): if 1 <= self.howto_page <= 3: if x in range(22, 96) and y in range(274, 325): self.howto_page -= 1 elif x in range(707, 781) and y in range(274, 325): self.howto_page += 1 def howto_arrow_hover(self, x, y): if x in range(22, 96) and y in range(274, 325): self.howto_left = True else: self.howto_left = False if x in range(707, 781) and y in range(274, 325): self.howto_right = True else: self.howto_right = False def draw_sprite(self, condition, location): if condition: sprite = arcade.Sprite(location, scale=0.24) sprite.set_position(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) sprite.draw() def draw_menu(self): arcade.draw_xywh_rectangle_textured( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, arcade.load_texture('images/menu/menu.png')) self.draw_sprite(self.gameplay.enable_sound, 'images/menu/sound_on.png') self.draw_sprite(not self.gameplay.enable_sound, 'images/menu/sound_off.png') self.draw_sprite(self.gameplay.enable_sound and self.sound_onoff_cover, 'images/menu/sound_on_cover.png') self.draw_sprite( not self.gameplay.enable_sound and self.sound_onoff_cover, 'images/menu/sound_off_cover.png') self.draw_sprite(self.start_cover, 'images/menu/start_cover.png') self.draw_sprite(self.how_cover, 'images/menu/how_cover.png') def draw_howto(self): arcade.draw_xywh_rectangle_textured( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, arcade.load_texture('images/how_to/menu_bg.png')) if 1 <= self.howto_page <= 3: arcade.draw_xywh_rectangle_textured( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, arcade.load_texture('images/how_to/howto_' + str(self.howto_page) + '.png')) self.draw_sprite(self.howto_left, 'images/how_to/arrow_left.png') self.draw_sprite(self.howto_right, 'images/how_to/arrow_right.png') if self.howto_page == 2: self.draw_howto_interface() else: self.stage = MENU self.howto_page = 1 def draw_game_over_hover(self): if self.game_over_cover: over = arcade.Sprite('images/game_over/game_over_cover.png', scale=0.24) over.set_position(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) over.draw() def draw_howto_interface(self): self.draw_sprite(self.player, 'images/how_to/howto_2-1.png') self.draw_sprite(self.range, 'images/how_to/howto_2-2.png') self.draw_sprite(self.melee, 'images/how_to/howto_2-3.png') self.draw_sprite(self.hp, 'images/how_to/howto_2-4.png') self.draw_sprite(self.floor, 'images/how_to/howto_2-5.png') self.draw_sprite(self.score, 'images/how_to/howto_2-6.png') self.draw_sprite(self.power, 'images/how_to/howto_2-7.png') self.draw_sprite(self.platform, 'images/how_to/howto_2-8.png') self.draw_sprite(self.monster, 'images/how_to/howto_2-9.png') def sound_on_mouse_motion(self, x, y, dx, dy): if self.stage == MENU: if x in range(274, 526) and y in range(151, 204): self.sound_fx.play_hover() elif x in range(382, 418) and y in range(87, 124): self.sound_fx.play_hover() else: self.sound_fx.reset_sound_play() elif self.stage == GAMEPLAY and self.gameplay.world.player.is_dead: if x in range(312, 489) and y in range(50, 100): self.sound_fx.play_hover() else: self.sound_fx.reset_sound_play() elif self.stage == HOWTOPLAY: if x in range(22, 96) and y in range(274, 325): self.sound_fx.play_hover() elif x in range(707, 781) and y in range(274, 325): self.sound_fx.play_hover() else: self.sound_fx.reset_sound_play() def sound_on_mouse_press(self, x, y): if self.stage == MENU: if x in range(274, 526) and y in range(151, 204): self.sound_fx.play_select() self.sound_fx.reset_sound_play() elif x in range(382, 418) and y in range(87, 124): self.sound_fx.play_select() self.sound_fx.reset_sound_play() elif self.stage == GAMEPLAY and self.gameplay.world.player.is_dead: if x in range(312, 489) and y in range(50, 100): self.sound_fx.play_main_menu() else: self.sound_fx.reset_sound_play() elif self.stage == HOWTOPLAY: if 1 <= self.howto_page <= 3: if x in range(22, 96) and y in range(274, 325): self.sound_fx.play_flip() elif x in range(707, 781) and y in range(274, 325): self.sound_fx.play_flip() else: self.sound_fx.reset_sound_play() else: if x in range(22, 96) and y in range(274, 325): self.sound_fx.play_close() elif x in range(707, 781) and y in range(274, 325): self.sound_fx.play_close() else: self.sound_fx.reset_sound_play() def on_draw(self): arcade.start_render() if self.stage == MENU: self.draw_menu() elif self.stage == GAMEPLAY: self.gameplay.on_draw() self.draw_game_over_hover() elif self.stage == HOWTOPLAY: self.draw_howto() def update(self, delta): # self.set_update_rate(1/70) if self.stage == GAMEPLAY: self.gameplay.update(delta) def on_key_press(self, key, key_modifiers): self.gameplay.on_key_press(key, key_modifiers) def on_key_release(self, key, key_modifiers): self.gameplay.on_key_release(key, key_modifiers) def on_mouse_motion(self, x, y, dx, dy): if self.gameplay.enable_sound: self.sound_on_mouse_motion(x, y, dx, dy) if self.stage == MENU: self.menu_hover(x, y) elif self.stage == GAMEPLAY: self.game_over_hover(x, y) elif self.stage == HOWTOPLAY: self.howto_arrow_hover(x, y) if self.howto_page == 2: self.all_howto_interface(x, y) def on_mouse_press(self, x, y, button, modifiers): if self.gameplay.enable_sound: self.sound_on_mouse_press(x, y) if self.stage == MENU: self.menu_press(x, y) if self.stage == GAMEPLAY: self.game_over_press(x, y) if self.stage == HOWTOPLAY: self.howto_press(x, y)
class SplitScreen(State): def __init__(self) -> None: self.gameplay1 = Gameplay() self.gameplay2 = Gameplay() self.popups1: List[Popup] = [] self.popups2: List[Popup] = [] self.current_popup1: Optional[Popup] = None self.current_popup2: Optional[Popup] = None self.finished = False self.end_screen = False def is_finished(self) -> bool: return self.finished def initialize(self) -> None: self.gameplay1.set_device(ctx.device1) self.gameplay1.initialize() self.gameplay2.set_device(ctx.device2) self.gameplay2.initialize() def update(self, switch_state: Callable) -> None: if not self.end_screen: if self.gameplay1.game_over and not self.gameplay2.game_over: self.gameplay2.game_over = True self.end_screen = True self.popups1.append( Popup("You lost!", color="red", gcolor="orange")) self.popups2.append( Popup("You won!", color="green", gcolor="yellow")) elif self.gameplay2.game_over and not self.gameplay1.game_over: self.gameplay1.game_over = True self.end_screen = True self.popups1.append( Popup("You won!", color="green", gcolor="yellow")) self.popups2.append( Popup("You lost!", color="red", gcolor="orange")) elif self.gameplay1.game_over and self.gameplay2.game_over: self.end_screen = True self.popups1.append(Popup("Draw!", color="cyan")) self.popups2.append(Popup("Draw!", color="cyan")) if self.gameplay1.cancel or self.gameplay2.cancel: if self.end_screen or self.gameplay1.countdown > 0: self.finished = True return else: self.gameplay1.game_over = self.gameplay1.cancel self.gameplay2.game_over = self.gameplay2.cancel self.gameplay1.cancel = False self.gameplay2.cancel = False self.gameplay1.update() self.gameplay2.update() if self.gameplay1.score.duel_lines > 0: hole = randint(0, 9) self.gameplay2.add_garbage(hole, self.gameplay1.score.duel_lines) self.gameplay1.score.duel_lines = 0 if self.gameplay2.score.duel_lines > 0: hole = randint(0, 9) self.gameplay1.add_garbage(hole, self.gameplay2.score.duel_lines) self.gameplay2.score.duel_lines = 0 self.popups1.extend(self.gameplay1.get_popups()) self.gameplay1.clear_popups() self.popups2.extend(self.gameplay2.get_popups()) self.gameplay2.clear_popups() if not self.current_popup1 and self.popups1: self.current_popup1 = self.popups1.pop(0) elif self.current_popup1: if not self.current_popup1.update(): self.current_popup1 = None if not self.current_popup2 and self.popups2: self.current_popup2 = self.popups2.pop(0) elif self.current_popup2: if not self.current_popup2.update(): self.current_popup2 = None def draw(self) -> None: self.gameplay1.draw(130, 80) self.gameplay2.draw(880, 80) if self.current_popup1: self.current_popup1.draw(130 + 155, 80 + 220) if self.current_popup2: self.current_popup2.draw(880 + 155, 80 + 220)
class Online(State): def __init__(self) -> None: self.gameplay1 = Gameplay() self.gameplay2 = Gameplay() self.popups1: List[Popup] = [] self.popups2: List[Popup] = [] self.current_popup1: Optional[Popup] = None self.current_popup2: Optional[Popup] = None self.waiting = True self.waiting_cycle = 0 self.last_waiting_cycle = ctx.now self.buffer = b"" self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.settimeout(10.0) self.finished = False self.end_screen = False def is_finished(self) -> bool: return self.finished def initialize(self) -> None: self.gameplay1.set_device(ctx.device1) self.gameplay1.initialize() self.gameplay2.set_device(Device("dummy")) self.gameplay2.initialize() try: self.socket.connect(config.server) except (ConnectionRefusedError, socket.timeout): print("unable to connect to server") self.finished = True def update(self, switch_state: Callable) -> None: read, write, error = select.select([self.socket], [self.socket], [self.socket], 0) if self.waiting: self.gameplay1.cancel_input.update() if self.socket in read: buffer = self.socket.recv(BUFFER_SIZE) if buffer == b"go": self.waiting = False self.current_popup2 = None elif buffer == b"ping": self.socket.sendall(b"pong") elif buffer == b"": print("server disconnected") self.finished = True elif self.gameplay1.cancel: self.socket.close() self.finished = True return if not self.end_screen: if self.gameplay1.game_over and not self.gameplay2.game_over: self.gameplay2.game_over = True self.end_screen = True self.popups1.append( Popup("You lost!", color="red", gcolor="orange")) self.popups2.append( Popup("You won!", color="green", gcolor="yellow")) elif self.gameplay2.game_over and not self.gameplay1.game_over: self.gameplay1.game_over = True self.end_screen = True self.popups1.append( Popup("You won!", color="green", gcolor="yellow")) self.popups2.append( Popup("You lost!", color="red", gcolor="orange")) elif self.gameplay1.game_over and self.gameplay2.game_over: self.end_screen = True self.popups1.append(Popup("Draw!", color="cyan")) self.popups2.append(Popup("Draw!", color="cyan")) if self.gameplay1.cancel: self.gameplay1.send = True self.gameplay1.cancel = False self.gameplay1.game_over = True if self.end_screen or self.gameplay1.countdown > 0: self.finished = True self.gameplay1.update() if self.socket in read: try: self.gameplay2 = jsonpickle.decode( protocol.recv(self.socket).decode()) except (RuntimeError, ConnectionResetError): error = [self.socket] if self.socket in write and self.gameplay1.send: self.gameplay1.send = False try: protocol.send(self.socket, jsonpickle.encode(self.gameplay1).encode()) except (ConnectionResetError, ConnectionAbortedError): error = [self.socket] if self.socket in error: if not self.end_screen: print("communication error") self.finished = True if self.gameplay2.score.duel_lines > 0: hole = randint(0, 9) self.gameplay1.add_garbage(hole, self.gameplay2.score.duel_lines) self.gameplay2.score.duel_lines = 0 self.gameplay1.score.duel_lines = 0 self.popups1.extend(self.gameplay1.get_popups()) self.gameplay1.clear_popups() self.popups2.extend(self.gameplay2.get_popups()) self.gameplay2.clear_popups() if not self.current_popup1 and self.popups1: self.current_popup1 = self.popups1.pop(0) elif self.current_popup1: if not self.current_popup1.update(): self.current_popup1 = None if not self.current_popup2 and self.popups2: self.current_popup2 = self.popups2.pop(0) elif self.current_popup2: if not self.current_popup2.update(): self.current_popup2 = None def draw(self) -> None: self.gameplay1.draw(130, 80) self.gameplay2.draw(880, 80, draw_piece=not self.waiting) if self.waiting: Text.draw("Awaiting", size=4, centerx=880 + 155, top=220) Text.draw("opponent", size=4, gcolor="red", centerx=880 + 155, top=280) string = "." * self.waiting_cycle Text.draw(string, size=8, gcolor="black", centerx=880 + 155, top=350) if ctx.now - self.last_waiting_cycle > 0.5: self.last_waiting_cycle = ctx.now self.waiting_cycle = (self.waiting_cycle + 1) % 4 if self.current_popup1: self.current_popup1.draw(130 + 155, 80 + 220) if self.current_popup2: self.current_popup2.draw(880 + 155, 80 + 220)
class Marathon(State): def __init__(self) -> None: self.gameplay = Gameplay() self.gravity = [ 1.00000, 0.79300, 0.61780, 0.47273, 0.35520, 0.26200, 0.18968, 0.13473, 0.09388, 0.06415, 0.04298, 0.02822, 0.01815, 0.01144, 0.00706, ] self.goal = 5 self.popups: List[Popup] = [] self.current_popup: Optional[Popup] = None self.end_screen = False self.finished = False self.pause = False def is_finished(self) -> bool: return self.finished def initialize(self) -> None: self.gameplay.set_device(ctx.device1) self.gameplay.initialize() def update(self, switch_state: Callable) -> None: if self.gameplay.game_over and not self.end_screen: self.end_screen = True self.popups.append(Popup("Game over!", color="red")) if self.gameplay.game_over and self.gameplay.cancel: self.finished = True return if self.gameplay.cancel: if self.gameplay.countdown > 0: self.finished = True return else: self.gameplay.game_over = True self.gameplay.cancel = False self.gameplay.update() if self.gameplay.score.lines > 0: self.goal -= self.gameplay.score.lines self.goal = max(0, self.goal) self.gameplay.score.lines = 0 if self.goal == 0: if self.gameplay.level == 15 and not self.end_screen: self.end_screen = True self.gameplay.game_over = True self.popups.append( Popup("You won!", color="green", gcolor="yellow") ) else: self.gameplay.level += 1 self.goal = 5 * self.gameplay.level self.gameplay.fall_interval = self.gravity[ self.gameplay.level - 1 ] self.popups.extend(self.gameplay.get_popups()) self.gameplay.clear_popups() if not self.current_popup and self.popups: self.current_popup = self.popups.pop(0) self.current_popup.duration *= 2 elif self.current_popup: if not self.current_popup.update(): self.current_popup = None def draw(self) -> None: self.gameplay.draw(200, 80) Text().draw("Level", centerx=125, top=300) Text().draw( str(self.gameplay.level), centerx=125, top=340, size=4, color="gold", ) Text().draw("Goal", centerx=125, top=450) Text().draw( str(self.goal), centerx=125, top=490, size=4, color="green" ) if self.current_popup: self.current_popup.draw(650, 250, center=False)