diff --git a/README.md b/README.md index dd6637c..6b315a5 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ # **Easy Game** -logo - -[comment]: <> (![python](https://img.shields.io/pypi/pyversions/pygame)) ![easy_game](https://img.shields.io/github/v/tag/PAIA-Playful-AI-Arena/easy_game) [![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-390/) -[![MLGame](https://img.shields.io/badge/MLGame-9.4.0-.svg)](https://github.com/PAIA-Playful-AI-Arena/MLGame) +[![MLGame](https://img.shields.io/badge/MLGame->9.5.3-.svg)](https://github.com/PAIA-Playful-AI-Arena/MLGame) [![pygame](https://img.shields.io/badge/pygame-2.0.1-.svg)](https://github.com/pygame/pygame/releases/tag/2.0.1) ---- -這是一個吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例 -![https://github.com/PAIA-Playful-AI-Arena/MLGame/raw/master/games/easy_game/asset/easy_game.gif](https://github.com/PAIA-Playful-AI-Arena/MLGame/raw/master/games/easy_game/asset/easy_game.gif) + +這是一個吃東西小遊戲,也是 PAIA 的遊戲教學範例 + +![demo](https://github.com/PAIA-Playful-AI-Arena/easy_game/blob/main/asset/easy_game.gif?raw=true) --- # 基礎介紹 @@ -65,12 +63,10 @@ game = EasyGame(time_to_play=1000, total_point_count=10, score=5, color="FF9800" ## 使用AI玩遊戲 ```bash -# python MLGame.py [options] easy_game [time_to_play] [total_point_count] [score] [color] -python MLGame.py -i ml_play_template.py easy_game --time_to_play 1200 --total_point_count 15 --score 10 --color FF9800 +# 在easy game中,打開終端機 +python -m mlgame -i ./ml/ml_play_template.py ./ --time_to_play 1200 --total_point_count 15 --score 10 --color FF9800 ``` -遊戲參數依序是[`time_to_play`] [`total_point_count`] [`score`] [`color`] - ## AI範例 ```python diff --git a/asset/img/background.jpg b/asset/img/background.jpg index 37411a5..e20b960 100644 Binary files a/asset/img/background.jpg and b/asset/img/background.jpg differ diff --git a/blockly.json b/blockly.json index 412873b..209b6bf 100644 --- a/blockly.json +++ b/blockly.json @@ -1,4 +1,6 @@ -{ +{"INIT_INFO": [ + ["ai_name", "name of ai", "AI編號"] + ], "GAME_STATUS": [ ["GAME_ALIVE", "alive", "存活"], ["GAME_PASS", "pass", "通關"], diff --git a/config.py b/config.py index afc979b..2f73949 100644 --- a/config.py +++ b/config.py @@ -1,20 +1,10 @@ - +import sys from os import path +sys.path.append(path.dirname(__file__)) -from mlgame.utils.parse_config import read_json_file, parse_config -from .src.game import EasyGame - -config_file = path.join(path.dirname(__file__), "game_config.json") - - -config_data = read_json_file(config_file) -GAME_VERSION = config_data["version"] -GAME_PARAMS = parse_config(config_data) - -# will be equal to config. GAME_SETUP["ml_clients"][0]["name"] +from src.game import EasyGame GAME_SETUP = { "game": EasyGame, - "ml_clients": EasyGame.ai_clients(), # "dynamic_ml_clients":True } diff --git a/game_config.json b/game_config.json index a12957c..a1adc48 100644 --- a/game_config.json +++ b/game_config.json @@ -1,12 +1,15 @@ { "game_name": "easy_game", - "version": "1.2.1", + "version": "2.1.0", "url": "https://github.com/PAIA-Playful-AI-Arena/easy_game", "description": "這是一個吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例", "logo": [ "./asset/logo.svg", "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/Paia-Desktop/master/media/easygame.svg" ], + "user_num": { + "min": 1,"max": 1 + }, "game_params": [ { "name": "time_to_play", diff --git a/main.py b/main.py index 1aa72ef..3485878 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ import sys sys.path.append(r"../..") from mlgame.view.view import PygameView -from mlgame.gamedev.generic import quit_or_esc +from mlgame.game.generic import quit_or_esc from src.game import EasyGame FPS = 30 diff --git a/ml/ml_play_manual.py b/ml/ml_play_manual.py index 5c612fe..99ac762 100644 --- a/ml/ml_play_manual.py +++ b/ml/ml_play_manual.py @@ -3,7 +3,7 @@ import pygame class MLPlay: - def __init__(self): + def __init__(self,ai_name,*args,**kwargs): print("Initial ml script") def update(self, scene_info: dict, keyboard:list=[], *args, **kwargs): diff --git a/ml/ml_play_template.py b/ml/ml_play_template.py index 02efb26..20db09d 100644 --- a/ml/ml_play_template.py +++ b/ml/ml_play_template.py @@ -1,6 +1,6 @@ import random class MLPlay: - def __init__(self): + def __init__(self,*args, **kwargs): print("Initial ml script") def update(self, scene_info: dict, *args, **kwargs): diff --git a/src/game.py b/src/game.py index 85f4f90..f44dbcf 100644 --- a/src/game.py +++ b/src/game.py @@ -3,8 +3,9 @@ from os import path import pygame -from mlgame.gamedev.game_interface import PaiaGame, GameResultState, GameStatus -from mlgame.view.test_decorator import check_game_progress, check_game_result +from mlgame.game.paia_game import PaiaGame, GameResultState, GameStatus +from mlgame.utils.enum import get_ai_name +from mlgame.view.decorator import check_game_progress, check_game_result from mlgame.view.view_model import create_text_view_data, create_asset_init_data, create_image_view_data, Scene, \ create_scene_progress_data from .game_object import Ball, Food @@ -17,8 +18,8 @@ class EasyGame(PaiaGame): This is a Interface of a game """ - def __init__(self, time_to_play, total_point_count, score, color): - super().__init__() + def __init__(self, time_to_play, total_point_count, score, color, *args, **kwargs): + super().__init__(user_num=1) self.game_result_state = GameResultState.FAIL self.scene = Scene(width=800, height=600, color="#4FC3F7", bias_x=0, bias_y=0) print(color) @@ -34,9 +35,13 @@ class EasyGame(PaiaGame): def update(self, commands): # handle command - ai_1p_cmd = commands[self.ai_clients()[0]["name"]][0] + ai_1p_cmd = commands[get_ai_name(0)] + if ai_1p_cmd is not None: + action = ai_1p_cmd[0] + else: + action = "NONE" # print(ai_1p_cmd) - self.ball.update(ai_1p_cmd) + self.ball.update(action) # update sprite self.foods.update() @@ -54,7 +59,7 @@ class EasyGame(PaiaGame): if not self.is_running: return "QUIT" - def game_to_player_data(self): + def get_data_from_game_to_player(self): """ send something to game AI we could send different data to different ai @@ -72,8 +77,7 @@ class EasyGame(PaiaGame): "status": self.get_game_status() } - for ai_client in self.ai_clients(): - to_players_data[ai_client['name']] = data_to_1p + to_players_data[get_ai_name(0)] = data_to_1p # should be equal to config. GAME_SETUP["ml_clients"][0]["name"] return to_players_data @@ -101,7 +105,9 @@ class EasyGame(PaiaGame): """ # TODO add music or sound bg_path = path.join(ASSET_PATH, "img/background.jpg") - background = create_asset_init_data("background", 800, 600, bg_path, "url") + background = create_asset_init_data( + "background", 800, 600, bg_path, + github_raw_url="https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/easy_game/main/asset/img/background.jpg") scene_init_data = {"scene": self.scene.__dict__, "assets": [ background @@ -139,7 +145,7 @@ class EasyGame(PaiaGame): "state": self.game_result_state, "attachment": [ { - "player": self.ai_clients()[0]["name"], + "player": get_ai_name(0), "rank": 1, "score": self.score } @@ -163,21 +169,10 @@ class EasyGame(PaiaGame): cmd_1p.append("RIGHT") else: cmd_1p.append("NONE") - ai_1p = self.ai_clients()[0]["name"] - return {ai_1p: cmd_1p} + return {get_ai_name(0): cmd_1p} def _create_foods(self, count: int = 5): for i in range(count): # add food to group food = Food(self.foods) pass - - @staticmethod - def ai_clients(): - """ - let MLGame know how to parse your ai, - you can also use this names to get different cmd and send different data to each ai client - """ - return [ - {"name": "1P"} - ] diff --git a/src/game_object.py b/src/game_object.py index 2d5c3c9..9eafbfb 100644 --- a/src/game_object.py +++ b/src/game_object.py @@ -2,11 +2,20 @@ import random import pygame.sprite +from mlgame.view.view_model import create_rect_view_data + +BALL_VEL = 10.5 + +BALL_H = 50 + +BALL_W = 50 + class Ball(pygame.sprite.Sprite): def __init__(self, color="#FFEB3B"): pygame.sprite.Sprite.__init__(self) - self.image = pygame.Surface([50, 50]) + self.origin_image = pygame.Surface([BALL_W, BALL_H]) + self.image = self.origin_image self.color = color self.rect = self.image.get_rect() self.rect.center = (400, 300) @@ -14,25 +23,31 @@ class Ball(pygame.sprite.Sprite): def update(self, motion): # for motion in motions: if motion == "UP": - self.rect.centery -= 10.5 + self.rect.centery -= BALL_VEL elif motion == "DOWN": - self.rect.centery += 10.5 + self.rect.centery += BALL_VEL elif motion == "LEFT": - self.rect.centerx -= 10.5 + self.rect.centerx -= BALL_VEL + # self.angle += 5 elif motion == "RIGHT": - self.rect.centerx += 10.5 + self.rect.centerx += BALL_VEL + # self.angle -= 5 + # self.image = pygame.transform.rotate(self.origin_image, self.angle) + # print(self.angle) + # center = self.rect.center + # self.rect = self.image.get_rect() + # self.rect.center = center @property def game_object_data(self): - return {"type": "rect", - "name": "ball", - "x": self.rect.x, - "y": self.rect.y, - "angle": 0, - "width": self.rect.width, - "height": self.rect.height, - "color": self.color - } + return create_rect_view_data( + "ball", + self.rect.x, + self.rect.y, + self.rect.width, + self.rect.height, + self.color + ) class Food(pygame.sprite.Sprite):