示例#1
0
class PyGame:
    BATCH = False
    FPS = 60
    TURN_LENGTH = 0.2
    frame = 0

    def __init__(self, window: pygame.Surface):
        self.end_game = None
        self.fullscreen = False
        self.window = window

        self.game = Engine()
        self.clock = pygame.time.Clock()
        self.active_weapons = ActiveWeapons()
        self.explosions = Explosions()
        self.lasers = Lasers()
        self.particles = Particles()
        self.shake = Shake()
        self.timer = time.time()

        self.show_explosions = True
        self.shake_enabled = True
        self.dirty_rect_enabled = False

        self.old_dirty_rects = []

        self.countries = Countries(self.game.countries.countries, SIZE)

    def start(self):
        global SIZE

        running = True
        self.turn_label = TextRect(TITLE_FONT, f"Round {self.game.turn}", GUI_COLOUR)
        self.turn_label.rect.topleft = (10, 10)

        while running:
            for event in pygame.event.get():
                if PyGame.quit_game(event):
                    running = False
                    pygame.quit()
                    return 1

                elif PyGame.press_f11(event):
                    self.toggle_fullscreen()

                elif event.type == pygame.VIDEORESIZE:
                    SIZE = event.size
                    pygame.display.set_mode(event.size, DEFAULT_FLAG)
                    self.countries.resize(*event.size)

            # Refresh screen
            self.dirty_rects = []
            self.refresh_screen = False

            self.window.fill(BLACK)

            if self.show_explosions and not self.dirty_rect_enabled:
                self.dirty_rects += self.explosions.draw(self.window)

            self.dirty_rects += self.turn_label.draw(self.window)
            self.dirty_rects += self.countries.draw(self.window)
            self.lasers.draw(self.window, self.FPS)
            self.dirty_rects += self.active_weapons.draw(self.window)

            if not self.dirty_rect_enabled:
                self.particles.draw(self.window, self.FPS)

            if time.time() - self.timer > self.TURN_LENGTH * self.game.turn:
                if not self.game.is_finished():
                    self.game.do_turn()
                    self.game.print_events()
                    self.animate_turn()
                    self.turn_label.text = f"Round {self.game.turn}"

                elif not self.end_game:
                    self.end_game = time.time()

                    if self.BATCH:
                        self.end_game += 3

            if (not self.dirty_rect_enabled
                and self.shake_enabled
                and self.shake.is_active()):

                self.shake.animate(self.window)
                self.refresh_screen = True

            if not self.dirty_rect_enabled or self.refresh_screen:
                pygame.display.update()
            else:
                temp = optimize_dirty_rects(deepcopy(self.dirty_rects + self.old_dirty_rects))
                pygame.display.update(temp)

            self.old_dirty_rects = self.dirty_rects
            self.clock.tick(self.FPS)

            if self.end_game and self.end_game < time.time():
                break

        if self.game.countries.get_alive_count():
            alive = self.game.countries.get_survivor()
            print(f"{alive} is the last one standing.")

        else:
            print("There were no survivors.")

        if self.BATCH:
            return 0
        else:
            return self._finish_game()

    def animate_turn(self):
        for event in self.game.events["Player"]:
            if event["Type"] == "Attack" and event["Success"]:
                start = self.countries.get_pos(event["Source"])
                end_pos = self.countries.get_pos(event["Target"])

                if event["Weapon"] == Weapons.LASER:
                    self.lasers.add(start, end_pos, self.TURN_LENGTH)
                else:
                    self.active_weapons.add(start, end_pos, event, self.TURN_LENGTH)

        for event in self.game.events["Death"]:
            end_pos = self.countries.get_pos(event["Target"])
            self.particles.add(end_pos)

        for event in self.game.events["Hit"]:
            if event["Weapon"] == Weapons.NUKE:
                self.shake.start(40)

            pos = self.countries.get_pos(event["Target"])
            self.explosions.add(pos, event["Weapon"])

    def screenshot(self):
        path = os.path.join("screenshots", str(PyGame.frame) + '.png')
        os.makedirs(os.path.dirname(path), exist_ok=True)
        pygame.image.save(self.window, path)
        PyGame.frame += 1

    def _finish_game(self):
        running = True
        while running:
            for event in pygame.event.get():
                if PyGame.quit_game(event):
                    running = False
                    pygame.quit()
                    return not PyGame.BATCH

                elif PyGame.press_f11(event):
                    self.toggle_fullscreen()

            self.clock.tick(self.FPS)

    @staticmethod
    def press_f11(event):
        return event.type == pygame.KEYUP and event.key == pygame.K_F11

    @staticmethod
    def quit_game(event):
        return (event.type == pygame.QUIT
                or (event.type == pygame.KEYUP
                    and event.key == pygame.K_ESCAPE))

    def toggle_fullscreen(self):
        self.fullscreen = not self.fullscreen

        if self.fullscreen:
            flag = DEFAULT_FLAG | pygame.FULLSCREEN

        pygame.display.set_mode(SIZE, flag)
