为啥我的 pygame 应用程序循环不能正常工作? [复制]
Posted
技术标签:
【中文标题】为啥我的 pygame 应用程序循环不能正常工作? [复制]【英文标题】:Why is my pygame application loop not working properly? [duplicate]为什么我的 pygame 应用程序循环不能正常工作? [复制] 【发布时间】:2020-06-08 18:11:23 【问题描述】:在浏览了 pygame 文档之后,我正在开发一款非常粗糙的自上而下的 2d 冒险游戏。但是,在无法在相机系统上找到任何东西后,我遇到了一些障碍,发现大多数相机教程已经有 5 年以上的历史了,而且似乎不再适用了。谁能帮我造个相机?
这是我主要执行的脚本
import sys, pygame
from PlayerObject import Player
pygame.init()
screen_height = 180
screen_width = 320
map_height = 1080
map_width = 1920
num_objects = 5
screen = pygame.display.set_mode((screen_width, screen_height))
player_image = pygame.image.load('models/hero.bmp').convert()
background = pygame.image.load('models/lobby.bmp').convert()
screen.blit(background, (0, 0))
objects = []
# randomly generates 5 entities with the 1st one being the controlled character
for i in range(num_objects):
o = Player(player_image, random.randint(0, screen_width), random.randint(0, screen_height), 10)
objects.append(o)
while 1:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
screen.blit(background, objects[0].pos, objects[0].pos)
objects[0].move_left()
screen.blit(objects[0].image, objects[0].pos)
if keys[pygame.K_RIGHT]:
screen.blit(background, objects[0].pos, objects[0].pos)
objects[0].move_right()
screen.blit(objects[0].image, objects[0].pos)
if keys[pygame.K_UP]:
screen.blit(background, objects[0].pos, objects[0].pos)
objects[0].move_up()
screen.blit(objects[0].image, objects[0].pos)
if keys[pygame.K_DOWN]:
screen.blit(background, objects[0].pos, objects[0].pos)
objects[0].move_down()
screen.blit(objects[0].image, objects[0].pos)
screen.blit(background)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
for o in objects:
screen.blit(background, o.pos, o.pos)
for num in range(num_objects - 1):
objects[num + 1].rand_move()
for o in objects:
screen.blit(o.image, o.pos)
pygame.display.update()
pygame.time.delay(100)
这是我的播放器类
import random
map_height = 180
map_width = 320
class Player:
def __init__(self, image, width, height, speed):
self.speed = speed
self.image = image
self.pos = image.get_rect().move(width, height)
self.image = image
def set_speed(self, speed):
self.speed = speed
def rand_move(self):
x = random.randint(-self.speed, self.speed)
y = random.randint(-self.speed, self.speed)
self.pos = self.pos.move(x, y)
# keeps player in boundaries
if self.pos.left < 0:
self.pos.left = 0
if self.pos.right > map_width:
self.pos.right = map_width
if self.pos.top < 0:
self.pos.top = 0
if self.pos.bottom > map_height:
self.pos.bottom = map_height
def move_left(self):
speed = self.speed
self.pos = self.pos.move(-speed, 0)
if self.pos.left < 0:
self.pos.left = 0
def move_right(self):
speed = self.speed
self.pos = self.pos.move(speed, 0)
if self.pos.right > map_width:
self.pos.right = map_width
def move_up(self):
speed = self.speed
self.pos = self.pos.move(0, -speed)
if self.pos.top < 0:
self.pos.top = 0
def move_down(self):
speed = self.speed
self.pos = self.pos.move(0, speed)
if self.pos.bottom > map_height:
self.pos.bottom = map_height
【问题讨论】:
【参考方案1】:您的基本误解是,您尝试在对象的位置绘制背景,然后移动对象并blit
最终将其移至新位置。这一切都没有必要。
通常,整个场景是在主应用程序循环的每一帧中绘制的。将背景绘制到整个窗口和blit
上面的每个对象就足够了。请注意,您不会立即看到窗口表面的变化。当显示被pygame.display.update()
或pygame.display.flip()
更新时,更改变得可见:
主应用程序循环必须:
通过pygame.event.pump()
或pygame.event.get()
处理事件。
根据输入事件和时间(分别为帧)更新游戏状态和对象位置
清空整个显示或绘制背景
绘制整个场景(blit
所有对象)
通过pygame.display.update()
或pygame.display.flip()
更新显示
例如:
while 1:
# handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# update objects (depends on input events and frames)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
objects[0].move_left()
if keys[pygame.K_RIGHT]:
objects[0].move_right()
if keys[pygame.K_UP]:
objects[0].move_up()
if keys[pygame.K_DOWN]:
objects[0].move_down()
for num in range(num_objects - 1):
objects[num + 1].rand_move()
# draw background
screen.blit(background, (0, 0))
# draw scene
for o in objects:
screen.blit(o.image, o.pos)
# update dispaly
pygame.display.update()
pygame.time.delay(100)
最小示例: repl.it/@Rabbid76/PyGame-MinimalApplicationLoop
【讨论】:
首先,非常感谢您的回复!我认为在阅读了您的 cmets 并摆弄了您作为示例提供的代码之后,我对 blitting 的理解更好了。说到这里,我将 screen.blit(background, (0,0) 更改为 screen.blit(background, (-L+speed, -T+speed) 其中 L 和 T 是我的字符的矩形位置,速度是角色每帧移动多远。这模拟了一个相机,但似乎角色在地图结束之前到达了屏幕边缘。我试过弄乱它,但似乎没有任何效果,你有什么建议吗?谢谢!! @AsianTemptation “但似乎角色在地图结束之前到达了屏幕边缘。” 我不明白你的意思。这是一个新问题吗? 嗯,我最初的问题是关于如何构建一个可行的相机,我已经构建了一个非常粗糙的相机,其中角色移动的速度比他下方的地图更新速度更快。我不知道如何描述,但他似乎在相对于屏幕窗口移动,我不确定如何让他保持居中。 @AsianTemptation 你的问题很广泛。请阅读How do I ask a good question? 和How to create a Minimal, Complete, and Verifiable example。我建议展示你到目前为止尝试过的帽子,然后再次Ask a public question。以上是关于为啥我的 pygame 应用程序循环不能正常工作? [复制]的主要内容,如果未能解决你的问题,请参考以下文章