Merge branch 'release/2.3.1-alpha'

This commit is contained in:
Kylin_on_Mac 2023-10-10 23:40:20 +08:00
commit ae5e82a17a
18 changed files with 246 additions and 230 deletions

View File

@ -2,7 +2,7 @@
![easy_game](https://img.shields.io/github/v/tag/PAIA-Playful-AI-Arena/easy_game) ![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/) [![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.5.3-<COLOR>.svg)](https://github.com/PAIA-Playful-AI-Arena/MLGame) [![MLGame](https://img.shields.io/badge/MLGame->10.3.2-<COLOR>.svg)](https://github.com/PAIA-Playful-AI-Arena/MLGame)
[![pygame](https://img.shields.io/badge/pygame-2.0.1-<COLOR>.svg)](https://github.com/pygame/pygame/releases/tag/2.0.1) [![pygame](https://img.shields.io/badge/pygame-2.0.1-<COLOR>.svg)](https://github.com/pygame/pygame/releases/tag/2.0.1)
@ -22,20 +22,11 @@
```python ```python
# main.py # main.py
game = EasyGame( game = EasyGame(
time_to_play, score_to_pass, level: int = 1,
green_food_count, red_food_count,
playground_size: list,
level: int = -1,
level_file: str = None, level_file: str = None,
sound: str = "off") sound: str = "off")
``` ```
- `level`: 選定內建關卡,預設為 1 選擇第一關。
- `time_to_play`:遊戲執行的終止時間,單位是 frame也就是遊戲內部更新畫面的次數每更新一次 frame +1
- `green_food_count`:遊戲中綠色食物的數量。
- `red_food_count`:遊戲中紅色食物的數量。
- `score_to_pass`:遊戲通關的點數,要超過這個分數才算過關。
- `playground_size`:可移動區域的大小。 使用逗號將數字隔開 `width,height` `100,200`
- `level`: 選定內建關卡,請注意,使用此設定將會覆蓋掉上述其他關卡參數設定,預設為 -1 不選擇任何關卡。
- `level_file`: 使用外部檔案作為關卡,請注意,使用此設定將會覆蓋掉關卡編號,並且不會自動進入下一關。 - `level_file`: 使用外部檔案作為關卡,請注意,使用此設定將會覆蓋掉關卡編號,並且不會自動進入下一關。
- `sound`: 音效。 - `sound`: 音效。
@ -83,10 +74,10 @@ python -m mlgame -i ./ml/ml_play_template.py ./ --time_to_play 1200 --green_food
import random import random
class MLPlay: class MLPlay:
def __init__(self): def __init__(self,ai_name,*args, **kwargs):
print("Initial ml script") print("Initial ml script")
def update(self, scene_info: dict): def update(self, scene_info: dict,,*args, **kwargs):
# print("AI received data from game :", scene_info) # print("AI received data from game :", scene_info)
@ -114,12 +105,16 @@ class MLPlay:
"foods": [ "foods": [
{ {
"x": 656, "x": 656,
"y": 210 "y": 210,
"type": "GOOD_1",
"score": 1
}, },
..., ...,
{ {
"x": 371, "x": 371,
"y": 217 "y": 217,
"type": "BAD_1",
"score": -1
} }
], ],
@ -131,8 +126,10 @@ class MLPlay:
- `frame`:遊戲畫面更新的編號 - `frame`:遊戲畫面更新的編號
- `ball_x`:主角方塊的X座標,表示方塊的左邊座標值。 - `ball_x`:主角方塊的X座標,表示方塊的左邊座標值。
- `ball_y`:主角方塊的Y座標,表示方塊的上方座標值。 - `ball_y`:主角方塊的Y座標,表示方塊的上方座標值。
- `foods`:食物的清單,清單內每一個物件都是一個食物的左上方座標值 - `foods`:食物的清單,清單內每一個物件都是一個食物的左上方座標值,也會提供此食物是什麼類型和分數多少。
- `type` 食物類型: `GOOD_1`, `GOOD_2`, `GOOD_3`, `BAD_1`, `BAD_2`, `BAD_3`
- `score`:目前得到的分數 - `score`:目前得到的分數
- `score_to_pass`:通關分數
- `status` 目前遊戲的狀態 - `status` 目前遊戲的狀態
- `GAME_ALIVE`:遊戲進行中 - `GAME_ALIVE`:遊戲進行中
- `GAME_PASS`:遊戲通關 - `GAME_PASS`:遊戲通關

View File

@ -11,8 +11,9 @@
["scene_info['status']", "game status", "遊戲狀態"], ["scene_info['status']", "game status", "遊戲狀態"],
["scene_info['ball_x']", "x coordinate of ball", "球的 x 座標"], ["scene_info['ball_x']", "x coordinate of ball", "球的 x 座標"],
["scene_info['ball_y']", "y coordinate of ball", "球的 y 座標"], ["scene_info['ball_y']", "y coordinate of ball", "球的 y 座標"],
["scene_info['score']", "x coordinate of platform", "平台的 x 座標"], ["scene_info['score']", "score", "目前的分數"],
["scene_info['foods']", "list of foods positions", "點點的位置清單"], ["scene_info['foods']", "list of foods positions", "點點的位置清單"],
["scene_info['score_to_pass']", "the score for next level", "通關分數"],
["scene_info", "dictionary of all information", "包含所有資訊的字典"] ["scene_info", "dictionary of all information", "包含所有資訊的字典"]
], ],
"CONSTANT": [ "CONSTANT": [
@ -22,8 +23,9 @@
[600, "bottom boundary", "下邊界"], [600, "bottom boundary", "下邊界"],
[30, "ball width", "球身的寬度"], [30, "ball width", "球身的寬度"],
[30, "ball height", "球身的高度"], [30, "ball height", "球身的高度"],
[8, "food width", "食物的寬度"], [8, "food lv1 size", "等級一食物的寬高度"],
[8, "food height", "食物的高度"] [12, "food lv2 size", "等級二食物的高度"],
[16, "food lv3 size", "等級三食物的高度"]
], ],
"ACTION": [ "ACTION": [
["['UP']", "moving up", "向上移動"], ["['UP']", "moving up", "向上移動"],

View File

@ -1,6 +1,6 @@
{ {
"game_name": "easy_game", "game_name": "easy_game",
"version": "2.2.1-beta", "version": "2.3.1-alpha",
"url": "https://github.com/PAIA-Playful-AI-Arena/easy_game", "url": "https://github.com/PAIA-Playful-AI-Arena/easy_game",
"description": "這是一個吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例", "description": "這是一個吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例",
"logo": [ "logo": [
@ -12,77 +12,14 @@
"max": 1 "max": 1
}, },
"game_params": [ "game_params": [
{
"name": "time_to_play",
"verbose": "遊戲總幀數",
"type": "int",
"max": 2000,
"min": 600,
"default": 600,
"help": "set the limit of frame count , actually time will be revised according to your FPS ."
},
{
"name": "green_food_count",
"verbose": "綠色食物數量",
"type": "int",
"choices": [
5,
10,
15,
20,
25,
30,
35,
40,
45,
50
],
"help": "set the total number of points",
"default": 10
},
{
"name": "red_food_count",
"verbose": "紅色食物數量",
"type": "int",
"choices": [
5,
10,
15,
20,
25,
30,
35,
40,
45,
50
],
"help": "set the total number of points",
"default": 10
},
{
"name": "score_to_pass",
"verbose": "通關分數",
"type": "int",
"min": 1,
"max": 30,
"default": 10,
"help": "set the score to win this game "
},
{
"name": "playground_size",
"verbose": "場地尺寸",
"type": "list",
"default": "400,400",
"help": "set the size of playground "
},
{ {
"name": "level", "name": "level",
"verbose": "內建關卡編號", "verbose": "內建關卡編號",
"type": "int", "type": "int",
"min": -1, "min": -1,
"max": 5, "max": 100,
"default": "-1", "default": 1,
"help": "選定內建關卡,請注意,使用此設定將會覆蓋掉其他關卡設定,預設為 -1 不選擇任何關卡。" "help": "選定內建關卡,預設為 1 選擇第一關。"
}, { }, {
"name": "level_file", "name": "level_file",
"verbose": "匯入關卡檔案", "verbose": "匯入關卡檔案",

View File

@ -5,6 +5,6 @@
200 200
], ],
"score_to_pass": 10, "score_to_pass": 10,
"green_food_count": 3, "green_food_count": [3,0,0],
"black_food_count": 0 "black_food_count": [0,0,0]
} }

View File

@ -5,6 +5,6 @@
200 200
], ],
"score_to_pass": 15, "score_to_pass": 15,
"green_food_count": 5, "green_food_count": [5,0,0],
"black_food_count": 0 "black_food_count": [0,0,0]
} }

View File

@ -5,6 +5,6 @@
300 300
], ],
"score_to_pass": 15, "score_to_pass": 15,
"green_food_count": 10, "green_food_count": [6,0,0],
"black_food_count": 0 "black_food_count": [2,0,0]
} }

