Beispiel #1
0
class Window(pyglet.window.Window):
    def __init__(self, map_file, config_file):
        super().__init__(resizable=True,
                         caption='Tourism Simulation',
                         visible=False)
        self.set_minimum_size(640, 480)
        self.set_maximum_size(2260, 3540)
        self.frame_rate = 1 / 60.0  # Target frame-rate, usually can't keep up

        self.icon1 = pyglet.image.load('./graphics/Icon1.png')
        self.icon2 = pyglet.image.load('./graphics/Icon2.png')
        self.set_icon(self.icon1, self.icon2)

        self.map = Map(self.width, self.height, map_file)
        self.set_visible(True)

        self.x = 800
        self.y = -800

        self.simulation = Simulation(2260, 3540, self.width, self.height,
                                     config_file)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if (buttons & mouse.LEFT) or (buttons & mouse.MIDDLE):
            self.x = self.x + dx
            self.y = self.y + dy
            if self.x > 1120:
                self.x = 1120
                pass

            if self.x < self.width - 1120:
                self.x = self.width - 1120
                pass

            if self.y > 1760:
                self.y = 1760
                pass
            pass

        if self.y < self.height - 1760:
            self.y = self.height - 1760
            pass

    def update(self, dt):
        self.simulation.update(dt)

    def on_draw(self):
        self.clear()
        self.map.draw(self.width, self.height, self.x, self.y)
        self.simulation.draw(self.x, self.y, self.width, self.height)
Beispiel #2
0
class AppEngine(pyglet.window.Window):
    def __init__(self):
        bit_map = assets.generate_map()
        super().__init__(bit_map.shape[1] * settings.BLOCK_SIZE,
                         bit_map.shape[0] * settings.BLOCK_SIZE +
                         settings.BLOCK_SIZE * 3,
                         "PAC-MAN",
                         resizable=False)
        self.map = Map(bit_map)
        self.event_loop = pyglet.app.EventLoop()
        pyglet.clock.schedule_interval(self.update, 1 / 120.0)

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE:
            self.close()
        self.map.keypress(symbol)

    def update(self, dt):
        self.map.update(dt)

    def on_draw(self):
        self.clear()
        self.map.draw()
