有没有更好的方法来移动一个精灵使用键盘与Pygame?

2024-05-19 02:30:19 发布

您现在位置:Python中文网/ 问答频道 /正文

目前,我有一个小的图像,我用键盘上的D和A键移动。代码的工作方式正是我想要的,但它似乎有点不必要的复杂。有没有更有效的方法?你知道吗

在主循环中,我的代码通过事件检查按下了什么键,但在那之后,如果不再按下某个键,它会检查是否按下了另一个键,以防用户在最初按下另一个键时按下了某个键。你知道吗

这是我的密码:

import pygame
import sys
from pygame.locals import *

SCREENX = 640
SCREENY = 480

LEFT = 'left'
RIGHT = 'right'


class Character(pygame.sprite.Sprite):
    def __init__(self, image_file):
        super().__init__()
        temp_image = pygame.image.load(image_file)
        self.image = pygame.transform.scale(temp_image, (100, 100))
        self.rect = self.image.get_rect()
        self.moving = False
        self.direction = RIGHT

    def start_move(self, direction):
        self.moving = True
        if direction != self.direction:
            self.image = pygame.transform.flip(self.image, True, False)
        self.direction = direction

    def stop_move(self):
        if self.moving:
            self.moving = False

    def move(self):
        if self.direction == RIGHT:
            self.rect.x += 5
        if self.direction == LEFT:
            self.rect.x -= 5

    def update(self):
        if self.moving:
            self.move()


def main():
    pygame.init()
    surface = pygame.display.set_mode((SCREENX, SCREENY))
    clock = pygame.time.Clock()

    sprites = pygame.sprite.Group()

    girl = Character("assets/girl.png")
    girl.rect.x = SCREENX/2
    girl.rect.y = SCREENY - girl.rect.height

    sprites.add(girl)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if not girl.moving:
                    if event.key == K_d:
                        girl.start_move(RIGHT)
                    if event.key == K_a:
                        girl.start_move(LEFT)
            if event.type == KEYUP:
                if event.key == K_a or event.key == K_d:
                    girl.stop_move()
                    keys_pressed = pygame.key.get_pressed()
                    if keys_pressed[K_d]:
                        girl.start_move(RIGHT)
                    if keys_pressed[K_a]:
                        girl.start_move(LEFT)

        surface.fill((255, 255, 255))
        sprites.update()
        sprites.draw(surface)
        pygame.display.update()
        clock.tick(60)


if __name__ == '__main__':
    main()

Tags: keyrectimageselfrighteventmoveif
1条回答
网友
1楼 · 发布于 2024-05-19 02:30:19

是的,您可以去掉大多数事件处理,可以泛化主循环,还可以去掉Character类的一些字段。你知道吗

请参阅我的注释:

import pygame
import sys
from pygame.locals import *

SCREENX = 640
SCREENY = 480


class Character(pygame.sprite.Sprite):
    def __init__(self, image_file):
        pygame.sprite.Sprite.__init__(self)
        temp_image = pygame.image.load(image_file)
        # only to the flipping of the image once
        self.image_r = pygame.transform.scale(temp_image, (100, 100))
        self.image_l = pygame.transform.flip(self.image_r, True, False)
        self.image = self.image_l
        self.rect = self.image.get_rect()

    def update(self, pressed_keys):
        move = 0
        if pressed_keys[K_d]: move += 1
        if pressed_keys[K_a]: move -= 1
        self.rect.move_ip(move*5, 0)

        # check which direction we're facing and set the image
        self.image = self.image_l if move < 0 else self.image_r

def main():
    pygame.init()
    surface = pygame.display.set_mode((SCREENX, SCREENY))
    clock = pygame.time.Clock()

    sprites = pygame.sprite.Group()

    girl = Character("assets/girl.png")
    girl.rect.x = SCREENX / 2
    girl.rect.y = SCREENY - girl.rect.height

    sprites.add(girl)

    while True:
        for event in pygame.event.get():
            # since we are in a function, we can simply return.
            # we don't care here what happens after we quit the main loop
            if event.type == QUIT: return pygame.quit()

        # get all pressed keys, and just let all sprites 
        # decide what they want to do with it
        keys_pressed = pygame.key.get_pressed()

        # you could wrap this information in a more
        # general container represeting the game state
        # See how the game loop does not care what a 
        # Sprite does with this information
        sprites.update(keys_pressed)

        surface.fill((255, 255, 255))
        sprites.draw(surface)
        pygame.display.update()
        clock.tick(60)


if __name__ == '__main__':
    main()

相关问题 更多 >

    热门问题