View File

@ -5,6 +5,6 @@
300 300
], ],
"score_to_pass": 15, "score_to_pass": 15,
"green_food_count": 7, "green_food_count": [8,0,0],
"black_food_count": 3 "black_food_count": [4,0,0]
} }

View File

@ -5,6 +5,6 @@
300 300
], ],
"score_to_pass": 15, "score_to_pass": 15,
"green_food_count": 7, "green_food_count": [8,3,0],
"black_food_count": 7 "black_food_count": [4,0,0]
} }

View File

@ -5,6 +5,6 @@
400 400
], ],
"score_to_pass": 15, "score_to_pass": 15,
"green_food_count": 7, "green_food_count": [8,4,0],
"black_food_count": 10 "black_food_count": [5,2,0]
} }

View File

@ -5,6 +5,6 @@
400 400
], ],
"score_to_pass": 20, "score_to_pass": 20,
"green_food_count": 7, "green_food_count": [8,4,2],
"black_food_count": 13 "black_food_count": [4,4,0]
} }

View File

@ -5,6 +5,6 @@
500 500
], ],
"score_to_pass": 20, "score_to_pass": 20,
"green_food_count": 10, "green_food_count": [6,4,2],
"black_food_count": 15 "black_food_count": [6,4,2]
} }

View File

