예제 #1
0
class Game:
    def __init__(self, eventManager):
        self.statem = StateMachine()
        self.eventManager = eventManager
        eventManager.add_listener(self)
        self.on = False

    def notify(self, event):
        if isinstance(event, EndGame):
            self.stop()
        elif isinstance(event, ChangeState):
            # pop request
            if not event.state:
                # false if no more states are left
                if not self.statem.pop():
                    self.eventManager.Post(EndGame())
            else:
                # push a new state on the stack
                self.statem.push(event.state)

    def stop(self):
        self.on = False

    def run(self, mode='norm'):
        self.on = True
        self.eventManager.post(Start())
        if mode == 'test':
            self.statem.push(STATE_TEST)
        elif mode == 'light':
            pass
        else:
            self.statem.push(STATE_INTRO1)
        while self.on:
            newTick = Tick()
            self.eventManager.post(newTick)
예제 #2
0
class GameEngine(object):
    """
    De grafische weergave van het scherm. Handelt de states.
    """
    def __init__(self):
        self.screen = pygame.display.get_surface()
        self.gamestate = StateMachine()
        self.data = None
        self.video = Video()
        self.audio = Audio(self)

        self.running = False
        self.all_maps_loaded = False
        self.force_bg_music = False

        self.clock = pygame.time.Clock()
        self.playtime = 0.0
        self.dt = 0.0
        self.key_timer = 0.0
        self.state_timer = 0.0

        self.debugfont = pygame.font.SysFont(DEBUGFONT, DEBUGFONTSIZE)
        self.key_input = None
        self.mouse_input = None

        self.show_debug = False
        self.debug_mode = False
        self.fps = FPS

        threading.Thread(target=self.load_all_maps).start()

    def load_all_maps(self):
        """..."""
        map_path = 'resources/maps/'
        Console.load_all_maps()
        try:
            # noinspection PyTypeChecker
            for map_name in MapTitle:
                map_name.value.append(
                    pytmx.load_pygame(map_path + map_name.name + '.tmx'))
        except pygame.error:
            # bij het sluiten van het spel voordat alle kaarten geladen zijn.
            pass
        self.all_maps_loaded = True
        Console.maps_loaded()

    def on_enter(self):
        """
        Voordat de loop van start gaat.
        """
        self.running = True
        push_object = screens.menu.create_menu(GameState.MainMenu, self)
        self.gamestate.push(push_object)

    def main_loop(self):
        """
        Start de game loop.
        """
        while self.running:
            # limit the redraw speed to 60 frames per second
            self.dt = self.clock.tick(self.fps) / 1000.0
            self.playtime += self.dt

            if not self.gamestate.is_empty():
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        self.running = False
                    self.single_input(event)
                self.multi_input()
                self.update()
                self.render()
            pygame.display.flip()

            # pop() het laadscherm wanneer dat kan.
            if not self.gamestate.is_empty():
                if self.gamestate.peek().name == GameState.LoadScreen:
                    if self.all_maps_loaded:
                        self.gamestate.pop()

            # als de stack leeg is, push Overworld. Dit vanwege geluid en kaarten laden.
            if self.gamestate.is_empty():
                if self.all_maps_loaded:
                    self.gamestate.push(Overworld(self))

    def single_input(self, event):
        """
        Handelt de muis en keyboard input af.
        :param event: pygame.event.get()
        """
        if event.type == pygame.MOUSEMOTION:
            pygame.mouse.set_visible(True)

        # if event.type == pygame.MOUSEBUTTONDOWN:          # todo, tijdelijk staan ze uit
        #     Console.mouse_down(event.pos, event.button)
        if event.type == pygame.KEYDOWN:
            # Console.keyboard_down(event.key, event.unicode)
            pygame.mouse.set_visible(False)

            if self.debug_mode:
                if event.key == Keys.Debug.value:
                    # simple boolean swith
                    self.show_debug ^= True
                if event.key == Keys.Kill.value:
                    # todo, deze, de key en de methode moeten uiteindelijk weg.
                    self._kill_game()

        if self.key_timer == 0.0:
            self.gamestate.peek().single_input(event, self.gamestate,
                                               self.audio)

    def multi_input(self):
        """
        Handelt de ingedrukt-houden muis en keyboard input af.
        Wordt op dit moment alleen maar gebruikt voor visuele oplichten van de buttons en character movement.
        """
        if self.key_timer == 0.0:

            self.key_input = pygame.key.get_pressed()
            self.mouse_input = None
            if pygame.mouse.get_pressed()[0]:
                pygame.mouse.set_visible(True)
                self.mouse_input = pygame.mouse.get_pos()

            self.gamestate.peek().multi_input(self.key_input, self.mouse_input,
                                              self.dt)

    def update(self):
        """
        Handelt de timer af.
        Update de waarden van de bovenste state.
        """
        if self.key_timer > 0.0:
            self.key_timer -= self.dt
        if self.key_timer <= 0.0:
            self.key_timer = 0.0

        if self.state_timer > 0.0:
            self.state_timer -= self.dt
        if self.state_timer < 0.0:  # todo, wat nou als hij precies op 0.0 uitkomt?
            self.state_timer = 0.0
            self.gamestate.pop()

        self.gamestate.peek().update(self.dt, self.gamestate, self.audio)

    def render(self):
        """
        Laat de weergave van de bovenste states zien.
        En de debugscherm.
        """
        if self.gamestate.new_state:  # als hij zn cycle afmaakt, maar er is een nieuwe staat dan kan het fout gaan
            self.gamestate.new_state = False  # dit maakt dat hij uit de cycle springt.
            return

        self.gamestate.peek().render()
        self._show_debug()

    @staticmethod
    def _kill_game():
        import sys
        pygame.quit()
        sys.exit()

    def change_fps(self):
        """..."""
        old_fps = self.fps
        if self.fps < 100:
            self.fps += 40
        else:
            self.fps = 20
        new_fps = self.fps
        return old_fps, new_fps

    def _show_debug(self):
        if self.show_debug:
            text = ("FPS:               {:.2f}".format(self.clock.get_fps()),
                    "dt:                {:.3f}".format(self.dt),
                    "playtime:          {:.2f}".format(self.playtime),
                    "key_timer:         {}".format(self.key_timer),
                    "state_timer:       {}".format(self.state_timer), "",
                    "mouse_input:       {}".format(self.mouse_input), "")
            try:
                text2 = ("menu_name:         {}".format(
                    self.gamestate.peek().name),
                         "cur_item:          {}".format(
                             self.gamestate.peek().cur_item),
                         "scr_capt:          {}".format(
                             self.gamestate.peek().scr_capt), "")
                text += text2
            except AttributeError:
                pass
            try:
                hero = self.gamestate.peek().window.party_sprites[0]
                text2 = ("map:               {}".format(
                    self.data.map_name), "prev_map:          {}".format(
                        self.gamestate.peek().window.prev_map_name),
                         "zoom:              {:.1f}".format(
                             self.gamestate.peek().window.current_map.
                             map_layer.zoom), "time_up:           {}".format(
                                 hero.time_up), "time_down:         {}".format(
                                     hero.time_down),
                         "time_left:         {}".format(hero.time_left),
                         "time_right:        {}".format(hero.time_right),
                         "time_delay:        {}".format(hero.time_delay),
                         "last_direction:    {}".format(hero.last_direction),
                         "move_direction:    {}".format(hero.move_direction),
                         "movespeed:         {}".format(hero.movespeed), "",
                         "old_position.x:    {}".format(hero.old_position[0]),
                         "old_position.y:    {}".format(hero.old_position[1]),
                         "", "hero.rect.x:       {}".format(hero.rect.x),
                         "hero.rect.y:       {}".format(hero.rect.y), "",
                         "true_position.x:   {}".format(hero.true_position[0]),
                         "true_position.y:   {}".format(hero.true_position[1]),
                         "", "step_count:        {}".format(
                             hero.step_count), "step_animation:    {}".format(
                                 hero.step_animation), "")
                text += text2
            except AttributeError:
                pass
            try:
                text2 = ("hc:                {}".format(
                    self.gamestate.peek().hc), )
                text += text2
            except AttributeError:
                pass
            try:
                import screens.party.invclickbox
                text2 = ("max_box_height:    {}".format(
                    screens.party.invclickbox.MAXBOXHEIGHT),
                         "layer_height:      {}".format(
                             self.gamestate.peek().invclick_box.layer_height),
                         "cur_item:          {}".format(
                             self.gamestate.peek().invclick_box.cur_item), "")
                text += text2
            except AttributeError:
                pass
            text2 = ("",
                     "prev_state:        {}".format(self.gamestate.prev_state),
                     "", "StateStack:")
            textb = []
            for state in self.gamestate.statestack:
                textb.append(str(state.name))
            textb.reverse()
            text2 += tuple(textb)
            text += text2

            pygame.gfxdraw.box(self.screen, DEBUGRECT, DEBUGRECTCOLOR)
            for count, line in enumerate(text):
                self.screen.blit(
                    self.debugfont.render(line, True,
                                          DEBUGFONTCOLOR).convert_alpha(),
                    (0, count * 10))
