python - Pygame KEYUP, KEYDOWN 导致幽灵移动
问题描述
我尝试学习 KEYUP 和 KEYDOWN。基本上,在用户撞到窗口的任何一侧后,游戏会按预期重置。即使没有按下或释放任何键,方块也不会再次开始移动。
理想的事件系列: - 用户崩溃 - 游戏在原始起始药水(静止)中以正方形重置 - 按下移动键并移动
任何关于为什么会发生这种情况的见解都会很棒。
谢谢
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
car_width = 75
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
def game_loop():
x = 200
y = 200
x_change = 0
y_change = 0
gameExit = False
while not gameExit:
# Movement logic
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x_change += 5
if event.key == pygame.K_LEFT:
x_change += -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
x_change += -5
if event.key == pygame.K_LEFT:
x_change += 5
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change += -5
if event.key == pygame.K_DOWN:
y_change += 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
y_change += 5
if event.key == pygame.K_DOWN:
y_change += -5
x += x_change
y += y_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, [x, y, 75, 75])
# Check if border hit
if x > display_width - car_width or x < 0:
crash()
if y > display_height - car_width or y < 0:
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
解决方案
拧全局变量、事件和大量标志。
只需用于pygame.key.get_pressed
获取键盘的当前状态。为每个箭头键分配一个移动矢量,将它们相加,标准化,然后就可以了。
另外,如果你想用矩形做一些事情,只需使用Rect
类。它会让你的生活轻松很多。
这是一个正在运行的示例:
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
car_width = 75
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
keymap = {
pygame.K_RIGHT: pygame.math.Vector2(1, 0),
pygame.K_LEFT: pygame.math.Vector2(-1, 0),
pygame.K_UP: pygame.math.Vector2(0, -1),
pygame.K_DOWN: pygame.math.Vector2(0, 1)
}
def game_loop():
# we want to draw a rect, so we simple use Rect
rect = pygame.rect.Rect(200, 200, 75, 75)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
# get the state of the keyboard
pressed = pygame.key.get_pressed()
# get all the direction vectors from the keymap of all keys that are pressed
vectors = (keymap[key] for key in keymap if pressed[key])
# add them up to we get a single vector of the final direction
direction = pygame.math.Vector2(0, 0)
for v in vectors:
direction += v
# if we have to move, we normalize the direction vector first
# this ensures we're always moving at the correct speed, even diagonally
if direction.length() > 0:
rect.move_ip(*direction.normalize()*5)
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, rect)
# Check if border hit
# See how easy the check is
if not gameDisplay.get_rect().contains(rect):
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
您的代码还有其他一些问题:
例如,如果您使用time.sleep(2)
,您的整个程序将冻结。这意味着您不能在等待时关闭窗口,并且窗口管理器等不会重绘窗口。
此外,您的代码包含一个无限循环。如果你经常碰壁,你会遇到堆栈溢出,因为game_loop
调用crash
又会game_loop
再次调用。起初这可能不是一个大问题,但要记住一些事情。
推荐阅读
- python - 如何在图中找到先决条件的总数
- blazor - 使用 bUnit 和 Moq 测试使用 Fluxor 的剃须刀组件
- python - 基于比较两个数据框 [Python],使用 Pandas 生成 3D“矩阵”
- elasticsearch - 使用 logstash 同时将数据插入两个不同的 Elasticsearch 索引
- html - HTML 包含多少种类型的标题?
- flutter - 电话包构建失败
- php - include_once 在 php 脚本上导致 505
- typescript - 如何发布包含 CSS 模块的基于 TypeScript 的 npm 模块?
- sql - 防止 SQLite 查询执行 USE TEMP B-TREE FOR GROUP BY
- c++ - 移动后重用变量