Исключение при использовании спрайта с пиганимом - PullRequest
0 голосов
/ 17 октября 2018

Добрый день.Я пытаюсь написать платформер.Основные действия, такие как создание карты, создание персонажа, взаимодействие и движение камеры, уже реализованы.Есть 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 должна быть больше нуля.

Я не понимаю, что и где является ошибкой, и что вообще ее вызвало.Буду благодарен за помощь.

Сами спрайты, при необходимости:

enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

1 Ответ

0 голосов
/ 18 октября 2018

В источнике для Класса Pyganimation фреймы определены как каждый элемент списка кортежей.В вашей программе этот список называется ANIMATION_STAY.

В ANIMATION_STAY вы устанавливаете значение вашей задержки равным 0.1, это ваша ошибка.Предполагается, что ANIMATION_DELAY будет целым числом, а не числом с плавающей запятой или двойным, поэтому вместо вашего 0.1.

используйте целое число. Позже в источнике, когда он делает это: assert frame[1] > 0, 'Frame %s duration must be greater than zero.' % (i), выдается ошибка.Ваша задержка должна быть >0, но она округляется до 0.

...