我的 pygame 精灵超时未对齐
My pygame sprites get missaligned overtime
我正在尝试开发平台游戏,但是当我开始实施重力和跳跃机制时,我的地形精灵在 y 轴上没有对齐,我真的不知道出了什么问题。
我的代码由主树组成 classes:
Player
:这个class玩家的逻辑都有了
Level
:这个有关卡的逻辑,这大概就是我的错误所在。
Tile
:class 生成地形的所有方块,也可能是问题的一部分。
还有一个名为 Game
的 class,但问题 100% 不是来自那里,因为 class 目前所做的一切都是初始化关卡 class .
import pygame, sys
pygame.init()
# Settings
tile_size = 64
fov = 10
screen_width = 1200
screen_height = tile_size * fov
level_data = [
' ',
' ',
' XX ',
'XX XXX ',
'XX XX',
'XXXX XX ',
'XXXX P XX ',
'XX X XXX XX X ',
' X XXX XX XX ',
' XXXX XXXXX XX XXX',
'XXXXXXX XXXXX XX XXX']
# Classes
class Game():
def __init__(self):
self.level = Level(screen)
self.status = 'level'
def run(self):
if self.status == 'level':
self.level.run()
class Level:
def __init__(self,display_surface):
# Basic setup
self.setup_level()
self.display_surface = display_surface
# Movement
self.x_shift = 0
self.y_shift = 0
def setup_level(self):
self.tiles = pygame.sprite.Group()
self.player = pygame.sprite.GroupSingle()
for row_index,row in enumerate(level_data):
for col_index,col in enumerate(row):
x = col_index * tile_size
y = (row_index * tile_size) - ((len(level_data) - fov) * tile_size)
if col == 'X':
tile = Tile((x,y))
self.tiles.add(tile)
if col == 'P':
player = Player((x,y))
self.player.add(player)
def apply_gravity(self):
player = self.player.sprite
self.y_shift = player.direction.y
def run(self):
# Tiles
self.tiles.update(self.x_shift,self.y_shift)
self.tiles.draw(self.display_surface)
# Player
self.player.update()
self.apply_gravity()
self.player.draw(self.display_surface)
class Tile(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
self.image = pygame.Surface((tile_size,tile_size))
self.image.fill('grey')
self.rect = self.image.get_rect(topleft = pos)
def update(self,x_shift,y_shift):
self.rect.x += x_shift
self.rect.y -= y_shift
class Player(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
# Image
self.image = pygame.Surface((32,64))
self.image.fill('red')
self.rect = self.image.get_rect(topleft = pos)
# Movement
self.direction = pygame.math.Vector2(0,0)
self.gravity = 0.8
def get_inputs(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.direction.y = -20
def apply_gravity(self):
self.direction.y += self.gravity
def update(self):
self.get_inputs()
self.apply_gravity()
# Game setup
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Platformer')
clock = pygame.time.Clock()
game = Game()
# Main
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill('black')
game.run()
pygame.display.update()
clock.tick(60)
这是一个很常见的问题,与pygame.Rect
. Since pygame.Rect
应该代表屏幕上的一个区域有关,pygame.Rect
对象只能存储整数数据。
The coordinates for Rect objects are all integers. [...]
当新偏移量添加到 Rect 对象的位置时,坐标的小数部分会丢失。如果每一帧都这样做,位置误差会随着时间累积。
self.rect.x += x_shift
self.rect.y -= y_shift
如果要以浮点精度存储对象位置,则必须将对象的位置分别存储在单独的变量和属性中,并同步 pygame.Rect
对象。 round
坐标并将其分配给矩形的位置(例如.topleft
):
class Tile(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
self.image = pygame.Surface((tile_size,tile_size))
self.image.fill('grey')
self.rect = self.image.get_rect(topleft = pos)
self.x = self.rect.x
self.y = self.rect.y
def update(self,x_shift,y_shift):
self.x += x_shift
self.y -= y_shift
self.rect.topleft = round(self.x), round(self.y)
我正在尝试开发平台游戏,但是当我开始实施重力和跳跃机制时,我的地形精灵在 y 轴上没有对齐,我真的不知道出了什么问题。
我的代码由主树组成 classes:
Player
:这个class玩家的逻辑都有了Level
:这个有关卡的逻辑,这大概就是我的错误所在。Tile
:class 生成地形的所有方块,也可能是问题的一部分。
还有一个名为 Game
的 class,但问题 100% 不是来自那里,因为 class 目前所做的一切都是初始化关卡 class .
import pygame, sys
pygame.init()
# Settings
tile_size = 64
fov = 10
screen_width = 1200
screen_height = tile_size * fov
level_data = [
' ',
' ',
' XX ',
'XX XXX ',
'XX XX',
'XXXX XX ',
'XXXX P XX ',
'XX X XXX XX X ',
' X XXX XX XX ',
' XXXX XXXXX XX XXX',
'XXXXXXX XXXXX XX XXX']
# Classes
class Game():
def __init__(self):
self.level = Level(screen)
self.status = 'level'
def run(self):
if self.status == 'level':
self.level.run()
class Level:
def __init__(self,display_surface):
# Basic setup
self.setup_level()
self.display_surface = display_surface
# Movement
self.x_shift = 0
self.y_shift = 0
def setup_level(self):
self.tiles = pygame.sprite.Group()
self.player = pygame.sprite.GroupSingle()
for row_index,row in enumerate(level_data):
for col_index,col in enumerate(row):
x = col_index * tile_size
y = (row_index * tile_size) - ((len(level_data) - fov) * tile_size)
if col == 'X':
tile = Tile((x,y))
self.tiles.add(tile)
if col == 'P':
player = Player((x,y))
self.player.add(player)
def apply_gravity(self):
player = self.player.sprite
self.y_shift = player.direction.y
def run(self):
# Tiles
self.tiles.update(self.x_shift,self.y_shift)
self.tiles.draw(self.display_surface)
# Player
self.player.update()
self.apply_gravity()
self.player.draw(self.display_surface)
class Tile(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
self.image = pygame.Surface((tile_size,tile_size))
self.image.fill('grey')
self.rect = self.image.get_rect(topleft = pos)
def update(self,x_shift,y_shift):
self.rect.x += x_shift
self.rect.y -= y_shift
class Player(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
# Image
self.image = pygame.Surface((32,64))
self.image.fill('red')
self.rect = self.image.get_rect(topleft = pos)
# Movement
self.direction = pygame.math.Vector2(0,0)
self.gravity = 0.8
def get_inputs(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.direction.y = -20
def apply_gravity(self):
self.direction.y += self.gravity
def update(self):
self.get_inputs()
self.apply_gravity()
# Game setup
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Platformer')
clock = pygame.time.Clock()
game = Game()
# Main
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill('black')
game.run()
pygame.display.update()
clock.tick(60)
这是一个很常见的问题,与pygame.Rect
. Since pygame.Rect
应该代表屏幕上的一个区域有关,pygame.Rect
对象只能存储整数数据。
The coordinates for Rect objects are all integers. [...]
当新偏移量添加到 Rect 对象的位置时,坐标的小数部分会丢失。如果每一帧都这样做,位置误差会随着时间累积。
self.rect.x += x_shift self.rect.y -= y_shift
如果要以浮点精度存储对象位置,则必须将对象的位置分别存储在单独的变量和属性中,并同步 pygame.Rect
对象。 round
坐标并将其分配给矩形的位置(例如.topleft
):
class Tile(pygame.sprite.Sprite):
def __init__(self,pos):
super().__init__()
self.image = pygame.Surface((tile_size,tile_size))
self.image.fill('grey')
self.rect = self.image.get_rect(topleft = pos)
self.x = self.rect.x
self.y = self.rect.y
def update(self,x_shift,y_shift):
self.x += x_shift
self.y -= y_shift
self.rect.topleft = round(self.x), round(self.y)