所以我写了一个pygame游戏,代码有点大,但我会解释我的问题是什么。如果需要,我也可以发布代码。
所以我在pygame中
有一个PlayerData
类和一个类,使用Python 3.3.2。类有 3 个方法,它们根据键盘输入改变位置向量,(特别是 x 坐标,因为它是 2D 的)。第三种方法是。它获取位置向量,并将其分配给玩家 rect.left/rect.top。运动功能有一个标志参数,我在课堂上使用它。EventManager
PlayerData
self.move_left(self)
self.move_right(self)
self.update_pos(self)
EventManager
到目前为止,这对于玩家阶层来说是清晰而体面的。问题来了。在我的EventManager
课堂上,我有一个 for 循环来检查按键是否被按下/释放。在__init__()
我只打电话self.player = playerData()
。如果按下某个键,我会调用该类self.player.move_left(flag=True)
中定义的键PlayerData
。如果释放相同的键,我调用self.player.move_left(flag=False)
,所以它停止减去像素向左移动。
再说一次,到目前为止,我觉得很好。但后来我点击了游戏循环,它是这样的:
Handle events
Update game state
Draw
在句柄事件块中,我检查键,如果按下,我调用PlayerData
方法来移动。(意味着重新定义在PlayerData
类中定义的位置向量的 x,y 坐标)。然后我转到更新数据块,在那里我调用Player.update_pos()
,它将新的位置坐标分配给玩家矩形形状。然后我重新绘制播放器。
问题是当我调用该update_pos()
方法时位置向量没有改变。这是代码。
import pygame
import sys
import datetime
from pygame.locals import *
from datetime import timedelta
class Vector(object):
''' Performs vector aritmetics
'''
def __init__(self, x, y):
self.x = x
self.y = y
def add(self, v):
x = self.x + v.x
y = self.y + v.y
return Vector(x, y)
class GroundTerrain(object):
''' Ground data structure.
Creates a ground data structure and her component's.
'''
def __init__(self):
self.position = Vector(0, 334) # TODO: Remove the hard coding
self.color = (128, 128, 128) # Gray
self.width = WINDOWWIDTH
self.height = 166
self.ground = {'shape': pygame.Rect((self.position.x, self.position.y),
(self.width, self.height)),
'color': self.color
}
def draw_ground(self):
''' Draw's the ground shape and color using pygame.draw.rect(...).
'''
pygame.draw.rect(WINDOWSURFACE, self.ground['color'],
self.ground['shape'])
class PlayerData(object):
''' Player data structure.
Creates a player data structure and handles few actions.
'''
def __init__(self):
self.ground = GroundTerrain()
self.position = Vector(15, 264) # TODO: Remove the hard coding
self.size = Vector(50, 70)
self.velocity = Vector(5, 5)
self.gravity = Vector(0, -10)
self.color = (0, 100, 0) # Dark Green
self.player = {'shape': pygame.Rect((self.position.x, self.position.y),
(self.size.x, self.size.y)),
'color': self.color}
def move_left(self, flag=False):
''' Moves the player shape horizontally
if it's inside window borders.
'''
if flag and self.position.x > 0:
self.position.x = self.position.x - self.velocity.x
def move_right(self, flag=False):
''' Moves the player shape horizontally
if it's inside window borders.
'''
if flag and self.position.x + self.size.x < WINDOWWIDTH:
self.position.x = self.position.x + self.velocity.x
def update_pos(self):
self.player['shape'].left = self.position.x
self.player['shape'].top = self.position.y
def draw_player(self):
''' Draw's the player shape and color using pygame.draw.rect(...).
'''
pygame.draw.rect(WINDOWSURFACE, self.player['color'],
self.player['shape'])
class EventManager(object):
''' Handles keyboard event's.
Toggles player variables according to the event's.
'''
def __init__(self):
self.player = PlayerData()
def set_variables(self):
''' Toggles player variables according to keyboard/mouse event's.
'''
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == ord('a'):
self.player.move_left(True)
if event.key == K_RIGHT or event.key == ord('d'):
self.player.move_right(True)
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == ord('a'):
self.player.move_left(False)
if event.key == K_RIGHT or event.key == ord('d'):
self.player.move_right(False)
#-------------------------------------------------------------------------
WINDOWWIDTH = 900
WINDOWHEIGHT = 500
WINDOWSURFACE = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Placeholder')
MAIN_CLOCK = pygame.time.Clock()
FPS = 40
def main():
pygame.init()
Ground = GroundTerrain()
Player = PlayerData()
EventHandle = EventManager()
while True:
# Handle events
EventHandle.set_variables()
# Update game state
Player.update_pos()
# Draw
WINDOWSURFACE.fill((0, 0, 0)) # Black
Ground.draw_ground()
Player.draw_player()
pygame.display.update()
MAIN_CLOCK.tick(FPS)
main()