From 82397c772da8842a03f16678d86a626323077a60 Mon Sep 17 00:00:00 2001 From: Vlad <89295404+Virashu@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:59:04 +0300 Subject: [PATCH] Implement stages --- assets/DataBase.db | Bin 45056 -> 45056 bytes danmaku/game.py | 122 +++++++++++++++++++++++++-------------------- danmaku/level.py | 65 ++++++++++++++++++++++++ danmaku/player.py | 4 +- danmaku/utils.py | 8 +++ 5 files changed, 143 insertions(+), 56 deletions(-) diff --git a/assets/DataBase.db b/assets/DataBase.db index 8d336d6dffc32ead4c8b7f5991a2334b41f4d65f..f510f7c46c30249703b9d2352b1f767ffc1442f3 100644 GIT binary patch delta 51 zcmZp8z|`=7X@WFk#zYxs#*B>#OX8UY_>(8IC&)ALCvO&1u;%CD5MX8CWMX7H!@oH< Hf3gDrlE)4F delta 37 tcmZp8z|`=7X@WFk`a~IL#`KK|OX8XN`Ew_;C&+IWRB-3toSQ${0RZ<342J*! diff --git a/danmaku/game.py b/danmaku/game.py index e13ea14..1003d32 100644 --- a/danmaku/game.py +++ b/danmaku/game.py @@ -21,57 +21,69 @@ from danmaku.pause import Pause from danmaku.background import Background from danmaku.drop import Drop, PowerUp, Points - - -LEVEL1 = (Enemy((150, 15), "basic enemy"),) -LEVEL2 = ( - Enemy((50, -25), "basic enemy"), - Enemy((200, -50), "basic enemy"), -) -LEVEL3 = (Enemy((110, 5), "strong enemy"),) -LEVEL4 = ( - Enemy((50, -25), "strong enemy"), - Enemy((200, -50), "strong enemy"), +from danmaku.level import Level, Stage + + +STAGE1 = Stage([Enemy((150, 15), "basic enemy")]) +STAGE2 = Stage([Enemy((50, -25), "basic enemy"), Enemy((200, -50), "basic enemy")]) +STAGE3 = Stage([Enemy((110, 5), "strong enemy")]) +STAGE4 = Stage([Enemy((50, -25), "strong enemy"), Enemy((200, -50), "strong enemy")]) +STAGE5 = Stage( + [ + Enemy((50, -20), "basic enemy"), + Enemy((200, -50), "basic enemy"), + Enemy((110, -35), "strong enemy"), + ] ) -LEVEL5 = ( - Enemy((50, -20), "basic enemy"), - Enemy((200, -50), "basic enemy"), - Enemy((110, -35), "strong enemy"), +STAGE6 = Stage( + [ + Enemy((50, -15), "strong enemy"), + Enemy((200, -50), "basic enemy"), + Enemy((110, -35), "strong enemy"), + ] ) -LEVEL6 = ( - Enemy((50, -15), "strong enemy"), - Enemy((200, -50), "basic enemy"), - Enemy((110, -35), "strong enemy"), -) -LEVEL7 = (Enemy((150, -40), "boss"),) -LEVEL8 = ( - Enemy((50, -15), "strong enemy"), - Enemy((200, -50), "strong enemy"), - Enemy((300 - 50, -35), "strong enemy"), +STAGE7 = Stage([Enemy((150, -40), "boss")]) + + +STAGE8 = Stage( + [ + Enemy((50, -15), "strong enemy"), + Enemy((200, -50), "strong enemy"), + Enemy((300 - 50, -35), "strong enemy"), + ] ) -LEVEL9 = ( - Enemy((50, -15), "strong enemy"), - Enemy((200, -50), "strong enemy"), - Enemy((300 - 50, -35), "strong enemy"), +STAGE9 = Stage( + [ + Enemy((50, -15), "strong enemy"), + Enemy((200, -50), "strong enemy"), + Enemy((300 - 50, -35), "strong enemy"), + ] ) -LEVEL10 = ( - Enemy((50, -15), "strong enemy"), - Enemy((200, -50), "boss"), - Enemy((300 - 50, -35), "strong enemy"), +STAGE10 = Stage( + [ + Enemy((50, -15), "strong enemy"), + Enemy((200, -50), "boss"), + Enemy((300 - 50, -35), "strong enemy"), + ] ) -LEVELS = ( - LEVEL1, - LEVEL2, - LEVEL3, - LEVEL4, - LEVEL5, - LEVEL6, - LEVEL7, - LEVEL8, - LEVEL9, - LEVEL10, + + +LEVEL1 = Level( + stages=[ + STAGE1, + STAGE2, + STAGE3, + STAGE4, + STAGE5, + STAGE6, + STAGE7, + ] ) +LEVEL2 = Level(stages=[STAGE8, STAGE9, STAGE10]) + +LEVELS = LEVEL1, LEVEL2 + # pylint: disable=attribute-defined-outside-init, missing-class-docstring class Game(vgame.Scene): @@ -97,8 +109,8 @@ def load(self): self.drops: list[Drop] = [] if self.new_game: - self.cur_level = 0 - self.enemies: list[Enemy] = list(LEVELS[self.cur_level]) + self.current_level: int = 0 + self.enemies: list[Enemy] = list(LEVELS[self.current_level].enemies) self.player = Player((self.width // 2, self.height - 50), "player") else: @@ -129,7 +141,7 @@ def load(self): ) saved_game = get_saved_game() - self.cur_level = saved_game["level"] + self.current_level: int = saved_game["level"] self.player.score = saved_game["score"] self.player.power = saved_game["power"] delete_saved_objects() @@ -150,7 +162,7 @@ def update_pause(self): set_saved_objects("enemy", self.enemies) set_saved_objects("bullet", self.bullets) set_saved_objects("player", [self.player]) - set_saved_game(self.cur_level, self.player.score, self.player.power) + set_saved_game(self.current_level, self.player.score, self.player.power) self.stop() def update_game(self): @@ -232,7 +244,7 @@ def update_game(self): self.next_level() if self.player.health <= 0: - set_saved_game(self.cur_level, self.player.score, self.player.power) + set_saved_game(self.current_level, self.player.score, self.player.power) self.exit_status = "lose" death_sfx = pygame.mixer.Sound(resource_path("sounds/death.wav")) death_sfx.set_volume(self.settings["sfx_volume"]["value"] / 100) @@ -243,11 +255,13 @@ def update_game(self): def next_level(self) -> None: """Start next level if possible""" - if len(LEVELS) > self.cur_level + 1: - self.cur_level += 1 - self.enemies = list(LEVELS[self.cur_level]) + if LEVELS[self.current_level].next_stage(): + self.enemies = list(LEVELS[self.current_level].enemies) + elif len(LEVELS) > self.current_level + 1: + self.current_level += 1 + self.enemies = list(LEVELS[self.current_level].enemies) else: - set_saved_game(self.cur_level, self.player.score, self.player.power) + set_saved_game(self.current_level, self.player.score, self.player.power) self.exit_status = "win" self.stop() @@ -308,7 +322,7 @@ def print_stats(self): print( f"HP: {self.player.health}", f"Score: {self.player.score}", - f"Level: {self.cur_level}", + f"Level: {self.current_level}", "", f"Enemies: {len(self.enemies)}", f"Bullets: {len(self.bullets)}", diff --git a/danmaku/level.py b/danmaku/level.py index e69de29..0b1597d 100644 --- a/danmaku/level.py +++ b/danmaku/level.py @@ -0,0 +1,65 @@ +""" + +Game contains levels +Level contains stages +Stage contains enemies and/or boss + +""" + +import pygame + +from danmaku.enemy import Enemy + + +class Stage: + enemies: list[Enemy] + + start_time: int + # appearance of enemies can be bound to time + + def __init__(self, enemies: list[Enemy]) -> None: + self.enemies = list(enemies) + + self.start_time = pygame.time.get_ticks() + + +class BossStage(Stage): + # +enemies: list[Enemy] + boss: Enemy + + ## Boss actions ## + # Boss actions are bound to time passed from stage start + # Actions are being stored in tuples in format: + # (time in milliseconds, action, args) + + # ( 1000, "move_to", (10, 20) ) + # ( 2000, "shoot_radial", () ) + + +class Level: + stages: list[Stage] + current_stage: int + + enemies: list # enemies from current stage + + def __init__(self, stages: list[Stage]) -> None: + self.stages = list(stages) + self.current_stage = 0 + self.enemies = list(self.stages[self.current_stage].enemies) + + def __len__(self) -> int: + return len(self.stages) + + def __getitem__(self, index: int) -> Stage: + return self.stages[index] + + def next_stage(self) -> bool: + if len(self.stages) > self.current_stage + 1: + self.current_stage += 1 + self.enemies = list(self.stages[self.current_stage].enemies) + return True + return False + + def set_stage(self, index: int) -> None: + self.current_stage = index + self.enemies = list(self.stages[self.current_stage].enemies) diff --git a/danmaku/player.py b/danmaku/player.py index 17dbac7..1f0398a 100644 --- a/danmaku/player.py +++ b/danmaku/player.py @@ -61,8 +61,8 @@ def __init__( self.texture_size = args["texture_size"] self.my_type = object_type - self.score = 0 - self.power = 1 + self.score: int = 0 + self.power: int = 1 self.hitbox_radius = args["hitbox_radius"] self.slow = False diff --git a/danmaku/utils.py b/danmaku/utils.py index 4cadd11..6e19741 100644 --- a/danmaku/utils.py +++ b/danmaku/utils.py @@ -51,3 +51,11 @@ class Direction(IntEnum): RIGHT = 1 UP = 2 DOWN = 3 + + +# def str_to_stage(stage_str: str) -> Stage: ... + + +# def str_to_level(level_str: str) -> Level: +# """Convert level string to level object.""" +# ...