Pygame:这个 spritesheet 代码适用于另一个项目,但不适用于这个项目。为啥?
Posted
技术标签:
【中文标题】Pygame:这个 spritesheet 代码适用于另一个项目,但不适用于这个项目。为啥?【英文标题】:Pygame: This spritesheet code works on another project, but not this one. Why?Pygame:这个 spritesheet 代码适用于另一个项目,但不适用于这个项目。为什么? 【发布时间】:2020-12-31 14:23:58 【问题描述】:我之前将以下 spritesheet 代码实现到我正在研究的原型中并且运行良好,但我正在尝试将其实现到我当前的项目中,但它不再有效,我看不出有任何原因就这样吧。
import math, random, sys
import pygame
from pygame.locals import *
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
class spritesheet:
def __init__(self, filename, cols, rows):
self.sheet = pygame.image.load(filename).convert_alpha()
self.cols = cols
self.rows = rows
self.totalCellCount = cols * rows
self.rect = self.sheet.get_rect()
w = self.cellWidth = self.rect.width / cols
h = self.cellHeight = self.rect.height / rows
hw, hh = self.cellCenter = (w / 2, h / 2)
self.cells = list([(index % cols * w, index // cols * h, w, h) for index in range(self.totalCellCount)])
self.handle = list([
(0, 0), (-hw, 0), (-w, 0),
(0, -hh), (-hw, -hh), (-w, -hh),
(0, -h), (-hw, -h), (-w, -h),])
def draw(self, surface, cellIndex, x, y, handle = 0):
surface.blit(self.sheet, (x + self.handle[handle][0], y + self.handle[handle][1]), self.cells[cellIndex])
使用上面的 spritesheet 代码,我用下面的代码将它渲染到我的屏幕上:
import os,pygame, spritesheet
import time, datetime
black = (0,0,0)
SCREEN_WIDTH = 1920
SCREEN_HEIGHT = 1080
HW = SCREEN_WIDTH/2
HH= SCREEN_HEIGHT/2
# Setup the clock for a decent framerate
clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
index = 0
def run_game(width, height, fps):
pygame.init()
global screen
screen = pygame.display.set_mode((width, height))
global clock
playing = True
while playing == True:
Render(screen)
#pygame.display.flip()
clock.tick(fps)
def Render(screen):
global index
global clock
CENTER_HANDLE=4
s = spritesheet.spritesheet("art_assets/christopher_working.png", 20,1)
spritesheet.events()
screen.fill(black)
s.draw(screen, index % s.totalCellCount, HW, HH, CENTER_HANDLE)
screen = pygame.transform.scale(screen,(1920,1080))
pygame.display.update()
index += 1
run_game(1920,1080,60)
而且效果很好!当我尝试在下面列出的当前项目中运行它时,它不再正常工作...
import pygame as pg
import battlesystem
import player_dialog
import random
import spritesheet
import sys
from os import path
from settings import *
class Game:
def __init__(self):
pg.mixer.pre_init(44100, -16, 1, 2048)
pg.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
pg.key.set_repeat(400, 80)
self.max_player_health = 100
self.current_player_health = self.max_player_health
self.current_enemy = ENEMIES['homework']
self.player_damage = 4
self.battle_flag = False
self.dialog_flag = False
self.christopher_working_flag = True
self.index = 0
self.i = 0
self.delay = 0
self.load_data()
def load_data(self):
# holds game folder path
game_folder = path.dirname(__file__)
# holds art assets
img_folder = path.join(game_folder, 'img')
# holds maps
self.map_folder = path.join(game_folder, 'maps')
# holds sounds
snd_folder = path.join(game_folder, 'snd')
# holds music
music_folder = path.join(game_folder, 'music')
self.player_img = pg.image.load(path.join(img_folder, PLAYER_IMG)).convert_alpha()
self.homework_img = pg.image.load(path.join(img_folder, HOMEWORK_IMG)).convert_alpha()
self.christopher_working = spritesheet.spritesheet('img/christopher_working.png', 20,1)
def run(self):
# game loop - set self.playing = False to end game
self.playing = True
while self.playing:
if self.battle_flag == True:
self.current_player_health = battlesystem.battle_system(self.screen, self.current_enemy, self.player_damage, self.current_player_health)
self.battle_flag = False
if self.dialog_flag == True:
player_dialog(temp_dialog)
self.events()
self.draw()
def quit(self):
pg.quit()
sys.exit()
def draw(self):
pg.display.set_caption(":.2f".format(self.clock.get_fps()))
#if self.christopher_working_flag == True:
self.screen.fill(BLACK)
self.christopher_working.draw(self.screen, self.index % self.christopher_working.totalCellCount, HW, HH, CENTER_HANDLE)
self.screen = pg.transform.scale(self.screen,(1024, 768))
self.index += 1
print(self.index % self.christopher_working.totalCellCount)
pg.display.update()
def events(self):
# catch all events here
if self.christopher_working_flag == True:
spritesheet.events()
for event in pg.event.get():
if event.type == pg.QUIT:
self.quit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
self.quit()
#def update(self):
#if self.player_health <= 0: add this later
g = Game()
while True:
g.run()
我在这里和那里删除了几行只是 cmets 或当前未使用的代码(为了可读性和帖子长度)。
在运行我当前的代码时,打印函数显示我的 self.index 变量正在递增......但我的 spritesheet 卡在显示我的 sprite 的第一帧,从不前进。我看不到这两种实现之间的任何功能差异。我知道我更改了某些变量的范围,但在需要时它们都应该可以访问。
谁能告诉我为什么这不起作用?我真的很感激!
【问题讨论】:
旁注(这不会解决问题),您已经实现了 2 个事件循环。由于pygame.event.get()
会从队列中删除所有事件,因此只有一个事件循环会获取事件,另一个循环不会获取事件。见Faster version of pygame.event.get()
将其替换为 self.christopher_working.draw(self.screen, self.index % self.christopher_working.totalCellCount, HW, HH, self.index) 返回了 IndexError: list index out of range。我从设置文件中导入我的 CENTER_HANDLE(对不起,应该提到!),我将它设置为 4(这是 spritesheet.py 中使用的值,用于在矩形中居中精灵。这个值在我的其他代码中工作正常。 self.index 旨在增加动画帧数,与最后一个参数无关。
【参考方案1】:
删除 self.screen = pg.transform.scale(self.screen,(1024, 768)) 解决了这个问题,我不完全确定为什么。我的原始图像是 640x345,我意识到这是一个疯狂的纵横比,但我仍然对为什么转换似乎不起作用感到困惑。
【讨论】:
以上是关于Pygame:这个 spritesheet 代码适用于另一个项目,但不适用于这个项目。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Pygame 中使用 Sprite Sheets 创建动画精灵?