diff --git a/game_config.json b/game_config.json index d0586ac..3dfca00 100644 --- a/game_config.json +++ b/game_config.json @@ -1,6 +1,6 @@ { "game_name": "swimming-squid", - "version": "2.4a6", + "version": " 1.0", "url": "https://github.com/PAIA-Playful-AI-Arena/swimming-squid", "description": "這是一個魷魚吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例", "logo": [ @@ -8,8 +8,8 @@ "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/swimming-squid/main/asset/logo.png" ], "user_num": { - "min": 1, - "max": 1 + "min": 2, + "max": 2 }, "game_params": [ { diff --git a/main.py b/main.py index 114ddf5..5c600e5 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ from src.game import SwimmingSquid FPS = 30 if __name__ == '__main__': pygame.init() - game = SwimmingSquid(level=15) + game = SwimmingSquid(level=1) scene_init_info_dict = game.get_scene_init_data() game_view = PygameView(scene_init_info_dict) frame_count = 0 diff --git a/ml/ml_play_manual.py b/ml/ml_play_manual.py deleted file mode 100644 index fa2f948..0000000 --- a/ml/ml_play_manual.py +++ /dev/null @@ -1,41 +0,0 @@ -import random -from pprint import pprint - -import orjson -import pygame - - -class MLPlay: - def __init__(self,ai_name,*args,**kwargs): - print("Initial ml script") - - def update(self, scene_info: dict, keyboard:list=[], *args, **kwargs): - """ - Generate the command according to the received scene information - """ - # pprint("AI received data from game :", orjson.dumps(scene_info)) - # pprint(scene_info) - actions = [] - - if pygame.K_w in keyboard or pygame.K_UP in keyboard: - actions.append("UP") - elif pygame.K_s in keyboard or pygame.K_DOWN in keyboard: - actions.append("DOWN") - - elif pygame.K_a in keyboard or pygame.K_LEFT in keyboard: - actions.append("LEFT") - elif pygame.K_d in keyboard or pygame.K_RIGHT in keyboard: - actions.append("RIGHT") - else: - actions.append("NONE") - - return actions - - - - def reset(self): - """ - Reset the status - """ - print("reset ml script") - pass diff --git a/src/env.py b/src/env.py index f928eeb..47f8532 100644 --- a/src/env.py +++ b/src/env.py @@ -12,16 +12,22 @@ PG_COLOR = "#B3E5FC" # ball -> squid # BALL_COLOR = "#FFEB3B" -SQUID_W = 40 -SQUID_H = 60 +SQUID_W = 30 +SQUID_H = 45 LEVEL_THRESHOLDS = [10, 30, 60, 100, 150,200] LEVEL_PROPERTIES = { - 1: {'size_ratio': 1.0, 'vel': 10}, - 2: {'size_ratio': 1.2, 'vel': 12}, - 3: {'size_ratio': 1.4, 'vel': 15}, - 4: {'size_ratio': 1.6, 'vel': 18}, - 5: {'size_ratio': 1.8, 'vel': 21}, - 6: {'size_ratio': 2.0, 'vel': 25}, + 1: {'size_ratio': 1.0, 'vel': 25}, + 2: {'size_ratio': 1.2, 'vel': 21}, + 3: {'size_ratio': 1.4, 'vel': 18}, + 4: {'size_ratio': 1.6, 'vel': 16}, + 5: {'size_ratio': 1.8, 'vel': 12}, + 6: {'size_ratio': 2.0, 'vel': 9}, +} + +COLLISION_SCORE = { + "WIN":10, + "LOSE":-10, + "DRAW":-5 } diff --git a/src/game.py b/src/game.py index 1485653..5b6c074 100644 --- a/src/game.py +++ b/src/game.py @@ -46,6 +46,7 @@ class SwimmingSquid(PaiaGame): self._level_file = level_file self.foods = pygame.sprite.Group() self.sound_controller = SoundController(sound) + self._collision_mode = False self._init_game() @@ -69,14 +70,16 @@ class SwimmingSquid(PaiaGame): game_params.playground_size_w, game_params.playground_size_h ) + if game_params.playground_size_h >= 500 and game_params.playground_size_w >= 500: + self._collision_mode = True self._score_to_pass = game_params.score_to_pass self._frame_limit = game_params.time_to_play self.playground.center = ((WIDTH - WIDTH_OF_INFO) / 2, HEIGHT / 2) # init game - self.squid1 = Squid(1) - self.squid2 = Squid(2) + self.squid1 = Squid(1, 200, 300) + self.squid2 = Squid(2, 500, 300) self.foods.empty() self._create_foods(Food1, game_params.food_1) self._create_foods(Food2, game_params.food_2) @@ -115,6 +118,8 @@ class SwimmingSquid(PaiaGame): self._check_foods_collision() # self._timer = round(time.time() - self._begin_time, 3) + if self._collision_mode: + self._check_squids_collision() self.frame_count += 1 self._frame_count_down = self._frame_limit - self.frame_count @@ -147,6 +152,20 @@ class SwimmingSquid(PaiaGame): elif isinstance(food, (Garbage1, Garbage2, Garbage3,)): self.sound_controller.play_eating_bad() + def _check_squids_collision(self): + hit = pygame.sprite.collide_rect(self.squid1, self.squid2) + if hit: + if self.squid1.lv > self.squid2.lv: + self.squid1.collision_between_squids(COLLISION_SCORE["WIN"], self.sound_controller) + self.squid2.collision_between_squids(COLLISION_SCORE["LOSE"], self.sound_controller) + elif self.squid1.lv < self.squid2.lv: + self.squid1.collision_between_squids(COLLISION_SCORE["LOSE"], self.sound_controller) + self.squid2.collision_between_squids(COLLISION_SCORE["WIN"], self.sound_controller) + else: + # draw + self.squid1.collision_between_squids(COLLISION_SCORE["DRAW"], self.sound_controller) + self.squid2.collision_between_squids(COLLISION_SCORE["DRAW"], self.sound_controller) + def get_data_from_game_to_player(self): """ send something to game AI @@ -163,14 +182,17 @@ class SwimmingSquid(PaiaGame): data_to_1p = { "frame": self.frame_count, - "squid_x": self.squid.rect.centerx, - "squid_y": self.squid.rect.centery, - "squid_w": self.squid.rect.width, - "squid_h": self.squid.rect.height, - "squid_vel": self.squid.vel, - "squid_lv": self.squid.lv, + "self_x": self.squid1.rect.centerx, + "self_y": self.squid1.rect.centery, + "self_w": self.squid1.rect.width, + "self_h": self.squid1.rect.height, + "self_vel": self.squid1.vel, + "self_lv": self.squid1.lv, + "opponent_x":self.squid2.rect.centerx, + "opponent_y":self.squid2.rect.centery, + "opponent_lv": self.squid2.lv, "foods": foods_data, - "score": self.squid.score, + "score": self.squid1.score, "score_to_pass": self._score_to_pass, "status": self.get_game_status() @@ -178,14 +200,17 @@ class SwimmingSquid(PaiaGame): data_to_2p = { "frame": self.frame_count, - "squid_x": self.squid.rect.centerx, - "squid_y": self.squid.rect.centery, - "squid_w": self.squid.rect.width, - "squid_h": self.squid.rect.height, - "squid_vel": self.squid.vel, - "squid_lv": self.squid.lv, + "self_x": self.squid2.rect.centerx, + "self_y": self.squid2.rect.centery, + "self_w": self.squid2.rect.width, + "self_h": self.squid2.rect.height, + "self_vel": self.squid2.vel, + "self_lv": self.squid2.lv, + "opponent_x": self.squid1.rect.centerx, + "opponent_y": self.squid1.rect.centery, + "opponent_lv": self.squid1.lv, "foods": foods_data, - "score": self.squid.score, + "score": self.squid2.score, "score_to_pass": self._score_to_pass, "status": self.get_game_status() @@ -204,6 +229,7 @@ class SwimmingSquid(PaiaGame): elif self.is_passed: status = GameStatus.GAME_PASS else: + print("GAME_OVER") status = GameStatus.GAME_OVER return status @@ -229,7 +255,10 @@ class SwimmingSquid(PaiaGame): @property def is_passed(self): - return self.squid1.score >= self._score_to_pass + if self.squid1.score >= self._score_to_pass or self.squid2.score >= self._score_to_pass: + return True + else: + return False @property def is_running(self): @@ -292,15 +321,24 @@ class SwimmingSquid(PaiaGame): foregrounds = [ ] - star_string = '+' * self.squid1.lv + star_string_1P = '+' * self.squid1.lv + star_string_2P = '+' * self.squid2.lv toggle_objs = [ - create_text_view_data(f"Squid Lv: {star_string}", 705, 50, "#EEEEEE", "20px Consolas BOLD"), - create_text_view_data(f"To Lv up: {LEVEL_THRESHOLDS[self.squid1.lv - 1]-self.squid1.score :04d} pt", 705, 80, "#EEEEEE", "20px Consolas BOLD"), - create_text_view_data(f"Vel : {self.squid1.vel:4d}", 705, 110, "#EEEEEE", "20px Consolas BOLD"), - create_text_view_data(f"Timer : {self._frame_count_down:04d}", 705, 150, "#EEEEEE", "20px Consolas BOLD"), - create_text_view_data(f"My Score: {self.squid1.score:04d} pt", 705, 180, "#EEEEEE", "20px Consolas BOLD"), - create_text_view_data(f"Goal : {self._score_to_pass:04d} pt", 705, 210, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"Timer : {self._frame_count_down:04d}", 705, 50, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"Goal : {self._score_to_pass:04d} pt", 705, 80, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data("1P", 705, 130, "#EEEEEE", "22px Consolas BOLD"), + create_text_view_data(f"Lv: {star_string_1P}", 705, 160, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"To Lv up: {LEVEL_THRESHOLDS[self.squid1.lv - 1]-self.squid1.score :04d} pt", 705, 190, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"Vel : {self.squid1.vel:4d}", 705, 220, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"1P Score: {self.squid1.score:04d} pt", 705, 250, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data("2P", 705, 310, "#EEEEEE", "22px Consolas BOLD"), + create_text_view_data(f"Lv: {star_string_2P}", 705, 340, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"To Lv up: {LEVEL_THRESHOLDS[self.squid2.lv - 1] - self.squid2.score :04d} pt", 705, + 370, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"Vel : {self.squid2.vel:4d}", 705, 400, "#EEEEEE", "20px Consolas BOLD"), + create_text_view_data(f"2P Score: {self.squid2.score:04d} pt", 705, 430, "#EEEEEE", "20px Consolas BOLD"), ] + scene_progress = create_scene_progress_data( frame=self.frame_count, background=backgrounds, object_list=game_obj_list, @@ -320,7 +358,13 @@ class SwimmingSquid(PaiaGame): { "player": get_ai_name(0), "rank": 1, - "score": self.squid.score, + "score": self.squid1.score, + "passed": self.is_passed + }, + { + "player": get_ai_name(1), + "rank": 2, + "score": self.squid2.score, "passed": self.is_passed } ] @@ -368,3 +412,9 @@ class SwimmingSquid(PaiaGame): ) pass + + def rank(self): + ''' + + ''' + pass diff --git a/src/game_object.py b/src/game_object.py index 7e8cc7f..d82e1c6 100644 --- a/src/game_object.py +++ b/src/game_object.py @@ -30,14 +30,14 @@ class Squid(pygame.sprite.Sprite): ANGLE_TO_RIGHT = math.radians(-10) ANGLE_TO_LEFT = math.radians(10) - def __init__(self, id): + def __init__(self, id, x, y): pygame.sprite.Sprite.__init__(self) self.id = id self.origin_image = pygame.Surface([SQUID_W, SQUID_H]) self.image = self.origin_image self.rect = self.image.get_rect() - self.rect.center = (350, 300) + self.rect.center = (x, y) self._score = 0 self._vel = LEVEL_PROPERTIES[1]['vel'] self._lv = 1 @@ -90,6 +90,22 @@ class Squid(pygame.sprite.Sprite): self._vel = LEVEL_PROPERTIES[new_lv]['vel'] self._lv = new_lv + def collision_between_squids(self, collision_score, sound_controller: SoundController): + self._score += collision_score + + new_lv = get_current_level(self._score) + + if new_lv > self._lv: + sound_controller.play_lv_up() + elif new_lv < self._lv: + sound_controller.play_lv_down() + if new_lv != self._lv: + self.rect.width = SQUID_W * LEVEL_PROPERTIES[new_lv]['size_ratio'] + self.rect.height = SQUID_H * LEVEL_PROPERTIES[new_lv]['size_ratio'] + self._vel = LEVEL_PROPERTIES[new_lv]['vel'] + self._lv = new_lv + + @property def score(self): return self._score