将精灵与pyganim

时间:2018-10-17 16:00:56

标签: python python-3.x animation pygame sprite

美好的一天。我正在尝试编写平台游戏。创建地图,创建角色,交互和相机移动等基本操作已经实现。有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)

init 中的文件“ C:\ Users \ User \ PycharmProjects \ teeworlds \ Player.py”,第28行     self.bolt_anim_stay = pyganim.PygAnimation(ANIMATION_STAY)

init

中的第168行“ C:\ Users \ User \ PycharmProjects \ teeworlds \ venv \ lib \ site-packages \ pyganim__init __。py”
assert frame[1] > 0, 'Frame %s duration must be greater than zero.' % (i)

AssertionError:帧0的持续时间必须大于零。

我不了解错误的内容和位置,以及导致错误的一般原因。我会很感谢您的帮助。

如有需要,可自行显示:

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here {{ 3}} enter image description here enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

Pyganimation Class帧的源中将其定义为元组列表的每个元素。在您的程序中,此列表称为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