예제 #3
0
파일: engine.py 프로젝트: thomas64/pyRPG2
class GameEngine(object):
    """
    De grafische weergave van het scherm. Handelt de states.
    """
    def __init__(self):
        self.screen = pygame.display.get_surface()
        self.gamestate = StateMachine()
        self.data = None
        self.video = Video()
        self.audio = Audio(self)

        self.running = False
        self.all_maps_loaded = False
        self.force_bg_music = False

        self.clock = pygame.time.Clock()
        self.playtime = 0.0
        self.dt = 0.0
        self.key_timer = 0.0
        self.state_timer = 0.0

        self.debugfont = pygame.font.SysFont(DEBUGFONT, DEBUGFONTSIZE)
        self.key_input = None
        self.mouse_input = None

        self.show_debug = False
        self.debug_mode = True
        self.fps = FPS

        threading.Thread(target=self.load_all_maps).start()

    def load_all_maps(self):
        """..."""
        map_path = 'resources/maps/'
        Console.load_all_maps()
        try:
            # noinspection PyTypeChecker
            for map_name in MapTitle:
                map_name.value.append(pytmx.load_pygame(map_path + map_name.name + '.tmx'))
        except pygame.error:
            # bij het sluiten van het spel voordat alle kaarten geladen zijn.
            pass
        self.all_maps_loaded = True
        Console.maps_loaded()

    def on_enter(self):
        """
        Voordat de loop van start gaat.
        """
        self.running = True
        push_object = screens.menu.create_menu(GameState.MainMenu, self)
        self.gamestate.push(push_object)

    def main_loop(self):
        """
        Start de game loop.
        """
        while self.running:
            # limit the redraw speed to 60 frames per second
            self.dt = self.clock.tick(self.fps)/1000.0
            self.playtime += self.dt

            if not self.gamestate.is_empty():
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        self.running = False
                    self.single_input(event)
                self.multi_input()
                self.update()
                self.render()
            pygame.display.flip()

            # pop() het laadscherm wanneer dat kan.
            if not self.gamestate.is_empty():
                if self.gamestate.peek().name == GameState.LoadScreen:
                    if self.all_maps_loaded:
                        self.gamestate.pop()

            # als de stack leeg is, push Overworld. Dit vanwege geluid en kaarten laden.
            if self.gamestate.is_empty():
                if self.all_maps_loaded:
                    self.gamestate.push(Overworld(self))

    def single_input(self, event):
        """
        Handelt de muis en keyboard input af.
        :param event: pygame.event.get()
        """
        if event.type == pygame.MOUSEMOTION:
            pygame.mouse.set_visible(True)

        # if event.type == pygame.MOUSEBUTTONDOWN:          # todo, tijdelijk staan ze uit
        #     Console.mouse_down(event.pos, event.button)
        if event.type == pygame.KEYDOWN:
            # Console.keyboard_down(event.key, event.unicode)
            pygame.mouse.set_visible(False)

            if self.debug_mode:
                if event.key == Keys.Debug.value:
                    # simple boolean swith
                    self.show_debug ^= True
                if event.key == Keys.Kill.value:
                    # todo, deze, de key en de methode moeten uiteindelijk weg.
                    self._kill_game()

        if self.key_timer == 0.0:
            self.gamestate.peek().single_input(event, self.gamestate, self.audio)

    def multi_input(self):
        """
        Handelt de ingedrukt-houden muis en keyboard input af.
        Wordt op dit moment alleen maar gebruikt voor visuele oplichten van de buttons en character movement.
        """
        if self.key_timer == 0.0:

            self.key_input = pygame.key.get_pressed()
            self.mouse_input = None
            if pygame.mouse.get_pressed()[0]:
                pygame.mouse.set_visible(True)
                self.mouse_input = pygame.mouse.get_pos()

            self.gamestate.peek().multi_input(self.key_input, self.mouse_input, self.dt)

    def update(self):
        """
        Handelt de timer af.
        Update de waarden van de bovenste state.
        """
        if self.key_timer > 0.0:
            self.key_timer -= self.dt
        if self.key_timer <= 0.0:
            self.key_timer = 0.0

        if self.state_timer > 0.0:
            self.state_timer -= self.dt
        if self.state_timer < 0.0:  # todo, wat nou als hij precies op 0.0 uitkomt?
            self.state_timer = 0.0
            self.gamestate.pop()

        self.gamestate.peek().update(self.dt, self.gamestate, self.audio)

    def render(self):
        """
        Laat de weergave van de bovenste states zien.
        En de debugscherm.
        """
        if self.gamestate.new_state:    # als hij zn cycle afmaakt, maar er is een nieuwe staat dan kan het fout gaan
            self.gamestate.new_state = False    # dit maakt dat hij uit de cycle springt.
            return

        self.gamestate.peek().render()
        self._show_debug()

    @staticmethod
    def _kill_game():
        import sys
        pygame.quit()
        sys.exit()

    def change_fps(self):
        """..."""
        old_fps = self.fps
        if self.fps < 100:
            self.fps += 40
        else:
            self.fps = 20
        new_fps = self.fps
        return old_fps, new_fps

    def _show_debug(self):
        if self.show_debug:
            text = (
                "FPS:               {:.2f}".format(self.clock.get_fps()),
                "dt:                {:.3f}".format(self.dt),
                "playtime:          {:.2f}".format(self.playtime),
                "key_timer:         {}".format(self.key_timer),
                "state_timer:       {}".format(self.state_timer),
                "",
                "mouse_input:       {}".format(self.mouse_input),
                ""
            )
            try:
                text2 = (
                    "menu_name:         {}".format(self.gamestate.peek().name),
                    "cur_item:          {}".format(self.gamestate.peek().cur_item),
                    "scr_capt:          {}".format(self.gamestate.peek().scr_capt),
                    ""
                )
                text += text2
            except AttributeError:
                pass
            try:
                hero = self.gamestate.peek().window.party_sprites[0]
                text2 = (
                    "map:               {}".format(self.data.map_name),
                    "prev_map:          {}".format(self.gamestate.peek().window.prev_map_name),
                    "zoom:              {:.1f}".format(self.gamestate.peek().window.current_map.map_layer.zoom),
                    "time_up:           {}".format(hero.time_up),
                    "time_down:         {}".format(hero.time_down),
                    "time_left:         {}".format(hero.time_left),
                    "time_right:        {}".format(hero.time_right),
                    "time_delay:        {}".format(hero.time_delay),
                    "last_direction:    {}".format(hero.last_direction),
                    "move_direction:    {}".format(hero.move_direction),
                    "movespeed:         {}".format(hero.movespeed),
                    "",
                    "old_position.x:    {}".format(hero.old_position[0]),
                    "old_position.y:    {}".format(hero.old_position[1]),
                    "",
                    "hero.rect.x:       {}".format(hero.rect.x),
                    "hero.rect.y:       {}".format(hero.rect.y),
                    "",
                    "true_position.x:   {}".format(hero.true_position[0]),
                    "true_position.y:   {}".format(hero.true_position[1]),
                    "",
                    "step_count:        {}".format(hero.step_count),
                    "step_animation:    {}".format(hero.step_animation),
                    ""
                )
                text += text2
            except AttributeError:
                pass
            try:
                text2 = (
                    "hc:                {}".format(self.gamestate.peek().hc),
                )
                text += text2
            except AttributeError:
                pass
            try:
                import screens.party.invclickbox
                text2 = (
                    "max_box_height:    {}".format(screens.party.invclickbox.MAXBOXHEIGHT),
                    "layer_height:      {}".format(self.gamestate.peek().invclick_box.layer_height),
                    "cur_item:          {}".format(self.gamestate.peek().invclick_box.cur_item),
                    ""
                )
                text += text2
            except AttributeError:
                pass
            text2 = (
                "",
                "prev_state:        {}".format(self.gamestate.prev_state),
                "",
                "StateStack:"
            )
            textb = []
            for state in self.gamestate.statestack:
                textb.append(str(state.name))
            textb.reverse()
            text2 += tuple(textb)
            text += text2

            pygame.gfxdraw.box(self.screen, DEBUGRECT, DEBUGRECTCOLOR)
            for count, line in enumerate(text):
                self.screen.blit(self.debugfont.render(line, True, DEBUGFONTCOLOR).convert_alpha(), (0, count * 10))