@ -5,6 +5,6 @@
500 500
], ],
"score_to_pass": 25, "score_to_pass": 25,
"green_food_count": 15, "green_food_count": [10,5,3],
"black_food_count": 30 "black_food_count": [12,7,4]
} }

View File

@ -5,6 +5,6 @@
600 600
], ],
"score_to_pass": 25, "score_to_pass": 25,
"green_food_count": 20, "green_food_count": [12,8,4],
"black_food_count": 40 "black_food_count": [25,10,5]
} }

View File

@ -1,7 +1,11 @@
{ {
"time_to_play": 1200, "time_to_play": 300,
"playground_size": [ "playground_size": [
500, 100,
200 200
] ],
"score_to_pass": 10,
"green_food_count": [3,0,0],
"black_food_count": [0,0,0]
} }

View File

@ -17,10 +17,24 @@ BALL_W = 30
# food # food
class FoodTypeEnum(StringEnum): class FoodTypeEnum(StringEnum):
GREEN = auto() GOOD_1 = auto()
RED = auto() GOOD_2 = auto()
FOOD_COLOR_MAP = {FoodTypeEnum.GREEN: "#009688", GOOD_3 = auto()
FoodTypeEnum.RED: "#FF1744"} BAD_1 = auto()
BAD_2 = auto()
BAD_3 = auto()
FOOD_COLOR_MAP = {
FoodTypeEnum.GOOD_1: "#009688",
FoodTypeEnum.GOOD_2: "#009688",
FoodTypeEnum.GOOD_3: "#009688",
FoodTypeEnum.BAD_1: "#FF1744",
FoodTypeEnum.BAD_2: "#FF1744",
FoodTypeEnum.BAD_3: "#FF1744"
}
FOOD_LV1_SIZE = 8
FOOD_LV2_SIZE = 12
FOOD_LV3_SIZE = 16
# path of assets # path of assets
ASSET_PATH = path.join(path.dirname(__file__), "..", "asset") ASSET_PATH = path.join(path.dirname(__file__), "..", "asset")

