Skip to content

Commit

Permalink
58 create 3d list to store bytesprites (#60)
Browse files Browse the repository at this point in the history
* Added functions to calculate logic and a data structure to store it all
  • Loading branch information
JeanAEckelberg authored Jul 1, 2023
1 parent 7ba56e8 commit 3c09fc3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
1 change: 1 addition & 0 deletions Visualiser2/bytesprites/bytesprite.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ByteSprite(pyg.sprite.Sprite):
__frame_index: int # Selects the sprite from the spritesheet to be used. Used for animation
__config: Config = Config()

# make sure that all inherited classes constructors only take screen as an parameter
def __init__(self, screen: pyg.Surface, filename: str, num_of_states: int, colorkey: pyg.Color | None = None,
object_type: int = 0, layer: int = 0, top_left: Vector = Vector(0, 0)):
# Add implementation here for selecting the sprite sheet to use
Expand Down
65 changes: 63 additions & 2 deletions Visualiser2/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pygame

from Visualiser2.adapter import Adapter
from Visualiser2.bytesprites.bytesprite import ByteSprite
from Visualiser2.config import Config
from Visualiser2.utils.log_reader import logs_to_dict
from game.utils.vector import Vector
Expand All @@ -25,11 +26,12 @@ def __init__(self):
self.simple_font = pygame.font.Font(None, 50)

self.tick: int = 0
self.bytesprites = pygame.sprite.Group()
self.bytesprite_templates = pygame.sprite.Group()
self.bytesprite_map: [[[ByteSprite]]] = list()

def load(self):
self.turn_logs = logs_to_dict()
self.bytesprites = self.adapter.populate_bytesprites()
self.bytesprite_templates = self.adapter.populate_bytesprites()

def prerender(self):
self.screen.fill(self.config.BACKGROUND_COLOR)
Expand All @@ -38,16 +40,75 @@ def prerender(self):
def render(self):
if self.tick % self.config.NUMBER_OF_FRAMES_PER_TURN == 0:
# NEXT TURN
self.recalc_animation(self.turn_logs[f'turn_{self.tick // self.config.NUMBER_OF_FRAMES_PER_TURN + 1:04d}'])
self.adapter.recalc_animation(
self.turn_logs[f'turn_{self.tick // self.config.NUMBER_OF_FRAMES_PER_TURN + 1:04d}'])
else:
# NEXT ANIMATION FRAME
self.continue_animation()
self.adapter.continue_animation()

self.adapter.render()
pygame.display.flip()
self.tick += 1

def recalc_animation(self, turn_data: dict) -> None:
"""
Determine what bytesprites are needed at which location and calls logic to determine active spritesheet and render
:param turn_data: A dictionary of all the turn data for current turn
:return: None
"""
game_map: [[dict]] = turn_data['game_board']['game_map']
# Iterate on each row on the game map
row: list
for y, row in enumerate(game_map):
# Add rows to bytesprite_map if needed
if len(self.bytesprite_map) < y + 1:
self.bytesprite_map.append(list())
# Iterate on each tile in the row
tile: dict
for x, tile in enumerate(row):
# Add tiles to row if needed
if len(self.bytesprite_map[y]) < x + 1:
self.bytesprite_map[y].append(list())
# Render layers on tile
temp_tile: dict | None = tile
z: int = 0
while temp_tile is not None:
# Add layers if needed
if len(self.bytesprite_map[y][x]) < z + 1:
self.bytesprite_map[y][x].append(None)

# Create or replace bytesprite at current tile on this current layer
if self.bytesprite_map[y][x][z] is None or self.bytesprite_map[y][x][z].object_type != temp_tile[
'object_type']:
sprite_class: ByteSprite | None = next(t for t in self.bytesprite_templates.sprites() if
isinstance(t, ByteSprite) and t.object_type == temp_tile[
'object_type'])
# Check that a bytesprite template exists for current object type
if sprite_class is None:
raise ValueError(
f'Must provide a bytesprite for each object type! Missing object_type: {temp_tile["object_type"]}')

# Instantiate a new bytesprite on current layer
self.bytesprite_map[y][x][z] = sprite_class.__class__(self.screen)

# Call render logic on bytesprite
self.bytesprite_map[y][x][z].update(temp_tile, z, Vector(y=y, x=x))
# increase iteration
temp_tile = temp_tile.get('occupied_by')
z += 1

# clean up additional layers
while len(self.bytesprite_map[y][x]) > z:
self.bytesprite_map[y][x].pop()

def continue_animation(self) -> None:
row: list
tile: list
sprite: ByteSprite
[[[sprite.set_image_and_render() for sprite in tile] for tile in row] for row in self.bytesprite_map]

def postrender(self):
self.adapter.clean_up()
self.clock.tick(self.config.FRAME_RATE)
Expand Down

0 comments on commit 3c09fc3

Please sign in to comment.