iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0

這次我們要以一個簡單的AI手動範例,講解透過AI玩遊戲時的運行過程。

Tutorial Game

AI介紹

請看MLGame官方教學文件 @AI_Structures

AI跟遊戲之間如何溝通

AI端

def update(self, scene_info: dict, keyboard=[], *args, **kwargs):
    # print(scene_info)
    # print(keyboard)
    if scene_info["status"] != "GAME_ALIVE":
        return "RESET"

    command = []
    if self.side == "1P":
        if pygame.K_RIGHT in keyboard:
            command.append("RIGHT")
        elif pygame.K_LEFT in keyboard:
            command.append("LEFT")
        elif pygame.K_UP in keyboard:
            command.append("UP")
        elif pygame.K_DOWN in keyboard:
            command.append("DOWN")

        if pygame.K_p in keyboard:
            command.append("SHOOT")
    else:
        if pygame.K_d in keyboard:
            command.append("RIGHT")
        elif pygame.K_a in keyboard:
            command.append("LEFT")
        elif pygame.K_w in keyboard:
            command.append("UP")
        elif pygame.K_s in keyboard:
            command.append("DOWN")

        if pygame.K_f in keyboard:
            command.append("SHOOT")

    if not command:
        command.append("NONE")

    return command
  • scene_info是PaiaGame執行def get_data_from_game_to_player(self)後獲得遊戲資訊,再將其分別傳給1P、2P…的AI,玩家可以藉由這個去撰寫AI的演算法或規則等
  • keyboard是mlgame會在遊戲運行的時候,偵測鍵盤輸入,並將在按下狀態的鍵的編號,存成list傳給AI
  • 這裡使用 pygameK_d 來取得按鍵的編號,大家也可以使用其他的方式喔!
  • 於是在 update 的時候我們根據哪些鍵被按下,把相對應要執行的遊戲指令存成list,在最後回傳給mlgame

PaiaGame端

def update(self, commands: dict):
    self.handle_event()
    self.game_mode.debugging(self.is_debug)
    if not self.is_paused:
        self.frame_count += 1
        self.game_mode.update(commands)
        if not self.is_running():
            return "RESET"
  • commands是mlgame以從哪個AI那收到的遊戲指令為key,指令為value,存成字典傳給PaiaGame
  • 然後PaiaGame再傳給我們這次遊戲執行的遊戲模式去處理

GameMode端

def update(self, command: dict) -> None:
    self.used_frame += 1
    self.players.update(command)
    self.get_player_end()
  • playerspygamesprite.Group類別,可以一次呼叫裡面存放著的遊戲玩家的update函式,這裡我們把遊戲指令傳給player

Player端

def update(self, command: dict) -> None:
    self.used_frame += 1
    # self.rect.center += self.vel
    self.act(command[self.id])
  • Player便將是自己id的指令交給act去執行
def act(self, action: list) -> None:
    if "RIGHT" in action:
        self.rect.x += self.vel.x
    elif "LEFT" in action:
        self.rect.x -= self.vel.x
    if "UP" in action:
        self.rect.y -= self.vel.y
    elif "DOWN" in action:
        self.rect.y += self.vel.y
    if "SHOOT" in action:
        pass
  • 於是Player就判斷指令執行相對應的行動
  • rect為玩家實際在遊戲程式中的樣子,藉由rect定義玩家的座標、大小,和控制玩家移動、縮放(MLGame框架使用的是Pygame的座標系統,但由於我們還沒做好說明文件,就在這放上兩張Google上找到的圖給大家看下吧)

rect

coordinate

  • 若要實作轉彎,可參考 TankMan的rotate函式 @TankMan.src.Player.rotate
  • SHOOT的指令,目前還未定義實際的行動,大家可以來試著寫寫看新的行動,或定義新的指令吧

看完這篇文章,快來試試透過另一隻程式,來遊玩你的遊戲是甚麼感覺?或是可以寫AI程式,來破關我們的遊戲喔!(偷偷宣傳一下,如果是國高中生,可以來報名明年的全國自走車大賽 @2022PTWA全國自走車大賽

更多MLGame遊戲專案

  1. 範例遊戲 easy_game
  2. 打磚塊 arkanoid
  3. 乒乓球 pingpong
  4. 賽車 Racing Car
  5. 迷宮自走車 Maze Car

上一篇
快速開始一個新的遊戲 @MLGame Template
下一篇
用程式寫遊戲給AI玩 @MLGameTemplate
系列文
用程式寫遊戲給AI玩30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言