diff options
-rw-r--r-- | brutalmaze/__init__.py | 2 | ||||
-rw-r--r-- | brutalmaze/__main__.py (renamed from brutalmaze/game.py) | 23 | ||||
-rw-r--r-- | brutalmaze/characters.py | 17 | ||||
-rw-r--r-- | brutalmaze/constants.py | 23 | ||||
-rw-r--r-- | brutalmaze/maze.py | 21 | ||||
-rw-r--r-- | brutalmaze/misc.py | 12 | ||||
-rw-r--r-- | brutalmaze/soundfx/__init__.py | 1 | ||||
-rw-r--r-- | brutalmaze/weapons.py | 10 | ||||
-rw-r--r-- | pyproject.toml | 4 |
9 files changed, 50 insertions, 63 deletions
diff --git a/brutalmaze/__init__.py b/brutalmaze/__init__.py index ce4296a..1eca2a1 100644 --- a/brutalmaze/__init__.py +++ b/brutalmaze/__init__.py @@ -1,3 +1,3 @@ """Minimalist thrilling shoot 'em up game""" -from .game import __version__ +from .__main__ import __version__ diff --git a/brutalmaze/game.py b/brutalmaze/__main__.py index 8b11228..a9a0e98 100644 --- a/brutalmaze/game.py +++ b/brutalmaze/__main__.py @@ -1,5 +1,5 @@ -# game.py - main module, starts game and main loop -# Copyright (C) 2017-2020 Nguyễn Gia Phong +# Game initialization and main loop +# Copyright (C) 2017-2021 Nguyễn Gia Phong # # This file is part of Brutal Maze. # @@ -16,12 +16,13 @@ # You should have received a copy of the GNU Affero General Public License # along with Brutal Maze. If not, see <https://www.gnu.org/licenses/>. -__version__ = '0.9.4' +__version__ = '1.0.0' import re from argparse import ArgumentParser, FileType, RawTextHelpFormatter from configparser import ConfigParser from contextlib import redirect_stdout +from importlib.resources import open_binary, path, read_text from io import StringIO from math import atan2, pi, radians from os.path import join as pathjoin, pathsep @@ -35,7 +36,7 @@ from palace import Context, Device, free, use_context from pygame import KEYDOWN, MOUSEBUTTONUP, QUIT, VIDEORESIZE from pygame.time import Clock, get_ticks -from .constants import HERO_SPEED, ICON, MIDDLE, SETTINGS, SFX, SFX_NOISE +from .constants import HERO_SPEED, MIDDLE, SFX from .maze import Maze from .misc import deg, join, play, sign @@ -55,7 +56,9 @@ class ConfigReader: def __init__(self, filenames): self.config = ConfigParser() - self.config.read(SETTINGS) # default configuration + # Default configuration + with path('brutalmaze', 'settings.ini') as settings: + self.config.read(settings) self.config.read(filenames) # Fallback to None when attribute is missing @@ -108,7 +111,9 @@ class Game: def __init__(self, config: ConfigReader): pygame.init() self.headless = config.headless and config.server - if not self.headless: pygame.display.set_icon(ICON) + if not self.headless: + with open_binary('brutalmaze', 'icon.png') as icon: + pygame.display.set_icon(pygame.image.load(icon)) self.actx = None if self.headless else Context(Device()) self._mute = config.muted @@ -138,7 +143,7 @@ class Game: use_context(self.actx) self.actx.listener.position = MIDDLE, -MIDDLE, 0 self.actx.listener.gain = not self._mute - self._source = play(SFX_NOISE) + self._source = play('noise.ogg') self._source.looping = True return self @@ -403,7 +408,7 @@ def main(): help='run server without graphics or sound') args = parser.parse_args() if args.defaultcfg is not None: - with open(SETTINGS) as settings: args.defaultcfg.write(settings.read()) + args.defaultcfg.write(read_text('brutalmaze', 'settings.ini')) args.defaultcfg.close() exit() @@ -426,5 +431,5 @@ def main(): while game.update(): game.user_control() -# Allow launching the game via invoking ``python -m brutalmaze.game'' +# Allow launching the game via invoking ``python -m brutalmaze'' if __name__ == '__main__': main() diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py index 1c37be9..12eebb5 100644 --- a/brutalmaze/characters.py +++ b/brutalmaze/characters.py @@ -1,5 +1,5 @@ -# characters.py - module for hero and enemy classes -# Copyright (C) 2017-2020 Nguyễn Gia Phong +# Hero and enemy classes +# Copyright (C) 2017-2021 Nguyễn Gia Phong # # This file is part of Brutal Maze. # @@ -23,10 +23,9 @@ from math import atan2, gcd, pi, sin from random import choice, randrange, shuffle from sys import modules -from .constants import (ADJACENTS, AROUND_HERO, ATTACK_SPEED, EMPTY, - ENEMIES, ENEMY, ENEMY_HP, ENEMY_SPEED, FIRANGE, - HEAL_SPEED, HERO_HP, MIDDLE, MIN_BEAT, SFX_HEART, - SFX_SLASH_HERO, SFX_SPAWN, SQRT2, TANGO, WALL) +from .constants import (ADJACENTS, AROUND_HERO, ATTACK_SPEED, EMPTY, ENEMIES, + ENEMY, ENEMY_HP, ENEMY_SPEED, FIRANGE, HEAL_SPEED, + HERO_HP, MIDDLE, MIN_BEAT, SQRT2, TANGO, WALL) from .misc import fill_aapolygon, play, randsign, regpoly, sign from .weapons import Bullet @@ -84,7 +83,7 @@ class Hero: if self.wound < 0: self.wound = 0.0 self.wounds.append(0.0) if self.next_beat <= 0: - play(SFX_HEART) + play('heart.ogg') self.next_beat = MIN_BEAT*(2 - self.wound/HERO_HP) else: self.next_beat -= 1000 / fps @@ -221,7 +220,7 @@ class Enemy: if self.maze.map[srcx+i//w][srcy+i//u] == WALL: return False self.awake = True self.maze.map[self.x][self.y] = ENEMY - play(SFX_SPAWN, self.x, self.y) + play('spawn.ogg', self.x, self.y) return True def fire(self): @@ -311,7 +310,7 @@ class Enemy: if not self.spin_queue and not self.fire() and not self.move(): self.spin_queue = randsign() * self.spin_speed if not self.maze.hero.dead: - play(SFX_SLASH_HERO, self.x, self.y, self.get_slash()) + play('slash-hero.ogg', self.x, self.y, self.get_slash()) if round(self.spin_queue) != 0: self.angle += sign(self.spin_queue) * pi / 2 / self.spin_speed self.spin_queue -= sign(self.spin_queue) diff --git a/brutalmaze/constants.py b/brutalmaze/constants.py index 396cc2b..69ea94d 100644 --- a/brutalmaze/constants.py +++ b/brutalmaze/constants.py @@ -1,5 +1,5 @@ -# constants.py - module for shared constants -# Copyright (C) 2017-2020 Nguyễn Gia Phong +# Shared constants +# Copyright (C) 2017-2021 Nguyễn Gia Phong # # This file is part of Brutal Maze. # @@ -20,23 +20,8 @@ __doc__ = 'Brutal Maze module for shared constants' from string import ascii_lowercase -import pygame -from pkg_resources import resource_filename as pkg_file - -SETTINGS = pkg_file('brutalmaze', 'settings.ini') -ICON = pygame.image.load(pkg_file('brutalmaze', 'icon.png')) - -SFX_NOISE = pkg_file('brutalmaze', 'soundfx/noise.ogg') -SFX_SPAWN = pkg_file('brutalmaze', 'soundfx/spawn.ogg') -SFX_SLASH_ENEMY = pkg_file('brutalmaze', 'soundfx/slash-enemy.ogg') -SFX_SLASH_HERO = pkg_file('brutalmaze', 'soundfx/slash-hero.ogg') -SFX_SHOT_ENEMY = pkg_file('brutalmaze', 'soundfx/shot-enemy.ogg') -SFX_SHOT_HERO = pkg_file('brutalmaze', 'soundfx/shot-hero.ogg') -SFX_MISSED = pkg_file('brutalmaze', 'soundfx/missed.ogg') -SFX_HEART = pkg_file('brutalmaze', 'soundfx/heart.ogg') -SFX_LOSE = pkg_file('brutalmaze', 'soundfx/lose.ogg') -SFX = (SFX_NOISE, SFX_SPAWN, SFX_SLASH_ENEMY, SFX_SLASH_HERO, - SFX_SHOT_ENEMY, SFX_SHOT_HERO, SFX_MISSED, SFX_HEART, SFX_LOSE) +SFX = ('noise.ogg', 'spawn.ogg', 'missed.ogg', 'heart.ogg', 'lose.ogg', + 'slash-enemy.ogg', 'slash-hero.ogg', 'shot-enemy.ogg', 'shot-hero.ogg') SQRT2 = 2 ** 0.5 INIT_SCORE = 2 diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py index d64e77f..a31fb86 100644 --- a/brutalmaze/maze.py +++ b/brutalmaze/maze.py @@ -1,5 +1,5 @@ -# maze.py - module for the maze class -# Copyright (C) 2017-2020 Nguyễn Gia Phong +# Maze class +# Copyright (C) 2017-2021 Nguyễn Gia Phong # # This file is part of Brutal Maze. # @@ -31,9 +31,8 @@ from .constants import (ADJACENTS, ATTACK_SPEED, BG_COLOR, BULLET_LIFETIME, CELL_NODES, CELL_WIDTH, COLORS, EMPTY, ENEMIES, ENEMY, ENEMY_HP, FG_COLOR, HERO, HERO_HP, HERO_SPEED, INIT_SCORE, JSON_SEPARATORS, - MAX_WOUND, MAZE_SIZE, MIDDLE, ROAD_WIDTH, - SFX_LOSE, SFX_MISSED, SFX_SLASH_ENEMY, SFX_SPAWN, - SQRT2, TANGO_VALUES, WALL, WALL_WIDTH) + MAX_WOUND, MAZE_SIZE, MIDDLE, ROAD_WIDTH, SQRT2, + TANGO_VALUES, WALL, WALL_WIDTH) from .misc import around, deg, fill_aapolygon, json_rec, play, regpoly, sign from .weapons import LockOn @@ -97,10 +96,6 @@ class Maze: self.next_move = self.glitch = self.next_slashfx = 0.0 self.slashd = self.hero.R + self.distance/SQRT2 - self.sfx_spawn = SFX_SPAWN - self.sfx_slash = SFX_SLASH_ENEMY - self.sfx_lose = SFX_LOSE - def new_cell(self, x, y): """Draw on the map a newly created cell whose coordinates are given. @@ -291,7 +286,7 @@ class Maze: if d > 0: wound = d * SQRT2 / self.distance if self.next_slashfx <= 0: - play(SFX_SLASH_ENEMY, enemy.x, enemy.y, wound) + play('slash-enemy.ogg', enemy.x, enemy.y, wound) self.next_slashfx = ATTACK_SPEED enemy.hit(wound / self.hero.spin_speed) if enemy.wound >= ENEMY_HP: @@ -321,7 +316,7 @@ class Maze: enemy = new_enemy(self, gridx, gridy) enemy.awake = True self.map[gridx][gridy] = ENEMY - play(SFX_SPAWN, enemy.x, enemy.y) + play('spawn.ogg', enemy.x, enemy.y) enemy.hit(wound) self.enemies.append(enemy) continue @@ -339,7 +334,7 @@ class Maze: if block: self.hero.next_strike = (abs(self.hero.spin_queue/self.fps) + ATTACK_SPEED) - play(SFX_MISSED, gain=wound) + play('missed.ogg', gain=wound) else: self.hit_hero(wound, bullet.color) play(bullet.sfx_hit, gain=wound) @@ -507,7 +502,7 @@ class Maze: self.destx = self.desty = MIDDLE self.stepx = self.stepy = 0 self.vx = self.vy = 0.0 - play(SFX_LOSE) + play('lose.ogg') self.dump_records() def reinit(self): diff --git a/brutalmaze/misc.py b/brutalmaze/misc.py index db1be00..94537db 100644 --- a/brutalmaze/misc.py +++ b/brutalmaze/misc.py @@ -1,5 +1,5 @@ -# misc.py - module for miscellaneous functions -# Copyright (C) 2017-2020 Nguyễn Gia Phong +# Miscellaneous functions +# Copyright (C) 2017-2021 Nguyễn Gia Phong # # This file is part of Brutal Maze. # @@ -19,6 +19,7 @@ __doc__ = 'Brutal Maze module for miscellaneous functions' from datetime import datetime +from importlib.resources import path as resource from itertools import chain from math import cos, degrees, pi, sin from os import path @@ -86,14 +87,15 @@ def json_rec(directory): """Return path to JSON file to be created inside the given directory based on current time local to timezone in ISO 8601 format. """ - return path.join( - directory, '{}.json'.format(datetime.now().isoformat()[:19])) + return path.join(directory, + '{}.json'.format(datetime.now().isoformat()[:19])) def play(sound: str, x: float = MIDDLE, y: float = MIDDLE, gain: float = 1.0) -> Source: """Play a sound at the given position.""" - source = Buffer(sound).play() + with resource('brutalmaze.soundfx', sound) as file: + source = Buffer(str(file)).play() source.spatialize = True source.position = x, -y, 0 source.gain = gain diff --git a/brutalmaze/soundfx/__init__.py b/brutalmaze/soundfx/__init__.py new file mode 100644 index 0000000..ddc4efe --- /dev/null +++ b/brutalmaze/soundfx/__init__.py @@ -0,0 +1 @@ +# This module intentional left blank to aid importlib.resources diff --git a/brutalmaze/weapons.py b/brutalmaze/weapons.py index e42f127..75ccb67 100644 --- a/brutalmaze/weapons.py +++ b/brutalmaze/weapons.py @@ -1,4 +1,4 @@ -# characters.py - module for weapon classes +# Weapon classes # Copyright (C) 2017-2020 Nguyễn Gia Phong # # This file is part of Brutal Maze. @@ -20,8 +20,7 @@ __doc__ = 'Brutal Maze module for weapon classes' from math import cos, sin -from .constants import (BG_COLOR, BULLET_LIFETIME, BULLET_SPEED, - ENEMY_HP, SFX_SHOT_ENEMY, SFX_SHOT_HERO, TANGO) +from .constants import BG_COLOR, BULLET_LIFETIME, BULLET_SPEED, ENEMY_HP, TANGO from .misc import fill_aapolygon, regpoly @@ -41,9 +40,9 @@ class Bullet: self.x, self.y, self.angle, self.color = x, y, angle, color self.fall_time = BULLET_LIFETIME if color == 'Aluminium': - self.sfx_hit = SFX_SHOT_ENEMY + self.sfx_hit = 'shot-enemy.ogg' else: - self.sfx_hit = SFX_SHOT_HERO + self.sfx_hit = 'shot-hero.ogg' def update(self, fps, distance): """Update the bullet.""" @@ -77,6 +76,7 @@ class Bullet: class LockOn: """Lock-on device to assist hero's aiming. + This is used as a mutable object to represent a grid of wall. Attributes: diff --git a/pyproject.toml b/pyproject.toml index 7f80517..05d26cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ module = 'brutalmaze' author = 'Nguyễn Gia Phong' author-email = 'mcsinyx@disroot.org' home-page = 'https://sr.ht/~cnx/brutalmaze' -requires = ['appdirs', 'palace', 'pygame>=2', 'setuptools'] +requires = ['appdirs', 'palace', 'pygame>=2'] description-file = 'README.rst' classifiers = [ 'Development Status :: 5 - Production/Stable', @@ -29,4 +29,4 @@ license = 'AGPLv3+' Documentation = 'https://brutalmaze.rtfd.io' [tool.flit.entrypoints.console_scripts] -brutalmaze = 'brutalmaze.game:main' +brutalmaze = 'brutalmaze.__main__:main' |