【发布时间】:2026-01-02 04:35:01
【问题描述】:
美好的一天。我正在尝试编写一个平台游戏。创建地图、创建角色、交互和摄像机移动等基本操作已经实现。有4个文件:
游戏.py:
负责创建窗口,并绘制其余部分。还用于在执行任何操作时启用和禁用标志。
import pygame
from pygame import *
import Camera as cam
import Player as plr
import Platform as plfm
WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30
def main():
global cameraX, cameraY
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption("JohnTeeworlds")
timer = pygame.time.Clock()
up = down = left = right = running = False
bg = Surface((32,32))
bg.convert()
bg.fill(Color("#000000"))
entities = pygame.sprite.Group()
player = plr.Player(32, 32)
platforms = []
x = y = 0
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P P",
"P P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P PPPPPPPP P",
"P P",
"P PPPPPPP P",
"P PPPPPP P",
"P P",
"P PPPPPPP P",
"P P",
"P PPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P P",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]
# build the level
for row in level:
for col in row:
if col == "P":
p = plfm.Platform(x, y)
platforms.append(p)
entities.add(p)
if col == "E":
e = plfm.ExitBlock(x, y)
platforms.append(e)
entities.add(e)
x += 32
y += 32
x = 0
total_level_width = len(level[0])*32
total_level_height = len(level)*32
camera = cam.Camera(cam.complex_camera, total_level_width, total_level_height)
entities.add(player)
while 1:
timer.tick(60)
for e in pygame.event.get():
if e.type == QUIT:
raise SystemExit
if e.type == KEYDOWN and e.key == K_ESCAPE:
raise SystemExit
if e.type == KEYDOWN and e.key == K_w:
up = True
if e.type == KEYDOWN and e.key == K_s:
down = True
if e.type == KEYDOWN and e.key == K_a:
left = True
if e.type == KEYDOWN and e.key == K_d:
right = True
if e.type == KEYDOWN and e.key == K_SPACE:
running = True
if e.type == KEYUP and e.key == K_w:
up = False
if e.type == KEYUP and e.key == K_s:
down = False
if e.type == KEYUP and e.key == K_d:
right = False
if e.type == KEYUP and e.key == K_a:
left = False
# draw background
for y in range(32):
for x in range(32):
screen.blit(bg, (x * 32, y * 32))
camera.update(player)
# update player, draw everything else
player.update(up, down, left, right, running, platforms)
for e in entities:
screen.blit(e.image, camera.apply(e))
pygame.display.update()
if __name__ == "__main__":
main()
平台.py:
只是描述它们外观的一类平台。
from pygame import *
class Entity(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
class Platform(Entity):
def __init__(self, x, y):
super().__init__()
self.image = Surface((32, 32))
self.image.convert()
self.image.fill(Color("#DDDDDD"))
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
super().__init__(x,y)
self.image.fill(Color("#0033FF"))
播放器.py:
类玩家。在这里,我们已经在处理运动、重力,好吧,我正在尝试向我的角色询问精灵,目前处于“等待”状态。这里出现错误,我会在下面描述。
import pygame
from pygame.sprite import Sprite
from pygame import Surface, Rect
import pygame.image
import Platform as plfm
import pyganim
ANIMATION_DELAY = 0.1
ANIMATION_STAY = [('images/player/player_stay/1.png', ANIMATION_DELAY)]
class Entity(Sprite):
def __init__(self):
super().__init__()
class Player(Entity):
def __init__(self, x, y):
super().__init__()
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((30,93))
self.image.convert()
self.rect = Rect(x, y, 30, 93)
self.image.set_colorkey((0, 0, 0))
self.bolt_anim_stay = pyganim.PygAnimation(ANIMATION_STAY)
self.bolt_anim_stay.play()
def update(self, up, down, left, right, running, platforms):
if up:
# only jump if on the ground
if self.onGround: self.yvel -= 10
if down:
pass
if running:
self.xvel = 12
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
# only accelerate with gravity if in the air
self.yvel += 0.3
# max falling speed
if self.yvel > 100: self.yvel = 100
if not(left or right):
self.xvel = 0
if not up:
self.image.fill((0, 0, 0))
self.bolt_anim_stay.blit(self.image, (0, 0))
# increment in x direction
self.rect.left += self.xvel
# do x-axis collisions
self.collide(self.xvel, 0, platforms)
# increment in y direction
self.rect.top += self.yvel
# assuming we're in the air
self.onGround = False
# do y-axis collisions
self.collide(0, self.yvel, platforms)
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, plfm.ExitBlock):
pygame.event.post(pygame.event.Event(QUIT))
if xvel > 0:
self.rect.right = p.rect.left
if xvel < 0:
self.rect.left = p.rect.right
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
还有 Camera.py:
摄像机的类,用于监控玩家在关卡上的移动。
from pygame import *
import Game as game
class Camera:
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return Rect(-l+game.HALF_WIDTH, -t+game.HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l+game.HALF_WIDTH, -t+game.HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling at the left edge
l = max(-(camera.width-game.WIN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-game.WIN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return Rect(l, t, w, h)
问题是我试图用图片创建一个对象。这是 ANIMATION_STAY。 然后我这样做,如果角色没有去任何地方,也没有跳跃,那么我会尝试绘制这个对象。
if not(left or right):
self.xvel = 0
if not up:
self.image.fill((0, 0, 0))
self.bolt_anim_stay.blit(self.image, (0, 0))
同样在构造函数中,我正在尝试播放这个动画。
self.bolt_anim_stay = pyganim.PygAnimation(ANIMATION_STAY)
self.bolt_anim_stay.play()
当你启动程序时会出现这个异常:
Traceback(最近一次调用最后一次):
文件“C:/Users/User/PycharmProjects/teeworlds/Game.py”,第 125 行,在 主要()
文件“C:/Users/User/PycharmProjects/teeworlds/Game.py”,第 31 行,在 main player = plr.Player(32, 32)
文件“C:\Users\User\PycharmProjects\teeworlds\Player.py”,第 28 行,在 init 中 self.bolt_anim_stay = pyganim.PygAnimation(ANIMATION_STAY)
文件“C:\Users\User\PycharmProjects\teeworlds\venv\lib\site-packages\pyganim__init__.py”,第 168 行,在 init
assert frame[1] > 0, 'Frame %s duration must be greater than zero.' % (i)
AssertionError:第 0 帧持续时间必须大于零。
我不明白错误是什么,在哪里,一般是什么原因造成的。我将不胜感激。
精灵本身,如果需要的话:
【问题讨论】:
-
在 self.image.fill 中你不应该提供颜色吗?这不是必需的参数吗?
-
@Thunderwood 喜欢这种颜色(“#DDDDDD”)?我看了视频指南,那里的人指出了这样的颜色(0, 0, 0)
-
你说得对,它的RGB,我的错
-
尝试将动画延迟设置为 1 并告诉我是否遇到同样的错误
-
抱歉删除了我之前的答案,
Pyganimation的来源有几个名称非常相似的变量,我把它们弄糊涂了,这让我的答案大打折扣大声笑
标签: python python-3.x animation pygame sprite