92
src/foods.py Normal file
View File

@ -0,0 +1,92 @@
import pygame.sprite
from games.easy_game.src.env import FoodTypeEnum, FOOD_COLOR_MAP, FOOD_LV1_SIZE, FOOD_LV2_SIZE, FOOD_LV3_SIZE
from mlgame.view.view_model import create_rect_view_data
class Food(pygame.sprite.Sprite):
def __init__(self, group):
pygame.sprite.Sprite.__init__(self, group)
self.image = pygame.Surface([8, 8])
self.type = None
self.score = 0
self.color = None
self.rect = self.image.get_rect()
self.angle = 0
def update(self) -> None:
pass
@property
def game_object_data(self):
return create_rect_view_data(
"food",
self.rect.x,
self.rect.y,
self.rect.width,
self.rect.height,
self.color
)
class GoodFoodLv1(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV1_SIZE, FOOD_LV1_SIZE])
self.type = FoodTypeEnum.GOOD_1
self.color = FOOD_COLOR_MAP[self.type]
self.score = 1
self.rect = self.image.get_rect()
class GoodFoodLv2(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV2_SIZE, FOOD_LV2_SIZE])
self.type = FoodTypeEnum.GOOD_2
self.color = FOOD_COLOR_MAP[self.type]
self.score = 2
self.rect = self.image.get_rect()
class GoodFoodLv3(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV3_SIZE, FOOD_LV3_SIZE])
self.type = FoodTypeEnum.GOOD_3
self.color = FOOD_COLOR_MAP[self.type]
self.score = 4
self.rect = self.image.get_rect()
class BadFoodLv1(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV1_SIZE, FOOD_LV1_SIZE])
self.type = FoodTypeEnum.BAD_1
self.color = FOOD_COLOR_MAP[self.type]
self.score = -1
self.rect = self.image.get_rect()
self.angle = 0
class BadFoodLv2(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV2_SIZE, FOOD_LV2_SIZE])
self.type = FoodTypeEnum.BAD_2
self.color = FOOD_COLOR_MAP[self.type]
self.score = -2
self.rect = self.image.get_rect()
class BadFoodLv3(Food):
def __init__(self, group):
super().__init__(group)
self.image = pygame.Surface([FOOD_LV3_SIZE, FOOD_LV3_SIZE])
self.type = FoodTypeEnum.BAD_3
self.color = FOOD_COLOR_MAP[self.type]
self.score = -4
self.rect = self.image.get_rect()

View File

