Добрый день.Я пытаюсь написать платформер.Основные действия, такие как создание карты, создание персонажа, взаимодействие и движение камеры, уже реализованы.Есть 4 файла:
Game.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()
Platform.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"))
Player.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()
При запуске программа выдает следующее исключение:
Трассировка (последний последний вызов):
Файл "C: / Users / User / PycharmProjects / teeworlds /Game.py ", строка 125, в main ()
Файл" C: /Users/User/PycharmProjects/teeworlds/Game.py ", строка 31, в основном игроке = 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 должна быть больше нуля.
Я не понимаю, что и где является ошибкой, и что вообще ее вызвало.Буду благодарен за помощь.
Сами спрайты, при необходимости: