collision

This commit is contained in:
yanshaoting 2024-01-31 17:44:24 +08:00
parent 1191ec6553
commit 97c4145d65
6 changed files with 111 additions and 80 deletions

View File

@ -1,6 +1,6 @@
{ {
"game_name": "swimming-squid", "game_name": "swimming-squid",
"version": "2.4a6", "version": " 1.0",
"url": "https://github.com/PAIA-Playful-AI-Arena/swimming-squid", "url": "https://github.com/PAIA-Playful-AI-Arena/swimming-squid",
"description": "這是一個魷魚吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例", "description": "這是一個魷魚吃東西小遊戲,除了讓你熟習所有基本操作,也是 PAIA 的遊戲教學範例",
"logo": [ "logo": [
@ -8,8 +8,8 @@
"https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/swimming-squid/main/asset/logo.png" "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/swimming-squid/main/asset/logo.png"
], ],
"user_num": { "user_num": {
"min": 1, "min": 2,
"max": 1 "max": 2
}, },
"game_params": [ "game_params": [
{ {

View File

@ -9,7 +9,7 @@ from src.game import SwimmingSquid
FPS = 30 FPS = 30
if __name__ == '__main__': if __name__ == '__main__':
pygame.init() pygame.init()
game = SwimmingSquid(level=15) game = SwimmingSquid(level=1)
scene_init_info_dict = game.get_scene_init_data() scene_init_info_dict = game.get_scene_init_data()
game_view = PygameView(scene_init_info_dict) game_view = PygameView(scene_init_info_dict)
frame_count = 0 frame_count = 0

View File

@ -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

View File

@ -12,16 +12,22 @@ PG_COLOR = "#B3E5FC"
# ball -> squid # ball -> squid
# BALL_COLOR = "#FFEB3B" # BALL_COLOR = "#FFEB3B"
SQUID_W = 40 SQUID_W = 30
SQUID_H = 60 SQUID_H = 45
LEVEL_THRESHOLDS = [10, 30, 60, 100, 150,200] LEVEL_THRESHOLDS = [10, 30, 60, 100, 150,200]
LEVEL_PROPERTIES = { LEVEL_PROPERTIES = {
1: {'size_ratio': 1.0, 'vel': 10}, 1: {'size_ratio': 1.0, 'vel': 25},
2: {'size_ratio': 1.2, 'vel': 12}, 2: {'size_ratio': 1.2, 'vel': 21},
3: {'size_ratio': 1.4, 'vel': 15}, 3: {'size_ratio': 1.4, 'vel': 18},
4: {'size_ratio': 1.6, 'vel': 18}, 4: {'size_ratio': 1.6, 'vel': 16},
5: {'size_ratio': 1.8, 'vel': 21}, 5: {'size_ratio': 1.8, 'vel': 12},
6: {'size_ratio': 2.0, 'vel': 25}, 6: {'size_ratio': 2.0, 'vel': 9},
}
COLLISION_SCORE = {
"WIN":10,
"LOSE":-10,
"DRAW":-5
} }

View File

@ -46,6 +46,7 @@ class SwimmingSquid(PaiaGame):
self._level_file = level_file self._level_file = level_file
self.foods = pygame.sprite.Group() self.foods = pygame.sprite.Group()
self.sound_controller = SoundController(sound) self.sound_controller = SoundController(sound)
self._collision_mode = False
self._init_game() self._init_game()
@ -69,14 +70,16 @@ class SwimmingSquid(PaiaGame):
game_params.playground_size_w, game_params.playground_size_w,
game_params.playground_size_h 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._score_to_pass = game_params.score_to_pass
self._frame_limit = game_params.time_to_play self._frame_limit = game_params.time_to_play
self.playground.center = ((WIDTH - WIDTH_OF_INFO) / 2, HEIGHT / 2) self.playground.center = ((WIDTH - WIDTH_OF_INFO) / 2, HEIGHT / 2)
# init game # init game
self.squid1 = Squid(1) self.squid1 = Squid(1, 200, 300)
self.squid2 = Squid(2) self.squid2 = Squid(2, 500, 300)
self.foods.empty() self.foods.empty()
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(Food2, game_params.food_2)
@ -115,6 +118,8 @@ class SwimmingSquid(PaiaGame):
self._check_foods_collision() self._check_foods_collision()
# self._timer = round(time.time() - self._begin_time, 3) # self._timer = round(time.time() - self._begin_time, 3)
if self._collision_mode:
self._check_squids_collision()
self.frame_count += 1 self.frame_count += 1
self._frame_count_down = self._frame_limit - self.frame_count self._frame_count_down = self._frame_limit - self.frame_count
@ -147,6 +152,20 @@ class SwimmingSquid(PaiaGame):
elif isinstance(food, (Garbage1, Garbage2, Garbage3,)): elif isinstance(food, (Garbage1, Garbage2, Garbage3,)):
self.sound_controller.play_eating_bad() 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): def get_data_from_game_to_player(self):
""" """
send something to game AI send something to game AI
@ -163,14 +182,17 @@ class SwimmingSquid(PaiaGame):
data_to_1p = { data_to_1p = {
"frame": self.frame_count, "frame": self.frame_count,
"squid_x": self.squid.rect.centerx, "self_x": self.squid1.rect.centerx,
"squid_y": self.squid.rect.centery, "self_y": self.squid1.rect.centery,
"squid_w": self.squid.rect.width, "self_w": self.squid1.rect.width,
"squid_h": self.squid.rect.height, "self_h": self.squid1.rect.height,
"squid_vel": self.squid.vel, "self_vel": self.squid1.vel,
"squid_lv": self.squid.lv, "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, "foods": foods_data,
"score": self.squid.score, "score": self.squid1.score,
"score_to_pass": self._score_to_pass, "score_to_pass": self._score_to_pass,
"status": self.get_game_status() "status": self.get_game_status()
@ -178,14 +200,17 @@ class SwimmingSquid(PaiaGame):
data_to_2p = { data_to_2p = {
"frame": self.frame_count, "frame": self.frame_count,
"squid_x": self.squid.rect.centerx, "self_x": self.squid2.rect.centerx,
"squid_y": self.squid.rect.centery, "self_y": self.squid2.rect.centery,
"squid_w": self.squid.rect.width, "self_w": self.squid2.rect.width,
"squid_h": self.squid.rect.height, "self_h": self.squid2.rect.height,
"squid_vel": self.squid.vel, "self_vel": self.squid2.vel,
"squid_lv": self.squid.lv, "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, "foods": foods_data,
"score": self.squid.score, "score": self.squid2.score,
"score_to_pass": self._score_to_pass, "score_to_pass": self._score_to_pass,
"status": self.get_game_status() "status": self.get_game_status()
@ -204,6 +229,7 @@ class SwimmingSquid(PaiaGame):
elif self.is_passed: elif self.is_passed:
status = GameStatus.GAME_PASS status = GameStatus.GAME_PASS
else: else:
print("GAME_OVER")
status = GameStatus.GAME_OVER status = GameStatus.GAME_OVER
return status return status
@ -229,7 +255,10 @@ class SwimmingSquid(PaiaGame):
@property @property
def is_passed(self): 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 @property
def is_running(self): def is_running(self):
@ -292,15 +321,24 @@ class SwimmingSquid(PaiaGame):
foregrounds = [ foregrounds = [
] ]
star_string = '+' * self.squid1.lv star_string_1P = '+' * self.squid1.lv
star_string_2P = '+' * self.squid2.lv
toggle_objs = [ toggle_objs = [
create_text_view_data(f"Squid Lv: {star_string}", 705, 50, "#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"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"Goal : {self._score_to_pass: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("1P", 705, 130, "#EEEEEE", "22px Consolas BOLD"),
create_text_view_data(f"Timer : {self._frame_count_down:04d}", 705, 150, "#EEEEEE", "20px Consolas BOLD"), create_text_view_data(f"Lv: {star_string_1P}", 705, 160, "#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"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"Goal : {self._score_to_pass:04d} pt", 705, 210, "#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( scene_progress = create_scene_progress_data(
frame=self.frame_count, background=backgrounds, frame=self.frame_count, background=backgrounds,
object_list=game_obj_list, object_list=game_obj_list,
@ -320,7 +358,13 @@ class SwimmingSquid(PaiaGame):
{ {
"player": get_ai_name(0), "player": get_ai_name(0),
"rank": 1, "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 "passed": self.is_passed
} }
] ]
@ -368,3 +412,9 @@ class SwimmingSquid(PaiaGame):
) )
pass pass
def rank(self):
'''
'''
pass

View File

@ -30,14 +30,14 @@ class Squid(pygame.sprite.Sprite):
ANGLE_TO_RIGHT = math.radians(-10) ANGLE_TO_RIGHT = math.radians(-10)
ANGLE_TO_LEFT = math.radians(10) ANGLE_TO_LEFT = math.radians(10)
def __init__(self, id): def __init__(self, id, x, y):
pygame.sprite.Sprite.__init__(self) pygame.sprite.Sprite.__init__(self)
self.id = id self.id = id
self.origin_image = pygame.Surface([SQUID_W, SQUID_H]) self.origin_image = pygame.Surface([SQUID_W, SQUID_H])
self.image = self.origin_image self.image = self.origin_image
self.rect = self.image.get_rect() self.rect = self.image.get_rect()
self.rect.center = (350, 300) self.rect.center = (x, y)
self._score = 0 self._score = 0
self._vel = LEVEL_PROPERTIES[1]['vel'] self._vel = LEVEL_PROPERTIES[1]['vel']
self._lv = 1 self._lv = 1
@ -90,6 +90,22 @@ class Squid(pygame.sprite.Sprite):
self._vel = LEVEL_PROPERTIES[new_lv]['vel'] self._vel = LEVEL_PROPERTIES[new_lv]['vel']
self._lv = new_lv 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 @property
def score(self): def score(self):
return self._score return self._score