From 607c00bc57fb68572754404cb5da0e7f7a5618e5 Mon Sep 17 00:00:00 2001 From: Viljami Ilola <+@hix.fi> Date: Sat, 30 Mar 2024 12:07:49 +0200 Subject: refactor enemies to add bounchers --- pyproject.toml | 9 +++-- src/sliceitoff/enemies/enemies.py | 75 +++++++++++++++------------------------ src/sliceitoff/text/__init__.py | 2 +- src/sliceitoff/text/text.py | 33 ++++++++++------- tests/test_enemies.py | 22 +++++++++--- 5 files changed, 74 insertions(+), 67 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a2002cd..e5c7888 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "sliceitoff" -version = "0.1" -description = "" +version = "0.2-alpha" +description = "Arcade game where one slices play area off avoiding enemies." authors = ["Viljami Ilola <+@hix.fi>"] readme = "README.md" packages = [{include = "sliceitoff", from = "src"}] @@ -32,4 +32,7 @@ source-roots = ["src/sliceitoff"] extension-pkg-whitelist = ["pygame"] [tool.pylint."messages control"] -disable = [ "c-extension-no-member" ] +#disable = [ "c-extension-no-member" ] +disable = [ + "too-few-public-methods" # pygame sprites and groups +] diff --git a/src/sliceitoff/enemies/enemies.py b/src/sliceitoff/enemies/enemies.py index 66ebcbd..41a19fa 100644 --- a/src/sliceitoff/enemies/enemies.py +++ b/src/sliceitoff/enemies/enemies.py @@ -2,22 +2,38 @@ import pygame from random import randrange from display import Scaling -from text import Fonts +from text import get_letter_surface -class EnemySprite(pygame.sprite.Sprite): +BALL_SPAWN_AREA = (0, 0, 300_000, 200_000) +BALL_MOVEMENT = (100, 100) + +class EnemyBall(pygame.sprite.Sprite): def __init__(self): super().__init__() - self.position = (0, 0) - self.movement = (0, 0) - - def set_position(self, position: tuple): - self.position = position + self.position = ( + randrange(BALL_SPAWN_AREA[0], BALL_SPAWN_AREA[2]), + randrange(BALL_SPAWN_AREA[1], BALL_SPAWN_AREA[3])) + self.movement = ( + randrange(0, BALL_MOVEMENT[0]*2) - BALL_MOVEMENT[0], + randrange(0, BALL_MOVEMENT[1]*2) - BALL_MOVEMENT[1]) + self.image = get_letter_surface( + ('8x8', 8_000, 0), + randrange(1,3)).subsurface( + (0,0,8_000*Scaling.factor,8_000*Scaling.factor)) self.update() + self.rect = None - def set_movement(self, movement: tuple): - self.movement = movement - - def update(self, dt = 0, **kwargs): + def update(self, dt = 0, wall_hit = None, **kwargs): + if wall_hit: + if self.rect.x < wall_hit.x: + self.movement = (abs(self.movement[0]), self.movement[1]) + if self.rect.y < wall_hit.y: + self.movement = (self.movement[0], abs(self.movement[1])) + if self.rect.x + self.rect.w >= wall_hit.x + wall_hit.w: + self.movement = (-abs(self.movement[0]), self.movement[1]) + if self.rect.y + self.rect.h >= wall_hit.y + wall_hit.h: + self.movement = (self.movement[0], -abs(self.movement[1])) + return if dt: self.position = ( self.position[0] + self.movement[0] * dt, @@ -26,34 +42,11 @@ class EnemySprite(pygame.sprite.Sprite): Scaling.scale_to_display(self.position), self.image.get_size()) - def force_right(self): - self.movement = (abs(self.movement[0]), self.movement[1]) - - def force_left(self): - self.movement = (-abs(self.movement[0]), self.movement[1]) - - def force_down(self): - self.movement = (self.movement[0], abs(self.movement[1])) - - def force_up(self): - self.movement = (self.movement[0], -abs(self.movement[1])) - -class EnemyBall(EnemySprite): - def __init__(self): - super().__init__() - letter = Fonts.fonts['8x8'].get(randrange(1,3)).subsurface((0,0,8,8)) - colored = letter.fill( "black", special_flags = pygame.BLEND_RGBA_MULT) - self.image = pygame.transform.scale_by(letter, 1_000 * Scaling.factor) - self.update() - class Enemies(pygame.sprite.Group): def __init__(self, field = None, count = 0): super().__init__() for _ in range(count): - enemy = EnemyBall() - enemy.set_position( (randrange(0,300_000), randrange(0,200_000)) ) - enemy.set_movement( (randrange(0,200)-100, randrange(0,200)-100) ) - self.add(enemy) + self.add(EnemyBall()) self.field = field def update(self, field_rects = [], **kwargs): @@ -68,14 +61,4 @@ class Enemies(pygame.sprite.Group): # now find field that enemy is partly on for field_rect in field_rects: if field_rect.colliderect(enemy): - self.wall_hit(field_rect, enemy) - - def wall_hit(self, field, enemy): - if enemy.rect.x < field.x: - enemy.force_right() - if enemy.rect.y < field.y: - enemy.force_down() - if enemy.rect.x + enemy.rect.w >= field.x + field.w: - enemy.force_left() - if enemy.rect.y + enemy.rect.h >= field.y + field.h: - enemy.force_up() + enemy.update(wall_hit = field_rect) diff --git a/src/sliceitoff/text/__init__.py b/src/sliceitoff/text/__init__.py index 082179e..59385be 100644 --- a/src/sliceitoff/text/__init__.py +++ b/src/sliceitoff/text/__init__.py @@ -1,3 +1,3 @@ """ text - fonts, letters, texts and related """ -from .text import TextPage, LetterSprite +from .text import TextPage, LetterSprite, get_letter_surface from .fonts import Font, Fonts diff --git a/src/sliceitoff/text/text.py b/src/sliceitoff/text/text.py index 83367e0..69a30bc 100644 --- a/src/sliceitoff/text/text.py +++ b/src/sliceitoff/text/text.py @@ -8,28 +8,35 @@ from .fonts import Fonts scaled_fonts = {} -class LetterSprite(pygame.sprite.Sprite): - """ Single letter at given properties hopefully from cache +def get_letter_surface(font_key, ch): + """ Get letter surface at given properties hopefully from cache args: font_key: (font name, width to scale, color) ch: 0-255 character on cp473 color: 0-15 as in CGA palette """ + font, w, color = font_key + if font not in Fonts.fonts: + return None + if font_key not in scaled_fonts: + scaled_fonts[font_key]=[None for _ in range(256)] + if scaled_fonts[font_key][ch] is None: + scaled_fonts[font_key][ch] = pygame.transform.scale_by( + Fonts.fonts[font].get(ch), + w/8 * Scaling.factor) + scaled_fonts[font_key][ch].fill( + CGA_COLORS[color], + special_flags = pygame.BLEND_RGBA_MULT) + return scaled_fonts[font_key][ch] + + +class LetterSprite(pygame.sprite.Sprite): + """ Make sprite out of letter surface at given position """ def __init__(self, font_key, ch, pos): super().__init__() self.dead = True - if font_key not in scaled_fonts: - scaled_fonts[font_key]=[None for _ in range(256)] - if scaled_fonts[font_key][ch] is None: - font, w, color = font_key - scaled_fonts[font_key][ch] = pygame.transform.scale_by( - Fonts.fonts[font].get(ch), - w/8 * Scaling.factor) - scaled_fonts[font_key][ch].fill( - CGA_COLORS[color], - special_flags = pygame.BLEND_RGBA_MULT) - self.image = scaled_fonts[font_key][ch] + self.image = get_letter_surface(font_key, ch) self.rect = self.image.get_rect().move(pos) self.direction = ( Scaling.factor * (1_000 - randrange(2_000)), diff --git a/tests/test_enemies.py b/tests/test_enemies.py index 315de88..ed114ae 100644 --- a/tests/test_enemies.py +++ b/tests/test_enemies.py @@ -1,19 +1,28 @@ import os import unittest +import pygame from pathlib import Path -from enemies.enemies import EnemySprite, Enemies +from enemies.enemies import EnemyBall, Enemies +from display import Scaling from text import Fonts -class TestEnemySprite(unittest.TestCase): +class TestEnemyBall(unittest.TestCase): + def setUp(self): + Fonts.load_fonts(os.path.join( + Path(__file__).parent.parent.resolve(), + "src", + "sliceitoff")) + def test_can_create(self): - enemy = EnemySprite() + enemy = EnemyBall() self.assertNotEqual(None, enemy) class TestEnemies(unittest.TestCase): def setUp(self): + Scaling.update_scaling((640,400)) Fonts.load_fonts(os.path.join( Path(__file__).parent.parent.resolve(), "src", @@ -30,4 +39,9 @@ class TestEnemies(unittest.TestCase): def test_update_notcrashing(self): enemies = Enemies(count = 6) for _ in range(10000): - enemies.update(dt=100) + enemies.update( + dt=100, + field_rects=[ + Scaling.active, + pygame.Rect(800,0,200,200) + ]) -- cgit v1.2.3