@ -9,65 +9,62 @@ from mlgame.utils.enum import get_ai_name
from mlgame.view.decorator import check_game_progress, check_game_result from mlgame.view.decorator import check_game_progress, check_game_result
from mlgame.view.view_model import * from mlgame.view.view_model import *
from .env import * from .env import *
from .env import FoodTypeEnum from .foods import *
from .game_object import Ball, Food from .game_object import Ball
from .sound_controller import SoundController from .sound_controller import SoundController
def revise_ball(ball: Ball, playground: pygame.Rect):
ball_rect = copy.deepcopy(ball.rect)
if ball_rect.left < playground.left:
ball_rect.left = playground.left
elif ball_rect.right > playground.right:
ball_rect.right = playground.right
if ball_rect.top < playground.top:
ball_rect.top = playground.top
elif ball_rect.bottom > playground.bottom:
ball_rect.bottom = playground.bottom
ball.rect = ball_rect
pass
class EasyGame(PaiaGame): class EasyGame(PaiaGame):
""" """
This is a Interface of a game This is a Interface of a game
""" """
def __init__( def __init__(
self, time_to_play, score_to_pass, green_food_count, red_food_count, self,
playground_size: list, level: int = 1,
level: int = -1,
level_file: str = None, level_file: str = None,
sound: str = "off", sound: str = "off",
*args, **kwargs): *args, **kwargs):
super().__init__(user_num=1) super().__init__(user_num=1)
# TODO reduce game config and use level file
self.game_result_state = GameResultState.FAIL self.game_result_state = GameResultState.FAIL
self.scene = Scene(width=WIDTH, height=HEIGHT, color=BG_COLOR, bias_x=0, bias_y=0) self.scene = Scene(width=WIDTH, height=HEIGHT, color=BG_COLOR, bias_x=0, bias_y=0)
self._level = level self._level = level
self._level_file = level_file self._level_file = level_file
if self._level_file is not None or level == "":
# set by injected file
self.set_game_params_by_file(self._level_file)
pass
elif self._level != -1:
# set by level number
self.set_game_params_by_level(self._level)
pass
else:
# set by game params
self._playground_w = int(playground_size[0])
self._playground_h = int(playground_size[1])
self.playground = pygame.Rect(
0, 0,
self._playground_w,
self._playground_h
)
self._green_food_count = green_food_count
self._red_food_count = red_food_count
self._score_to_pass = score_to_pass
self._frame_limit = time_to_play
self.playground.center = (WIDTH / 2, HEIGHT / 2)
self.foods = pygame.sprite.Group() self.foods = pygame.sprite.Group()
self.sound_controller = SoundController(sound) self.sound_controller = SoundController(sound)
self.init_game()
def set_game_params_by_level(self, level): if path.isfile(self._level_file) or self._level_file == "":
# set by injected file
self._init_game_by_file(self._level_file)
pass
else:
self._init_game_by_level(self._level)
def _init_game_by_level(self, level: int):
level_file_path = os.path.join(LEVEL_PATH, f"{level:03d}.json") level_file_path = os.path.join(LEVEL_PATH, f"{level:03d}.json")
self.set_game_params_by_file(level_file_path) self._init_game_by_file(level_file_path)
def set_game_params_by_file(self, level_file_path: str): def _init_game_by_file(self, level_file_path: str):
try: try:
with open(level_file_path) as f: with open(level_file_path) as f:
game_params = json.load(f) game_params = json.load(f)
self._set_game_params(game_params)
except: except:
# If the file doesn't exist, use default parameters # If the file doesn't exist, use default parameters
print("此關卡檔案不存在,遊戲將會會自動使用第一關檔案 001.json。") print("此關卡檔案不存在,遊戲將會會自動使用第一關檔案 001.json。")
@ -76,9 +73,8 @@ class EasyGame(PaiaGame):
game_params = json.load(f) game_params = json.load(f)
self._level = 1 self._level = 1
self._level_file = None self._level_file = None
self._set_game_params(game_params) finally:
# set game params
def _set_game_params(self, game_params):
self._playground_w = int(game_params["playground_size"][0]) self._playground_w = int(game_params["playground_size"][0])
self._playground_h = int(game_params["playground_size"][1]) self._playground_h = int(game_params["playground_size"][1])
self.playground = pygame.Rect( self.playground = pygame.Rect(
@ -86,22 +82,31 @@ class EasyGame(PaiaGame):
self._playground_w, self._playground_w,
self._playground_h self._playground_h
) )
self._green_food_count = int(game_params["green_food_count"]) self._green_food_count = game_params["green_food_count"]
self._red_food_count = int(game_params["black_food_count"]) self._red_food_count = game_params["black_food_count"]
self._score_to_pass = int(game_params["score_to_pass"]) self._score_to_pass = int(game_params["score_to_pass"])
self._frame_limit = int(game_params["time_to_play"]) self._frame_limit = int(game_params["time_to_play"])
self.playground.center = (WIDTH / 2, HEIGHT / 2) self.playground.center = (WIDTH / 2, HEIGHT / 2)
def init_game(self): # init game
self.ball = Ball() self.ball = Ball()
self.foods.empty() self.foods.empty()
self.score = 0 self.score = 0
self._create_foods(self._green_food_count, FoodTypeEnum.GREEN)
self._create_foods(self._red_food_count, FoodTypeEnum.RED) # todo validate food count
self._create_foods(GoodFoodLv1, self._green_food_count[0])
self._create_foods(GoodFoodLv2, self._green_food_count[1])
self._create_foods(GoodFoodLv3, self._green_food_count[2])
self._create_foods(BadFoodLv1, self._red_food_count[0])
self._create_foods(BadFoodLv2, self._red_food_count[1])
self._create_foods(BadFoodLv3, self._red_food_count[2])
self.frame_count = 0 self.frame_count = 0
self._frame_count_down = self._frame_limit self._frame_count_down = self._frame_limit
self.sound_controller.play_music() self.sound_controller.play_music()
def update(self, commands): def update(self, commands):
# handle command # handle command
ai_1p_cmd = commands[get_ai_name(0)] ai_1p_cmd = commands[get_ai_name(0)]
@ -111,24 +116,13 @@ class EasyGame(PaiaGame):
action = "NONE" action = "NONE"
self.ball.update(action) self.ball.update(action)
self.revise_ball(self.ball, self.playground) revise_ball(self.ball, self.playground)
# update sprite # update sprite
self.foods.update() self.foods.update()
# handle collision # handle collision
hits = pygame.sprite.spritecollide(self.ball, self.foods, True)
if hits:
for food in hits: self._check_foods_collision()
if food.type == FoodTypeEnum.GREEN:
self.sound_controller.play_eating_good()
self.score += 1
self._create_foods(1, FoodTypeEnum.GREEN)
elif food.type == FoodTypeEnum.RED:
self.sound_controller.play_eating_bad()
self._create_foods(1, FoodTypeEnum.RED)
self.score -= 1
# self._timer = round(time.time() - self._begin_time, 3) # self._timer = round(time.time() - self._begin_time, 3)
self.frame_count += 1 self.frame_count += 1
@ -138,6 +132,17 @@ class EasyGame(PaiaGame):
if not self.is_running: if not self.is_running:
return "RESET" return "RESET"
def _check_foods_collision(self):
hits = pygame.sprite.spritecollide(self.ball, self.foods, True)
if hits:
for food in hits:
self.score += food.score
self._create_foods(food.__class__, 1)
if isinstance(food, (GoodFoodLv1,GoodFoodLv2,GoodFoodLv3,)):
self.sound_controller.play_eating_good()
elif isinstance(food, (BadFoodLv1,BadFoodLv2,BadFoodLv3,)):
self.sound_controller.play_eating_bad()
def get_data_from_game_to_player(self): def get_data_from_game_to_player(self):
""" """
send something to game AI send something to game AI
@ -146,13 +151,16 @@ class EasyGame(PaiaGame):
to_players_data = {} to_players_data = {}
foods_data = [] foods_data = []
for food in self.foods: for food in self.foods:
foods_data.append({"x": food.rect.x, "y": food.rect.y}) # TODO add good food and bad food
foods_data.append({"x": food.rect.x, "y": food.rect.y, "type": food.type, "score": food.score})
data_to_1p = { data_to_1p = {
"frame": self.frame_count, "frame": self.frame_count,
"ball_x": self.ball.rect.centerx, "ball_x": self.ball.rect.centerx,
"ball_y": self.ball.rect.centery, "ball_y": self.ball.rect.centery,
"foods": foods_data, "foods": foods_data,
"score": self.score, "score": self.score,
"score_to_pass":self._score_to_pass,
"status": self.get_game_status() "status": self.get_game_status()
} }
@ -181,9 +189,9 @@ class EasyGame(PaiaGame):
elif self.is_passed and self._level != -1: elif self.is_passed and self._level != -1:
# win and use level will enter next level # win and use level will enter next level
self._level += 1 self._level += 1
self.set_game_params_by_level(self._level) self._init_game_by_level(self._level)
self.init_game() self._init_game()
pass pass
@ -199,7 +207,6 @@ class EasyGame(PaiaGame):
""" """
Get the initial scene and object information for drawing on the web Get the initial scene and object information for drawing on the web
""" """
# TODO add music or sound
# bg_path = path.join(ASSET_PATH, "img/background.jpg") # bg_path = path.join(ASSET_PATH, "img/background.jpg")
# background = create_asset_init_data( # background = create_asset_init_data(
# "background", WIDTH, HEIGHT, bg_path, # "background", WIDTH, HEIGHT, bg_path,
@ -280,25 +287,10 @@ class EasyGame(PaiaGame):
cmd_1p.append("NONE") cmd_1p.append("NONE")
return {get_ai_name(0): cmd_1p} return {get_ai_name(0): cmd_1p}
def _create_foods(self, count: int = 5, type: FoodTypeEnum = FoodTypeEnum.GREEN): def _create_foods(self, FOOD_TYPE, count: int = 5):
for i in range(count): for i in range(count):
# add food to group # add food to group
food = Food(self.foods, type) food = FOOD_TYPE(self.foods)
food.rect.centerx = random.randint(self.playground.left, self.playground.right) food.rect.centerx = random.randint(self.playground.left, self.playground.right)
food.rect.centery = random.randint(self.playground.top, self.playground.bottom) food.rect.centery = random.randint(self.playground.top, self.playground.bottom)
pass pass
def revise_ball(self, ball: Ball, playground: pygame.Rect):
ball_rect = copy.deepcopy(ball.rect)
if ball_rect.left < playground.left:
ball_rect.left = playground.left
elif ball_rect.right > playground.right:
ball_rect.right = playground.right
if ball_rect.top < playground.top:
ball_rect.top = playground.top
elif ball_rect.bottom > playground.bottom:
ball_rect.bottom = playground.bottom
ball.rect = ball_rect
pass

View File

@ -1,6 +1,7 @@
import pygame.sprite import pygame.sprite
from games.easy_game.src.env import FoodTypeEnum, FOOD_COLOR_MAP, BALL_COLOR, BALL_VEL, BALL_H, BALL_W from games.easy_game.src.env import BALL_COLOR, BALL_VEL, BALL_H, BALL_W
from games.easy_game.src.foods import Food
from mlgame.view.view_model import create_rect_view_data from mlgame.view.view_model import create_rect_view_data
@ -44,26 +45,3 @@ class Ball(pygame.sprite.Sprite):
) )
class Food(pygame.sprite.Sprite):
def __init__(self, group, type: FoodTypeEnum):
pygame.sprite.Sprite.__init__(self, group)
self.image = pygame.Surface([8, 8])
self.type = type
self.color = FOOD_COLOR_MAP[type]
self.rect = self.image.get_rect()
self.angle = 0
def update(self) -> None:
pass
@property
def game_object_data(self):
return create_rect_view_data(
"food",
self.rect.x,
self.rect.y,
self.rect.width,
self.rect.height,
self.color
)