Как обнаружить предыдущее движение в Python Pygame? - PullRequest
1 голос
/ 08 марта 2020

Я хотел бы обнаружить предыдущее движение персонажа, чтобы отобразить анимацию по отношению к предыдущему движению. Например, если предыдущее движение было «move_right», когда персонаж остановился, я хотел бы отобразить изображение, повернутое вправо. И то же самое для левого. Можете ли вы помочь мне?

РЕДАКТИРОВАТЬ

Я поставлю вам часть кода, надеюсь, это поможет вам.

import pygame
import constants
import time


clock = pygame.time.Clock()



class Player(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.velocity = 5
        self.HeatBox = constants.S_PLAYER_HEATBOX
        self.rect = self.HeatBox.get_rect()
        self.rect.x = 500
        self.rect.y = 300
        self.WalkCount = 0

    def move_right(self):
        self.rect.x += self.velocity

    def move_left(self):
        self.rect.x -= self.velocity

    def move_up(self):
        self.rect.y -= self.velocity

    def move_down(self):
        self.rect.y += self.velocity


def draw_game():

    global SURFACE_MAIN, Player

    SURFACE_MAIN.fill(constants.COLOR_DEFAULT_BG)

    SURFACE_MAIN.blit(constants.S_BACKGROUND, (0, 0))

    SURFACE_MAIN.blit(constants.S_PLAYER_HEATBOX, game.player.rect)

    if game.player.WalkCount + 1 >= 40:
         game.player.WalkCount = 0

    if game.pressed.get(pygame.K_RIGHT): 

    SURFACE_MAIN.blit(constants.S_PLAYER_W_RIGHT[game.player.WalkCount//10], 
    game.player.rect)
    game.player.move_right()

    if game.pressed.get(pygame.K_LEFT):

    SURFACE_MAIN.blit(constants.S_PLAYER_W_LEFT[game.player.WalkCount//10], 
    game.player.rect)  
    game.player.move_left()

    if game.pressed.get(pygame.K_UP):
        game.player.move_up()

    if game.pressed.get(pygame.K_DOWN):
        game.player.move_down()


    pygame.display.flip()



def game_main_loop():

    game_quit = False

    while not game_quit:

        clock.tick(60)

        events_list = pygame.event.get()

        for event in events_list:
            if event.type == pygame.QUIT:
                game_quit = True

            elif event.type == pygame.KEYDOWN:
                game.pressed[event.key] = True
            elif event.type == pygame.KEYUP:
                game.pressed[event.key] = False

        draw_game()

    pygame.quit()
    exit()


def game_initialize():

    global SURFACE_MAIN, Player

    pygame.init()

    pygame.display.set_caption("RogueLike")
    SURFACE_MAIN = pygame.display.set_mode((constants.GAME_WIDTH, 
    constants.GAME_HEIGHT))

class gameplay:

    def __init__(self):
        self.player = Player()
        self.pressed = {}

game = gameplay()

if __name__ == '__main__':
game_initialize()
game_main_loop()

В файле с именем константы .py У меня есть все мои спрайты

S_BACKGROUND = pygame.image.load('Sprites/Map/Map_Test_3.png')                              
S_PLAYER_HEATBOX = pygame.image.load('Sprites/Heros/Knight/HeatBox.png')
S_PLAYER_RIGHT = 
             [pygame.image.load('Sprites/Heros/Knight/Right/sprite_0.png'),
              pygame.image.load('Sprites/Heros/Knight/Right/sprite_1.png'),
              pygame.image.load('Sprites/Heros/Knight/Right/sprite_2.png'),
              pygame.image.load('Sprites/Heros/Knight/Right/sprite_3.png')]
S_PLAYER_LEFT = 
             [pygame.image.load('Sprites/Heros/Knight/Left/sprite_0.png'),
              pygame.image.load('Sprites/Heros/Knight/Left/sprite_1.png'),
              pygame.image.load('Sprites/Heros/Knight/Left/sprite_2.png'),
              pygame.image.load('Sprites/Heros/Knight/Left/sprite_3.png')]
S_PLAYER_W_RIGHT = 
             [pygame.image.load('Sprites/Heros/Knight/W_Right/sprite_0.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Right/sprite_1.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Right/sprite_2.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Right/sprite_3.png')]
S_PLAYER_W_LEFT = 
             [pygame.image.load('Sprites/Heros/Knight/W_Left/sprite_0.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Left/sprite_1.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Left/sprite_2.png'),
              pygame.image.load('Sprites/Heros/Knight/W_Left/sprite_3.png')]

# Left : means sprites turned to the right when the character is stopped.
# Right : means sprites turned to the left when the character is stopped.
# W_Left : means sprites turned to theleft when the character is walking.
# W_Right : means sprites turned to the right when the character is walking.
# S_ : means Sprites

1 Ответ

0 голосов
/ 10 марта 2020

Мое понимание вашего вопроса состоит в том, что вы sh Игрок спрайт, чтобы "повернуть" направление самого предыдущего движения. Например, если игрок в последний раз двигался влево, спрайт должен отображаться как лицом влево.

Подобного рода вещи довольно легко достигаются путем установки значения Sprite image в правильное растровое изображение. Этому нет никакого объяснения, поэтому я не совсем понимаю, что представляет собой «HeatBox», поэтому я буду игнорировать это. И image, и rect являются специальными для PyGame Sprite Class . Они используются кодом библиотеки спрайтов для рисования и обнаружения столкновений для спрайта. Было бы лучше использовать другое имя переменной для каких-то других целей.

class Player(pygame.sprite.Sprite):
    DIR_LEFT = 0 
    DIR_RIGHT= 1       # This might be better as an Enumerated Type
    DIR_UP   = 2
    DIR_DOWN = 3

    def __init__(self):
        super().__init__()
        self.velocity  = 5
        self.heat_box  = constants.S_PLAYER_HEATBOX
        self.heat_rect = self.HeatBox.get_rect()
        self.image     = S_PLAYER_LEFT[0]             # Initially face left
        self.rect      = self.image.get_rect()
        self.rect.x    = 500
        self.rect.y    = 300
        self.walk_count= 0                            # animation frame count
        self.last_dir  = Player.DIR_LEFT              # direction last walked

    def move_right(self):
        if ( self.last_dir != Player.DIR_RIGHT ):     # changed direction?
            self.walk_count = -1                      # so next-frame is 0
            self.last_dir = Player.DIR_RIGHT          # now face right
        # continue walking right
        self.rect.x += self.velocity
        self.walk_count += 1
        if ( walk_count >= len( S_PLAYER_W_RIGHT ) ): # loop the animation
            self.walk_count = 0
        self.image = S_PLAYER_W_RIGHT[ self.walk_count ]

    def move_left(self):
        if ( self.last_dir != Player.DIR_LEFT ):      # changed direction?
            self.walk_count = -1                      # so next-frame is 0
            self.last_dir = Player.DIR_LEFT           # now face left
        # continue walking left
        self.rect.x -= self.velocity
        self.walk_count += 1
        if ( walk_count >= len( S_PLAYER_W_LEFT ) ):  # loop the animation
            self.walk_count = 0
        self.image = S_PLAYER_W_LEFT[ self.walk_count ]

    # TODO: Much the same for Up/Down too

При изменении направления счетчик animation-l oop (walk_count) сбрасывается, и растровое изображение для нового направление, присвоенное Player.image и запоминаемое в Player.last_dir.

Таким образом, в основном класс Player запоминает как направление, на которое направлен спрайт, так и то, какой кадр анимации был нарисован ранее. Если игрок продолжает двигаться в том же направлении, анимация будет проходить для каждого движения. Если направление изменилось, анимация сбрасывается для другого набора растровых изображений.

Чтобы привлечь игрока на экран, добавьте его в группу спрайтов и скажите группе: Нарисуй себя в своей главной л oop. В качестве бонуса вы также можете использовать все функции столкновения между группами спрайтов .

player_group = pygame.sprite.GroupSingle()
player_group.add( Player() )                  # create the player

...

# main loop
player_group.draw( screen )

Примечание: CamelCase имена переменных изменены на lower_case для соответствия Руководство по PEP-8 .

...