revised some code
This commit is contained in:
parent
5adde7b48d
commit
9fe7846f1b
|
@ -1,3 +1,3 @@
|
||||||
log.txt
|
*.log
|
||||||
ideas.md
|
ideas.md
|
||||||
__pycache__/
|
__pycache__/
|
|
@ -15,7 +15,7 @@ class NA:
|
||||||
|
|
||||||
Action = Move | Idle | NA
|
Action = Move | Idle | NA
|
||||||
|
|
||||||
action_timing = {
|
ACTION_TIMING = {
|
||||||
Move: 50,
|
Move: 50,
|
||||||
Idle: 10,
|
Idle: 10,
|
||||||
NA: 1
|
NA: 1
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from enum import Enum
|
|
||||||
from actions import Action, Idle, NA
|
from actions import Action, Idle, NA
|
||||||
|
|
||||||
class Entity():
|
class Entity():
|
||||||
|
@ -7,16 +6,16 @@ class Entity():
|
||||||
class Item(Entity):
|
class Item(Entity):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Character(Entity):
|
class Creature(Entity):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.speed = 1
|
self.speed = 1
|
||||||
self.action: Action = NA()
|
self.action: Action = NA()
|
||||||
|
|
||||||
class Player(Character):
|
class Player(Creature):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
class Enemy(Character):
|
class Enemy(Creature):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
|
28
floor.py
28
floor.py
|
@ -1,35 +1,38 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from entity import Character, Entity, Item
|
from entity import Creature, Item
|
||||||
|
|
||||||
class TileType(Enum):
|
class TileType(Enum):
|
||||||
|
"""
|
||||||
|
An enum who has the different types of tiles
|
||||||
|
"""
|
||||||
WALL = 1
|
WALL = 1
|
||||||
AIR = 2
|
AIR = 2
|
||||||
|
|
||||||
class EntityMap:
|
class EntityMap:
|
||||||
"""
|
"""
|
||||||
Class that stores entities in an special way in order to be able to reach in O(1) the values
|
A class that stores entities in an special way in order to be able to reach in O(1) the values
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.items = {} # K: Position V: List(Item)
|
self.items = {} # K: Position V: List(Item)
|
||||||
self.pos_creatures = {} # K: Position V: Creature
|
self.pos_creatures = {} # K: Position V: Creature
|
||||||
self.creatures_pos = {} # K: Creature V: Position
|
self.creatures_pos = {} # K: Creature V: Position
|
||||||
|
|
||||||
def get_item(self, x, y):
|
def get_item(self, x, y) -> Item | None:
|
||||||
return self.items.get((x, y))
|
return self.items.get((x, y))
|
||||||
|
|
||||||
def get_creature(self, x, y):
|
def get_creature(self, x, y) -> Item | None:
|
||||||
return self.pos_creatures.get((x, y))
|
return self.pos_creatures.get((x, y))
|
||||||
|
|
||||||
def get_creature_position(self, creature: Character):
|
def get_creature_position(self, creature: Creature) -> Tuple[int, int]:
|
||||||
return self.creatures_pos.get(creature)
|
return self.creatures_pos[creature]
|
||||||
|
|
||||||
def add_item(self, x, y, item: Item):
|
def add_item(self, x, y, item: Item) -> None:
|
||||||
if (x, y) not in self.items:
|
if (x, y) not in self.items:
|
||||||
self.items[(x, y)] = []
|
self.items[(x, y)] = []
|
||||||
self.items[(x, y)].append(item)
|
self.items[(x, y)].append(item)
|
||||||
|
|
||||||
def add_creature(self, x, y, creature: Character) -> bool:
|
def add_creature(self, x, y, creature: Creature) -> bool:
|
||||||
if (x, y) in self.pos_creatures:
|
if (x, y) in self.pos_creatures:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -37,24 +40,27 @@ class EntityMap:
|
||||||
self.creatures_pos[creature] = (x, y)
|
self.creatures_pos[creature] = (x, y)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pop_creature_pos(self, x, y) -> Character | None:
|
def pop_creature_pos(self, x, y) -> Creature | None:
|
||||||
if (x, y) in self.pos_creatures:
|
if (x, y) in self.pos_creatures:
|
||||||
creature = self.pos_creatures.pop((x, y))
|
creature = self.pos_creatures.pop((x, y))
|
||||||
self.creatures_pos.pop(creature)
|
self.creatures_pos.pop(creature)
|
||||||
return creature
|
return creature
|
||||||
|
|
||||||
def pop_creature_ref(self, creature: Character) -> Tuple[int, int] | None:
|
def pop_creature_ref(self, creature: Creature) -> Tuple[int, int] | None:
|
||||||
if creature in self.creatures_pos:
|
if creature in self.creatures_pos:
|
||||||
pos = self.creatures_pos.pop(creature)
|
pos = self.creatures_pos.pop(creature)
|
||||||
self.pos_creatures.pop(pos)
|
self.pos_creatures.pop(pos)
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
class Floor:
|
class Floor:
|
||||||
|
"""
|
||||||
|
A class that represents a specific floor of the dungeon
|
||||||
|
"""
|
||||||
def __init__(self, width, height):
|
def __init__(self, width, height):
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.grid = [[TileType.AIR] * height] * width
|
self.grid = [[TileType.AIR] * height] * width
|
||||||
self.entities = EntityMap()
|
self.entities = EntityMap()
|
||||||
|
|
||||||
def get_tile(self, x, y):
|
def get_tile(self, x, y) -> TileType:
|
||||||
return self.grid[x][y]
|
return self.grid[x][y]
|
||||||
|
|
85
game.py
85
game.py
|
@ -1,7 +1,8 @@
|
||||||
from terminal import Terminal
|
from terminal import Terminal
|
||||||
from entity import Character, Player, Item, Enemy
|
from entity import Creature, Player, Enemy
|
||||||
from actions import *
|
from actions import *
|
||||||
from floor import Floor, TileType
|
from floor import Floor, TileType
|
||||||
|
import sys
|
||||||
|
|
||||||
TEXTURES = {
|
TEXTURES = {
|
||||||
TileType.WALL: '#',
|
TileType.WALL: '#',
|
||||||
|
@ -17,34 +18,52 @@ class Game:
|
||||||
self.should_exit = False
|
self.should_exit = False
|
||||||
self.ticks = 0
|
self.ticks = 0
|
||||||
self.schedule = {}
|
self.schedule = {}
|
||||||
|
self.redirect_io('prints.log', 'errors.log')
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.restore_io()
|
||||||
|
|
||||||
|
def restore_io(self) -> None:
|
||||||
|
sys.stdout = self.stdout_original
|
||||||
|
sys.stderr = self.stderr_original
|
||||||
|
self.stdout_file.close()
|
||||||
|
self.stderr_file.close()
|
||||||
|
|
||||||
|
def redirect_io(self, stdout_file, stderr_file) -> None:
|
||||||
|
self.stdout_original = sys.stdout
|
||||||
|
self.stderr_original = sys.stderr
|
||||||
|
self.stdout_file = open(stdout_file, 'w')
|
||||||
|
self.stderr_file = open(stderr_file, 'w')
|
||||||
|
sys.stdout = self.stdout_file
|
||||||
|
sys.stderr = self.stderr_file
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""
|
"""
|
||||||
Runs the game
|
Runs the game
|
||||||
"""
|
"""
|
||||||
self.instance_character(3, 3, self.player)
|
self.instance_creature(3, 3, self.player)
|
||||||
self.render()
|
self.render()
|
||||||
while not self.should_exit:
|
while not self.should_exit:
|
||||||
action_was_performed = self.step()
|
self.step()
|
||||||
if action_was_performed:
|
if self.action_was_performed:
|
||||||
self.render()
|
self.render()
|
||||||
|
|
||||||
def instance_character(self, x, y, character: Character):
|
def instance_creature(self, x, y, creature: Creature):
|
||||||
"""
|
"""
|
||||||
Instances a character in space and time
|
Instances a creature in space and time
|
||||||
"""
|
"""
|
||||||
self.floor.entities.add_creature(x, y, character)
|
self.floor.entities.add_creature(x, y, creature)
|
||||||
self.reschedule(character)
|
self.reschedule(creature)
|
||||||
|
|
||||||
def reschedule(self, character: Character):
|
def reschedule(self, creature: Creature):
|
||||||
"""
|
"""
|
||||||
Calculates turns for the next avaliable ticks untill player turn
|
Calculates the ticks in which the creature will perform its next action
|
||||||
"""
|
"""
|
||||||
time = (action_timing[character.action.__class__] // character.speed) + self.ticks
|
time = (ACTION_TIMING[creature.action.__class__] // creature.speed) + self.ticks
|
||||||
if self.schedule.get(time):
|
if self.schedule.get(time):
|
||||||
self.schedule[time].append(character)
|
self.schedule[time].append(creature)
|
||||||
else:
|
else:
|
||||||
self.schedule[time] = [character]
|
self.schedule[time] = [creature]
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
"""
|
"""
|
||||||
|
@ -61,38 +80,34 @@ class Game:
|
||||||
|
|
||||||
def step(self):
|
def step(self):
|
||||||
"""
|
"""
|
||||||
Perfoms a step in the game. Returns True if any creature did an action, and False otherwise
|
Perfoms a step in the game. Sets the `action_was_performed` attribute accordingly
|
||||||
"""
|
"""
|
||||||
creaturas = self.schedule.get(self.ticks)
|
self.action_was_performed = False
|
||||||
if creaturas:
|
creatures = self.schedule.get(self.ticks)
|
||||||
for creatura in creaturas:
|
if creatures:
|
||||||
if isinstance(creatura, Player):
|
for creature in creatures:
|
||||||
self.get_event()
|
if isinstance(creature, Player):
|
||||||
elif isinstance(creatura, Enemy):
|
self.input_event()
|
||||||
creatura.calculate_action()
|
elif isinstance(creature, Enemy):
|
||||||
self.reschedule(creatura)
|
creature.calculate_action()
|
||||||
self.perform(creatura)
|
self.reschedule(creature)
|
||||||
|
self.perform(creature)
|
||||||
self.schedule.pop(self.ticks)
|
self.schedule.pop(self.ticks)
|
||||||
|
self.action_was_performed = True
|
||||||
self.ticks += 1
|
self.ticks += 1
|
||||||
return True
|
|
||||||
else:
|
|
||||||
self.ticks += 1
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
def perform(self, creature: Creature):
|
||||||
def perform(self, character: Character):
|
|
||||||
"""
|
"""
|
||||||
Performs an action for a creature
|
Performs an action for a creature
|
||||||
"""
|
"""
|
||||||
if isinstance(character.action, Move):
|
if isinstance(creature.action, Move):
|
||||||
pos = self.floor.entities.pop_creature_ref(character)
|
pos = self.floor.entities.pop_creature_ref(creature)
|
||||||
if pos:
|
if pos:
|
||||||
self.floor.entities.add_creature(pos[0] + character.action.x, pos[1] + character.action.y, character)
|
self.floor.entities.add_creature(pos[0] + creature.action.x, pos[1] + creature.action.y, creature)
|
||||||
|
|
||||||
|
def input_event(self):
|
||||||
def get_event(self):
|
|
||||||
"""
|
"""
|
||||||
Waits for a game event to happen
|
Waits for a game event to happen, and behaves accordingly
|
||||||
"""
|
"""
|
||||||
keycode = self.term.get_key()
|
keycode = self.term.get_key()
|
||||||
if keycode == "q":
|
if keycode == "q":
|
||||||
|
|
Loading…
Reference in New Issue