コード例 #1
0
ファイル: main.py プロジェクト: thomas64/pyRPG
    def _init_map(self):
        """
        Laad de tmx data en maak daaruit een group variabele.
        Maak een grid aan en een map.
        Vul bomen, waters en obstacles.
        """
        tmx_data = pytmx.load_pygame(MAPPATH)
        map_data = pyscroll.data.TiledMapData(tmx_data)
        map_layer = pyscroll.BufferedRenderer(map_data, (WINDOWWIDTH, WINDOWHEIGHT), clamp_camera=True)
        self.group = pyscroll.PyscrollGroup(map_layer=map_layer, default_layer=PLAYERLAYER)

        self.grid_sprite = GridSprite(tmx_data.width * tmx_data.tilewidth,
                                      tmx_data.height * tmx_data.tileheight,
                                      GRIDSIZE, GRIDLAYER)

        self.map1 = Map(tmx_data)

        for rect in tmx_data.get_layer_by_name("trees"):
            self.map1.add_rect_to_list(rect, self.map1.tree_rects)
            self.map1.add_rect_to_list(rect, self.map1.obstacle_rects)
        for rect in tmx_data.get_layer_by_name("water"):
            self.map1.add_rect_to_list(rect, self.map1.water_rects)
            self.map1.add_rect_to_list(rect, self.map1.low_obst_rects)
        for rect in tmx_data.get_layer_by_name("warphole"):
            self.map1.warphole_rect = pygame.Rect(rect.x, rect.y, rect.width, rect.height)
コード例 #2
0
ファイル: screen.py プロジェクト: henkburgstra/pyRPG
    def __init__(self):
        global SCREENHEIGHT, SCREENWIDTH
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()
        info = pygame.display.Info()
        if info.current_h != -1:
            SCREENWIDTH = info.current_w
            SCREENHEIGHT = info.current_h
        self._screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT), pygame.DOUBLEBUF | pygame.FULLSCREEN)
        self._background = pygame.Surface(self._screen.get_size())
        self._background.fill(BLACK)
        self._background = self._background.convert()
        self._window = pygame.Surface(WINDOWSIZE)
        self._window = self._window.convert()

        self._clock = pygame.time.Clock()
        self._fps = FPS
        self._debugfont = pygame.font.SysFont('courier', 11)
        self._buttonfont = pygame.font.SysFont('sans', 14)

        self._debug = False

        self._is_viewing = False
        self._view_x, self._view_y = (0, 0)

        self._key_input = None
        self._init_buttons()

        self._map = Map('resources/maps/area01/new.tmx', PLAYERLAYER, *WINDOWSIZE)
        self._player = []       # lijst van hero sprite classes, incl rect voor visuele locatie
        i = 0
        for hero_raw in Output.HERO_SORT:
            hero = data.heroes[hero_raw]
            if hero in data.party:
                self._player.append(Hero((336 + i * 32, 272 + i * 32), hero.BMP))
                # vul in de map de lijst van rects van alle heroes
                self._map.add_rect_to_list(self._player[i].rect, self._map.heroes)
                self._map.add_rect_to_list(self._player[i].rect, self._map.obstacles)
                i += 1
        self._pointer = Pointer(POINTERLAYER)
        self._moverange = MoveRange(MOVERANGESIZE, MOVERANGELAYER)

        # speler 0 alagos is de eerste cu
        self._cu = 0
        self._start_of_turn()

        self._map.add_sprite_to_map_layer_group(self._moverange)
        # voeg de LIJST van hero sprites toe aan de visuele groep
        self._map.add_sprite_to_map_layer_group(self._player)
        self._map.add_sprite_to_map_layer_group(self._pointer)
