Merge pull request 'development' (#11) from development into master

Reviewed-on: #11
This commit is contained in:
Jakub Klupieć 2021-06-03 15:42:55 +02:00
commit 342a74c1d8
21 changed files with 364 additions and 31 deletions

100
data.txt Normal file
View File

@ -0,0 +1,100 @@
{"weight": 9, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 11, "eatable": true, "toughness": 0, "resource": "wood"}
{"weight": 5, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 11, "eatable": true, "toughness": 0, "resource": "wood"}
{"weight": 7, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 7, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 5, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 5, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 1, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 2, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 4, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 1, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 3, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 6, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 7, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 1, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 6, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 2, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 10, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 6, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 11, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 2, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 3, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 6, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 8, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 6, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 9, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 9, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 11, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 4, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 4, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 4, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 1, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 5, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 3, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 0, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 10, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 9, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 4, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 10, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 10, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 11, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 8, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 7, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 1, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 11, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 11, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 3, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 2, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 4, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 6, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 2, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 10, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 0, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 10, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 9, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 2, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 8, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 9, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 6, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 5, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 4, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 0, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 8, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 2, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 2, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 11, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 0, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 9, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 0, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 5, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 3, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 0, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 7, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 4, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 4, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 3, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 8, "eatable": false, "toughness": 3, "resource": "wood"}
{"weight": 10, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 3, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 3, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 1, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 1, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 5, "eatable": true, "toughness": 1, "resource": "food"}
{"weight": 5, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 9, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 3, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 6, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 7, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 9, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 10, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 9, "eatable": false, "toughness": 0, "resource": "wood"}
{"weight": 11, "eatable": true, "toughness": 0, "resource": "wood"}
{"weight": 10, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 5, "eatable": true, "toughness": 3, "resource": "food"}
{"weight": 10, "eatable": false, "toughness": 1, "resource": "wood"}
{"weight": 10, "eatable": true, "toughness": 2, "resource": "food"}
{"weight": 5, "eatable": true, "toughness": 0, "resource": "water"}
{"weight": 0, "eatable": false, "toughness": 2, "resource": "wood"}
{"weight": 10, "eatable": false, "toughness": 2, "resource": "wood"}

28
generate_test_data.py Normal file
View File

@ -0,0 +1,28 @@
import random
def generate_data():
f = open("data.txt", "w")
for i in range(100):
weight = random.randint(0, 11)
eatable = bool(random.randint(0, 1))
toughness = random.randint(0, 3)
f.write('{')
f.write(
f'"weight": {weight}, "eatable": {str(eatable).lower()}, "toughness": {toughness}, "resource": "{get_resource_type(weight, eatable, toughness)}"')
f.write('}')
f.write('\n')
f.close()
def get_resource_type(weight, eatable, toughness):
if weight > 10 or eatable is False:
return "wood"
if toughness < 1:
return "water"
return "food"
generate_data()

View File

@ -1,3 +1,5 @@
import random
import pygame import pygame
from settings import SCREEN_WIDTH, SCREEN_HEIGHT from settings import SCREEN_WIDTH, SCREEN_HEIGHT

View File

@ -1,5 +1,5 @@
class InventoryComponent: class InventoryComponent:
def __init__(self, maxitems=10): def __init__(self, maxitems=100):
self.maxitems = maxitems self.maxitems = maxitems
self.items = {} self.items = {}

View File

@ -1,5 +1,6 @@
class PathfindingComponent: class PathfindingComponent:
def __init__(self, target_pos): def __init__(self, target_pos, searching_for_resource=False):
self.target_grid_pos = (int(target_pos[0] / 32), int(target_pos[1] / 32)) self.target_grid_pos = (int(target_pos[0] / 32), int(target_pos[1] / 32))
self.searching_for_resource = False
self.current_target = None self.current_target = None
self.path = None self.path = None

View File

@ -1,3 +1,29 @@
import random
from survival.generators.resource_type import ResourceType
class ResourceComponent: class ResourceComponent:
def __init__(self, resource_type): def __init__(self, resource_type):
self.resource_type = resource_type self.resource_type = resource_type
w, e, t = self.generate_attributes(resource_type)
self.weight = w
self.eatable = e
self.toughness = t
@staticmethod
def generate_attributes(resource_type):
if resource_type == ResourceType.WOOD:
weight = random.randint(10, 15)
eatable = False
toughness = random.randint(10, 15)
elif resource_type == ResourceType.WATER:
weight = random.randint(1, 2)
eatable = True
toughness = 0
else:
weight = random.randint(1, 7)
eatable = True
toughness = random.randint(2, 5)
return weight, eatable, toughness

48
survival/decision_tree.py Normal file
View File

@ -0,0 +1,48 @@
import json
import os
from sklearn import tree
from sklearn.feature_extraction import DictVectorizer
from survival.components.resource_component import ResourceComponent
class DecisionTree:
def __init__(self):
self.clf = None
self.vec = None
def build(self, depth: int):
path = os.path.join("..", "data.txt")
samples = list()
results = list()
with open(path, "r") as training_file:
for sample in training_file:
sample, result = self.process_input(sample)
samples.append(sample)
results.append(result)
self.vec = DictVectorizer()
self.clf = tree.DecisionTreeClassifier(max_depth=depth)
self.clf = self.clf.fit(self.vec.fit_transform(samples).toarray(), results)
# print(tree.export_text(self.clf, feature_names=self.vec.get_feature_names()))
def predict_answer(self, resource: ResourceComponent):
params = {
"weight": resource.weight,
"eatable": resource.eatable,
"toughness": resource.toughness
}
return self.clf.predict(self.vec.transform(params).toarray())
@staticmethod
def process_input(line):
data = json.loads(line.strip())
result = data['resource']
del data['resource']
sample = data
return sample, result

View File

View File

@ -6,6 +6,7 @@ from survival.components.movement_component import MovementComponent
from survival.components.position_component import PositionComponent from survival.components.position_component import PositionComponent
from survival.components.sprite_component import SpriteComponent from survival.components.sprite_component import SpriteComponent
from survival.components.time_component import TimeComponent from survival.components.time_component import TimeComponent
from survival.systems.automation_system import AutomationComponent
class PlayerGenerator: class PlayerGenerator:
@ -20,6 +21,7 @@ class PlayerGenerator:
world.add_component(player, InventoryComponent()) world.add_component(player, InventoryComponent())
camera_target = CameraTargetComponent(pos) camera_target = CameraTargetComponent(pos)
world.add_component(player, camera_target) world.add_component(player, camera_target)
world.add_component(player, AutomationComponent())
game_map.add_entity(player, pos) game_map.add_entity(player, pos)
sprite = SpriteComponent('stevenson.png') sprite = SpriteComponent('stevenson.png')
sprite.set_scale(1) sprite.set_scale(1)

View File

@ -1,26 +1,23 @@
import random import random
from enum import Enum
from survival import GameMap from survival import GameMap
from survival.components.OnCollisionComponent import OnCollisionComponent from survival.components.OnCollisionComponent import OnCollisionComponent
from survival.components.inventory_component import InventoryComponent from survival.components.inventory_component import InventoryComponent
from survival.components.position_component import PositionComponent from survival.components.position_component import PositionComponent
from survival.components.resource_component import ResourceComponent from survival.components.resource_component import ResourceComponent
from survival.components.sprite_component import SpriteComponent from survival.components.sprite_component import SpriteComponent
from survival.decision_tree import DecisionTree
from survival.esper import World from survival.esper import World
from survival.generators.resource_type import ResourceType
from survival.settings import RESOURCES_AMOUNT from survival.settings import RESOURCES_AMOUNT
class ResourceType(Enum):
FOOD = 1
WATER = 2
WOOD = 3
class ResourceGenerator: class ResourceGenerator:
def __init__(self, world, game_map): def __init__(self, world, game_map):
self.world = world self.world = world
self.map = game_map self.map = game_map
self.decision_tree = DecisionTree()
self.built_tree = self.decision_tree.build(10)
def generate_resources(self, player: int): def generate_resources(self, player: int):
for x in range(RESOURCES_AMOUNT): for x in range(RESOURCES_AMOUNT):
@ -37,7 +34,7 @@ class ResourceGenerator:
resource_type = random.choice(list(ResourceType)) resource_type = random.choice(list(ResourceType))
sprite = SpriteComponent(sprites[resource_type]) sprite = SpriteComponent(sprites[resource_type])
col = OnCollisionComponent() col = OnCollisionComponent()
col.addCallback(self.remove_resource, world=self.world, game_map=self.map, entity=obj, player=player) col.addCallback(self.remove_resource, world=self.world, game_map=self.map, resource_ent=obj, player=player, decision_tree=self.decision_tree)
self.world.add_component(obj, pos) self.world.add_component(obj, pos)
self.world.add_component(obj, sprite) self.world.add_component(obj, sprite)
self.world.add_component(obj, col) self.world.add_component(obj, col)
@ -51,10 +48,12 @@ class ResourceGenerator:
return free_pos return free_pos
@staticmethod @staticmethod
def remove_resource(world: World, game_map: GameMap, entity: int, player: int): def remove_resource(world: World, game_map: GameMap, resource_ent: int, player: int, decision_tree: DecisionTree):
pos = world.component_for_entity(entity, PositionComponent) pos = world.component_for_entity(resource_ent, PositionComponent)
resource = world.component_for_entity(entity, ResourceComponent) resource = world.component_for_entity(resource_ent, ResourceComponent)
inventory = world.component_for_entity(player, InventoryComponent) inventory = world.component_for_entity(player, InventoryComponent)
inventory.add_item(resource.resource_type, 1) answer = decision_tree.predict_answer(resource)
# print(answer)
inventory.add_item(ResourceType.get_from_string(answer), 1)
game_map.remove_entity(pos.grid_position) game_map.remove_entity(pos.grid_position)
world.delete_entity(entity, immediate=True) world.delete_entity(resource_ent, immediate=True)

View File

@ -0,0 +1,18 @@
from enum import Enum
class ResourceType(Enum):
FOOD = 1
WATER = 2
WOOD = 3
@staticmethod
def get_from_string(string):
if string == 'food':
return ResourceType.FOOD
elif string == 'water':
return ResourceType.WATER
elif string == 'wood':
return ResourceType.WOOD
else:
raise Exception("Unknown resource type")

View File

@ -76,3 +76,6 @@ class TileGenerator:
found_biome = TileGenerator.Biomes[0] found_biome = TileGenerator.Biomes[0]
return found_biome return found_biome
# {"weight": 2, "size": 3, "eatable": true, "resource": "food"}

View File

@ -1,5 +1,7 @@
from survival import esper from survival import esper
from survival.systems.automation_system import AutomationSystem
from survival.systems.camera_system import CameraSystem from survival.systems.camera_system import CameraSystem
from survival.systems.collection_system import ResourceCollectionSystem
from survival.systems.collision_system import CollisionSystem from survival.systems.collision_system import CollisionSystem
from survival.systems.direction_system import DirectionSystem from survival.systems.direction_system import DirectionSystem
from survival.systems.draw_system import DrawSystem from survival.systems.draw_system import DrawSystem
@ -13,13 +15,15 @@ class WorldGenerator:
def create_world(self, camera, game_map): def create_world(self, camera, game_map):
world = esper.World() world = esper.World()
world.add_processor(InputSystem(camera)) world.add_processor(InputSystem(camera, game_map))
world.add_processor(CameraSystem(camera)) world.add_processor(CameraSystem(camera))
world.add_processor(MovementSystem(game_map), priority=1) world.add_processor(MovementSystem(game_map), priority=2)
world.add_processor(CollisionSystem(game_map), priority=2) world.add_processor(CollisionSystem(game_map), priority=3)
world.add_processor(DrawSystem(camera)) world.add_processor(DrawSystem(camera))
world.add_processor(ResourceCollectionSystem(), priority=1)
world.add_processor(TimeSystem()) world.add_processor(TimeSystem())
world.add_processor(PathfindingMovementSystem(game_map), priority=3) world.add_processor(AutomationSystem(game_map))
world.add_processor(PathfindingMovementSystem(game_map), priority=4)
world.add_processor(DirectionSystem()) world.add_processor(DirectionSystem())
return world return world

View File

@ -4,7 +4,9 @@ from typing import Tuple, List
from survival import GameMap from survival import GameMap
from survival.components.position_component import PositionComponent from survival.components.position_component import PositionComponent
from survival.components.resource_component import ResourceComponent
from survival.enums import Direction from survival.enums import Direction
from survival.esper import World
class Action(Enum): class Action(Enum):
@ -38,7 +40,7 @@ def get_moved_position(position: Tuple[int, int], direction: Direction):
return position[0] + vector[0], position[1] + vector[1] return position[0] + vector[0], position[1] + vector[1]
def get_states(state: State, game_map: GameMap) -> List[Tuple[Action, State, int]]: def get_states(state: State, game_map: GameMap, world: World) -> List[Tuple[Action, State, int]]:
states = list() states = list()
states.append((Action.ROTATE_LEFT, State(state.position, state.direction.rotate_left(state.direction)), 1)) states.append((Action.ROTATE_LEFT, State(state.position, state.direction.rotate_left(state.direction)), 1))
@ -47,6 +49,10 @@ def get_states(state: State, game_map: GameMap) -> List[Tuple[Action, State, int
target_position = get_moved_position(state.position, state.direction) target_position = get_moved_position(state.position, state.direction)
if not game_map.is_colliding(target_position): if not game_map.is_colliding(target_position):
states.append((Action.MOVE, State(target_position, state.direction), game_map.get_cost(target_position))) states.append((Action.MOVE, State(target_position, state.direction), game_map.get_cost(target_position)))
elif game_map.get_entity(target_position) is not None:
ent = game_map.get_entity(target_position)
if world.has_component(ent, ResourceComponent):
states.append((Action.MOVE, State(target_position, state.direction), 3))
return states return states
@ -68,7 +74,7 @@ def heuristic(new_node: Node, goal: Tuple[int, int]):
return abs(new_node.state.position[0] - goal[0]) + abs(new_node.state.position[1] - goal[1]) return abs(new_node.state.position[0] - goal[0]) + abs(new_node.state.position[1] - goal[1])
def graph_search(game_map: GameMap, start: PositionComponent, goal: tuple): def graph_search(game_map: GameMap, start: PositionComponent, goal: tuple, world: World):
fringe = PriorityQueue() fringe = PriorityQueue()
explored = list() explored = list()
@ -97,7 +103,7 @@ def graph_search(game_map: GameMap, start: PositionComponent, goal: tuple):
explored_states.add((tuple(node.state.position), node.state.direction)) explored_states.add((tuple(node.state.position), node.state.direction))
# Get all possible states # Get all possible states
for state in get_states(node.state, game_map): for state in get_states(node.state, game_map, world):
sub_state = (tuple(state[1].position), state[1].direction) sub_state = (tuple(state[1].position), state[1].direction)
new_node = Node(state=state[1], new_node = Node(state=state[1],
parent=node, parent=node,

View File

@ -0,0 +1,62 @@
from survival import esper, GameMap
from survival.components.moving_component import MovingComponent
from survival.components.pathfinding_component import PathfindingComponent
from survival.components.position_component import PositionComponent
from survival.components.resource_component import ResourceComponent
class AutomationComponent:
pass
class AutomationSystem(esper.Processor):
def __init__(self, game_map: GameMap):
self.game_map = game_map
def process(self, dt):
for ent, (automation, pos) in self.world.get_components(AutomationComponent, PositionComponent):
if self.world.has_component(ent, PathfindingComponent):
continue
resource = self.detect_closest_resource(pos, ent)
if resource is None:
# TODO: Check if target position is not out of map bounds
self.world.add_component(ent, PathfindingComponent((pos.grid_position[0] * 32 + 64, pos.grid_position[1] * 32 + 64)))
# Move somewhere else
else:
target = self.world.component_for_entity(resource, PositionComponent).grid_position
self.world.add_component(ent, PathfindingComponent((target[0] * 32, target[1] * 32), True))
# Go collect target resource
def detect_closest_resource(self, position: PositionComponent, target_entity: int):
entity_position = position.grid_position
x_range = [entity_position[0] - 5, entity_position[0] + 5]
y_range = [entity_position[1] - 5, entity_position[1] + 5]
# Check if range is not out of map bounds
if x_range[0] < 0:
x_range[0] = 0
if x_range[1] >= self.game_map.width:
x_range[1] = self.game_map.width - 1
if y_range[0] < 0:
y_range[0] = 0
if y_range[1] >= self.game_map.height:
y_range[1] = self.game_map.height - 1
found_resource = [-1, 200000]
for y in range(y_range[0], y_range[1]):
for x in range(x_range[0], x_range[1]):
ent = self.game_map.get_entity([x, y])
if ent == target_entity:
continue
if ent is not None and self.world.has_component(ent, ResourceComponent):
res_position = self.world.component_for_entity(ent, PositionComponent).grid_position
distance = abs(entity_position[0] - res_position[0]) + abs(entity_position[1] - res_position[1])
if found_resource[1] > distance:
found_resource = [ent, distance]
if found_resource[0] == -1:
return None
else:
return found_resource[0]

View File

@ -0,0 +1,20 @@
from survival import esper
from survival.components.direction_component import DirectionChangeComponent
from survival.components.moving_component import MovingComponent
from survival.components.position_component import PositionComponent
from survival.graph_search import Action
from survival.systems.pathfinding_movement_system import CollectingResourceComponent
class ResourceCollectionSystem(esper.Processor):
def __init__(self):
pass
def process(self, dt):
for ent, (collect, pos) in self.world.get_components(CollectingResourceComponent, PositionComponent):
if self.world.has_component(ent, MovingComponent) or self.world.has_component(ent, DirectionChangeComponent):
continue
if collect.action == Action.MOVE:
self.world.remove_component(ent, CollectingResourceComponent)
self.world.add_component(ent, MovingComponent())

View File

@ -1,16 +1,18 @@
import pygame import pygame
from survival import esper from survival import esper, GameMap
from survival.components.direction_component import DirectionChangeComponent from survival.components.direction_component import DirectionChangeComponent
from survival.components.input_component import InputComponent from survival.components.input_component import InputComponent
from survival.components.moving_component import MovingComponent from survival.components.moving_component import MovingComponent
from survival.components.pathfinding_component import PathfindingComponent from survival.components.pathfinding_component import PathfindingComponent
from survival.components.position_component import PositionComponent from survival.components.position_component import PositionComponent
from survival.components.resource_component import ResourceComponent
class InputSystem(esper.Processor): class InputSystem(esper.Processor):
def __init__(self, camera): def __init__(self, camera, game_map: GameMap):
self.camera = camera self.camera = camera
self.game_map = game_map
def process(self, dt): def process(self, dt):
for ent, (inp, pos) in self.world.get_components(InputComponent, PositionComponent): for ent, (inp, pos) in self.world.get_components(InputComponent, PositionComponent):
@ -20,6 +22,10 @@ class InputSystem(esper.Processor):
pos = pygame.mouse.get_pos() pos = pygame.mouse.get_pos()
pos = (pos[0] - self.camera.camera.left, pos[1] - self.camera.camera.top) pos = (pos[0] - self.camera.camera.left, pos[1] - self.camera.camera.top)
if not self.world.has_component(ent, PathfindingComponent): if not self.world.has_component(ent, PathfindingComponent):
target_ent = self.game_map.get_entity([int(pos[0] / 32), int(pos[1]/ 32)])
if target_ent is not None and self.world.has_component(target_ent, ResourceComponent):
self.world.add_component(ent, PathfindingComponent(pos, True))
else:
self.world.add_component(ent, PathfindingComponent(pos)) self.world.add_component(ent, PathfindingComponent(pos))
if self.world.has_component(ent, MovingComponent): if self.world.has_component(ent, MovingComponent):

View File

@ -8,21 +8,30 @@ from survival.graph_search import graph_search, Action
from survival.systems.input_system import PathfindingComponent from survival.systems.input_system import PathfindingComponent
class CollectingResourceComponent:
def __init__(self, action):
self.action = action
class PathfindingMovementSystem(esper.Processor): class PathfindingMovementSystem(esper.Processor):
def __init__(self, game_map): def __init__(self, game_map):
self.game_map = game_map self.game_map = game_map
pass
def process(self, dt): def process(self, dt):
for ent, (pos, pathfinding, movement) in self.world.get_components(PositionComponent, PathfindingComponent, for ent, (pos, pathfinding, movement) in self.world.get_components(PositionComponent, PathfindingComponent,
MovementComponent): MovementComponent):
if pathfinding.path is None: if pathfinding.path is None:
pathfinding.path = graph_search(self.game_map, pos, pathfinding.target_grid_pos) pathfinding.path = graph_search(self.game_map, pos, pathfinding.target_grid_pos, self.world)
if len(pathfinding.path) < 1: if len(pathfinding.path) < 1:
self.world.remove_component(ent, PathfindingComponent) self.world.remove_component(ent, PathfindingComponent)
continue continue
if pathfinding.searching_for_resource and len(pathfinding.path) == 1:
self.world.add_component(ent, CollectingResourceComponent(pathfinding.path.pop(0)))
self.world.remove_component(ent, PathfindingComponent)
continue
if self.world.has_component(ent, MovingComponent) or self.world.has_component(ent, DirectionChangeComponent): if self.world.has_component(ent, MovingComponent) or self.world.has_component(ent, DirectionChangeComponent):
continue continue

View File

@ -9,4 +9,3 @@ class TimeSystem(esper.Processor):
if time.timer > 1000: if time.timer > 1000:
time.add_time(1) time.add_time(1)
time.timer = 0 time.timer = 0
print(time)

View File

@ -2,7 +2,7 @@ import pygame.font
from survival import settings from survival import settings
from survival.components.inventory_component import InventoryComponent from survival.components.inventory_component import InventoryComponent
from survival.generators.resource_generator import ResourceType from survival.generators.resource_type import ResourceType
from survival.image import Image from survival.image import Image