Beispiel #3
0
class Game:
    """
    Starts the game loop.

    The main game loop consists of an event
    loop, the update loop (things updated every
    frame), and the draw loop.

    """
    def __init__(self, network):
        """
        Set up display and game map.
        
        Arguments:
            network {Network} -- Connection to server
        """
        pygame.init()

        # Connection to the server
        self.network = network
        self.player_num = self.network.get_player_num()
        print("You are player", self.player_num)

        # Set up display window
        pygame.display.set_caption(
            "A Game of Shapes - Player " +
            str(self.player_num))  # NOTE: Display player num here?
        screen_res = (WINDOW_WIDTH, WINDOW_HEIGHT)
        self.screen = pygame.display.set_mode(screen_res,
                                              flags=pygame.RESIZABLE)

        # Set up font
        pygame.font.init()
        self.game_font = pygame.font.SysFont("Verdana", 60)

        # Set up gameplay map
        self.map = Map(self.screen, self.player_num)

        # Represents the state of game
        # Modified by server and sent to clients
        self.gamestate = self.network.get_gamestate()
        is_turn = self.gamestate.is_players_turn(self.player_num)

        # Effects of turn that are sent across network
        self.turn = {"move": None, "attack": None, "phase": NOT_TURN}

        # Let the starting player begin moving units
        if is_turn:
            self.turn["phase"] = SELECT_UNIT_TO_MOVE

        # Clock tracks time from beginning of game
        self.clock = pygame.time.Clock()

        # Keep track of user's cursor. Updates every frame
        self.mouse_position = pygame.mouse.get_pos()

        # Show waiting screen until other player connects
        self.waiting_screen()
        # Start the game
        self.game_loop()

    def game_loop(self):
        """
        Loop until window is closed.
        """
        while True:
            self.event_loop()
            self.update()
            self.draw()

    def event_loop(self):
        """
        Handle user input.

        Events include mouse clicks
        and keyboard presses.
        """
        events = pygame.event.get()
        for event in events:

            # Client closes window
            if event.type == pygame.QUIT:
                self.exit_game()

            # User hovers over tile
            if event.type == pygame.MOUSEMOTION:
                self.map.handle_hover(self.mouse_position)

            # Only process clicks if it's this player's turn
            if self.gamestate.is_players_turn(self.player_num):
                # User is placing tiles
                if self.turn["phase"] == PLACE_TILES:
                    pass
                else:  # Attack!
                    # User clicks button
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        self.turn = self.map.handle_click(
                            self.mouse_position, self.turn)
                    # User presses a key
                    # TODO: Delete or implement keydown
                    elif event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_SPACE:
                            self.turn["phase"] == ATTACKING

    def update(self):
        """
        Update variables that change every frame.
        """
        self.time = self.clock.tick(60)
        self.mouse_position = pygame.mouse.get_pos()

        # Other player's turn
        if self.turn["phase"] == NOT_TURN:
            players_turn = self.network.request_turn()
            if players_turn == self.player_num:
                self.update_gamestate()
                self.turn["phase"] = SELECT_UNIT_TO_MOVE

        # Check if turn ended
        if self.turn["phase"] == END_TURN:
            # Send moves and attacks made to server
            self.network.send_turn(self.turn)
            self.gamestate.change_turns()
            self.turn["phase"] = NOT_TURN

        # Check if someone has won
        if self.gamestate.game_is_over:
            self.gameover()

    def update_gamestate(self):
        """
        Pull in new information from server and apply changes.
        """
        new_gamestate = self.network.get_gamestate()

        self.update_health(new_gamestate)
        self.update_positions(new_gamestate)

        self.turn["attack"] = None
        self.turn["move"] = None

        self.gamestate = new_gamestate

    def update_health(self, new_gamestate):
        """
        Update units with any health changes.
        """
        if new_gamestate.unit_health != self.gamestate.unit_health:
            for unit_type, health in new_gamestate.unit_health.items():
                unit = self.map.get_unit_by_type(unit_type)
                if unit:
                    unit.change_health(health)
                    if not unit.is_alive:
                        self.map.kill_unit(unit)

    def update_positions(self, new_gamestate):
        """
        Update units with changes in position.
        """
        if new_gamestate.unit_locations != self.gamestate.unit_locations:
            # Update map with any moved units
            for unit_type, location in new_gamestate.unit_locations.items():
                if location:
                    col, row = location
                    unit = self.map.get_unit_by_type(unit_type)
                    self.map.move(unit, col, row)

    def draw(self):
        """
        Draw graphics and display on screen.
        """
        self.screen.fill(colors.lightgray)

        # Display player statistics
        self.display_statistics()
        self.display_help()

        # Display game board
        self.map.draw()

        pygame.display.update()

    def display_statistics(self):
        """
        Display player information.
        """
        #TODO:  Generalize the placement of text.
        #       Create function for reused code.
        #       Set alignment of text.

        # Font size is equal to line spacing
        SIZE = 20

        font = pygame.font.SysFont("Verdana", SIZE)

        # Display player turn
        is_turn = self.gamestate.is_players_turn(self.player_num)
        turn_text = ""
        text_color = ""
        if is_turn:
            turn_text = "Your Turn"
            text_color = colors.darkgreen
        else:
            turn_text = "Enemy Turn"
            text_color = colors.darkred
        textsurface = font.render(turn_text, False, text_color)
        text_rect = textsurface.get_rect(center=[WINDOW_WIDTH / 2, SIZE * 3])
        self.screen.blit(textsurface, text_rect)

        # Display unit statistics
        if self.player_num == 1:
            # Display "Unit Information"
            location = [20, SIZE * 5]  # Beginning of unit info.
            textsurface = font.render("Your Units", False, colors.white)
            self.screen.blit(textsurface, location)
            for unit in self.map.players_units:
                # Increment horizontal placement
                location[1] += SIZE
                health = str(unit.health) + "/" + str(unit.max_health)
                textsurface = font.render(unit.archetype + ": " + health,
                                          False, unit.color)
                self.screen.blit(textsurface, location)

            # Display "Enemy Unit Information"
            location = [self.screen.get_width() - 150,
                        SIZE * 5]  # Beginning of unit info.
            textsurface = font.render("Enemy Units", False, colors.white)
            self.screen.blit(textsurface, location)
            for unit in self.map.enemy_units:
                # Increment horizontal placement
                location[1] += SIZE
                health = str(unit.health) + "/" + str(unit.max_health)
                textsurface = font.render(unit.archetype + ": " + health,
                                          False, unit.color)
                self.screen.blit(textsurface, location)

        elif self.player_num == 2:
            # Display "Unit Information"
            location = [self.screen.get_width() - 150,
                        SIZE * 5]  # Beginning of unit info.
            textsurface = font.render("Your Units", False, colors.white)
            self.screen.blit(textsurface, location)
            for unit in self.map.players_units:
                # Increment horizontal placement
                location[1] += SIZE
                health = str(unit.health) + "/" + str(unit.max_health)
                textsurface = font.render(unit.archetype + ": " + health,
                                          False, unit.color)
                self.screen.blit(textsurface, location)

            # Display "Enemy Information"
            location = [20, SIZE * 5]  # Beginning of unit info.
            textsurface = font.render("Enemy Units", False, colors.white)
            self.screen.blit(textsurface, location)
            for unit in self.map.enemy_units:
                # Increment horizontal placement
                location[1] += SIZE
                health = str(unit.health) + "/" + str(unit.max_health)
                textsurface = font.render(unit.archetype + ": " + health,
                                          False, unit.color)
                self.screen.blit(textsurface, location)

    def display_help(self):
        """
        Display help text.
        """
        LOCATION = [0, WINDOW_HEIGHT - 25]
        SIZE = 16
        font = pygame.font.SysFont("Verdana", SIZE)
        phase_text = ""

        # Change help text based on phase
        if self.turn["phase"] == SELECT_UNIT_TO_MOVE:
            phase_text = "HELP: Select a unit by clicking on it with your mouse."
        elif self.turn["phase"] == MOVING:
            phase_text = "HELP: Choose a tile to move your unit or click on the unit to deselect."
        elif self.turn["phase"] == ATTACKING:
            phase_text = "HELP: Attack by clicking an emeny unit"
        textsurface = font.render(phase_text, False, colors.white)
        self.screen.blit(textsurface, LOCATION)

    def waiting_screen(self):
        """
        Display a waiting message until
        other client connects.
        """
        self.network.send_command("start")
        reply = self.network.receive()
        self.gamestate = self.network.get_gamestate()

        while not self.gamestate.ready():
            # Update events so window can be closed
            events = pygame.event.get()
            for event in events:
                if event.type == pygame.QUIT:
                    self.exit_game()

            # Display waiting text
            self.screen.fill(colors.darkgray)
            textsurface = self.game_font.render("Waiting for player 2...",
                                                False, colors.white)
            text_rect = textsurface.get_rect(center=(WINDOW_CENTER))
            self.screen.blit(textsurface, text_rect)
            pygame.display.update()

            # Update gamestate to check if other player is connected
            self.gamestate = self.network.get_gamestate()

    def gameover(self):
        self.network.send_turn(self.turn)
        # Loop until player resets or quits
        # while not self.gamestate.ready():
        while True:

            # Show text and how to reset
            self.display_endgame_results()

            events = pygame.event.get()
            for event in events:
                if event.type == pygame.QUIT:
                    self.exit_game()

                # Press space to restart or esc to exit
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        # Tell server that you're ready
                        self.network.send_command("start")
                    elif event.key == pygame.K_ESCAPE:
                        self.exit_game()

            # Update gamestate to check if other player is ready
            self.gamestate = self.network.get_gamestate()

        # Clear the map
        self.map.reset()

        # Determine turn to start back with
        is_turn = self.gamestate.is_players_turn(self.player_num)
        if is_turn:
            self.turn["phase"] = SELECT_UNIT_TO_MOVE

    def display_endgame_results(self):
        """
        Display winning/losing text.
        """
        self.screen.fill(colors.lightgray)

        # Show results
        if self.gamestate.winner == self.player_num:
            textsurface = self.game_font.render("You won!", False,
                                                colors.darkgreen)
        else:
            textsurface = self.game_font.render("You lost...", False,
                                                colors.darkred)
        text_rect = textsurface.get_rect(center=(WINDOW_CENTER))
        self.screen.blit(textsurface, text_rect)

        #TODO: display endgame statistics slightly differently
        self.display_statistics()

        pygame.display.update()

    def exit_game(self):
        print("Exiting game...")
        self.network.close()
        pygame.quit()
        sys.exit(0)
