commit 5e0376b4cf68f2da5654a59cc63d932eb29057d2 Author: PABLO Date: Thu May 15 02:06:11 2025 +0300 add: project diff --git a/DATA/Levels/Default/data.json b/DATA/Levels/Default/data.json new file mode 100644 index 0000000..dec7f90 --- /dev/null +++ b/DATA/Levels/Default/data.json @@ -0,0 +1 @@ +{"name": "Default", "start_point": {"x": 4, "y": 8}, "enemy_types": [[{"type": "little_spider", "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png"}], [{"type": "wolf", "sprite": "DATA/Sprites/Enemies/Tier 2/wolf.png"}]], "enemy_spawns": [[{"x": 1, "y": 3, "tier": 1, "sleep": 200, "delay": 600}, {"x": 12, "y": 7, "tier": 1, "sleep": 200, "delay": 9000}, {"x": 1, "y": 4, "tier": 1, "sleep": 200, "delay": 800}, {"x": 10, "y": 0, "tier": 1, "sleep": 200, "delay": 600}]], "size": [13, 10], "floor": [{"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 0}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 0}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 0}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 0}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 0}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 13, "y": 1}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 13, "y": 2}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 13, "y": 3}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 13, "y": 4}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 13, "y": 5}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 0, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 6}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 0, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 7}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 1, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 2, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 12, "y": 8}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 3, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 4, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 5, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 9, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 10, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 11, "y": 9}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 6, "y": 10}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 7, "y": 10}, {"sprite": "DATA/Sprites/Floor/floor_grey.png", "x": 8, "y": 10}]} \ No newline at end of file diff --git a/DATA/Levels/level_1/data.json b/DATA/Levels/level_1/data.json new file mode 100644 index 0000000..f1c7b75 --- /dev/null +++ b/DATA/Levels/level_1/data.json @@ -0,0 +1,108 @@ +{ + "name": "default", + "starting_position": { + "x": 6, + "y": 1 + }, + "enemies": [ + { + "type": "spider", + "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png", + "x": 1, + "y": 6 + }, + { + "type": "spider", + "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png", + "x": 1, + "y": 2 + }, + { + "type": "spider", + "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png", + "x": 12, + "y": 3 + }, + { + "type": "spider", + "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png", + "x": 10, + "y": 8 + } + ], + "floor": [ + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 0, + "x_start": 6, + "x_end": 8 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 1, + "x_start": 3, + "x_end": 11 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 1, + "x_start": 3, + "x_end": 11 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 2, + "x_start": 1, + "x_end": 12 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 3, + "x_start": 0, + "x_end": 12 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 4, + "x_start": 0, + "x_end": 12 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 5, + "x_start": 1, + "x_end": 13 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 6, + "x_start": 1, + "x_end": 13 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 7, + "x_start": 1, + "x_end": 13 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 8, + "x_start": 4, + "x_end": 11 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 9, + "x_start": 5, + "x_end": 8 + }, + { + "sprite": "DATA/Sprites/Floor/floor_grey.png", + "y": 10, + "x_start": 5, + "x_end": 6 + } + ] + +} \ No newline at end of file diff --git a/DATA/Sprites/Enemies/Tier 0/healthy_food.aseprite b/DATA/Sprites/Enemies/Tier 0/healthy_food.aseprite new file mode 100644 index 0000000..42d44fa Binary files /dev/null and b/DATA/Sprites/Enemies/Tier 0/healthy_food.aseprite differ diff --git a/DATA/Sprites/Enemies/Tier 0/healthy_food.png b/DATA/Sprites/Enemies/Tier 0/healthy_food.png new file mode 100644 index 0000000..e0c2b3a Binary files /dev/null and b/DATA/Sprites/Enemies/Tier 0/healthy_food.png differ diff --git a/DATA/Sprites/Enemies/Tier 1/little-spider.aseprite b/DATA/Sprites/Enemies/Tier 1/little-spider.aseprite new file mode 100644 index 0000000..903a978 Binary files /dev/null and b/DATA/Sprites/Enemies/Tier 1/little-spider.aseprite differ diff --git a/DATA/Sprites/Enemies/Tier 1/little-spider.png b/DATA/Sprites/Enemies/Tier 1/little-spider.png new file mode 100644 index 0000000..fe9c423 Binary files /dev/null and b/DATA/Sprites/Enemies/Tier 1/little-spider.png differ diff --git a/DATA/Sprites/Floor/floor_grey.aseprite b/DATA/Sprites/Floor/floor_grey.aseprite new file mode 100644 index 0000000..48b6918 Binary files /dev/null and b/DATA/Sprites/Floor/floor_grey.aseprite differ diff --git a/DATA/Sprites/Floor/floor_grey.png b/DATA/Sprites/Floor/floor_grey.png new file mode 100644 index 0000000..f3131c0 Binary files /dev/null and b/DATA/Sprites/Floor/floor_grey.png differ diff --git a/DATA/Sprites/Floor/move_ghost.aseprite b/DATA/Sprites/Floor/move_ghost.aseprite new file mode 100644 index 0000000..b59773c Binary files /dev/null and b/DATA/Sprites/Floor/move_ghost.aseprite differ diff --git a/DATA/Sprites/Floor/move_ghost.png b/DATA/Sprites/Floor/move_ghost.png new file mode 100644 index 0000000..874d83b Binary files /dev/null and b/DATA/Sprites/Floor/move_ghost.png differ diff --git a/DATA/Sprites/Floor/simple_border.aseprite b/DATA/Sprites/Floor/simple_border.aseprite new file mode 100644 index 0000000..dd98e11 Binary files /dev/null and b/DATA/Sprites/Floor/simple_border.aseprite differ diff --git a/DATA/Sprites/Floor/simple_border.png b/DATA/Sprites/Floor/simple_border.png new file mode 100644 index 0000000..dc16d67 Binary files /dev/null and b/DATA/Sprites/Floor/simple_border.png differ diff --git a/DATA/Sprites/Snake/body-rotate.aseprite b/DATA/Sprites/Snake/body-rotate.aseprite new file mode 100644 index 0000000..cc4ef42 Binary files /dev/null and b/DATA/Sprites/Snake/body-rotate.aseprite differ diff --git a/DATA/Sprites/Snake/body-rotate.png b/DATA/Sprites/Snake/body-rotate.png new file mode 100644 index 0000000..06c3c36 Binary files /dev/null and b/DATA/Sprites/Snake/body-rotate.png differ diff --git a/DATA/Sprites/Snake/body.aseprite b/DATA/Sprites/Snake/body.aseprite new file mode 100644 index 0000000..fce8482 Binary files /dev/null and b/DATA/Sprites/Snake/body.aseprite differ diff --git a/DATA/Sprites/Snake/body.png b/DATA/Sprites/Snake/body.png new file mode 100644 index 0000000..f3a53f9 Binary files /dev/null and b/DATA/Sprites/Snake/body.png differ diff --git a/DATA/Sprites/Snake/head.aseprite b/DATA/Sprites/Snake/head.aseprite new file mode 100644 index 0000000..482db0b Binary files /dev/null and b/DATA/Sprites/Snake/head.aseprite differ diff --git a/DATA/Sprites/Snake/head.png b/DATA/Sprites/Snake/head.png new file mode 100644 index 0000000..30ba40a Binary files /dev/null and b/DATA/Sprites/Snake/head.png differ diff --git a/DATA/Sprites/Snake/tail.aseprite b/DATA/Sprites/Snake/tail.aseprite new file mode 100644 index 0000000..f55b22a Binary files /dev/null and b/DATA/Sprites/Snake/tail.aseprite differ diff --git a/DATA/Sprites/Snake/tail.png b/DATA/Sprites/Snake/tail.png new file mode 100644 index 0000000..8c21d5d Binary files /dev/null and b/DATA/Sprites/Snake/tail.png differ diff --git a/__pycache__/fill_level.cpython-313.pyc b/__pycache__/fill_level.cpython-313.pyc new file mode 100644 index 0000000..ee4fd74 Binary files /dev/null and b/__pycache__/fill_level.cpython-313.pyc differ diff --git a/fill_level.py b/fill_level.py new file mode 100644 index 0000000..caf4a5e --- /dev/null +++ b/fill_level.py @@ -0,0 +1,109 @@ +import json + + +class filler(): + def __init__(self, name = "None", floor_code = []): + self.name = name + self.floor_code = floor_code if floor_code else self.get_default_floor_code() + + def export2json(self): + filename = f"DATA/Levels/{self.name}/data.json" + with open(filename, 'w') as f: + json.dump(self.level_data, f) + + def fill_level(self, floor_code, name = "Default"): + self.level_data = { + "name": name, + "start_point": { + "x": 4, + "y": 8, + }, + "enemy_types": [ + [ + { + "type": "little_spider", + "sprite": "DATA/Sprites/Enemies/Tier 1/little-spider.png", + } + ], + [ + { + "type": "wolf", + "sprite": "DATA/Sprites/Enemies/Tier 2/wolf.png", + } + ], + ], + "enemy_spawns": [[ + { "x" : 1, "y" : 3, "tier": 1, "sleep": 200, "delay": 600}, + { "x" : 12, "y" : 7,"tier": 1, "sleep": 200, "delay": 9000 }, + { "x" : 1, "y" : 4, "tier": 1,"sleep": 200, "delay": 800 }, + { "x" : 10, "y" : 0,"tier": 1, "sleep": 200, "delay": 600 } + ]], + + "size" : [], + "floor": [] + } + # Загрузка пола + + # floor_code - закодированная информация об уровне, представляет собой ас массив последовательностей 2х чисел: + # начало пола, конец пола + # Ключами являются координаты по y + + sprite = "DATA/Sprites/Floor/floor_grey.png" + y = 0 + x_max = 1 + y_max = 1 + + while y < 15: + if y in floor_code: + for x_len in floor_code[y]: + x = x_len["s"] + while x <= x_len["e"]: + if x > x_max: x_max = x + self.level_data["floor"].append({"sprite": sprite, "x": x, "y": y}) + x = x+1 + if y > y_max: y_max = y + y = y + 1 + else: + break + + self.level_data["size"] = [x_max, y_max] + + def get_default_floor_code(self): + return { + 0: [ + { "s" : 5, "e" : 6 }, + { "s" : 10, "e" : 12 }, + ], + 1:[ + { "s" : 5, "e" : 13 }, + ], + 2:[ + { "s" : 4, "e" : 13 }, + ], + 3:[ + { "s" : 1, "e" : 13 }, + ], + 4:[ + { "s" : 1, "e" : 13 }, + ], + 5:[ + { "s" : 1, "e" : 13 }, + ], + 6:[ + { "s" : 0, "e" : 12 }, + ], + 7:[ + { "s" : 0, "e" : 12 }, + ], + 8:[ + { "s" : 1, "e" : 12 }, + ], + 9:[ + { "s" : 3, "e" : 11 }, + ], + 10:[ + { "s" : 6, "e" : 8 }, + ] + } + + diff --git a/main.py b/main.py new file mode 100644 index 0000000..a57e0bd --- /dev/null +++ b/main.py @@ -0,0 +1,401 @@ +import arcade +import json +import math +import random +from fill_level import filler + +SCREEN_WIDTH = 800 +SCREEN_HEIGHT = 600 + +# class food(): +# def __init__(self, x, y, healf = 1): +# self.x = x +# self.y = y +# self.healf = healf + +# class body(): +# def __init__(self, x, y, rotate, type): +# self.x = x +# self.y = y +# self.rotate = rotate +# self.type = type + +# class SNAKE(): +# def __init__(self, star_point_x, star_point_y, start_rotate = 0): +# self.tail_rot = 0 +# self.body = [ +# body(star_point_x, star_point_y, start_rotate, "head"), +# body(star_point_x - 1, star_point_y, start_rotate, "tail") +# ] +# def check_contact(self,x,y): +# cont = 0 +# for body in self.body: +# if body.x == x and body.y == y: +# cont = 1 +# return cont + # def calculate_coeff(self, degr): + # return math.cos(math.radians(degr)) + math.sin(math.radians(degr)) + + # def convert_rot_to_body(self, deg0, deg1 ): + # # deg1 - угол ближайшей к голове части + # # deg0 - угол переходной части (он особый) + # deg0 = deg0 % 360 + # deg1 = deg1 % 360 + # if (deg0 == 180 and deg1 == 270) or (deg0 == 270 and deg1 == 90): + # return 180 + # if (deg0 == 90 and deg1 == 270) or (deg0 == 0 and deg1 == 90): + # return 0 + # if ((deg0 == 90) and deg1 == 180) or (deg0 == 180 and deg1 == 0): + # return 90 + # if (deg0 == 0 and deg1 == 180) or (deg0 == 270 and deg1 == 0): + # return 270 + # return 0 + # def convert_rot_to_tail(self, deg0, deg2): + +class Level_data(): + def __init__(self, level_data_json = []): + if level_data_json: + self.fill_grid(level_data_json) + + def fill_grid(self, level_data_json): + self.name = level_data_json["name"] + self.floor = level_data_json["floor"] + self.size = level_data_json["size"] + self.enemy_types = level_data_json["enemy_types"] + self.enemy_spawns = level_data_json["enemy_spawns"] + self.start_point = level_data_json["start_point"] + +class MYGAME(arcade.Window): + + def __init__(self, width, height): + super().__init__(width, height) + arcade.set_background_color(arcade.color.AMAZON) + + def setup(self, level_name): + + print(f"Upload level: {level_name}") + + with open(f'./DATA/Levels/{level_name}/data.json', 'r') as file: + self.Lvl_data = Level_data(json.load(file)) + + if self.Lvl_data.name : + print(f"{self.Lvl_data.name} loaded") + else: + print("Error to load level") + + self.player_body_list = arcade.SpriteList() + self.floor_list = arcade.SpriteList() + self.enemies_list = arcade.SpriteList() + self.enemy_spawn = arcade.SpriteList() + self.tecnical_list = arcade.SpriteList() + + grid = fill_empty_grid() + self.floor_grid = self.arr2grid(self.Lvl_data.floor, grid) + self.print_grid(self.floor_grid) + + # food + self.food_list = arcade.SpriteList() + self.food_sleep = 200 + self.delay = 200 + self.food = [] + + # Счет + self.score = 0 + self.scale_ = 1.4 + + screen_center = [SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2] + self.level_start = [screen_center[0] - self.Lvl_data.size[0] * 16 * self.scale_, screen_center[1] - self.Lvl_data.size[1] * 16 * self.scale_] + + # Загрузка змеи + self.player_body_list.append(arcade.Sprite(f"./DATA/Sprites/Snake/head.png", self.scale_, self.Lvl_data.start_point["x"], self.Lvl_data.start_point["y"], 0)) + self.player_body_list.append(arcade.Sprite(f"./DATA/Sprites/Snake/tail.png", self.scale_, self.Lvl_data.start_point["x"]-1, self.Lvl_data.start_point["y"], 0)) + self.player_body_list[0].type = "head" + self.player_body_list[1].type = "tail" + + for body in self.player_body_list: + body.healf = 3 + body.center_x = self.level_start[0] - 16 + ( body.center_x ) * 32 * self.scale_ + body.center_y = self.level_start[1] - 16 + ( body.center_y ) * 32 * self.scale_ + + # Загрузка пола + for floor in self.Lvl_data.floor: + floor_sprite = arcade.Sprite(floor["sprite"], self.scale_) + floor_sprite.center_x = self.level_start[0] - 16 + ( floor["x"] ) * 32 * self.scale_ + floor_sprite.center_y = self.level_start[1] - 16 + ( floor["y"] ) * 32 * self.scale_ + self.floor_list.append(floor_sprite) + + + def calculate_rot(self, degr1, degr2): + # deg1 - угол ближайшей к голове части + # deg2 - угол дальней от голове части + degr1 = degr1 % 360 + degr2 = degr2 % 360 + if (degr1 == 180 and degr2 == 270) or (degr1 == 90 and degr2 == 0): + return 180 + if (degr1 == 0 and degr2 == 90) or (degr1 == 270 and degr2 == 180): + return 0 + if ((degr1 == 90) and degr2 == 180) or (degr1 == 0 and degr2 == 270): + return 90 + if (degr1 == 270 and degr2 == 0) or (degr1 == 180 and degr2 == 90): + return 270 + return 90 + + def calc_tail_rotate(self): + tail = self.player_body_list[len(self.player_body_list)-1] + pre_last = self.player_body_list[len(self.player_body_list)-2] + + grad = 0 + pos_x = tail.center_x + pos_y = tail.center_y + + while not((pre_last.center_x == pos_x) and (pre_last.center_y == pos_y)): + pos_x = tail.center_x + int(math.cos(math.radians(grad))) * 32 * self.scale_ + pos_y = tail.center_y + int(math.sin(math.radians(grad))) * 32 * self.scale_ + grad += 90 + return grad - 90 + + def update_sprite(self, type): + return f"./DATA/Sprites/Snake/{type}.png" + + def player_move(self, vector): + i = len(self.player_body_list)-1 + self.tail_rot = self.player_body_list[i].angle + + while i > 0: + self.player_body_list[i].center_x = self.player_body_list[i-1].center_x + self.player_body_list[i].center_y = self.player_body_list[i-1].center_y + self.player_body_list[i].angle = self.player_body_list[i-1].angle + self.player_body_list[i].type = self.player_body_list[i-1].type + self.player_body_list[i].texture = self.player_body_list[i-1].texture + i -= 1 + + self.player_body_list[0].angle = vector * 90 + self.player_body_list[0].center_x = int(math.cos(math.radians(self.player_body_list[0].angle))) * 32 * self.scale_ + self.player_body_list[0].center_x + self.player_body_list[0].center_y = int(math.sin(math.radians(self.player_body_list[0].angle))) * 32 * self.scale_ + self.player_body_list[0].center_y + self.player_body_list[0].angle = 360 - self.player_body_list[0].angle + + if self.player_body_list[0].angle != self.player_body_list[1].angle: + self.player_body_list[1].type = "body-rotate" + self.player_body_list[1].angle = 360 - self.calculate_rot(360 - self.player_body_list[0].angle, 360 - self.player_body_list[1].angle) + else: + self.player_body_list[1].type = "body" + + self.player_body_list[1].texture = arcade.load_texture(self.update_sprite(self.player_body_list[1].type)) + + self.player_body_list[ len(self.player_body_list) - 1 ].type = "tail" + self.player_body_list[ len(self.player_body_list) - 1 ].texture = arcade.load_texture(self.update_sprite( self.player_body_list[ len(self.player_body_list) - 1 ].type )) + self.player_body_list[ len(self.player_body_list) - 1 ].angle = 360 - self.calc_tail_rotate() + + def add_body(self): + + last_body = self.player_body_list[len(self.player_body_list)-1] + + new_body = arcade.Sprite(self.update_sprite( "tail" ), self.scale_,last_body.center_x, last_body.center_y, self.tail_rot) + v_x = int(math.cos(math.radians(360 - self.tail_rot))) * 32 * self.scale_ + v_y = int(math.sin(math.radians(360 - self.tail_rot))) * 32 * self.scale_ + + new_body.center_x = last_body.center_x - v_x + new_body.center_y = last_body.center_y - v_y + + l = len(self.player_body_list) - 1 + + if 360 - self.player_body_list[l].angle != 360 - self.tail_rot: + self.player_body_list[l].type = "body-rotate" + self.player_body_list[l].angle = 360 - self.calculate_rot(360 - self.player_body_list[l].angle, 360 - self.tail_rot) + else: + self.player_body_list[l].type = "body" + + self.player_body_list[l].texture = arcade.load_texture(self.update_sprite(self.player_body_list[l].type)) + self.player_body_list.append(new_body) + + def spawn_food(self): + spawn = False + while spawn == False: + x = random.randint(0, 14) + y = random.randint(0, 14) + if self.floor_grid[y][x] == 1: + food_sprite = arcade.Sprite(f"./DATA/Sprites/Enemies/Tier 0/healthy_food.png", self.scale_) + food_sprite.center_x = self.level_start[0] - 16 + ( x ) * 32 * self.scale_ + food_sprite.center_y = self.level_start[1] - 16 + ( y ) * 32 * self.scale_ + if arcade.check_for_collision_with_list(food_sprite, self.floor_list) != [] and arcade.check_for_collision_with_list(food_sprite, self.player_body_list) == []: + self.food_list.append(food_sprite) + spawn = True + else: + food_sprite.kill() + + def find_way(self, enemy): + if enemy.detect == 0: + vector = 0 + while vector != 360 and self.check_floor(vector, enemy) == 0: + vector += 90 + if vector == 360: + enemy.angle = random.randint(0, 3) * 90 + else: + enemy.angle = 360 - vector + + def enemy_move(self, enemy): + if self.check_floor(360 - enemy.angle, enemy): + enemy.center_x = int(math.cos(math.radians(360 - enemy.angle))) * 32 * self.scale_ + enemy.center_x + enemy.center_y = int(math.sin(math.radians(360 - enemy.angle))) * 32 * self.scale_ + enemy.center_y + def check_detect(self, enemy): + pass + def update(self): + # Food + self.food_sleep -= 1 + if self.food_sleep <= 0: + self.spawn_food() + self.food_sleep = self.delay + + list = arcade.check_for_collision_with_list(self.player_body_list[0], self.food_list) + if list != []: + self.food_list.remove(list[0]) + self.score += 1 + self.spawn_food() + self.add_body() + # Enemy + for enemy in self.enemies_list: + enemy.sleep -= 1 + self.check_detect(enemy) + if (enemy.sleep == enemy.delay / 2 ): + self.find_way(enemy) + elif (enemy.sleep == 0 ): + self.enemy_move(enemy) + enemy.sleep = enemy.delay + + + # Enemy_spawn + for spawn in self.Lvl_data.enemy_spawns[0]: + spawn["sleep"] -= 1 + if spawn["sleep"] <= 0: + spawn["sleep"] = spawn["delay"] + self.spawn_enemy(spawn["y"], spawn["x"], spawn["tier"]) + + def spawn_enemy(self, y, x, tier): + type = random.randint(0, len(self.Lvl_data.enemy_types[tier-1])) + + if (type == 0): + enemy_sprite = arcade.Sprite("./DATA/Sprites/Enemies/Tier 1/little-spider.png", self.scale_) + posible = arcade.check_for_collision_with_list(enemy_sprite, self.player_body_list) == [] + posible = posible and arcade.check_for_collision_with_list(enemy_sprite, self.enemies_list) == [] + if posible: + enemy_sprite.damage = 1 + enemy_sprite.healf = 1 + enemy_sprite.toxic = 0 + enemy_sprite.detect = 0 + enemy_sprite.sleep = 200 + enemy_sprite.delay = 200 + enemy_sprite.hear_radius = 1 * 32 * self.scale_ + enemy_sprite.angle = 90 + enemy_sprite.center_x = self.level_start[0] - 16 + ( x ) * 32 * self.scale_ + enemy_sprite.center_y = self.level_start[1] - 16 + ( y ) * 32 * self.scale_ + self.enemies_list.append(enemy_sprite) + else: + enemy_sprite.kill() + # print_spawn("tier: " + str(type), x, y) + + + def print_grid(self, grid): + x = 0 + y = 14 + print_ = '' + while y >= 0: + while x < 15: + print_ += " " if grid[y][x] == 0 else "1 " + x += 1 + print(print_) + print_ = '' + y -= 1 + x = 0 + + + def arr2grid(self, arr, grid): + for point in arr: + grid[point["y"]][point["x"]] = 1 + return grid + + # Обработка нажатий + MOVEMENT_SPEED = 1 + def check_floor(self, vector, sprite): + rotate = 90 * vector + v_x = int(math.cos(math.radians(rotate))) * 32 * self.scale_ + v_y = int(math.sin(math.radians(rotate))) * 32 * self.scale_ + + new_pos = arcade.Sprite( "./DATA/Sprites/Floor/move_ghost.png", self.scale_, sprite.center_x + v_x, sprite.center_y + v_y ) + + posible = arcade.check_for_collision_with_list(new_pos, self.floor_list) != [] + posible = posible and arcade.check_for_collision_with_list(new_pos, self.player_body_list) == [] + posible = posible and arcade.check_for_collision_with_list(new_pos, self.enemies_list) == [] + new_pos.kill() + + return posible + + def on_key_press(self, key, modifiers): + """Вызывается при нажатии пользователем клавиши""" + # Get the first sprite (head) from the player list + if len(self.player_body_list) == 0: + return + + if key in (arcade.key.UP, arcade.key.W): + if self.check_floor(1, self.player_body_list[0]) and self.player_body_list[0].angle != 90: + self.player_move(1) + + elif key in (arcade.key.DOWN, arcade.key.S): + if self.check_floor(3, self.player_body_list[0]) and self.player_body_list[0].angle != 270: + self.player_move(3) + + elif key in (arcade.key.LEFT, arcade.key.A): + if self.check_floor(2, self.player_body_list[0]) and (self.player_body_list[0].angle != 360 and self.player_body_list[0].angle != 0): + self.player_move(2) + + elif key in (arcade.key.RIGHT, arcade.key.D): + if self.check_floor(0, self.player_body_list[0]) and self.player_body_list[0].angle != 180: + self.player_move(0) + + # def on_key_release(self, key, modifiers): + # if len(self.player_body_list) > 0: + # self.player_sprite = self.player_body_list[0] + + # if key in (arcade.key.UP, arcade.key.DOWN, arcade.key.W, arcade.key.S): + # self.player_sprite.change_y = 0 + # elif key in (arcade.key.LEFT, arcade.key.RIGHT, arcade.key.A, arcade.key.D): + # self.player_sprite.change_x = 0 + def on_draw(self): + self.update() + # Очищаем экран перед каждой отрисовкой + self.clear() + # Отрисовываем все спрайты + self.floor_list.draw() + self.tecnical_list.draw() + self.food_list.draw() + self.enemies_list.draw() + self.player_body_list.draw() + + +def print_spawn(who, x, y): + print(f"Spawn: {who}\nx: {x}\ny: {y}") + +def fill_empty_grid(): + grid = [] + y = 0 + x = 0 + while y < 15: + grid.append([]) + while x < 15: + grid[y].append([x]) + grid[y][x] = 0 + x = x + 1 + y = y + 1 + x = 0 + return grid + +def main(): + filler_ = filler("Default") + filler_.fill_level(filler_.floor_code) + filler_.export2json() + + game = MYGAME(SCREEN_WIDTH, SCREEN_HEIGHT) + game.setup( "Default" ) + arcade.run() + +if __name__ == "__main__": + main() \ No newline at end of file