コード例 #3
0
ファイル: main.py プロジェクト: thomas64/pyRPG
class BattleScreen(object):
    """
    De grafische weergave van het scherm.
    """
    def __init__(self):
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()
        self.screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT), pygame.DOUBLEBUF)  # | pygame.FULLSCREEN)
        self.background = pygame.Surface(self.screen.get_size())
        self.background.fill(BLACK)
        self.background = self.background.convert()
        self.window = pygame.Surface((WINDOWWIDTH, WINDOWHEIGHT))
        self.window.fill(DARKGRAY)
        self.window = self.window.convert()

        self.state = StateMachine()

        self.running = False

        self.clock = pygame.time.Clock()
        self.playtime = 0
        self.milliseconds = 0
        self.timer = 0

        self.debugfont = pygame.font.SysFont('courier', 11)
        self.titlefont = pygame.font.SysFont('sans', 25, True)

        self.key_input = None
        self._init_map()
        self._init_units()
        self._init_buttons()

        self.pointer_sprite = PointerSprite(POINTERLAYER)
        self.group.add(self.pointer_sprite)

        self.moverange_sprite = MoveRangeSprite(MOVERANGESIZE, MOVERANGELAYER)

        self.cu = 0

        self.show_grid = False
        self.show_cbox = False
        self.show_debug = False

        self.scroll_timer = 0
        self.scroll_step = [0, 0]
        self.scroll_current = [0, 0]

        self.start_of_turn()

    def _init_map(self):
        """
        Laad de tmx data en maak daaruit een group variabele.
        Maak een grid aan en een map.
        Vul bomen, waters en obstacles.
        """
        tmx_data = pytmx.load_pygame(MAPPATH)
        map_data = pyscroll.data.TiledMapData(tmx_data)
        map_layer = pyscroll.BufferedRenderer(map_data, (WINDOWWIDTH, WINDOWHEIGHT), clamp_camera=True)
        self.group = pyscroll.PyscrollGroup(map_layer=map_layer, default_layer=PLAYERLAYER)

        self.grid_sprite = GridSprite(tmx_data.width * tmx_data.tilewidth,
                                      tmx_data.height * tmx_data.tileheight,
                                      GRIDSIZE, GRIDLAYER)

        self.map1 = Map(tmx_data)

        for rect in tmx_data.get_layer_by_name("trees"):
            self.map1.add_rect_to_list(rect, self.map1.tree_rects)
            self.map1.add_rect_to_list(rect, self.map1.obstacle_rects)
        for rect in tmx_data.get_layer_by_name("water"):
            self.map1.add_rect_to_list(rect, self.map1.water_rects)
            self.map1.add_rect_to_list(rect, self.map1.low_obst_rects)
        for rect in tmx_data.get_layer_by_name("warphole"):
            self.map1.warphole_rect = pygame.Rect(rect.x, rect.y, rect.width, rect.height)

    def _init_units(self):
        """
        Maak een lijst van units aan. Zet de party sprites erin. Voeg ze toe aan de view groep.
        """
        self.units = []
        i = 0
        for hero in data.party:
            self.units.append(UnitSprite(hero.BMP, [320 + i * 32, 320 + i * 32]))
            # todo, dit moet nog de echte hero class worden
            i += 1
        self.group.add(self.units)

    def _init_buttons(self):
        """
        Maak de knoppen aan en zet ze in een lijst.
        Plaats ook de bijbehorende keys in een lijst.
        """
        button_view = ButtonSprite((SCREENWIDTH-200,   SCREENHEIGHT-300), "V",     pygame.K_v)
        button_up = ButtonSprite((SCREENWIDTH-150,     SCREENHEIGHT-300), "Up",    pygame.K_UP)
        button_down = ButtonSprite((SCREENWIDTH-150,   SCREENHEIGHT-250), "Down",  pygame.K_DOWN)
        button_left = ButtonSprite((SCREENWIDTH-200,   SCREENHEIGHT-250), "Left",  pygame.K_LEFT)
        button_right = ButtonSprite((SCREENWIDTH-100,  SCREENHEIGHT-250), "Right", pygame.K_RIGHT)
        button_cancel = ButtonSprite((SCREENWIDTH-100, SCREENHEIGHT-200), "C",     pygame.K_c)

        self.buttons = [button_view, button_up, button_down, button_left, button_right, button_cancel]

    def run(self):
        """
        Start de game loop.
        """
        self.running = True
        self.state.push(State.Play)
        self.state.push(State.Intro)

        while self.running:
            self.milliseconds = self.clock.tick(FPS)        # limit the redraw speed to 60 frames per second
            self.playtime += self.milliseconds

            currentstate = self.state.peek()
            self.handle_view(currentstate)
            self.handle_multi_input(currentstate)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                self.handle_single_input(event, currentstate)
            self.handle_triggers(currentstate)

        pygame.quit()

    def handle_view(self, currentstate):
        """
        Laat de weergave van de verschillende states zien.
        :param currentstate: bovenste state van de stack
        """
        if currentstate == State.Intro:
            self.handle_timer(INTROTIME, currentstate)
            self.render_intro()
        if currentstate == State.Play:
            self.render_play(self.units[self.cu].rect.center)
        if currentstate == State.Menu:
            self.render_menu()
        if currentstate == State.Help:
            self.render_help()
        if currentstate == State.Scroll:
            if self.playtime > self.scroll_timer + SCROLLTIME:
                self.render_play(self.scroll_current)
                self.scroll_timer = 0
                self.scroll_step = [0, 0]
                self.scroll_current = [0, 0]
                self.state.pop(currentstate)
            else:
                self.render_play(self.scroll_current)
                self.scroll_current[0] -= self.scroll_step[0] * self.milliseconds
                self.scroll_current[1] -= self.scroll_step[1] * self.milliseconds
        if currentstate == State.View:
            self.render_play(self.pointer_sprite.rect.center)

        pygame.display.flip()
        self.screen.blit(self.background, (0, 0))

    def handle_multi_input(self, currentstate):
        """
        Handelt de ingedrukt-houden muis en keyboard input af.
        :param currentstate: bovenste state van de stack
        """
        self.key_input = pygame.key.get_pressed()
        if pygame.mouse.get_pressed()[0]:
            pos = pygame.mouse.get_pos()
            for button in self.buttons:
                if button.rect.collidepoint(pos):
                    self.key_input = list(self.key_input)
                    self.key_input[button.key] = 1

        if currentstate == State.Play:
            self.units[self.cu].speed(self.key_input)
            self.units[self.cu].direction(self.key_input)
            self.units[self.cu].check_obstacle(self.map1.obstacle_rects, self.map1.low_obst_rects,
                                               self.moverange_sprite, self.map1.width, self.map1.height)

        if currentstate == State.View:
            self.pointer_sprite.move(self.key_input, self.map1.width, self.map1.height)

    def handle_single_input(self, event, currentstate):
        """
        Handelt de muis en keyboard input af.
        :param event: pygame.event.get()
        :param currentstate: bovenste state van de stack
        """
        key_input = None

        if event.type == pygame.KEYDOWN:            # handle key down events
            print("Keyboard, key={}, unicode={}".format(event.key, event.unicode))

            if event.key == pygame.K_c:
                key_input = 'c'
            elif event.key == pygame.K_v:
                key_input = 'v'

            if currentstate == State.Menu:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                elif event.key == pygame.K_SPACE:
                    self.state.pop(currentstate)

            if currentstate == State.Help:
                if event.key in [pygame.K_ESCAPE, pygame.K_SPACE, pygame.K_RETURN]:
                    self.state.pop(currentstate)

            if currentstate == State.Play:
                if event.key == pygame.K_ESCAPE:
                    self.state.push(State.Menu)
                elif event.key == pygame.K_SPACE:
                    self.units[self.cu].align_to_grid(TILESIZE)
                elif event.key == pygame.K_F1:
                    self.state.push(State.Help)
                elif event.key == pygame.K_F10:
                    self.show_grid ^= True
                elif event.key == pygame.K_F11:
                    self.show_cbox ^= True
                elif event.key == pygame.K_F12:
                    self.show_debug ^= True             # simple boolean swith

        if event.type == pygame.MOUSEBUTTONDOWN:    # handle mouse down events
            print("Mouse, pos={}, button={}".format(event.pos, event.button))

            if event.button == 1:
                for button in self.buttons:
                    if button.rect.collidepoint(event.pos):

                        if button.key == pygame.K_c:
                            key_input = 'c'
                        elif button.key == pygame.K_v:
                            key_input = 'v'

        if currentstate == State.View:
            if key_input == 'c' or key_input == 'v':
                self.state.pop(currentstate)
                scroll_begin = list(self.pointer_sprite.rect.center)
                scroll_end = list(self.units[self.cu].rect.center)
                self.start_of_scroll(scroll_begin, scroll_end)

        if currentstate == State.Play:
            if key_input == 'c':
                self.end_of_turn()
            elif key_input == 'v':
                self.units[self.cu].stand()
                self.units[self.cu].animate()
                self.state.push(State.View)

    def handle_triggers(self, currentstate):
        """
        Handelt de triggers en conditions af.
        :param currentstate: bovenste state van de stack
        """
        if currentstate == State.Play:
            if self.units[self.cu].rect.colliderect(self.map1.warphole_rect):
                self.state.push(State.Menu)
                import game
                game.PartyWindow(None).ShowModal()
                print("Warp!")

    def handle_timer(self, wait_time, currentstate):
        """
        Laat het spel een bepaalde tijd in de huidige state verblijven.
        Na de bepaalde tijd, pop de state.
        :param wait_time: is de ingestelde wachttijd
        :param currentstate: bovenste state van de stack
        """
        if self.timer == 0:
            self.timer = self.playtime

        if self.playtime > self.timer + wait_time:
            self.timer = 0
            self.state.pop(currentstate)

    def render_intro(self):
        """
        Render the game intro.
        """
        bg_rect = self.background.get_rect()

        somewords = self.titlefont.render('Battle...!', True, GREEN)
        text_rect = somewords.get_rect()
        text_rect.center = bg_rect.width/2, bg_rect.height/2

        self.screen.blit(somewords, text_rect.topleft)

    def render_play(self, center_pixel):
        """
        Render the game play.
        :param center_pixel: de pixel op de map waar het midden van de window op moet locaten
        """
        def draw_grid():
            """
            Voeg de grid toe aan de group om hem weer te laten geven.
            """
            if self.show_grid:
                self.group.add(self.grid_sprite)
            else:
                self.group.remove(self.grid_sprite)

        def draw_cboxes():
            """
            Voeg de gekleurde rects toe aan de group om ze weer te laten geven.
            Ga in de group de spritelist langs en bekijk of er ColorBoxSprites tussen zitten.
            Indien zo, verwijder die.
            Als F11 aanstaat, voeg de cbox_sprites list weer toe aan de group.
            """
            for sprite in self.group:
                if isinstance(sprite, ColorBoxSprite):
                    self.group.remove(sprite)

            if self.show_cbox:
                self.map1.current_sprite.rect.topleft = self.units[self.cu].rect.topleft
                self.group.add(self.map1.cbox_sprites)
                self.group.add(self.map1.current_sprite)

        def draw_moverange():
            """
            Als moverange niet in de group zit (en dat gebeurt bij end_of_turn, want daar wordt hij eruit gehaald).
            En hij is niet aan het scrollen.
            Update dan de moverange van plaats en voeg hem weer toe aan de group.
            Dit gebeurt steeds maar eenmalig aan het begin van een beurt.
            Toch zijn deze twee regels uit start_of_turn gehaald, want anders zou hij de moverange al updaten
            tijdens het scrollen, en dat is niet de bedoeling. Vandaar deze oplossing. Ik weet nog niet of hij
            wel netjes is aangezien ik nog een keer op currentstate check, en op scrollen.
            """
            if self.moverange_sprite not in self.group:
                currentstate = self.state.peek()
                if currentstate != State.Scroll:
                    self.moverange_sprite.update(self.units[self.cu].rect.center)
                    self.group.add(self.moverange_sprite)

        def show_window():
            """
            Tekent alles in de window.
            """
            somewords = self.titlefont.render('This is the play screen. Esc for Menu. F1 for help', True, GREEN)

            self.pointer_sprite.update(center_pixel)

            self.group.center(center_pixel)
            self.group.draw(self.window)
            self.window.blit(somewords, (0, 0))
            self.screen.blit(self.window, WINDOWPOS)

        def show_buttons():
            """
            Tekent de knoppen op het scherm.
            """
            for button in self.buttons:
                button.draw(self.screen, self.key_input)

        def show_debug():
            """
            Geeft debug informatie weer linksboven in het scherm.
            """
            if self.show_debug:
                cu = self.units[self.cu]
                text = ("FPS:              {}".format(int(self.clock.get_fps())),
                        "milliseconds:     {}".format(int(self.milliseconds)),
                        "playtime:         {}".format(int(self.playtime)),
                        "time_up:          {}".format(cu.time_up),
                        "time_down:        {}".format(cu.time_down),
                        "time_left:        {}".format(cu.time_left),
                        "time_right:       {}".format(cu.time_right),
                        "time_delay:       {}".format(cu.time_delay),
                        "cu:               {}".format(self.cu),
                        "last_direction:   {}".format(cu.last_direction),
                        "move_direction:   {}".format(cu.move_direction),
                        "movespeed:        {}".format(cu.movespeed),
                        "start_position.x: {}".format(self.map1.start_pos_rect.x),
                        "start_position.y: {}".format(self.map1.start_pos_rect.y),
                        "old_position.x:   {}".format(cu.old_position[0]),
                        "old_position.y    {}".format(cu.old_position[1]),
                        "new_position.x:   {}".format(cu.rect.x),
                        "new_position.y    {}".format(cu.rect.y),
                        "pointer.x:        {}".format(self.pointer_sprite.rect.centerx),
                        "pointer.y:        {}".format(self.pointer_sprite.rect.centery),
                        "step_count:       {}".format(cu.step_count),
                        "step_animation:   {}".format(cu.step_animation),
                        )
                for count, line in enumerate(text):
                    self.screen.blit(self.debugfont.render(line, True, WHITE), (0, count * 10))

        draw_grid()
        draw_cboxes()
        draw_moverange()
        show_window()
        show_buttons()
        show_debug()

    def render_menu(self):
        """
        Render the game menu.
        """
        somewords = self.titlefont.render('You are in the Menu. Space to play. Esc exits.', True, GREEN)
        self.screen.blit(somewords, (0, 0))

    def render_help(self):
        """
        Render the help screen.
        """
        somewords = self.titlefont.render('Help is here. space, escape or return.', True, GREEN)
        self.screen.blit(somewords, (0, 0))

    def start_of_turn(self):
        """
        Vul de lijst van hero_rects met de actuele rects van de units.
        Als een unit nog niet in de obstacles staat, voeg hem toe.
        Verwijder de huidige hero van hero_rects en obstacles.
        Voeg de start positie toe, voeg de current_spirte toe.
        Vernieuw de cbox lijst volledig.
        """
        for unit in self.units:
            if unit.rect not in self.map1.hero_rects:
                self.map1.add_rect_to_list(unit.rect, self.map1.hero_rects)
            if unit.rect not in self.map1.obstacle_rects:
                self.map1.add_rect_to_list(unit.rect, self.map1.obstacle_rects)
        self.map1.del_rect_from_list(self.units[self.cu].rect, self.map1.hero_rects)
        self.map1.del_rect_from_list(self.units[self.cu].rect, self.map1.obstacle_rects)

        self.map1.start_pos_rect = pygame.Rect(self.units[self.cu].rect)
        self.map1.current_sprite = ColorBoxSprite(self.units[self.cu].rect, 'hero', GRIDLAYER)

        self.map1.clear_cbox()
        self.map1.add_all_lists_to_cbox()

    def end_of_turn(self):
        """
        Laat de huidige unit afronden, kies een volgende unit uit de party. Begin scrollen.
        """
        self.units[self.cu].align_to_grid(TILESIZE)
        self.units[self.cu].stand()
        self.units[self.cu].animate()

        self.group.remove(self.moverange_sprite)

        scroll_begin = list(self.units[self.cu].rect.center)

        self.cu += 1
        if self.cu > len(data.party) - 1:
            self.cu = 0

        scroll_end = list(self.units[self.cu].rect.center)

        self.start_of_scroll(scroll_begin, scroll_end)
        self.start_of_turn()

    def start_of_scroll(self, begin, end):
        """
        Stel de voorwaarden in om te kunnen scrollen.
        :param begin: start x en y positie
        :param end: finish x en y positie
        """
        self.scroll_timer = self.playtime
        # scroll_step = [10, 15] is het aantal pixels per seconde
        self.scroll_step = [(begin[0] - end[0]) / SCROLLTIME,
                            (begin[1] - end[1]) / SCROLLTIME]
        self.scroll_current = list(begin)
        self.state.push(State.Scroll)