示例#2
0
class PyGame:
    BATCH = False
    FPS = 60
    TURN_LENGTH = 1

    def __init__(self, window: pygame.Surface):
        self.end_game = None
        self.fullscreen = False
        self.window = window

        self.game = GameLogic()
        self.clock = pygame.time.Clock()
        self.active_weapons = ActiveWeapons()
        self.explosions = Explosions()
        self.lasers = Lasers()
        self.particles = Particles()
        self.shake = Shake()
        self.timer = time.time()

        self.countries = Countries(self.game.countries.countries, SIZE)

    def start(self):
        global SIZE

        running = True
        self.turn_surface = TITLE_FONT.render("ROUND " + str(self.game.turn),
                                              True, GUI_COLOUR)

        while running:
            for event in pygame.event.get():
                if PyGame.quit_game(event):
                    running = False
                    pygame.quit()
                    return 0

                elif PyGame.press_f11(event):
                    self.toggle_fullscreen()

                elif event.type == pygame.VIDEORESIZE:
                    SIZE = event.size
                    pygame.display.set_mode(event.size, DEFAULT_FLAG)
                    self.countries.resize(*event.size)

            # Refresh screen
            self.window.fill(BLACK)
            self.explosions.draw(self.window)
            self.window.blit(self.turn_surface, (10, 10))

            self.countries.draw(self.window)
            self.lasers.draw(self.window, self.FPS)
            self.particles.draw(self.window, self.FPS)
            self.active_weapons.draw(self.window)

            if time.time() - self.timer > self.TURN_LENGTH * self.game.turn:
                if not self.game.is_finished():
                    self.game.do_turn()
                    self.game.print_events()
                    self.animate_turn()
                    self.turn_surface = TITLE_FONT.render(
                        f"Round {self.game.turn}", True, GUI_COLOUR)

                elif not self.end_game:
                    self.end_game = time.time()

                    if self.BATCH:
                        self.end_game += 5

            if self.shake.is_active():
                self.shake.animate(self.window)

            pygame.display.update()
            self.clock.tick(self.FPS)

            if self.end_game and self.end_game < time.time():
                break

        if self.game.countries.get_alive_count():
            alive = self.game.countries.get_survivor()
            print(f"{alive} is the last one standing.")

        else:
            print("There were no survivors.")

        if not self.BATCH:
            self._finish_game()

    def animate_turn(self):
        for event in self.game.events:
            if "Attack" in event:
                if event["Attack"]["Success"]:
                    start = self.countries.get_pos(event["Attack"]["Source"])
                    end_pos = self.countries.get_pos(event["Attack"]["Target"])

                    if event["Attack"]["Weapon"] == Weapons.LASER:
                        self.lasers.add(start, end_pos, self.TURN_LENGTH)
                    else:
                        self.active_weapons.add(start, end_pos, event,
                                                self.TURN_LENGTH)

            elif "Death" in event:
                end_pos = self.countries.get_pos(event["Death"]["Target"])
                self.particles.add(end_pos)

            elif "Hit" in event:
                if event["Hit"]["Weapon"] == Weapons.NUKE:
                    self.shake.start(40)

                pos = self.countries.get_pos(event["Hit"]["Target"])
                self.explosions.add(pos, event["Hit"]["Weapon"])

    def _finish_game(self):
        running = True
        while running:
            for event in pygame.event.get():
                if PyGame.quit_game(event):
                    running = False
                    pygame.quit()
                    return 0

                elif PyGame.press_f11(event):
                    self.toggle_fullscreen()

            self.clock.tick(self.FPS)

    @staticmethod
    def press_f11(event):
        return event.type == pygame.KEYUP and event.key == pygame.K_F11

    @staticmethod
    def quit_game(event):
        return (event.type == pygame.QUIT or
                (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE))

    def toggle_fullscreen(self):
        self.fullscreen = not self.fullscreen

        if self.fullscreen:
            flag = DEFAULT_FLAG | pygame.FULLSCREEN

        pygame.display.set_mode(SIZE, flag)
示例#3
0
class PyGame:
    BATCH = False
    FPS = 60
    WIDTH = 800
    HEIGHT = 600
    TURN_LENGTH = 1

    def __init__(self, window: pygame.Surface):
        self.game = GameLogic()
        self.window = window
        self.clock = pygame.time.Clock()
        self.active_weapons = ActiveWeapons()
        self.explosions = Explosions()
        self.particles = Particles()
        self.timer = time.time()
        self.end_game = None

        self.countries = Countries(self.game.countries.countries, self.WIDTH,
                                   self.HEIGHT)

    def start(self):
        running = True
        self.turn_surface = TITLE_FONT.render("Round " + str(self.game.turn),
                                              True, GREY)

        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                    pygame.quit()
                    return 0

            # Refresh screen
            self.window.fill(BLACK)
            self.window.blit(self.turn_surface, (0, 0))

            self.countries.draw(self.window)
            self.explosions.draw(self.window)
            self.particles.draw(self.window, self.FPS)

            explosions = self.active_weapons.draw(self.window)
            for e in explosions:
                self.explosions.add(*e)

            if time.time() - self.timer > self.TURN_LENGTH * self.game.turn:
                if not self.game.is_finished():
                    self.game.do_turn()
                    self.game.print_events()
                    self.animate_turn()
                    self.turn_surface = TITLE_FONT.render(
                        "Round " + str(self.game.turn), True, GREY)

                elif not self.end_game:
                    self.end_game = time.time()
                    self.end_game += int(not self.BATCH)

            pygame.display.update()
            self.clock.tick(self.FPS)

            if self.end_game and self.end_game < time.time():
                break

        if self.game.countries.get_alive_count() == 1:
            alive = self.game.countries.get_survivor()
            print(alive, "is the last one standing.")

        else:
            print("There were no survivors.")

        if not self.BATCH:
            self._finish_game()

    def animate_turn(self):
        for event in self.game.events:
            if "Source" in event and "Target" in event and event["Success"]:
                start = self.countries.countries[event["Source"]].inner.center
                end = self.countries.countries[event["Target"]].inner.center

                self.active_weapons.add(start, end, event, self.TURN_LENGTH)

            elif "Death" in event:
                pos = self.countries.get_pos(event["Death"]["Target"])
                self.particles.add(pos)

    def _finish_game(self):
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                    pygame.quit()

                    return 0

            self.clock.tick(self.FPS)