Skip to content
This repository has been archived by the owner on Feb 18, 2025. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ShelkovkinaM committed Feb 18, 2024
2 parents 88f5c34 + 49fb2a1 commit 2701e9e
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 72 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 弾幕 (Danmaku)
![pylint](https://img.shields.io/badge/PyLint-9.72-yellow?logo=python&logoColor=white)
![pylint](https://img.shields.io/badge/PyLint-9.95-yellow?logo=python&logoColor=white)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

## Goal
Expand Down
4 changes: 4 additions & 0 deletions danmaku/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def get_game_history() -> list[dict[str, int]]:


def delete_last_game():
"""Remove last game record from database"""
games = list(iter(SavedGame.select()))
SavedGame.delete_by_id(games[-1])
SavedGame.update()
Expand Down Expand Up @@ -155,6 +156,7 @@ def delete_saved_objects() -> None:


def get_settings() -> dict:
"""Get all settings"""
settings = {}
for setting in Settings.select():
match setting.type:
Expand All @@ -178,12 +180,14 @@ def get_settings() -> dict:


def delete_settings():
"""Delete all settings"""
for setting in Settings.select():
Settings.delete_by_id(setting)
Settings.update()


def set_settings(settings: dict) -> None:
"""Set settings from dictionary"""
for key, value in settings.items():
s = Settings.get(Settings.name == key)
s.value = value
Expand Down
2 changes: 1 addition & 1 deletion danmaku/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
db = SqliteDatabase(resource_path("DataBase.db"))


# pylint: disable=missing-class-docstring
# pylint: disable=missing-class-docstring,too-few-public-methods


class BaseModel(Model):
Expand Down
92 changes: 56 additions & 36 deletions danmaku/game/animated.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Animated(GameObject):
width_height (tuple[int | float, int | float]): Width and height of the object.
speed (int | float): Speed of the object.
frames (list[str]): List of frames
freq (int | float): Frequency of animation
freq (int | float | None, optional): Frequency of animation
period (int | float | None, optional): Period of animation. Defaults to None.
You can pass freq as '0' and just use period
Expand All @@ -26,8 +26,8 @@ def __init__(
xy: tuple[int | float, int | float],
width_height: tuple[int | float, int | float],
speed: int | float,
frames,
freq: int | float,
frames: list[str],
freq: int | float | None = None,
period: int | float | None = None,
) -> None:
super().__init__(xy, width_height, speed)
Expand All @@ -37,16 +37,17 @@ def __init__(
if period is not None:
self.animation_period = period
self.animation_freq = 1 / period
else:
elif freq is not None:
self.animation_freq = freq
self.animation_period = 1 / freq
else:
raise ValueError("You must pass period or freq")
self.animation_current = 0
self.animation_last = 0
self.last_direction = 0

if len(frames):
self.texture_file = self.animation_frames[
self.animation_current]
self.texture_file = self.animation_frames[self.animation_current]

def can_animate(self) -> bool:
"""Check if possible to animate"""
Expand All @@ -57,13 +58,58 @@ def can_animate(self) -> bool:
return True
return False

def animate(self, direction_vector: tuple[int | float, int | float] = (0, 0)) -> None:
"""Animate one frame if possible
def animate(self) -> None:
"""Animate one frame if possible"""
if self.can_animate():
self.animation_current = (self.animation_current + 1) % len(
self.animation_frames
)
self.texture_file = self.animation_frames[self.animation_current]"""
self.texture_file = self.animation_frames[self.animation_current]


class AnimatedDirectional(Animated):
"""Base class for animated objects, that change animations based on direction"""

def __init__(
self,
xy: tuple[int | float, int | float],
width_height: tuple[int | float, int | float],
speed: int | float,
frames: list[str],
freq: int | float | None = None,
period: int | float | None = None,
) -> None:
super().__init__(xy, width_height, speed, [], freq, period)
self.last_direction = 0

self.animation_frames = {
Direction.LEFT: [],
Direction.RIGHT: [],
Direction.UP: [],
Direction.DOWN: [],
Direction.STATIC: [],
}

for file in frames:
if "left" in file:
self.animation_frames[Direction.LEFT].append(file)
if "right" in file:
self.animation_frames[Direction.RIGHT].append(file)
if "up" in file:
self.animation_frames[Direction.UP].append(file)
if "down" in file:
self.animation_frames[Direction.DOWN].append(file)
if "static" in file or "idle" in file:
self.animation_frames[Direction.STATIC].append(file)

self.texture_file = self.animation_frames[Direction.STATIC][
self.animation_current
]

def animate(
self, direction_vector: tuple[int | float, int | float] = (0, 0)
) -> None:
"""Animate one frame if possible"""

if self.can_animate():
direction = None
Expand All @@ -77,6 +123,7 @@ def animate(self, direction_vector: tuple[int | float, int | float] = (0, 0)) ->
direction = Direction.LEFT
elif direction_vector[1] < 0:
direction = Direction.UP

if direction == Direction.STATIC:
a = ""
if self.last_direction == Direction.UP:
Expand All @@ -98,30 +145,3 @@ def animate(self, direction_vector: tuple[int | float, int | float] = (0, 0)) ->
self.animation_current
]
self.last_direction = direction

def frames_from_str(self, str_frames, adress):
files: list[str] = str_frames.split(";")
self.animation_frames = {
Direction.LEFT: [],
Direction.RIGHT: [],
Direction.UP: [],
Direction.DOWN: [],
Direction.STATIC: []
}

for i in files:
path = f"/{adress}/{i}"
if "left" in i:
self.animation_frames[Direction.LEFT].append(path)
if "right" in i:
self.animation_frames[Direction.RIGHT].append(path)
if "up" in i:
self.animation_frames[Direction.UP].append(path)
if "down" in i:
self.animation_frames[Direction.DOWN].append(path)
if "static" in i or "idle" in i:
self.animation_frames[Direction.STATIC].append(path)

self.texture_file = self.animation_frames[Direction.STATIC][
self.animation_current
]
9 changes: 1 addition & 8 deletions danmaku/game/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,10 @@ def __init__(
pass

super().__init__((x, y), (width, height), 0, frames, 0, period=0.1)
self.texture_size = self.width, self.height
self.texture_size = int(self.width), int(self.height)

def draw(self, graphics: vgame.graphics.Graphics):
graphics.draw_sprite(self)

def update(self, delta: int | float):
self.animate()

def animate(self, direction_vector: tuple[int | float, int | float] = (0, 0)) -> None:
if self.can_animate():
self.animation_current = (self.animation_current + 1) % len(
self.animation_frames
)
self.texture_file = self.animation_frames[self.animation_current]
16 changes: 11 additions & 5 deletions danmaku/game/enemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
from random import randint, choices
from math import sin, cos, pi

from danmaku.game.animated import Animated
from danmaku.game.animated import AnimatedDirectional
from danmaku.game.bullet import Bullet
from danmaku.database import get_enemy_type
from danmaku.game.shooter import Shooter
from danmaku.game.drop import PowerUp, Points, Drop


class Enemy(Shooter, Animated):
class Enemy(Shooter, AnimatedDirectional):
"""Enemy object."""

def __init__(
Expand Down Expand Up @@ -38,10 +38,14 @@ def __init__(
)

frames = list(map(lambda x: f"/enemy/{x}", args["texture_file"].split(";")))
Animated.__init__(
self, xy, args["texture_size"], args["speed"], frames, 0, period=0.1
AnimatedDirectional.__init__(
self,
xy,
args["texture_size"],
args["speed"],
frames,
period=0.1,
)
self.frames_from_str(args["texture_file"], "enemy")
self.texture_size = args["texture_size"]
self.my_type = object_type
self.cost: int = args["cost"]
Expand Down Expand Up @@ -89,6 +93,7 @@ def shoot_radial(
def shoot_cluster(
self, waves: int = 1, n: int = 10, base_angle: int = 0, arc: int = 180
) -> list[Bullet]:
"""Shoot spiral wave of bullets"""
bullets: list[Bullet] = []
for wave in range(waves):
for i, a in enumerate(range(0, arc, arc // n)):
Expand All @@ -102,6 +107,7 @@ def shoot_cluster(
return bullets

def generate_drops(self) -> list[Drop]:
"""Generate drops"""
drops: list[Drop] = []
count = 1
if self.my_type == "boss":
Expand Down
4 changes: 3 additions & 1 deletion danmaku/game/entity.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Base class for alive objects"""

from danmaku.game.gameobject import GameObject
import pygame

from danmaku.database import get_settings
from danmaku.game.gameobject import GameObject
from danmaku.utils import resource_path


Expand Down Expand Up @@ -31,6 +32,7 @@ def get_damage(self, damage: int | float):
self.damage_sound(3)

def damage_sound(self, channel: int):
"""Play damage sound"""
pygame.mixer.init()
sound = pygame.mixer.Sound(resource_path("sounds/hit.wav"))
sound.set_volume(get_settings()["sfx_volume"]["value"] / 100)
Expand Down
24 changes: 23 additions & 1 deletion danmaku/game/level.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@


class Stage:
"""Base stage
Contains enemies"""

_enemies: list[Enemy]

_start_time: int
Expand All @@ -23,14 +27,20 @@ def __init__(self, enemies: list[Enemy]) -> None:

self._start_time = pygame.time.get_ticks()

def update(self) -> None: ...
def update(self) -> None:
"""WIP
Update all enemies on the stage"""

@property
def enemies(self) -> list[Enemy]:
"""Enemies on the stage"""
return self._enemies


class BossStage(Stage):
"""Stage centered on boss"""

# +enemies: list[Enemy]
_boss: Enemy

Expand Down Expand Up @@ -60,6 +70,7 @@ def update(self) -> None:

@property
def boss(self) -> Enemy:
"""Boss property"""
return self._boss

@property
Expand All @@ -68,6 +79,12 @@ def enemies(self) -> list[Enemy]:


class Level:
"""Game level
Contains stages
For chapter separation by theme
(can contain only one boss, but with multiple boss stages)"""

stages: list[Stage]
current_stage: int

Expand All @@ -86,15 +103,20 @@ def __getitem__(self, index: int) -> Stage:

@property
def stage(self) -> Stage:
"""Current stage"""
return self.stages[self.current_stage]

def next_stage(self) -> bool:
"""Switch stage to next if possible
Returns: bool - success"""
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:
"""Set stage by index"""
self.current_stage = index
self.enemies = list(self.stages[self.current_stage].enemies)
Loading

0 comments on commit 2701e9e

Please sign in to comment.