コード例 #4
0
ファイル: screen.py プロジェクト: henkburgstra/pyRPG
class BattleWindow(object):
    def __init__(self):
        global SCREENHEIGHT, SCREENWIDTH
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()
        info = pygame.display.Info()
        if info.current_h != -1:
            SCREENWIDTH = info.current_w
            SCREENHEIGHT = info.current_h
        self._screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT), pygame.DOUBLEBUF | pygame.FULLSCREEN)
        self._background = pygame.Surface(self._screen.get_size())
        self._background.fill(BLACK)
        self._background = self._background.convert()
        self._window = pygame.Surface(WINDOWSIZE)
        self._window = self._window.convert()

        self._clock = pygame.time.Clock()
        self._fps = FPS
        self._debugfont = pygame.font.SysFont('courier', 11)
        self._buttonfont = pygame.font.SysFont('sans', 14)

        self._debug = False

        self._is_viewing = False
        self._view_x, self._view_y = (0, 0)

        self._key_input = None
        self._init_buttons()

        self._map = Map('resources/maps/area01/new.tmx', PLAYERLAYER, *WINDOWSIZE)
        self._player = []       # lijst van hero sprite classes, incl rect voor visuele locatie
        i = 0
        for hero_raw in Output.HERO_SORT:
            hero = data.heroes[hero_raw]
            if hero in data.party:
                self._player.append(Hero((336 + i * 32, 272 + i * 32), hero.BMP))
                # vul in de map de lijst van rects van alle heroes
                self._map.add_rect_to_list(self._player[i].rect, self._map.heroes)
                self._map.add_rect_to_list(self._player[i].rect, self._map.obstacles)
                i += 1
        self._pointer = Pointer(POINTERLAYER)
        self._moverange = MoveRange(MOVERANGESIZE, MOVERANGELAYER)

        # speler 0 alagos is de eerste cu
        self._cu = 0
        self._start_of_turn()

        self._map.add_sprite_to_map_layer_group(self._moverange)
        # voeg de LIJST van hero sprites toe aan de visuele groep
        self._map.add_sprite_to_map_layer_group(self._player)
        self._map.add_sprite_to_map_layer_group(self._pointer)

    def _init_buttons(self):
        self._button_view = Button((SCREENWIDTH-200,   SCREENHEIGHT-300), "V")
        self._button_up = Button((SCREENWIDTH-150,     SCREENHEIGHT-300), "Up")
        self._button_down = Button((SCREENWIDTH-150,   SCREENHEIGHT-250), "Down")
        self._button_left = Button((SCREENWIDTH-200,   SCREENHEIGHT-250), "Left")
        self._button_right = Button((SCREENWIDTH-100,  SCREENHEIGHT-250), "Right")
        self._button_cancel = Button((SCREENWIDTH-100, SCREENHEIGHT-200), "C")

        self._buttons = [self._button_view, self._button_up, self._button_down, self._button_left, self._button_right,
                         self._button_cancel]
        self._keys = [pygame.K_v, pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT,
                      pygame.K_c]

    def _start_of_turn(self):
        # de rect van de player die aan de beurt is weer verwijderen en ken de start_pos toe
        self._map.del_rect_from_list(self._player[self._cu].rect, self._map.heroes)
        self._map.del_rect_from_list(self._player[self._cu].rect, self._map.obstacles)
        self._map.add_rect_to_list(self._player[self._cu].rect, self._map.start_pos)
        self._moverange.update(self._player[self._cu].rect.center)

    def _end_of_turn(self):
        self._moverange.update(CLEARPOS)
        self._player[self._cu].align_to_grid(GRIDSIZE)
        # voeg de betreffende rect toe aan de lists en verwijder de rect van start_pos
        self._map.add_rect_to_list(self._player[self._cu].rect, self._map.heroes)
        self._map.add_rect_to_list(self._player[self._cu].rect, self._map.obstacles)
        self._map.start_pos = []

        # van waar tot waar moet je scrollen
        start_x, start_y = self._player[self._cu].rect.center
        self._cu += 1
        if self._cu > len(data.party) - 1:
            self._cu = 0
        end_x, end_y = self._player[self._cu].rect.center
        self._scroll_map(start_x, start_y, end_x, end_y)

        self._reset_vars()
        self._start_of_turn()

    def _reset_vars(self):
        self._is_viewing = False
        self._view_x, self._view_y = self._player[self._cu].rect.center

    def run(self):
        game_over = False
        while not game_over:

            self._clock.tick(self._fps)
            self._key_input = pygame.key.get_pressed()

            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    for button in self._buttons:
                        self._key_input = button.handle_event()

                # if 'down' in self._button_up.handleEvent(event):
                #     pipo = list(pygame.key.get_pressed())
                #     pipo[pygame.K_UP] = pygame.K_UP
                #     self._player[self._cu].handle_movement(pipo)
                if event.type == pygame.QUIT:
                    game_over = True
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        game_over = True
                    if event.key == pygame.K_F10:
                        self._map.show_grid()
                    if event.key == pygame.K_F11:
                        self._map.show_info(1)
                    if event.key == pygame.K_F12:
                        if self._debug:
                            self._debug = False
                        else:
                            self._debug = True
                    if event.key == pygame.K_SPACE:
                        self._player[self._cu].align_to_grid(GRIDSIZE)
                    if event.key == pygame.K_v:
                        if self._is_viewing:
                            self._is_viewing = False
                            self._scroll_map(self._view_x, self._view_y, *self._player[self._cu].rect.center)
                        else:
                            self._is_viewing = True
                            self._view_x, self._view_y = self._player[self._cu].rect.center
                    if event.key == pygame.K_c:
                        if self._is_viewing:
                            self._is_viewing = False
                            self._scroll_map(self._view_x, self._view_y, *self._player[self._cu].rect.center)
                        else:
                            self._end_of_turn()

            if self._is_viewing:
                self._view_map(self._key_input)
            else:
                if self._key_input is None:
                    continue
                self._player[self._cu].set_speed(self._key_input)
                self._player[self._cu].set_fallback()
                self._player[self._cu].handle_movement(self._key_input)
                self._check_obstacle()

                self._pointer.update(self._player[self._cu].rect.center)
                self._map.center_window(self._player[self._cu].rect.center)

            self._draw()

        pygame.quit()

    def _draw(self):
        self._show_buttons()
        self._map.show_info(0)
        self._map.draw_group(self._window)
        self._screen.blit(self._window, WINDOWPOS)
        if self._debug:
            self._show_debug()
        pygame.display.flip()
        self._screen.blit(self._background, (0, 0))

    def _show_buttons(self):
        for count, key in enumerate(self._keys):
            if self._key_input[key]:
                self._buttons[count].bgcolor = DARKGRAY
            else:
                self._buttons[count].bgcolor = BLACK

        for button in self._buttons:
            button.draw(self._background)

    def _show_debug(self):
        # noinspection PyProtectedMember
        text = ("FPS:            {}".format(int(self._clock.get_fps())),
                "press_up:       {}".format(self._player[self._cu]._press_up),
                "press_down:     {}".format(self._player[self._cu]._press_down),
                "press_left:     {}".format(self._player[self._cu]._press_left),
                "press_right:    {}".format(self._player[self._cu]._press_right),
                "direction:      {}".format(self._player[self._cu]._direction),
                "movespeed:      {}".format(self._player[self._cu]._movespeed),
                "cu:             {}".format(self._cu),
                "start_pos.x:    {}".format(self._map.start_pos[0].left if self._map.start_pos != [] else "None"),
                "start_pos.y     {}".format(self._map.start_pos[0].top if self._map.start_pos != [] else "None"),
                "player.x:       {}".format(self._player[self._cu].rect.left),
                "player.y:       {}".format(self._player[self._cu].rect.top),
                "view.x:         {}".format(self._view_x),
                "view.y:         {}".format(self._view_y),
                "step_count:     {}".format(self._player[self._cu]._step_count),
                "step_animation: {}".format(self._player[self._cu]._step_animation),
                "step_delay:     {}".format(self._player[self._cu]._step_delay),
                "is_viewing:     {}".format(self._is_viewing),
                )
        for count, line in enumerate(text):
            self._screen.blit(self._debugfont.render(line, True, WHITE), (0, count * 10))

    def _view_map(self, keys):
        if keys[pygame.K_UP]:
            self._view_y -= VIEWSPEED
        if keys[pygame.K_DOWN]:
            self._view_y += VIEWSPEED
        if keys[pygame.K_LEFT]:
            self._view_x -= VIEWSPEED
        if keys[pygame.K_RIGHT]:
            self._view_x += VIEWSPEED

        if self._view_x < 0:
            self._view_x = 0
        if self._view_y < 0:
            self._view_y = 0
        if self._view_x > self._map.width:
            self._view_x = self._map.width
        if self._view_y > self._map.height:
            self._view_y = self._map.height

        self._pointer.update((self._view_x, self._view_y))
        self._map.center_window((self._view_x, self._view_y))

    def _scroll_map(self, start_x, start_y, end_x, end_y):
        step_x = (start_x - end_x) / SCROLLSPEED
        step_y = (start_y - end_y) / SCROLLSPEED
        tmp_x = start_x
        tmp_y = start_y
        for _ in range(SCROLLSPEED):
            self._clock.tick(self._fps)
            tmp_x -= step_x
            tmp_y -= step_y
            self._pointer.update((tmp_x, tmp_y))
            self._map.center_window((tmp_x, tmp_y))
            self._draw()

    def _check_obstacle(self):
        # loop tegen de rand van een obstacle aan
        # er mag maar 1 obstacle in deze lijst zijn
        if len(self._player[self._cu].rect.collidelistall(self._map.obstacles)) == 1:
            # obj_nr is het nummer van de betreffende obstacle
            obj_nr = self._player[self._cu].rect.collidelist(self._map.obstacles)
            self._player[self._cu].move_side(self._map.obstacles[obj_nr])

        # loop tegen de rand van een low obstacle aan, bijv water
        if len(self._player[self._cu].rect.collidelistall(self._map.low_obst)) == 1:
            obj_nr = self._player[self._cu].rect.collidelist(self._map.low_obst)
            self._player[self._cu].move_side(self._map.low_obst[obj_nr])

        # loop tegen de rand van je moverange
        if pygame.sprite.collide_mask(self._player[self._cu], self._moverange):
            self._player[self._cu].fallback()

        # loop tegen een obstacle of low_obst aan
        while self._player[self._cu].rect.collidelist(self._map.obstacles) > -1 or \
                self._player[self._cu].rect.collidelist(self._map.low_obst) > -1:
            self._player[self._cu].move_back()