diff --git a/src/env.py b/src/env.py index e84a53e..462a6da 100644 --- a/src/env.py +++ b/src/env.py @@ -10,31 +10,31 @@ PG_COLOR = "#B3E5FC" # ball -> squid # BALL_COLOR = "#FFEB3B" -BALL_VEL = 10 -BALL_W = 50 -BALL_H = 70 -BALL_GROWTH_SCORE_STEP = 15 -BALL_GROWTH_SIZE_STEP=10 -BALL_GROWTH_VEL_STEP=3 -BALL_SIZE_MAX = 125 -BALL_SIZE_MIN = 20 -BALL_VEL_MAX = 25 -BALL_VEL_MIN = 10 +SQUID_VEL = 10 +SQUID_W = 50 +SQUID_H = 70 +SQUID_GROWTH_SCORE_STEP = 15 +SQUID_GROWTH_SIZE_STEP=10 +SQUID_GROWTH_VEL_STEP=3 +SQUID_SIZE_MAX = 125 +SQUID_SIZE_MIN = 20 +SQUID_VEL_MAX = 25 +SQUID_VEL_MIN = 10 ASSET_IMAGE_DIR = path.join(path.dirname(__file__), "../asset/img") # food class FoodTypeEnum(StringEnum): - GOOD_1 = auto() - GOOD_2 = auto() - GOOD_3 = auto() + FOOD_1 = auto() + FOOD_2 = auto() + FOOD_3 = auto() 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.FOOD_1: "#009688", + FoodTypeEnum.FOOD_2: "#009688", + FoodTypeEnum.FOOD_3: "#009688", FoodTypeEnum.BAD_1: "#FF1744", FoodTypeEnum.BAD_2: "#FF1744", FoodTypeEnum.BAD_3: "#FF1744" @@ -49,4 +49,22 @@ LEVEL_PATH = path.join(path.dirname(__file__), "..", "levels") SOUND_PATH = path.join(path.dirname(__file__), "..", "asset", "sounds") MUSIC_PATH = path.join(path.dirname(__file__), "..", "asset", "music") +BG_PATH = path.join(ASSET_IMAGE_DIR, "background.png") +SQUID_PATH = path.join(ASSET_IMAGE_DIR, "squid.png") +FOOD01_PATH = path.join(ASSET_IMAGE_DIR, "food_01.png") +FOOD02_PATH = path.join(ASSET_IMAGE_DIR, "food_02.png") +FOOD03_PATH = path.join(ASSET_IMAGE_DIR, "food_03.png") +GARBAGE01_PATH = path.join(ASSET_IMAGE_DIR, "garbage_01.png") +GARBAGE02_PATH = path.join(ASSET_IMAGE_DIR, "garbage_02.png") +GARBAGE03_PATH = path.join(ASSET_IMAGE_DIR, "garbage_03.png") + +BG_URL = BG_PATH +SQUID_URL = SQUID_PATH +FOOD01_URL = FOOD01_PATH +FOOD02_URL = FOOD02_PATH +FOOD03_URL = FOOD03_PATH +GARBAGE01_URL = GARBAGE01_PATH +GARBAGE02_URL = GARBAGE02_PATH +GARBAGE03_URL = GARBAGE03_PATH +# BAR_URL = "https://raw.githubusercontent.com/PAIA/dont_touch/master/asset/image/bar.png" diff --git a/src/foods.py b/src/foods.py index bba39bd..e656fca 100644 --- a/src/foods.py +++ b/src/foods.py @@ -7,6 +7,8 @@ from .env import FoodTypeEnum, FOOD_COLOR_MAP, FOOD_LV1_SIZE, FOOD_LV2_SIZE, FOO from mlgame.view.view_model import create_rect_view_data, create_image_view_data FOOD1_VEL = 1 +FOOD2_VEL = 2 +FOOD3_VEL = 4 class Food(pygame.sprite.Sprite): @@ -15,103 +17,109 @@ class Food(pygame.sprite.Sprite): 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 set_center_x_and_y(self, x: int, y: int): - self.rect.centerx = x - self.rect.centery = y + self.rect_float_x = 0 + self.rect_float_y = 0 + self.image_id = "" def update(self, *args, **kwargs) -> None: pass @property def game_object_data(self): - return create_rect_view_data( - "food", + return create_image_view_data( + self.image_id, 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 Food1(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() - self.rect_float_x = 0 - self.rect_float_y = 0 - self._vel = FOOD1_VEL def set_center_x_and_y(self, x: int, y: int): self.rect.centerx = x self.rect.centery = y self.rect_float_x = self.rect.centerx self.rect_float_y = self.rect.centery + +class Food1(Food): + def __init__(self, group): + super().__init__(group) + self.image = pygame.Surface([FOOD_LV1_SIZE, FOOD_LV1_SIZE]) + self.type = FoodTypeEnum.FOOD_1 + self.color = FOOD_COLOR_MAP[self.type] + self.score = 1 + self.rect = self.image.get_rect() + self.image_id="food01" + self._vel = FOOD1_VEL + def update(self, playground: Rect, squid: pygame.sprite.Sprite): self.rect_float_x += self._vel - self.rect_float_y += random.choice([-0.3,-0.5,-0.7,0,0.3,0.5,0.7]) + self.rect_float_y += random.choice([-0.3, -0.5, -0.7, 0, 0.3, 0.5, 0.7]) self.rect.centerx = self.rect_float_x self.rect.centery = self.rect_float_y if self.rect.left < playground.left and self._vel < 0.0: self._vel = FOOD1_VEL - elif self.rect.right > playground.right and self._vel>0.0: + elif self.rect.right > playground.right and self._vel > 0.0: self._vel = - FOOD1_VEL - @property - def game_object_data(self): - return create_image_view_data( - "food01", - self.rect.x, - self.rect.y, - self.rect.width, - self.rect.height - ) + +class Food2(Food): + def __init__(self, group): + super().__init__(group) + + self.image = pygame.Surface([FOOD_LV2_SIZE, FOOD_LV2_SIZE]) + self.type = FoodTypeEnum.FOOD_1 + self.score = 2 + self.rect = self.image.get_rect() + self.image_id="food02" + self._vel = FOOD2_VEL + + def update(self, playground: Rect, squid: pygame.sprite.Sprite): + + self.rect_float_x += self._vel + self.rect_float_y += random.choice([-0.5, -0.7, -1, -1.3, 0, 1, 1.3, 0.3, 0.5, 0.7]) + self.rect.centerx = self.rect_float_x + self.rect.centery = self.rect_float_y + + if self.rect.left < playground.left and self._vel < 0.0: + self._vel = FOOD2_VEL + elif self.rect.right > playground.right and self._vel > 0.0: + self._vel = - FOOD2_VEL + + + + +class Food3(Food): + def __init__(self, group): + super().__init__(group) + + self.image = pygame.Surface([FOOD_LV3_SIZE, FOOD_LV3_SIZE]) + self.type = FoodTypeEnum.FOOD_3 + self.score = 4 + self.rect = self.image.get_rect() + self.image_id="food03" + self._vel = FOOD3_VEL + + + def update(self, playground: Rect, squid: pygame.sprite.Sprite): + + self.rect_float_x += self._vel + self.rect_float_y += random.choice([-0.7, -1, -1.3, -1.7, 0, 1.7, 1, 1.3, 0.3, 0.7]) + self.rect.centerx = self.rect_float_x + self.rect.centery = self.rect_float_y + + if self.rect.left < playground.left and self._vel < 0.0: + self._vel = FOOD3_VEL + elif self.rect.right > playground.right and self._vel > 0.0: + self._vel = - FOOD3_VEL + + class BadFoodLv1(Food): def __init__(self, group): super().__init__(group) diff --git a/src/game.py b/src/game.py index d610690..053d301 100644 --- a/src/game.py +++ b/src/game.py @@ -72,8 +72,7 @@ class EasyGame(PaiaGame): game_params.playground_size_h, game_params.playground_size_w ) - self._good_food_count = game_params.good_food_count - self._bad_food_count = game_params.bad_food_count + self._score_to_pass = game_params.score_to_pass self._frame_limit = game_params.time_to_play self.playground.center = (WIDTH / 2, HEIGHT / 2) @@ -81,21 +80,9 @@ class EasyGame(PaiaGame): # init game self.ball = Squid() self.foods.empty() - - if not isinstance(self._good_food_count, list) or len(self._good_food_count) < 3: - raise Exception( - "你的關卡檔案格式有誤,請在'good_food_count' 欄位後面填入一個長度為3的陣列,舉例: [1,2,3]") - elif not isinstance(self._bad_food_count, list) or len(self._bad_food_count) < 3: - raise Exception("你的關卡檔案格式有誤,請在'bad_food_count' 欄位後面填入一個長度為3的陣列,舉例: [1,2,3]") - - else: - self._create_foods(GoodFoodLv1, self._good_food_count[0]) - self._create_foods(GoodFoodLv2, self._good_food_count[1]) - self._create_foods(GoodFoodLv3, self._good_food_count[2]) - self._create_foods(BadFoodLv1, self._bad_food_count[0]) - self._create_foods(BadFoodLv2, self._bad_food_count[1]) - self._create_foods(BadFoodLv3, self._bad_food_count[2]) - self._create_foods(Food1, game_params.food_1) + self._create_foods(Food1, game_params.food_1) + self._create_foods(Food2, game_params.food_2) + self._create_foods(Food3, game_params.food_3) self.frame_count = 0 self._frame_count_down = self._frame_limit @@ -134,7 +121,7 @@ class EasyGame(PaiaGame): # growth play special sound self.ball.eat_food_and_change_level_and_play_sound(food, self.sound_controller) self._create_foods(food.__class__, 1) - if isinstance(food, (GoodFoodLv1, GoodFoodLv2, GoodFoodLv3,)): + if isinstance(food, (Food1, Food2, Food3,)): self.sound_controller.play_eating_good() elif isinstance(food, (BadFoodLv1, BadFoodLv2, BadFoodLv3,)): self.sound_controller.play_eating_bad() @@ -216,20 +203,15 @@ class EasyGame(PaiaGame): # background = create_asset_init_data( # "background", WIDTH, HEIGHT, bg_path, # github_raw_url="https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/easy_game/main/asset/img/background.jpg") - bg_path = path.join(ASSET_IMAGE_DIR, "background.png") - squid_path = path.join(ASSET_IMAGE_DIR, "squid.png") - food01_path = path.join(ASSET_IMAGE_DIR, "food_01.png") - # TODO - food01_url = food01_path - bg_url = bg_path - squid_url = squid_path scene_init_data = { "scene": self.scene.__dict__, "assets": [ - create_asset_init_data("bg", 1000, 1000, bg_path, bg_url), - create_asset_init_data("squid", BALL_W, BALL_H, squid_path, squid_url), - create_asset_init_data("food01", 20, 20, food01_path, food01_url) + create_asset_init_data("bg", 1000, 1000, BG_PATH, BG_URL), + create_asset_init_data("squid", SQUID_W, SQUID_H, SQUID_PATH, SQUID_URL), + create_asset_init_data("food01", FOOD_LV1_SIZE, FOOD_LV1_SIZE, FOOD01_PATH, FOOD01_URL), + create_asset_init_data("food02", FOOD_LV2_SIZE,FOOD_LV2_SIZE, FOOD02_PATH, FOOD02_URL), + create_asset_init_data("food03", FOOD_LV3_SIZE,FOOD_LV3_SIZE, FOOD03_PATH, FOOD03_URL), ], "background": [ create_image_view_data( diff --git a/src/game_object.py b/src/game_object.py index 93cda81..5c7707c 100644 --- a/src/game_object.py +++ b/src/game_object.py @@ -6,8 +6,8 @@ from typing import List import pydantic import pygame.sprite -from .env import BALL_VEL, BALL_H, BALL_W, BALL_GROWTH_SCORE_STEP, BALL_GROWTH_SIZE_STEP, \ - BALL_SIZE_MAX, BALL_GROWTH_VEL_STEP, BALL_VEL_MAX, BALL_SIZE_MIN, BALL_VEL_MIN +from .env import SQUID_VEL, SQUID_H, SQUID_W, SQUID_GROWTH_SCORE_STEP, SQUID_GROWTH_SIZE_STEP, \ + SQUID_SIZE_MAX, SQUID_GROWTH_VEL_STEP, SQUID_VEL_MAX, SQUID_SIZE_MIN, SQUID_VEL_MIN from .foods import Food from .sound_controller import SoundController from mlgame.view.view_model import create_rect_view_data, create_image_view_data @@ -20,8 +20,6 @@ class LevelParams(pydantic.BaseModel): score_to_pass: int = 10 time_to_play: int = 300 - good_food_count: List[int] = [] - bad_food_count: List[int] = [] food_1: int = 3 food_2: int = 0 @@ -36,12 +34,12 @@ class Squid(pygame.sprite.Sprite): ANGLE_TO_LEFT = math.radians(10) def __init__(self): pygame.sprite.Sprite.__init__(self) - self.origin_image = pygame.Surface([BALL_W, BALL_H]) + self.origin_image = pygame.Surface([SQUID_W, SQUID_H]) self.image = self.origin_image self.rect = self.image.get_rect() self.rect.center = (400, 300) self._score = 0 - self._vel = BALL_VEL + self._vel = SQUID_VEL self._lv = 1 self.angle =0 def update(self, motion): @@ -79,10 +77,10 @@ class Squid(pygame.sprite.Sprite): def eat_food_and_change_level_and_play_sound(self, food: Food, sound_controller: SoundController): self._score += food.score - new_lv = math.ceil((self._score - BALL_GROWTH_SCORE_STEP + 1) / BALL_GROWTH_SCORE_STEP) - self.rect.width = max(BALL_SIZE_MIN, min(BALL_W + new_lv * BALL_GROWTH_SIZE_STEP, BALL_SIZE_MAX)) - self.rect.height = max(BALL_SIZE_MIN, min(BALL_H + new_lv * BALL_GROWTH_SIZE_STEP, BALL_SIZE_MAX)) - self._vel = max(BALL_VEL_MIN, min(BALL_VEL + new_lv * BALL_GROWTH_VEL_STEP, BALL_VEL_MAX)) + new_lv = math.ceil((self._score - SQUID_GROWTH_SCORE_STEP + 1) / SQUID_GROWTH_SCORE_STEP) + self.rect.width = max(SQUID_SIZE_MIN, min(SQUID_W + new_lv * SQUID_GROWTH_SIZE_STEP, SQUID_SIZE_MAX)) + self.rect.height = max(SQUID_SIZE_MIN, min(SQUID_H + new_lv * SQUID_GROWTH_SIZE_STEP, SQUID_SIZE_MAX)) + self._vel = max(SQUID_VEL_MIN, min(SQUID_VEL + new_lv * SQUID_GROWTH_VEL_STEP, SQUID_VEL_MAX)) if new_lv > self._lv: sound_controller.play_lv_up() elif new_lv < self._lv: