From 42e9eb9e8b5c37a8f48971d5389921d8a89ec44d Mon Sep 17 00:00:00 2001 From: s475275 Date: Sun, 19 Mar 2023 20:25:07 +0100 Subject: [PATCH] Klasy dla jednostek, warstwy renderowania --- res/map.txt | 2 +- src/main.py | 153 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 93 insertions(+), 62 deletions(-) diff --git a/res/map.txt b/res/map.txt index bfa98fc..795a6cf 100644 --- a/res/map.txt +++ b/res/map.txt @@ -3,7 +3,7 @@ LRRRRRRRRRRRRRRRRR---R--- ---R------R------R---R--- RRRR------RRRRRRRRRRRR--- R--R-------------R------- -R--RRRRRRRRRRRRRRR------- +R--RRRRRRRRRRRRRRRH------ R--R---R---R-----R------- R--R---R---R-----RRRRRRR- R--R-------------R------- diff --git a/src/main.py b/src/main.py index 0346b06..571d486 100644 --- a/src/main.py +++ b/src/main.py @@ -2,44 +2,107 @@ from pathlib import Path import pygame as pg from random import randint + +class Entity: + def __init__(self, state, position, tile): + self.state = state + self.position = position + self.tile = tile + + def move(self, move_vector): + raise NotImplementedError() + + +class Agent(Entity): + def move(self, move_vector): + proposed_pos = self.position + move_vector + move_valid = True + + if proposed_pos != self.state.landfill_pos and proposed_pos not in self.state.roads_pos: + move_valid = False + if proposed_pos.x < 0 or proposed_pos.x >= self.state.world_limits.x: + move_valid = False + if proposed_pos.y < 0 or proposed_pos.y >= self.state.world_limits.y: + move_valid = False + + if move_valid: + self.position = proposed_pos + + class SimulationState: def __init__(self): - self.landfill_pos = pg.Vector2(0, 0) + self.landfill_pos = [] self.roads_pos = [] self.houses_pos = [] map_path = Path("../res/map.txt") with open(map_path, "r") as map_file: - map_data = map_file.read().replace('\n', '') - for y in range(0, 13): - for x in range(0, 25): - pos = x + 25*y - tile = map_data[pos] + map_data = map_file.readlines() + max_x = len(map_data[0].replace('\n', '')) + max_y = len(map_data) + for y in range(0, max_y): + for x in range(0, max_x): + tile = map_data[y].replace('\n', '')[x] if tile == "L": - self.landfill_pos = pg.Vector2(x, y) + self.landfill_pos.append(pg.Vector2(x, y)) if tile == "R": self.roads_pos.append(pg.Vector2(x, y)) if tile == "H": self.houses_pos.append(pg.Vector2(x, y)) + self.world_limits = pg.Vector2(max_x, max_y) - self.agent_pos = self.landfill_pos + self.entities = [Agent(self, self.landfill_pos[0], pg.Vector2(2, 0))] - self.world_limits = pg.Vector2(25, 13) + def update(self, move_agent): + for entity in self.entities: + entity.move(move_agent) - def updateAgent(self, move_agent): - proposed_pos = self.agent_pos + move_agent - move_valid = True - if proposed_pos != self.landfill_pos and proposed_pos not in self.roads_pos: - move_valid = False - if proposed_pos.x < 0 or proposed_pos.x >= self.world_limits.x: - move_valid = False - if proposed_pos.y < 0 or proposed_pos.y >= self.world_limits.y: - move_valid = False +class Layer: + def __init__(self, sim, texture_file): + self.sim = sim + self.texture_atlas = pg.image.load(texture_file) - if move_valid: - self.agent_pos = proposed_pos + def renderTile(self, surface, position, tile): + # pozycja na ekranie + sprite_pos = position.elementwise() * self.sim.cell_size + + # tekstura + pos_in_atlas = tile.elementwise() * self.sim.cell_size + texture = pg.Rect(int(pos_in_atlas.x), + int(pos_in_atlas.y), + self.sim.cell_size.x, + self.sim.cell_size.y) + + # render + surface.blit(self.texture_atlas, sprite_pos, texture) + + def render(self, surface): + raise NotImplementedError() + + +class EntityLayer(Layer): + def __init__(self, sim, texture_file, simulation_state, entities): + super().__init__(sim, texture_file) + self.simulation_state = simulation_state + self.entities = entities + + def render(self, surface): + for entity in self.entities: + self.renderTile(surface, entity.position, entity.tile) + + +class StructureLayer(Layer): + def __init__(self, sim, texture_file, simulation_state, structures_pos, tile): + super().__init__(sim, texture_file) + self.simulation_state = simulation_state + self.structures_pos = structures_pos + self.tile = tile + + def render(self, surface): + for position in self.structures_pos: + self.renderTile(surface, position, self.tile) class Interface: @@ -50,10 +113,13 @@ class Interface: self.simulation_state = SimulationState() self.move_agent = pg.Vector2(0, 0) - # tilesy + # rendering self.cell_size = pg.Vector2(64, 64) - textures_path = Path("../res/tiles.png") - self.textures = pg.image.load(textures_path) + texture_file = Path("../res/tiles.png") + self.layers = [StructureLayer(self, texture_file, self.simulation_state, self.simulation_state.landfill_pos, pg.Vector2(3, 0)), + StructureLayer(self, texture_file, self.simulation_state, self.simulation_state.roads_pos, pg.Vector2(0, 0)), + StructureLayer(self, texture_file, self.simulation_state, self.simulation_state.houses_pos, pg.Vector2(1, 0)), + EntityLayer(self, texture_file, self.simulation_state, self.simulation_state.entities)] # okno pg.display.set_caption("Inteligentna śmieciarka") @@ -97,7 +163,7 @@ class Interface: self.move_agent = moves[randint(0,3)] def update(self): - self.simulation_state.updateAgent(self.move_agent) + self.simulation_state.update(self.move_agent) def render(self): if not self.debug_mode: @@ -105,43 +171,8 @@ class Interface: else: self.window.fill((68, 8, 0)) - # render wysypiska - landfill_pos = self.simulation_state.landfill_pos.elementwise() * self.cell_size - landfill_texture_pos = pg.Vector2(3, 0).elementwise() * self.cell_size - landfill_texture = pg.Rect(int(landfill_texture_pos.x), - int(landfill_texture_pos.y), - int(self.cell_size.x), - int(self.cell_size.y)) - self.window.blit(self.textures, landfill_pos, landfill_texture) - - # render dróg - for road_pos in self.simulation_state.roads_pos: - adjusted_road_pos = road_pos.elementwise() * self.cell_size - road_texture_pos = pg.Vector2(0, 0).elementwise() * self.cell_size - road_texture = pg.Rect(int(road_texture_pos.x), - int(road_texture_pos.y), - int(self.cell_size.x), - int(self.cell_size.y)) - self.window.blit(self.textures, adjusted_road_pos, road_texture) - - # render domów - for house_pos in self.simulation_state.houses_pos: - adjusted_house_pos = house_pos.elementwise() * self.cell_size - house_texture_pos = pg.Vector2(1, 0).elementwise() * self.cell_size - house_texture = pg.Rect(int(house_texture_pos.x), - int(house_texture_pos.y), - int(self.cell_size.x), - int(self.cell_size.y)) - self.window.blit(self.textures, adjusted_house_pos, house_texture) - - # render agenta - agent_pos = self.simulation_state.agent_pos.elementwise() * self.cell_size - agent_texture_pos = pg.Vector2(2, 0).elementwise() * self.cell_size - agent_texture = pg.Rect(int(agent_texture_pos.x), - int(agent_texture_pos.y), - int(self.cell_size.x), - int(self.cell_size.y)) - self.window.blit(self.textures, agent_pos, agent_texture) + for layer in self.layers: + layer.render(self.window) pg.display.update()