当我在 Pygame 中按相应的键时图像不会移动
Image won't move when I press corresponding keys in Pygame
我只是为了好玩和学习新东西而开始编写代码,但是我已经 运行 解决了这个问题,并且希望得到一些关于我做错了什么的具体意见。在我的项目中,此时我正在尝试使用箭头键使图像左右移动。我已经让图像正常显示,但它不会响应按键而移动。欢迎任何意见。
`import pygame, sys, random
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
surface = screen.get_rect()
DIS = (100, 100)
pygame.image.load('sprite_soldier.png')
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player = screen.blit(player_soldier, (screen_width/2 - 10, screen_height - 100))
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width/2 - 10, screen_height - 100, 20, 20)
player_x = player.x
move_left = False
move_right = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
move_right = True
if event.key == pygame.K_LEFT:
move_left = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
move_right = False
if event.key == pygame.K_LEFT:
move_left = False
if move_right:
player_x += 10
elif move_left:
player_x -= 10
if player.x >= screen_width:
move_right = False
if player.x <= 0:
move_left = False
pygame.display.flip()
clock.tick(60)
您必须每帧再次将图像绘制到屏幕上。你可以这样做:
import pygame, sys, random
pygame.init()
FPS = 60
clock = pygame.time.Clock()
screen_width, screen_height = 1280, 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
DIS = (100, 100)
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player_rect = player_soldier.get_rect(center=screen_width / 2 - 10, screen_height - 100)
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width / 2 - 10, screen_height - 100, 20, 20)
move_left = False
move_right = False
def draw():
screen.fill(bg_color)
screen.blit(player_soldier, player_rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
move_right = True
if event.key == pygame.K_LEFT:
move_left = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
move_right = False
if event.key == pygame.K_LEFT:
move_left = False
if move_right:
player_rect.x += 10
elif move_left:
player_rect.x -= 10
if player_rect.x >= screen_width:
move_right = False
if player_rect.x <= 0:
move_left = False
pygame.display.flip()
clock.tick(FPS)
我还更改了一些内容,例如添加 player_rect 变量。
我还尝试使用 FPS 变量和一些空行使其更具可读性。
您错过了在应用程序循环中的新位置绘制播放器:
while True:
# [...]
screen.fill(0)
player = screen.blit(player_soldier, (player_x, screen_height - 100))
pygame.display.flip()
clock.tick(60)
使用 pygame.key.get_pressed()
代替 KEYDOWN
事件:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_x += 10 * (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT])
screen.fill(0)
player = screen.blit(player_soldier, (player_x, screen_height - 100))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
典型的 PyGame 应用程序循环必须:
- 限制每秒帧数以限制 CPU 使用
pygame.time.Clock.tick
- 通过调用
pygame.event.pump()
or pygame.event.get()
. 来处理事件
- 根据输入事件和时间(分别为帧)更新对象的游戏状态和位置
- 清除整个显示或绘制背景
- 绘制整个场景(
blit
所有对象)
- 通过调用
pygame.display.update()
or pygame.display.flip()
更新显示
键盘事件(参见 pygame.event 模块)仅在键状态改变时发生一次。 KEYDOWN
事件在每次按下一个键时发生一次。 KEYUP
每松开一个键就会出现一次。使用键盘事件进行单个操作或逐步移动。
pygame.key.get_pressed()
returns a sequence with the state of each key. If a key is held down, the state for the key is True
, otherwise False
. Use pygame.key.get_pressed()
评估按钮的当前状态并获得连续移动
完整示例:
import pygame, sys, random
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
surface = screen.get_rect()
DIS = (100, 100)
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player_rect = player_soldier.get_rect(midbottom = (screen_width/2, screen_height))
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width/2 - 10, screen_height - 100, 20, 20)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_rect.x += 10 * (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT])
player_rect.clamp_ip(surface)
screen.fill(0)
player = screen.blit(player_soldier, player_rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
您已经更新了玩家的位置,但还没有将 sprite 复制到新位置。此外,您还必须在 blit 更新之前“清除”屏幕,否则您只会画一条线。
# screen.fill() will 'clear' the screen of previous blits
screen.fill('black)
# Show the player at the new position
screen.blit(player_soldier, (player_x, screen_height - 100))
# pygame.display.flip() will show the updated screen
pygame.display.flip()
clock.tick(60)
屏幕必须在 drawing/bliting 个精灵之前清空。这样可以防止拖尾效应。
Sprites 必须每帧 redrawn/blited 到屏幕才能实现 'movement'。
这两个步骤必须在显示新屏幕之前的每一帧完成。
我只是为了好玩和学习新东西而开始编写代码,但是我已经 运行 解决了这个问题,并且希望得到一些关于我做错了什么的具体意见。在我的项目中,此时我正在尝试使用箭头键使图像左右移动。我已经让图像正常显示,但它不会响应按键而移动。欢迎任何意见。
`import pygame, sys, random
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
surface = screen.get_rect()
DIS = (100, 100)
pygame.image.load('sprite_soldier.png')
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player = screen.blit(player_soldier, (screen_width/2 - 10, screen_height - 100))
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width/2 - 10, screen_height - 100, 20, 20)
player_x = player.x
move_left = False
move_right = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
move_right = True
if event.key == pygame.K_LEFT:
move_left = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
move_right = False
if event.key == pygame.K_LEFT:
move_left = False
if move_right:
player_x += 10
elif move_left:
player_x -= 10
if player.x >= screen_width:
move_right = False
if player.x <= 0:
move_left = False
pygame.display.flip()
clock.tick(60)
您必须每帧再次将图像绘制到屏幕上。你可以这样做:
import pygame, sys, random
pygame.init()
FPS = 60
clock = pygame.time.Clock()
screen_width, screen_height = 1280, 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
DIS = (100, 100)
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player_rect = player_soldier.get_rect(center=screen_width / 2 - 10, screen_height - 100)
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width / 2 - 10, screen_height - 100, 20, 20)
move_left = False
move_right = False
def draw():
screen.fill(bg_color)
screen.blit(player_soldier, player_rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
move_right = True
if event.key == pygame.K_LEFT:
move_left = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
move_right = False
if event.key == pygame.K_LEFT:
move_left = False
if move_right:
player_rect.x += 10
elif move_left:
player_rect.x -= 10
if player_rect.x >= screen_width:
move_right = False
if player_rect.x <= 0:
move_left = False
pygame.display.flip()
clock.tick(FPS)
我还更改了一些内容,例如添加 player_rect 变量。 我还尝试使用 FPS 变量和一些空行使其更具可读性。
您错过了在应用程序循环中的新位置绘制播放器:
while True:
# [...]
screen.fill(0)
player = screen.blit(player_soldier, (player_x, screen_height - 100))
pygame.display.flip()
clock.tick(60)
使用 pygame.key.get_pressed()
代替 KEYDOWN
事件:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_x += 10 * (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT])
screen.fill(0)
player = screen.blit(player_soldier, (player_x, screen_height - 100))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
典型的 PyGame 应用程序循环必须:
- 限制每秒帧数以限制 CPU 使用
pygame.time.Clock.tick
- 通过调用
pygame.event.pump()
orpygame.event.get()
. 来处理事件
- 根据输入事件和时间(分别为帧)更新对象的游戏状态和位置
- 清除整个显示或绘制背景
- 绘制整个场景(
blit
所有对象) - 通过调用
pygame.display.update()
orpygame.display.flip()
更新显示
键盘事件(参见 pygame.event 模块)仅在键状态改变时发生一次。 KEYDOWN
事件在每次按下一个键时发生一次。 KEYUP
每松开一个键就会出现一次。使用键盘事件进行单个操作或逐步移动。
pygame.key.get_pressed()
returns a sequence with the state of each key. If a key is held down, the state for the key is True
, otherwise False
. Use pygame.key.get_pressed()
评估按钮的当前状态并获得连续移动
完整示例:
import pygame, sys, random
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Invader slim")
surface = screen.get_rect()
DIS = (100, 100)
player_image = pygame.image.load('sprite_soldier.png').convert_alpha()
player_soldier = pygame.transform.scale(player_image, DIS)
player_rect = player_soldier.get_rect(midbottom = (screen_width/2, screen_height))
bg_color = pygame.Color(0, 100, 100)
green = pygame.Color(0, 255, 0)
white = pygame.Color('white')
light_gray = pygame.Color(200, 200, 200)
torpedo = pygame.Rect(screen_width/2 - 10, screen_height - 100, 20, 20)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_rect.x += 10 * (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT])
player_rect.clamp_ip(surface)
screen.fill(0)
player = screen.blit(player_soldier, player_rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
您已经更新了玩家的位置,但还没有将 sprite 复制到新位置。此外,您还必须在 blit 更新之前“清除”屏幕,否则您只会画一条线。
# screen.fill() will 'clear' the screen of previous blits
screen.fill('black)
# Show the player at the new position
screen.blit(player_soldier, (player_x, screen_height - 100))
# pygame.display.flip() will show the updated screen
pygame.display.flip()
clock.tick(60)
屏幕必须在 drawing/bliting 个精灵之前清空。这样可以防止拖尾效应。
Sprites 必须每帧 redrawn/blited 到屏幕才能实现 'movement'。
这两个步骤必须在显示新屏幕之前的每一帧完成。