Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

58 create 3d list to store bytesprites #60

Merged
merged 6 commits into from
Jul 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
JeanAEckelberg marked this conversation as resolved.
Show resolved Hide resolved
"""
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