Add pathfinding usage

This commit is contained in:
Jakub Klupieć 2021-04-19 01:41:02 +02:00
parent 3463bd0415
commit 4467ca555e
8 changed files with 76 additions and 13 deletions

View File

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

View File

@ -6,3 +6,9 @@ class PositionComponent:
self.position = pos
self.grid_position = grid_pos
self.direction = Direction.DOWN
def rotate_left(self):
self.direction = Direction.rotate_left(self.direction)
def rotate_right(self):
self.direction = Direction.rotate_right(self.direction)

View File

@ -25,3 +25,10 @@ class Direction(IntEnum):
return -1, 0
elif direction == Direction.RIGHT:
return 1, 0
@staticmethod
def from_vector(vector):
if vector[0] == 0:
return Direction.DOWN if vector[1] == 1 else Direction.UP
else:
return Direction.LEFT if vector[0] == -1 else Direction.RIGHT

View File

@ -13,10 +13,13 @@ def valid_neighbor(n, game_map, visited):
def breadth_first_search(game_map, start, target):
visited = [[False for _ in range(game_map.width)] for _ in range(game_map.height)]
visited = [[False for _ in range(game_map.height)] for _ in range(game_map.width)]
q = Queue()
came_from = dict()
came_from[start] = (-1, -1)
start = tuple(start)
target = tuple(target)
came_from[start] = None
q.append(start)
visited[start[0]][start[1]] = True
@ -42,13 +45,14 @@ def breadth_first_search(game_map, start, target):
path = list()
current = target
if came_from.get(start, None) is not None:
path.append(start)
return path
while current != start:
path.append(current)
if current not in came_from:
path.clear()
return path
current = came_from[current]
path.append(start)
path.reverse()
return path

View File

@ -20,7 +20,6 @@ class CollisionSystem(esper.Processor):
vector = Direction.get_vector(pos.direction)
moving.target = tuple(map(operator.add, vector, pos.grid_position))
moving.direction_vector = vector
if self.check_collision(moving.target):
self.world.remove_component(ent, MovingComponent)
else:

View File

@ -3,23 +3,30 @@ import pygame
from survival import esper
from survival.components.input_component import InputComponent
from survival.components.moving_component import MovingComponent
from survival.components.pathfinding_component import PathfindingComponent
from survival.components.position_component import PositionComponent
from survival.enums import Direction
class InputSystem(esper.Processor):
def __init__(self):
self.map = None
def __init__(self, camera):
self.camera = camera
def process(self, dt):
for ent, (inp, pos) in self.world.get_components(InputComponent, PositionComponent):
keys = pygame.key.get_pressed()
mouse = pygame.mouse.get_pressed(3)
if mouse[0] == 1:
pos = pygame.mouse.get_pos()
pos = (pos[0] - self.camera.camera.left, pos[1] - self.camera.camera.top)
if self.world.has_component(ent, PathfindingComponent):
self.world.remove_component(ent, PathfindingComponent)
self.world.add_component(ent, PathfindingComponent(pos))
if self.world.has_component(ent, MovingComponent):
continue
if keys[pygame.K_LEFT]:
pos.direction = Direction.rotate_left(pos.direction)
pos.rotate_left()
elif keys[pygame.K_RIGHT]:
pos.direction = Direction.rotate_right(pos.direction)
pos.rotate_right()
elif keys[pygame.K_UP]:
self.world.add_component(ent, MovingComponent())

View File

@ -0,0 +1,34 @@
from survival import esper
from survival.components.movement_component import MovementComponent
from survival.components.moving_component import MovingComponent
from survival.components.position_component import PositionComponent
from survival.enums import Direction
from survival.pathfinding import breadth_first_search
from survival.systems.input_system import PathfindingComponent
class PathfindingMovementSystem(esper.Processor):
def __init__(self, game_map):
self.game_map = game_map
pass
def process(self, dt):
for ent, (pos, pathfinding, movement) in self.world.get_components(PositionComponent, PathfindingComponent,
MovementComponent):
if pathfinding.path is None:
pathfinding.path = breadth_first_search(self.game_map, pos.grid_position, pathfinding.target_grid_pos)
if len(pathfinding.path) < 1:
self.world.remove_component(ent, PathfindingComponent)
continue
if self.world.has_component(ent, MovingComponent):
continue
target = pathfinding.path.pop(0)
vector = (target[0] - pos.grid_position[0], target[1] - pos.grid_position[1])
direction = Direction.from_vector(vector)
if direction != pos.direction:
pos.direction = direction
self.world.add_component(ent, MovingComponent())

View File

@ -4,6 +4,7 @@ from survival.systems.collision_system import CollisionSystem
from survival.systems.draw_system import DrawSystem
from survival.systems.input_system import InputSystem
from survival.systems.movement_system import MovementSystem
from survival.systems.pathfinding_movement_system import PathfindingMovementSystem
from survival.systems.time_system import TimeSystem
@ -11,11 +12,12 @@ class WorldGenerator:
def create_world(self, camera, game_map):
world = esper.World()
world.add_processor(InputSystem())
world.add_processor(InputSystem(camera))
world.add_processor(CameraSystem(camera))
world.add_processor(MovementSystem(), priority=1)
world.add_processor(CollisionSystem(game_map), priority=2)
world.add_processor(DrawSystem(camera))
world.add_processor(TimeSystem())
world.add_processor(PathfindingMovementSystem(game_map), priority=3)
return world