pygame 精灵不随 self.rect.move_ip 移动
pygame sprite not moving with self.rect.move_ip
我正在 pygame 开发一款游戏,我已经在屏幕上找到了基本绘图,但用户输入让我感到困惑。我有一个播放器 class:
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.surf = pygame.Surface((75, 25))
self.surf.fill((255, 255, 255))
self.rect = self.surf.get_rect()
def update(self, pressed_keys):
if pressed_keys[K_UP]:
self.rect.move_ip(0, -5)
if pressed_keys[K_DOWN]:
self.rect.move_ip(0, 5)
if pressed_keys[K_LEFT]:
self.rect.move_ip(-5, 0)
if pressed_keys[K_RIGHT]:
self.rect.move_ip(5, 0)
pygame.event.pump()
但是每当我按下按键时,什么也没有发生。这是绘制内容的脚本结尾:
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
pressed_keys = pygame.key.get_pressed()
player.update(pressed_keys)
screen.fill((0, 0, 0))
surf = pygame.Surface((50, 50))
surf.fill((0, 0, 0))
rect = surf.get_rect()
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
pygame.display.flip()
我不知道发生了什么,但我找不到任何相关信息来修复它。一切都画对了,但没有别的。
您必须 blit
rect
属性中存储的位置的玩家:
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
screen.blit(player.surf, player.rect)
问题:在屏幕上闪烁时出现逻辑错误
在你的游戏循环中:
player.update
是移动 播放器按键
blit
正在绘制始终固定在中心的玩家 (SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
- 尽管玩家的位置移动了
因此你的播放器卡在视觉上在屏幕中心,尽管你移动了它并且它的位置(在rect
中)被箭头键改变了。
调试
添加一些调试 print
语句
- 在
blit
之前监控玩家位置是否在更新后移动:.
- 在
blit
之后监视其 return 绘制矩形的值
print("player's rect after update:", player.rect)
drawn_rect = screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
print("rect drawn by blit:", drawn_rect)
研究
假设您 blit
的意图是:
- 最初绘制时让玩家在屏幕上居中
- 使用
blit
在屏幕上绘制玩家
让我们查阅 PyGame 文档以获得一些支持。
将 Surface
对象居中
阅读 Surface
文档,了解 如何将 与 get_rect()
居中:
You can pass keyword argument values to this function. These named values will be applied to the attributes of the Rect before it is returned. An example would be mysurf.get_rect(center=(100, 100))
to create a rectangle for the Surface centered at a given position.
使用blit
来自 blit(source, dest, area=None, special_flags=0)
上的文档
Draws a source
Surface onto this Surface. The draw can be positioned with the dest
argument. The dest
argument can either be a pair of coordinates representing the position of the upper left corner of the blit or a Rect
设计修复
Spawn初始位置的玩家,例如centered
(在屏幕上),创建过程中。
然后你的游戏循环有 single responsibility 到 draw
player
screen
。
玩家:居中、移动、抽签
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.surf = pygame.Surface((75, 25))
self.surf.fill((255, 255, 255))
self.rect = self.centered() # spawn it centerd
def update(self, pressed_keys):
if pressed_keys[K_UP]:
self.move(0, -5)
if pressed_keys[K_DOWN]:
self.move(0, 5)
if pressed_keys[K_LEFT]:
self.move(-5, 0)
if pressed_keys[K_RIGHT]:
self.move(5, 0)
pygame.event.pump()
## added some methods
def centered():
return self.surf.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
def move(x, y):
self.rect.move_ip(x,y)
def draw_on(surface): # visitor-pattern
surface.blit(self.surf, self.rect)
注意:在 Player
中添加了一些功能
centered
定位在恒定屏幕尺寸的中心
move
以向量 (x,y) 移动玩家
draw_on
在给定的表面上绘制玩家 sprite/surface,就像您的 screen
绘图
然后在你的游戏循环中替换:
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
通过新命令:
# new player is centered, moved player is located anywhere
player.draw_on(screen)
注意:_visitor-pattern- 将语句更改为形式为 <subject>.<verb>(<object>)
的人类可读句子,并且比以前少了一个参数(内部化)。
奖金:建议
可以改进面向对象的设计以增强可读性、简化测试和简化使用:
- 通过命令动作等功能控制玩家
- 选择一种简单的游戏语言(领域术语)
- 并用它来命名你的抽象(对象、函数、变量)
示例:Player
、screen
、move
、centered
、draw
、_to
、_on
(名词, 类似形容词或动词, 用介词表示关系)
通常,设计改进可以更轻松地识别逻辑错误或在调试过程中分析控制流 - 希望如此。
我正在 pygame 开发一款游戏,我已经在屏幕上找到了基本绘图,但用户输入让我感到困惑。我有一个播放器 class:
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.surf = pygame.Surface((75, 25))
self.surf.fill((255, 255, 255))
self.rect = self.surf.get_rect()
def update(self, pressed_keys):
if pressed_keys[K_UP]:
self.rect.move_ip(0, -5)
if pressed_keys[K_DOWN]:
self.rect.move_ip(0, 5)
if pressed_keys[K_LEFT]:
self.rect.move_ip(-5, 0)
if pressed_keys[K_RIGHT]:
self.rect.move_ip(5, 0)
pygame.event.pump()
但是每当我按下按键时,什么也没有发生。这是绘制内容的脚本结尾:
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
pressed_keys = pygame.key.get_pressed()
player.update(pressed_keys)
screen.fill((0, 0, 0))
surf = pygame.Surface((50, 50))
surf.fill((0, 0, 0))
rect = surf.get_rect()
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
pygame.display.flip()
我不知道发生了什么,但我找不到任何相关信息来修复它。一切都画对了,但没有别的。
您必须 blit
rect
属性中存储的位置的玩家:
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
screen.blit(player.surf, player.rect)
问题:在屏幕上闪烁时出现逻辑错误
在你的游戏循环中:
player.update
是移动 播放器按键blit
正在绘制始终固定在中心的玩家(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
- 尽管玩家的位置移动了
因此你的播放器卡在视觉上在屏幕中心,尽管你移动了它并且它的位置(在rect
中)被箭头键改变了。
调试
添加一些调试 print
语句
- 在
blit
之前监控玩家位置是否在更新后移动:. - 在
blit
之后监视其 return 绘制矩形的值
print("player's rect after update:", player.rect)
drawn_rect = screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
print("rect drawn by blit:", drawn_rect)
研究
假设您 blit
的意图是:
- 最初绘制时让玩家在屏幕上居中
- 使用
blit
在屏幕上绘制玩家
让我们查阅 PyGame 文档以获得一些支持。
将 Surface
对象居中
阅读 Surface
文档,了解 如何将 与 get_rect()
居中:
You can pass keyword argument values to this function. These named values will be applied to the attributes of the Rect before it is returned. An example would be
mysurf.get_rect(center=(100, 100))
to create a rectangle for the Surface centered at a given position.
使用blit
来自 blit(source, dest, area=None, special_flags=0)
Draws a
source
Surface onto this Surface. The draw can be positioned with thedest
argument. Thedest
argument can either be a pair of coordinates representing the position of the upper left corner of the blit or a Rect
设计修复
Spawn初始位置的玩家,例如centered
(在屏幕上),创建过程中。
然后你的游戏循环有 single responsibility 到 draw
player
screen
。
玩家:居中、移动、抽签
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.surf = pygame.Surface((75, 25))
self.surf.fill((255, 255, 255))
self.rect = self.centered() # spawn it centerd
def update(self, pressed_keys):
if pressed_keys[K_UP]:
self.move(0, -5)
if pressed_keys[K_DOWN]:
self.move(0, 5)
if pressed_keys[K_LEFT]:
self.move(-5, 0)
if pressed_keys[K_RIGHT]:
self.move(5, 0)
pygame.event.pump()
## added some methods
def centered():
return self.surf.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
def move(x, y):
self.rect.move_ip(x,y)
def draw_on(surface): # visitor-pattern
surface.blit(self.surf, self.rect)
注意:在 Player
centered
定位在恒定屏幕尺寸的中心move
以向量 (x,y) 移动玩家
draw_on
在给定的表面上绘制玩家 sprite/surface,就像您的screen
绘图
然后在你的游戏循环中替换:
screen.blit(player.surf, (SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
通过新命令:
# new player is centered, moved player is located anywhere
player.draw_on(screen)
注意:_visitor-pattern- 将语句更改为形式为 <subject>.<verb>(<object>)
的人类可读句子,并且比以前少了一个参数(内部化)。
奖金:建议
可以改进面向对象的设计以增强可读性、简化测试和简化使用:
- 通过命令动作等功能控制玩家
- 选择一种简单的游戏语言(领域术语)
- 并用它来命名你的抽象(对象、函数、变量)
示例:Player
、screen
、move
、centered
、draw
、_to
、_on
(名词, 类似形容词或动词, 用介词表示关系)
通常,设计改进可以更轻松地识别逻辑错误或在调试过程中分析控制流 - 希望如此。