类播放器-动画停止第一帧

时间:2018-06-20 20:47:43

标签: python-3.x pyglet

快速提问。我有播放器类,运行正常。除了一个小细节。这是课程:

from dict.entity_dict import player, player_class
from collections import OrderedDict
import pyglet, random

key = pyglet.window.key

class Player(pyglet.sprite.Sprite):

    dir_stand = "south"
    dir_run = "south"
    sprite_stand = 3
    sprite_run = 3
    image = None
    s = 0

    def __init__(self, game):
        self.game = game

        self.keyboard = key.KeyStateHandler()

        self.statistics_base = OrderedDict()

        self.image_stand = pyglet.resource.image(player.get("player_stand", {'x': None}).get("resource"))
        self.image_run = pyglet.resource.image(player.get("player_run", {'x': None}).get("resource"))
        self.image_stand_width = player.get("player_stand", {'x': None}).get("width")
        self.image_stand_height = player.get("player_stand", {'x': None}).get("height")
        self.image_run_width = player.get("player_run", {'x': None}).get("width")
        self.image_run_height = player.get("player_run", {'x': None}).get("height")

        self.vx = self.game.wd / 2
        self.vy = self.game.wh / 2

        self.load_sprite()

    def class_player(self, type):
        self.statistics_base["hp"] = player_class.get(type, {'x': None}).get("hp")
        self.statistics_base["atk"] = player_class.get(type, {'x': None}).get("atk")
        self.statistics_base["dif"] = player_class.get(type, {'x': None}).get("dif")
        self.statistics_base["atk_sp"] = player_class.get(type, {'x': None}).get("atk_sp")
        self.statistics_base["dif_sp"] = player_class.get(type, {'x': None}).get("dif_sp")
        self.statistics_base["vel"] = player_class.get(type, {'x': None}).get("vel")
        for stat in self.statistics_base:
            if self.statistics_base[stat] is None:
                self.statistics_base[stat] = 10


    def animation(self, image, da, width, height):
        frame_list = [image.get_region(x=width * i, y=height * da, width=46, height=58) for i in range(22)]
        image_animation = pyglet.image.Animation.from_image_sequence(frame_list, 0.10, True)

        return image_animation

    def direction_sprite(self):
        if self.dir_stand == "north":
            self.sprite_stand = 7
        elif self.dir_stand == "east":
            self.sprite_stand = 5
        elif self.dir_stand == "south":
            self.sprite_stand = 3
        elif self.dir_stand == "west":
            self.sprite_stand = 1
        if self.dir_run == "north":
            self.sprite_run = 7
        elif self.dir_run == "north-east":
            self.sprite_run = 6
        elif self.dir_run == "east":
            self.sprite_run = 5
        elif self.dir_run == "south-east":
            self.sprite_run = 4
        elif self.dir_run == "south":
            self.sprite_run = 3
        elif self.dir_run == "south-west":
            self.sprite_run = 2
        elif self.dir_run == "west":
            self.sprite_run = 1
        elif self.dir_run == "north-west":
            self.sprite_run = 0

    def load_sprite(self):
        if not self.keyboard[key.W] and not self.keyboard[key.S] and not self.keyboard[key.D] and not self.keyboard[key.A]:
            self.keyboard.clear()
            img = self.image_stand
            img_width = self.image_stand_width
            img_height = self.image_stand_height
            da = self.sprite_stand
        else:
            img = self.image_run
            img_width = self.image_run_width
            img_height = self.image_run_height
            da = self.sprite_run

        self.direction_sprite()
        self.image = self.animation(img, da, img_width, img_height)
        self.image.width, self.image.height = img_width, img_height
        self.image.anchor_x, self.image.anchor_y = img_width // 2, img_height // 2

        self.sprite = pyglet.sprite.Sprite(self.image, batch=self.game.Batch, group=self.game.GroupEntitySprite)


        self.sprite.x = self.vx
        self.sprite.y = self.vy

    def key_player(self):
        if self.keyboard[key.W]:
            self.vy += 1
            self.dir_stand = "north"
            self.dir_run = "north"
        if self.keyboard[key.S]:
            self.vy -= 1
            self.dir_stand = "south"
            self.dir_run = "south"
        if self.keyboard[key.D]:
            self.vx += 1
            self.dir_stand = "east"
            self.dir_run = "east"
        if self.keyboard[key.A]:
            self.vx -= 1
            self.dir_stand = "west"
            self.dir_run = "west"
        if self.keyboard[key.W] and self.keyboard[key.D]:
            random1 = random.randint(1, 2)
            if random1 == 1:
                self.dir_stand = "north"
            else:
                self.dir_stand = "east"
            self.dir_run = "north-east"
        if self.keyboard[key.S] and self.keyboard[key.D]:
            random2 = random.randint(1, 2)
            if random2 == 1:
                self.dir_stand = "south"
            else:
                self.dir_stand = "east"
            self.dir_run = "south-east"
        if self.keyboard[key.W] and self.keyboard[key.A]:
            random3 = random.randint(1, 2)
            if random3 == 1:
                self.dir_stand = "north"
            else:
                self.dir_stand = "west"
            self.dir_run = "north-west"
        if self.keyboard[key.S] and self.keyboard[key.A]:
            random4 = random.randint(1, 2)
            if random4 == 1:
                self.dir_stand = "south"
            else:
                self.dir_stand = "west"
            self.dir_run = "south-west"

    def update(self):
        self.key_player()
        self.load_sprite()

由于要更新Player的sprite,因此我需要调用“ load_sprite”函数,该函数会导致动画不断被调用。结果,相同的动画不会出现,并且仍停留在第一帧。那我该怎么解决?

编辑:修改了脚本,包括for循环。如果看到的话,我使用Batch和OrderedGroup修改了该组。这样,我们可以清楚地看到我遇到的问题。

我遇到的问题是由于调用pyglet.sprite.Sprite以便更新执行的动画这一事实。但是,与此同时,由于不断调用pyglet.sprite.Sprite,因此无法完全显示动画。

enter image description here

1 个答案:

答案 0 :(得分:1)

首先,可以通过设置精灵的image属性来更改精灵的动画,而不用创建新的Sprite实例。其次,仅在实际需要时更改其动画。那就是方向改变的时候。

我添加了一个简单的示例(伪)代码来大致显示我的意思。

def animation(image, da, width, height):
    frame_list = [image.get_region(x=width * i, y=height * da, width=46, height=58) for i in range(22)]
    image_animation = pyglet.image.Animation.from_image_sequence(frame_list, 0.10, True)
    return image_animation


class Player:

    def __init__(self, standing_animations, running_animations):
        # ... code ...
        self.standing_animations = standing_animations   # List of animations 
        self.running_animations  = running_animations    # List of animations
        self.current_animation = standing_animations[0]  # Just to have a default animation
        self.previous_running_direction  = None
        self.previous_standing_direction = None

    def load_sprite(self):
        self.sprite.x = self.vx
        self.sprite.y = self.vy

        if self.previous_running_direction == self.dir_run and self.previous_standing_direction == self.dir_stand:
            return  # Don't do anything more in here

        if not self.keyboard[key.W] and not self.keyboard[key.S] and not self.keyboard[key.D] and not self.keyboard[key.A]:
            self.keyboard.clear()
            self.current_animation = self.standing_animations[self.sprite_stand]
        else:
            self.current_animation = self.running_animations[self.sprite_run]

        self.sprite.image = self.current_animation

    def update(self):
        self.previous_running_direction  = self.dir_run
        self.previous_standing_direction = self.dir_stand
        self.key_player()
        self.load_sprite()