158 lines
6.9 KiB
Python
158 lines
6.9 KiB
Python
import json
|
|
|
|
import pygame
|
|
|
|
from src.entities.Interactable import Interactable
|
|
from src.game.TerrainTile import TerrainTile
|
|
from src.game.Screen import Locations
|
|
|
|
from src.entities.Entity import Entity
|
|
from src.entities.Pickupable import Pickupable
|
|
from src.entities.Statistics import Statistics
|
|
|
|
# TODO: Map should determine entities' position
|
|
class Map:
|
|
def __init__(self, filename, screen):
|
|
# TODO: Should map be self-aware of its own loacation?
|
|
self.screen = screen
|
|
# tekstowa macierz terenów
|
|
self.terrain = []
|
|
# tereny bez kolizji
|
|
self.terrainTilesList = []
|
|
# grupa objektów kolizyjnych (tereny kolizyjne i entities)
|
|
self.collidables = pygame.sprite.Group()
|
|
# lista wszystkich entity
|
|
self.entities = []
|
|
|
|
with open(filename, 'rt') as f:
|
|
for line in f:
|
|
self.terrain.append(line)
|
|
|
|
self.tileSize = int(self.screen.mapSize/20)
|
|
|
|
self.tileWidth = len(self.terrain[0])
|
|
self.tileHeight = len(self.terrain)
|
|
self.width = self.tileWidth * self.tileSize
|
|
self.height = self.tileHeight * self.tileSize
|
|
|
|
self.terrainDraw()
|
|
|
|
for entity in self.loadEntities(filename):
|
|
self.addEntity(entity)
|
|
|
|
# Returns a list of entities loaded from mapfile
|
|
def loadEntities(self, mapFileName):
|
|
mapFile = mapFileName.split('.txt')[0]
|
|
entitiesFilePath = mapFile + "Entities.json"
|
|
actualEntities = []
|
|
with open(entitiesFilePath, 'rt') as file:
|
|
entityListJson = json.loads(file.read())
|
|
for entity in entityListJson:
|
|
try:
|
|
# Creates a pickupable object
|
|
if entity["isPickupable"]:
|
|
actualEntities.append(Pickupable(entity["name"] + ".png",
|
|
self.tileSize,
|
|
(entity["position"]["x"] * self.tileSize, entity["position"]["y"] * self.tileSize),
|
|
Statistics(entity["effect"]["hp"],
|
|
entity["effect"]["hunger"],
|
|
entity["effect"]["thirst"],
|
|
entity["effect"]["stamina"])))
|
|
# Creates an interactable object
|
|
elif "effect" in entity:
|
|
actualEntities.append(Interactable(entity["name"] + ".png",
|
|
self.tileSize,
|
|
(entity["position"]["x"] * self.tileSize,
|
|
entity["position"]["y"] * self.tileSize),
|
|
Statistics(entity["effect"]["hp"],
|
|
entity["effect"]["hunger"],
|
|
entity["effect"]["thirst"],
|
|
entity["effect"]["stamina"])))
|
|
# Creates plain entity
|
|
else:
|
|
actualEntities.append(Entity(entity["name"] + ".png",
|
|
self.tileSize,
|
|
(entity["position"]["x"] * self.tileSize, entity["position"]["y"] * self.tileSize)))
|
|
except KeyError:
|
|
print("Failed to load entity " + entity)
|
|
return actualEntities
|
|
|
|
def terrainDraw(self):
|
|
for row, tiles in enumerate(self.terrain):
|
|
for col, tile in enumerate(tiles):
|
|
if tile == 's':
|
|
object = TerrainTile(col, row, 'sand.png', self.tileSize, 15)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.terrainTilesList.append(object)
|
|
elif tile == ',':
|
|
object = TerrainTile(col, row, 'floor.png', self.tileSize, 0)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.terrainTilesList.append(object)
|
|
elif tile == '.':
|
|
object = TerrainTile(col, row, 'grass.png', self.tileSize, 10)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.terrainTilesList.append(object)
|
|
elif tile == 'c':
|
|
object = TerrainTile(col, row, 'clay.png', self.tileSize, 20)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.terrainTilesList.append(object)
|
|
elif tile == 'x':
|
|
object = TerrainTile(col, row, 'water.png', self.tileSize, 0)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.collidables.add(object)
|
|
elif tile == 'w':
|
|
object = TerrainTile(col, row, 'wall.png', self.tileSize, 0)
|
|
self.screen.draw(object, Locations.MAP, 0, 0)
|
|
self.collidables.add(object)
|
|
|
|
def getEntityOnCoord(self, coord):
|
|
result = None
|
|
for entity in self.entities:
|
|
if entity.rect.x == coord[0] and entity.rect.y == coord[1]:
|
|
result = entity
|
|
return result
|
|
|
|
# W przypadku podania kordynatów playera, powinno zwrócić teren na którym jest player
|
|
def getTileOnCoord_old(self, coord):
|
|
result = None
|
|
for tile in self.terrainTilesList:
|
|
if tile.rect.x == coord[0] and tile.rect.y == coord[1]:
|
|
result = tile
|
|
return result
|
|
|
|
|
|
def getTileOnCoord(self, coord):
|
|
result = None
|
|
for tile in self.terrainTilesList:
|
|
if tile.rect.collidepoint(coord[0], coord[1]):
|
|
result = tile
|
|
break
|
|
return result
|
|
|
|
# TODO: REMOVE DONT ADD
|
|
def addEntity(self, entity, DONTADD=False):
|
|
# TODO: This method should set entities coords
|
|
self.screen.draw(entity, Locations.MAP, 0, 0)
|
|
# dodajemy bo wszystkie entity są kolizyjne
|
|
self.collidables.add(entity)
|
|
if not DONTADD:
|
|
self.entities.append(entity)
|
|
|
|
# Usuwa entity lub teren z mapy
|
|
def removeSpriteFromMap(self, sprite):
|
|
if self.collidables.has(sprite):
|
|
self.collidables.remove(sprite)
|
|
if sprite in self.entities:
|
|
self.entities.remove(sprite)
|
|
if sprite in self.terrainTilesList:
|
|
self.terrainTilesList.remove(sprite)
|
|
# TODO: Suspicious?
|
|
self.screen.removeSprite(sprite)
|
|
|
|
# add object to map.collidables list to be collidable
|
|
def collision(self, x, y):
|
|
for b in self.collidables:
|
|
if b.rect.x == x and b.rect.y == y:
|
|
return True
|
|
return False
|