iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0

今天的內容是讓怪物動起來

怪物的移動設定

一開始共15步,先左移5次,再右移十次

然後就循環左10次再右10次,共20步

每過20步,就再往下一步

實作,怪物更新程式碼

  • 初始化移動步數

    class Mob(pygame.sprite.Sprite):
        def __init__(self, construction: dict, **kwargs):
            self.move_steps = 15
    
  • 每走一步,move_steps-1,然後當 move_steps 歸零時,重設為 20,並往下走一步

    class Mob(pygame.sprite.Sprite):
        def update(self) -> None:
            if self.move_steps > 10:
                    self.move_right()
                else:
                    self.move_left()
                self.move_steps -= 1
                if self.move_steps <= 0:
                    self.move_steps = 20
                    self.move_down()
    
  • BattleModeupdate 會不斷被執行,透過 Group().update() 即可呼叫該 Group() 裡的 sprite 物件繼承 Sprite() 類別就都會有的 update() 函式

    class BattleMode:
        def update(self, command: dict) -> None:
        self.mobs.update()
    

修正怪物移動

  • 此時那些怪物的移動,應該會很快,然後就邊移動邊掉下去了

  • 原因是遊戲是每幀都會呼叫一次 update 函式,若 30 FPS,就是每秒一洞30次,每過一輪就又往下一步

  • 所以我們需要增加移動冷卻時間,並且增加當在冷卻時間的時候,vel 重新設為 0

    # before
    class Mob(pygame.sprite.Sprite):
        def update(self) -> None:
            if self.move_steps > 10:
                    self.move_right()
                else:
                    self.move_left()
                self.move_steps -= 1
                if self.move_steps <= 0:
                    self.move_steps = 20
                    self.move_down()
    
    # after
    class Mob(pygame.sprite.Sprite):
        def update(self) -> None:
            if self.used_frame - self.last_move_frame > self.move_cd:
                if self.move_steps > 10:
                    self.move_right()
                else:
                    self.move_left()
                self.move_steps -= 1
                if self.move_steps <= 0:
                    self.move_steps = 20
                    self.move_down()
                self.last_move_frame = self.used_frame
            else:
                self.vel = Vec(0, 0)
    
    • 現在時間減掉上次移動時間,若超過冷卻時間,則執行移動函式,並更新上次移動時間為現在時間,否則速度為零
  • 別忘了,初始化變數

    class Mob(pygame.sprite.Sprite):
        def __init__(self, construction: dict, **kwargs):
            self.last_move_frame = 0
            self.move_cd = 15
    

最後,不知道大家有沒有遇到這個 Bug?

  • 由於 mlgame 是不會等到 AI 回傳指令後才執行後續的程式,所以有可能會遇到回傳的字典,用 key 索引後,是 None,所以可以在 act 的最開始,先判定

  • actionNone,則返回 None,跳出函式

    class Player(pygame.sprite.Sprite):
        def act(self, action: list) -> None:
            if not action:
                return
    

本日進度完整程式碼 點我

day_18_end_view


上一篇
實作!雙人射擊遊戲 —— 新增怪物
下一篇
實作!雙人射擊遊戲 —— 新增子彈
系列文
用程式寫遊戲給AI玩30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言