2017-02-03 156 views
2

我想用精靈表在pygame中創建一個自頂向下的RPG。pygame動畫精靈表

我希望能夠按空間,例如,攻擊可能會觸發攻擊動畫,然後回到正常

import pygame 
from pygame.locals import * 

pygame.init() 

image = pygame.image.load("sprite_sheet.png") 

clock = pygame.time.Clock() 

screen = pygame.display.set_mode((400, 250)) 

class Player(pygame.sprite.Sprite): 
    def __init__(self): 
     super().__init__() 

     self.current_animation = 0 
     self.max_animation = 5 

     self.animation_cooldown = 150 
     self.last_animation = pygame.time.get_ticks() 

     self.status = {"prev": "standing", 
         "now": "standing"} 

    def animate_attack(self): 
     time_now = pygame.time.get_ticks() 

     if time_now - self.last_animation >= self.animation_cooldown: 
      self.last_animation = pygame.time.get_ticks() 
      if self.current_animation == self.max_animation: 
       self.current_animation = 0 

       joshua.status["now"] = joshua.status["prev"] 
      else: 
       self.current_animation += 1 


joshua = Player() 

while True: 
    screen.fill(0) 
    for event in pygame.event.get(): 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_SPACE: 
       joshua.status["prev"] = joshua.status["now"] 
       joshua.status["now"] = "attacking" 

    if joshua.status["now"] == "attacking": 
     joshua.animate_attack() 

    screen.blit(image, (0, 0), (joshua.current_animation * 64, 0, 64, 64)) 

    pygame.display.flip() 

    clock.tick(60) 

上面這段代碼是什麼我有。如果我按空格一旦它會通過動畫並停止,但如果我加倍按空間它將循環它,因爲它是如何編程的。

想在動畫一些幫助,謝謝

回答

0

問題是由以下調用時空間被擠壓的第二時間造成的:

joshua.status["prev"] = joshua.status["now"] 

這同時設置「上一頁」和「現在「國家是」攻擊「。 其結果是,當國家在animate_attack()方法重置, 它仍將是「攻擊」:

joshua.status["now"] = joshua.status["prev"] 

作爲速戰速決,請務必只改變狀態,如果尚未設置:

if event.key == pygame.K_SPACE: 
    if not joshua.status["now"] == "attacking": 
     joshua.status["prev"] = joshua.status["now"] 
     joshua.status["now"] = "attacking" 

作爲一個更好的修復,您應該封裝狀態, 這樣只有Player類曾經與自己的狀態的交易,例如:

class Player(): 
    def __init__(self): 
     self.current_animation = 0 
     self.max_animation = 5 
     self.animation_cooldown = 150 
     self.last_animation = pygame.time.get_ticks() 
     self.status = "standing" # Simplified state 

    def attack(self): 
     self.status = "attacking" 

    def animate_attack(self): 
     if self.status == "attacking": 
      time_now = pygame.time.get_ticks() 
      if time_now - self.last_animation >= self.animation_cooldown: 
       self.last_animation = pygame.time.get_ticks() 
       if self.current_animation == self.max_animation: 
        self.current_animation = 0 
        self.status = "standing" # Reset state 
       else: 
        self.current_animation += 1 

這樣,也沒有必要了解國家的任何外部類:

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_SPACE: 
       joshua.attack() 

    joshua.animate_attack() 

    screen.fill(0) 
    screen.blit(image, (0, 0), (joshua.current_animation * 64, 0, 64, 64)) 
    pygame.display.flip() 
    clock.tick(60) 
+0

非常感謝你。假設我擁有WASD的控件,並嘗試通過將狀態設置爲「左」向左移動來進行移動。如果我處於攻擊中間並點擊W,它會覆蓋攻擊並停止動畫。在觸發另一個事件之前有什麼辦法讓動畫完成? –

+0

您可以使用單獨的狀態變量,例如 ,例如'self.movement'(「站立」,「左側」,...) 和'self.attacking'(True,False)。 這樣,您可以獨立於攻擊狀態更新移動狀態 。 對於動畫,如果'self.attacking'爲True 則計算當前的攻擊幀,否則使用適當的幀作爲當前移動的 。 – Meyer