使用Pygame在MVC模式中处理动画

1 投票
1 回答
750 浏览
提问于 2025-04-18 07:23

我现在正在用Python和Pygame实现MVC模式,但我搞不清楚怎么正确处理动画。假设我们有一个可以攻击的模型对象:

class ModelObject:
    def attack():
        if not self.attacking:
            self.attacking = True
            # Then compute some stuff

    def isattacking():
        return self.attacking

还有一个视图对象,它通过显示攻击动画来渲染这个模型对象:

class ViewObject(pygame.Sprite):

    attacking_ressource = [] # List of surfaces for animation
    default_ressource = None

    def update():
        # Detect the model object is attacking
        if self.model.isattacking():
            # Create animation if needed
            if self.attacking_animation is None:
                self.attacking_animation = iter(self.attacking_ressource)
            # Set image
            self.image = next(self.attacking_animation, self.default_ressource)
        else:
            # Reset animation
            self.attacking_animation = None
            self.image = self.default_ressource

问题是,模型怎么知道自己不再攻击了呢?视图可以在动画结束时通知模型,但我觉得这不是MVC模式应该的做法。或者,可以在模型中设置一个动画计数器,但这似乎也不太对。

1 个回答

1

我觉得你搞错了方向。

攻击的持续时间不应该和动画一样长,而是动画的时间应该和攻击的时间相匹配。

所以ViewObject是没问题的,因为它已经在询问模型是否还在攻击。


至于ModelObject,攻击持续多久以及如何记录时间就看你自己了。比如,你可以在attack里调用pygame.time.get_ticks(),这个函数会告诉你自从游戏开始以来经过了多少毫秒,然后你可以定期再检查一次,像这样:

class ModelObject:
    def attack():
        if not self.attacking:
            self.attacking = True
            self.started = pygame.time.get_ticks()
            # Then compute some stuff

    def isattacking():
        return self.attacking

    def update():
        # attack lasts 1000ms
        self.attacking &= pygame.time.get_ticks() - self.started < 1000

撰写回答