class Game(object):
    def __init__(self, screen, tutorialMenu, fakeNewsMenu, saveFile=None):
        self.isRunning = False
        if saveFile is None:
            self.map = Map("assets/maps/default.json")
            self.player = Player()
        else:
            self.load(saveFile)

        self.openMenu = "[Esc] Open Menu"
        self.openMenu = screen.fonts["25"].render(self.openMenu, 1,
                                                  (255, 255, 255))
        self.closeMenu = "[Esc] Close Menu"
        self.closeMenu = screen.fonts["25"].render(self.closeMenu, 1,
                                                   (255, 255, 255))
        self.ennemyController = EnnemyController(5)
        button_help = Button((700, 300), (300, 60),
                             "How to Build Walls",
                             tutorialMenu.run,
                             screen=screen)
        button_help.build(screen)

        button_fakeNewsMenu = Button((1100, 300), (300, 60),
                                     "Fake News",
                                     fakeNewsMenu.run,
                                     screen=screen)
        button_fakeNewsMenu.build(screen)

        button_quit = Button((1500, 300), (300, 60), "Quit", self.stop)
        button_quit.build(screen)
        self.pauseMenu = Menu(None,
                              [button_help, button_fakeNewsMenu, button_quit],
                              True)

        self.winMenu = Menu(pygame.image.load("assets/img/youWon.jpg"), [],
                            True)
        button_continue = Button((10, 1000), (300, 60), "4 Years Later >>",
                                 self.winMenu.stop)
        button_continue.build(screen)
        self.winMenu.buttons.append(button_continue)

        button_quit = Button((10, 1000), (300, 60), "Quit Because I'm Bad",
                             exit)
        button_quit.build(screen)
        self.loseMenu = Menu(pygame.image.load("assets/img/youLose.jpg"),
                             [button_quit], True)
        button_continue = Button((400, 1000), (300, 60),
                                 "Continue & Sue Bedin", self.loseMenu.stop)
        button_continue.build(screen)
        self.loseMenu.buttons.append(button_continue)

        self.invocations = []
        self.twats = []

        button_resume = Button((300, 300), (300, 60), "Resume",
                               self.pauseMenu.stop)
        button_resume.build(screen)
        self.pauseMenu.buttons.append(button_resume)
        self.gameEndTime = cst.GAME_TIME

        self.ballots = {
            "republican": Ballot((1800, 20), "assets/img/republican.png"),
            "democrat": Ballot((1800, 140), "assets/img/democrat.png"),
        }

    def load(self, saveFile):
        """
        Loads the game from a save file, creates an empty game if the save is None
        """
        save = json.load(open(saveFile, "r"))
        self.map = Map(save['map'])
        self.player = Player(save['player'])

    def update(self, screen):
        self.gameEndTime = int(self.gameEndTime - screen.timeElapsed)
        if self.gameEndTime <= 0:
            if self.ballots["republican"].votes > self.ballots[
                    "democrat"].votes:
                self.winMenu.run(screen)
            else:
                button_info = Button((100, 800), (
                    700, 60
                ), f'You : {self.ballots["republican"].votes} - Bedin : {self.ballots["democrat"].votes}',
                                     exit)
                button_info.build(screen)
                button_info.clickable = False
                self.loseMenu.buttons.append(button_info)
                self.loseMenu.run(screen)
            self.stop()

        if self.player.popularity < 20:
            button_info = Button(
                (100, 800), (500, 60),
                f"Your popularity went below 20% ... You Bad Boy", exit)
            button_info.build(screen)
            button_info.clickable = False
            self.loseMenu.buttons.append(button_info)
            self.loseMenu.run(screen)
            self.stop()

        for event in screen.events():
            action = self.player.eventUpdate(event)
            if action == "HIT":
                self.ennemyController.hit(self.player.hitbox,
                                          self.player.damage)
            elif action == "KAMEHAMEHA":
                self.ennemyController.hit(self.player.hitbox, 50)
            elif action == "BUILDWALL":
                self.invocations.append(
                    Wall([
                        self.player.position[0] + 205, self.player.position[1]
                    ]))

            if event.type == pygame.locals.KEYDOWN:
                if event.key == pygame.locals.K_ESCAPE:
                    self.pauseMenu.run(screen, self)

        for inv in self.invocations[:]:
            result = inv.update(self.ennemyController)
            if result == "DEAD":
                del self.invocations[self.invocations.index(inv)]

        self.player.update(screen, self.ennemyController, self.invocations,
                           self.twats)

        for twat in self.twats[:]:
            result = twat.update(screen)
            if result == "DEAD":
                del self.twats[self.twats.index(twat)]

        deaths, baddeaths, democrat_votes, republican_votes = self.ennemyController.update(
            screen, self.player.popularity)
        self.player.addSpecialAttack(deaths * 5)
        for baddeath in range(baddeaths):
            twat = Twat(screen,
                        [random.randint(200, 1400),
                         random.randint(30, 600)])
            self.twats.append(twat)
            self.player.popularity -= twat.rt * 0.1
            self.player.updatePopularity(screen)

        self.player.popularity += deaths * 0.2
        self.player.updatePopularity(screen)

        for key, ballot in self.ballots.items():
            if key == "democrat":
                ballot.add_votes(democrat_votes)
            elif key == "republican":
                ballot.add_votes(republican_votes)
            ballot.update(screen)

    def draw(self, screen):
        self.map.draw(screen, self.player)
        self.ennemyController.draw(screen)
        for inv in self.invocations:
            inv.draw(screen)

        self.player.draw(screen)
        for twat in self.twats:
            twat.draw(screen)

        for key, ballot in self.ballots.items():
            ballot.draw(screen)

    def stop(self):
        self.isRunning = False
        self.pauseMenu.stop()

    def getTimeDisplay(self):
        return str(datetime.timedelta(seconds=self.gameEndTime))

    def run(self, screen):
        self.isRunning = True
        while self.isRunning:
            self.update(screen)
            self.draw(screen)
            screen.blit(self.openMenu, (10, 10))
            self.gameEndTimeDisplay = screen.fonts["75"].render(
                self.getTimeDisplay(), 0, (255, 255, 255))
            screen.blit(self.gameEndTimeDisplay, (10, 30))
            screen.flip()