【发布时间】:2020-06-03 14:54:27
【问题描述】:
我目前正在 Pygame 中开发一个小型 2d 游戏。里面是一个继承自 Character 类的 Player 类。 Player 类有一个处理键盘输入的移动函数:
import pygame
import os
import sys
import time
pygame.init()
#window size
screen_width = 540
screen_height = 405
win = pygame.display.set_mode((screen_width, screen_height))
#Village Background
#Village Background Overlay
#Background Music
#time for FPS management
clock = pygame.time.Clock()
class Character(object):
def __init__(self, x, y, character_width, character_height):
self.x = x #character x position
self.y = y #character y position
self.character_width = character_width
self.character_height = character_height
self.velocity = 5 #character speed
self.walk_count = 0
self.hitbox = (self.x + 20, self.y, 28, 28)
这是我的播放器类:
class Player_Red(Character):
def __init__(self, x, y, character_width, character_height):
super().__init__(x, y, character_width, character_height)
self.red_char_right = False
self.red_char_left = False
self.red_char_down = False
self.red_char_up = False
self.latest_dir = "DOWN"
self.pause = False
def draw(self, win):
if not self.red_char_right and not self.red_char_left and not self.red_char_down and not self.red_char_up: #first display of character
win.blit(red_char_walk_down[0], (self.x,self.y))
if self.walk_count + 1 >= 27: #go to first image if no image to display left
self.walk_count = 0
if self.red_char_right: #display images red_char_right
win.blit(red_char_walk_right[self.walk_count//3], (self.x,self.y))
self.walk_count += 1
elif self.red_char_left: #display images red_char_left
win.blit(red_char_walk_left[self.walk_count//3], (self.x,self.y))
self.walk_count += 1
elif self.red_char_down: #display images red_char_down
win.blit(red_char_walk_down[self.walk_count//3], (self.x,self.y))
self.walk_count += 1
elif self.red_char_up: #display images red_char_up
win.blit(red_char_walk_up[self.walk_count//3], (self.x,self.y))
self.walk_count += 1
else: #display latest char image if no input
if self.latest_dir == "right":
win.blit(red_char_walk_right[0], (self.x,self.y))
if self.latest_dir == "left":
win.blit(red_char_walk_left[0], (self.x,self.y))
if self.latest_dir == "down":
win.blit(red_char_walk_down[0], (self.x,self.y))
if self.latest_dir == "up":
win.blit(red_char_walk_up[0], (self.x,self.y))
self.hitbox = (self.x + 5, self.y + 1, 21, 30)
def movement(self, win):
keys = pygame.key.get_pressed() #keyboard input
t = time.localtime()
current_time = time.strftime("%H:%M:%S", t)
for event in pygame.event.get():
print(current_time)
if event.type == pygame.KEYUP:
if event.key == pygame.K_ESCAPE:
self.pause = not self.pause
if self.pause:
return
if keys[pygame.K_a] and self.x > 5:
self.latest_dir = "left"
if '{}: {}'.format(self.x, self.y) not in village_left_border: #handling a key
self.x -= self.velocity
self.red_char_right = False
self.red_char_left = True
self.red_char_down = False
self.red_char_up = False
elif keys[pygame.K_d] and self.x < screen_width-self.character_width:
self.latest_dir = "right"
if '{}: {}'.format(self.x, self.y) not in village_right_border: #handling d key
self.x += self.velocity
self.red_char_right = True
self.red_char_left = False
self.red_char_down = False
self.red_char_up = False
elif keys[pygame.K_w] and self.y > 5:
self.latest_dir = "up"
if '{}: {}'.format(self.x, self.y) not in village_upper_border: #handling w key
self.y -= self.velocity
self.red_char_right = False
self.red_char_left = False
self.red_char_down = False
self.red_char_up = True
elif keys[pygame.K_s] and self.y < screen_height-self.character_height:
self.latest_dir = "down"
if '{}: {}'.format(self.x, self.y) not in village_lower_border: #handling s key
self.y += self.velocity
self.red_char_right = False
self.red_char_left = False
self.red_char_down = True
self.red_char_up = False
else: #no key pressed
self.red_char_right = False
self.red_char_left = False
self.red_char_down = False
self.red_char_up = False
self.walk_count = 0
为了澄清,它是口袋妖怪系列中的红色精灵。这是我的其余代码:
def redraw_game_window():
#display background
#display place
#character
Player.draw(win)
#display background overlay
win.blit(background_village_overlay, (0,0))
pygame.display.update()
#checking if player is before a door
check_buildings()
Player = Player_Red(250, 150, 32, 32)
#borders of the map
#Sounds
def sound_handling()
#Mainloop
run = True
while run:
clock.tick(27) #FPS rate
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#Player
Player.movement(win)
#Sounds
sound_handling()
#Entering buildings
check_buildings()
#Update Window
redraw_game_window()
#Mainloop End
pygame.quit()
以上是我的大部分代码。我为我跳过的东西留下了 cmets,也让代码保持清晰。游戏以每秒 27 帧的速度运行。我在角色类的移动方法中包含了一个打印语句,以查看它查找事件的频率(因为我想构建一个需要处理 KEYUP - K_ESCAPE 事件的主菜单)。我希望代码检查每一帧中的 KEYUP - K_ESCAPE 事件,但是当我运行代码时,我得到以下信息:
17:29:20; 17:29:41; 17:30:37; 17:30:39; 17:30:50; 17:30:50;
我不明白为什么代码没有在 pygame.event.get() 循环中输入 for 事件,每滴答声意味着每秒 27 次。它有时只是不进入它 20 秒,有时每秒两次。我已经看过如果我将 print 语句放在 for 循环之外会发生什么,并且移动方法每秒调用 27 次,所以它只是 for 循环不能正常运行。如果对我的代码有任何问题,请提出。
【问题讨论】:
-
您在主循环中执行 pygame.event.get() 两次,并在此之上分别处理 pygame.key.get_pressed() 。一旦你检查了 Quit,一旦你检查了 Escape,剩下的就是其他输入。我怀疑这不是预期的方法。但是,我认为问题在于,如果给定帧中没有发生任何事件,则 for 循环不会运行,因此不会触发打印。因为它仍然会定期检查,但有时它没有什么可报告的。下次您进行测试时,请按住键盘按钮或其他东西。
-
是的,你是对的。我在与 pygame.K_ESCAPE 事件相同的循环中检查 pygame.QUIT 不起作用!非常感谢先生!