Sprite 显示但不会切换动画或在 PyGame 中随按键移动
Sprite displays but won't switch animations or move with key presses in PyGame
构建一个简单的 PyGame,其中我需要玩家精灵根据箭头键的按下来移动和更改图像。我在 Sprite1 class 中添加了 facing 函数,并在游戏循环中按键的 if 语句中调用它,希望它会在每次按下键时改变图像,但它似乎不想更新精灵的按键后的图像。我面对的功能有问题吗?还是用别的东西?
import pygame
pygame.init()
#game Window
screen_width = 800
screen_height = 400
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Warrior Quest')
#game variables
main_menu = True
#background image
background_img = pygame.image.load('background.png')
#button images
start_img = pygame.image.load('startbutton.PNG')
cancel_img = pygame.image.load('cancelbutton.PNG')
title_img = pygame.image.load('warriorquestTile.PNG')
#background function
def draw_bg():
screen.blit(background_img, (0,0))
class Sprite1(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.faceUp = True
self.faceDown = False
self.faceLeft = False
self.faceRight = False
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect()
def draw(self):
screen.blit(self.image, self.rect)
def facing(self):
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect.w = self.image.get_rect().w
self.rect.h = self.image.get_rect().h
elif self.faceDown == True:
self.image = pygame.image.load('playerDown.png').convert_alpha()
self.rect = self.image.get_rect()
elif self.faceLeft == True:
self.image = pygame.image.load('playerLeft.png').convert_alpha()
self.rect = self.image.get_rect()
elif self.faceRight == True:
self.image = pygame.image.load('playerRight.png').convert_alpha()
self.rect = self.image.get_rect()
#setup player
player = Sprite1()
player.rect.x = 400
player.rect.y = 380
class Button():
def __init__(self,x,y,image):
self.image = image
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.clicked = False
def draw(self):
action = False
#get mouse position
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
action = True
self.clicked = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
#draw Button
screen.blit(self.image, self.rect)
return action
#create buttons
start_button = Button(screen_width // 2 -350, screen_height // 2, start_img)
cancel_button = Button(screen_width // 2 + 150, screen_height // 2, cancel_img)
title_button = Button(300,400,title_img)
#game loop running
running = True
while running:
draw_bg()
if main_menu == True:
if start_button.draw():
main_menu = False
if cancel_button.draw():
running = False
else:
player.draw()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.rect.x>5:
player.faceLeft = True
player.facing()
player.rect.x -= 5
if keys[pygame.K_RIGHT] and player.rect.x<790:
player.faceRight = True
player.facing()
player.rect.x += 5
if keys[pygame.K_UP] and player.rect.y>10:
player.faceUp = True
player.facing()
player.rect.y -= 5
if keys[pygame.K_DOWN]and player.rect.y<395:
player.faceDown = True
player.facing()
player.rect.y += 5
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.update()
pygame.quit()
每次更新精灵时,都会将其矩形重置为图像的矩形:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect()
相反,只更新宽度和高度:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect.w = self.image.get_rect().w
self.rect.h = self.image.get_rect().h
pygame.Surface.get_rect.get_rect()
returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit
at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the center of the rectangle can be specified with the keyword argument center
. These keyword argument are applied to the attributes of the pygame.Rect
before it is returned (see pygame.Rect
关键字参数的完整列表)。
通过保持矩形的中心位置来保持精灵的位置:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect(center = self.rect.center)
此外,不要在应用程序循环中加载图像。加载图像非常耗时,因为必须读取和解释图像文件。在应用程序开始时加载一次图像:
设置新的face*
属性是不够的,您还必须重新设置其他face*
属性。我建议使用具有不同状态的单个属性 face
:
class Sprite1(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.player_img = pygame.image.load('player.png').convert_alpha()
self.player_down_img = pygame.image.load('playerDown.png').convert_alpha()
self.player_left_img = pygame.image.load('playerLeft.png').convert_alpha()
self.player_right_img = pygame.image.load('playerRight.png').convert_alpha()
self.face = "up"
self.image = self.player_img
self.rect = self.image.get_rect()
def draw(self):
screen.blit(self.image, self.rect)
def facing(self):
if self.face == "up" :
self.image = self.player_img
elif self.face == "down":
self.image = self.player_down_img
elif self.face == "left":
self.image = self.player_left_img
elif self.face == "right":
self.image = self.player_right_img
self.rect = self.image.get_rect(center = self.rect.center)
running = True
while running:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.rect.x>5:
player.face = "up"
player.facing()
player.rect.x -= 5
if keys[pygame.K_RIGHT] and player.rect.x<790:
player.face = "down"
player.facing()
player.rect.x += 5
if keys[pygame.K_UP] and player.rect.y>10:
player.face = "left"
player.facing()
player.rect.y -= 5
if keys[pygame.K_DOWN]and player.rect.y<395:
player.face = "right":
player.facing()
player.rect.y += 5
构建一个简单的 PyGame,其中我需要玩家精灵根据箭头键的按下来移动和更改图像。我在 Sprite1 class 中添加了 facing 函数,并在游戏循环中按键的 if 语句中调用它,希望它会在每次按下键时改变图像,但它似乎不想更新精灵的按键后的图像。我面对的功能有问题吗?还是用别的东西?
import pygame
pygame.init()
#game Window
screen_width = 800
screen_height = 400
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Warrior Quest')
#game variables
main_menu = True
#background image
background_img = pygame.image.load('background.png')
#button images
start_img = pygame.image.load('startbutton.PNG')
cancel_img = pygame.image.load('cancelbutton.PNG')
title_img = pygame.image.load('warriorquestTile.PNG')
#background function
def draw_bg():
screen.blit(background_img, (0,0))
class Sprite1(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.faceUp = True
self.faceDown = False
self.faceLeft = False
self.faceRight = False
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect()
def draw(self):
screen.blit(self.image, self.rect)
def facing(self):
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect.w = self.image.get_rect().w
self.rect.h = self.image.get_rect().h
elif self.faceDown == True:
self.image = pygame.image.load('playerDown.png').convert_alpha()
self.rect = self.image.get_rect()
elif self.faceLeft == True:
self.image = pygame.image.load('playerLeft.png').convert_alpha()
self.rect = self.image.get_rect()
elif self.faceRight == True:
self.image = pygame.image.load('playerRight.png').convert_alpha()
self.rect = self.image.get_rect()
#setup player
player = Sprite1()
player.rect.x = 400
player.rect.y = 380
class Button():
def __init__(self,x,y,image):
self.image = image
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.clicked = False
def draw(self):
action = False
#get mouse position
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
action = True
self.clicked = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
#draw Button
screen.blit(self.image, self.rect)
return action
#create buttons
start_button = Button(screen_width // 2 -350, screen_height // 2, start_img)
cancel_button = Button(screen_width // 2 + 150, screen_height // 2, cancel_img)
title_button = Button(300,400,title_img)
#game loop running
running = True
while running:
draw_bg()
if main_menu == True:
if start_button.draw():
main_menu = False
if cancel_button.draw():
running = False
else:
player.draw()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.rect.x>5:
player.faceLeft = True
player.facing()
player.rect.x -= 5
if keys[pygame.K_RIGHT] and player.rect.x<790:
player.faceRight = True
player.facing()
player.rect.x += 5
if keys[pygame.K_UP] and player.rect.y>10:
player.faceUp = True
player.facing()
player.rect.y -= 5
if keys[pygame.K_DOWN]and player.rect.y<395:
player.faceDown = True
player.facing()
player.rect.y += 5
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.update()
pygame.quit()
每次更新精灵时,都会将其矩形重置为图像的矩形:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect()
相反,只更新宽度和高度:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect.w = self.image.get_rect().w
self.rect.h = self.image.get_rect().h
pygame.Surface.get_rect.get_rect()
returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit
at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the center of the rectangle can be specified with the keyword argument center
. These keyword argument are applied to the attributes of the pygame.Rect
before it is returned (see pygame.Rect
关键字参数的完整列表)。
通过保持矩形的中心位置来保持精灵的位置:
if self.faceUp == True:
self.image = pygame.image.load('player.png').convert_alpha()
self.rect = self.image.get_rect(center = self.rect.center)
此外,不要在应用程序循环中加载图像。加载图像非常耗时,因为必须读取和解释图像文件。在应用程序开始时加载一次图像:
设置新的face*
属性是不够的,您还必须重新设置其他face*
属性。我建议使用具有不同状态的单个属性 face
:
class Sprite1(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.player_img = pygame.image.load('player.png').convert_alpha()
self.player_down_img = pygame.image.load('playerDown.png').convert_alpha()
self.player_left_img = pygame.image.load('playerLeft.png').convert_alpha()
self.player_right_img = pygame.image.load('playerRight.png').convert_alpha()
self.face = "up"
self.image = self.player_img
self.rect = self.image.get_rect()
def draw(self):
screen.blit(self.image, self.rect)
def facing(self):
if self.face == "up" :
self.image = self.player_img
elif self.face == "down":
self.image = self.player_down_img
elif self.face == "left":
self.image = self.player_left_img
elif self.face == "right":
self.image = self.player_right_img
self.rect = self.image.get_rect(center = self.rect.center)
running = True
while running:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.rect.x>5:
player.face = "up"
player.facing()
player.rect.x -= 5
if keys[pygame.K_RIGHT] and player.rect.x<790:
player.face = "down"
player.facing()
player.rect.x += 5
if keys[pygame.K_UP] and player.rect.y>10:
player.face = "left"
player.facing()
player.rect.y -= 5
if keys[pygame.K_DOWN]and player.rect.y<395:
player.face = "right":
player.facing()
player.rect.y += 5