Merge pull request 'dev-jakklu' (#5) from dev-jakklu into master
Reviewed-on: #5
BIN
assets/apple.png
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
assets/atlas.png
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
BIN
assets/map1.png
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
assets/map2.png
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
assets/map3.png
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
assets/map4.png
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 807 B |
11
assets/srgb_profile_fix.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import os
|
||||||
|
import pygame as pg
|
||||||
|
|
||||||
|
for i in os.listdir('.'):
|
||||||
|
try:
|
||||||
|
img = pg.image.load(i)
|
||||||
|
pg.image.save(img, i)
|
||||||
|
except:
|
||||||
|
print("Failed to fix image " + i)
|
||||||
|
|
||||||
|
print('Success. All images were fixed!')
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
assets/stone.png
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 98 B |
BIN
assets/tree.png
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
assets/water.png
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
assets/wood.png
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 1.4 KiB |
@ -1,21 +1,10 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from settings import SCREEN_WIDTH, SCREEN_HEIGHT
|
from settings import SCREEN_WIDTH, SCREEN_HEIGHT
|
||||||
from survival import esper
|
|
||||||
from survival.camera import Camera
|
from survival.camera import Camera
|
||||||
from survival.components.camera_target_component import CameraTargetComponent
|
|
||||||
from survival.components.input_component import InputComponent
|
|
||||||
from survival.components.movement_component import MovementComponent
|
|
||||||
from survival.components.position_component import PositionComponent
|
|
||||||
from survival.components.sprite_component import SpriteComponent
|
|
||||||
from survival.game_map import GameMap
|
from survival.game_map import GameMap
|
||||||
from survival.player_generator import PlayerGenerator
|
from survival.player_generator import PlayerGenerator
|
||||||
from survival.resource_generator import ResourceGenerator
|
from survival.resource_generator import ResourceGenerator
|
||||||
from survival.systems.camera_system import CameraSystem
|
|
||||||
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.world_generator import WorldGenerator
|
from survival.world_generator import WorldGenerator
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
18
survival/building_generator.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from survival.components.collision_component import CollisionComponent
|
||||||
|
from survival.components.inventory_component import InventoryComponent
|
||||||
|
from survival.components.position_component import PositionComponent
|
||||||
|
from survival.components.sprite_component import SpriteComponent
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingGenerator:
|
||||||
|
def create_home(self, world, game_map):
|
||||||
|
home = world.create_entity()
|
||||||
|
pos = PositionComponent([32, 32], [32, 32])
|
||||||
|
world.add_component(home, pos)
|
||||||
|
world.add_component(home, InventoryComponent())
|
||||||
|
|
||||||
|
game_map.add_entity(home, pos)
|
||||||
|
sprite = SpriteComponent('stone.png')
|
||||||
|
sprite.set_scale(2)
|
||||||
|
world.add_component(home, sprite)
|
||||||
|
world.add_component(home, CollisionComponent())
|
12
survival/components/direction_component.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from survival.enums import Direction
|
||||||
|
|
||||||
|
|
||||||
|
class DirectionChangeComponent:
|
||||||
|
def __init__(self, direction):
|
||||||
|
self.direction = direction
|
||||||
|
|
||||||
|
def rotate_left(self):
|
||||||
|
self.direction = Direction.rotate_left(self.direction)
|
||||||
|
|
||||||
|
def rotate_right(self):
|
||||||
|
self.direction = Direction.rotate_right(self.direction)
|
24
survival/components/inventory_component.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
class InventoryComponent:
|
||||||
|
def __init__(self, maxitems):
|
||||||
|
self.maxitems = maxitems
|
||||||
|
self.items = {}
|
||||||
|
|
||||||
|
def addItem(self, item, count):
|
||||||
|
if item not in self.items:
|
||||||
|
self.items[item] = count
|
||||||
|
else:
|
||||||
|
self.items[item] = self.items[item] + count
|
||||||
|
if self.items[item] > self.maxitems:
|
||||||
|
self.items[item] = self.maxitems
|
||||||
|
|
||||||
|
def removeItem(self, item, count):
|
||||||
|
if self.items:
|
||||||
|
self.items[item] = self.items[item] - count
|
||||||
|
if self.items[item] < 0:
|
||||||
|
self.items[item] = 0
|
||||||
|
|
||||||
|
def hasItem(self, item):
|
||||||
|
if self.items[item] != 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
@ -1,5 +1,4 @@
|
|||||||
class MovingComponent:
|
class MovingComponent:
|
||||||
def __init__(self, direction, target):
|
def __init__(self):
|
||||||
self.direction = direction
|
self.target = None
|
||||||
self.movement_target = target
|
self.direction_vector = None
|
||||||
self.checked_collision = False
|
|
||||||
|
5
survival/components/pathfinding_component.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class PathfindingComponent:
|
||||||
|
def __init__(self, target_pos):
|
||||||
|
self.target_grid_pos = (int(target_pos[0] / 32), int(target_pos[1] / 32))
|
||||||
|
self.current_target = None
|
||||||
|
self.path = None
|
@ -1,4 +1,15 @@
|
|||||||
|
from survival.enums import Direction
|
||||||
|
|
||||||
|
|
||||||
class PositionComponent:
|
class PositionComponent:
|
||||||
def __init__(self, pos, grid_pos):
|
def __init__(self, pos, grid_pos, direction=Direction.DOWN):
|
||||||
self.position = pos
|
self.position = pos
|
||||||
self.grid_position = grid_pos
|
self.grid_position = grid_pos
|
||||||
|
self.direction = direction
|
||||||
|
self.direction_change_timer = 0
|
||||||
|
|
||||||
|
def rotate_left(self):
|
||||||
|
return Direction.rotate_left(self.direction)
|
||||||
|
|
||||||
|
def rotate_right(self):
|
||||||
|
return Direction.rotate_right(self.direction)
|
||||||
|
20
survival/components/time_component.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class TimeComponent:
|
||||||
|
def __init__(self, minute, hour, day, timer):
|
||||||
|
self.minute = minute
|
||||||
|
self.hour = hour
|
||||||
|
self.day = day
|
||||||
|
self.timer = timer
|
||||||
|
|
||||||
|
def add_time(self, minutes):
|
||||||
|
self.minute += minutes
|
||||||
|
if self.minute >= 60:
|
||||||
|
temp = self.minute - 60
|
||||||
|
self.hour += 1
|
||||||
|
if self.hour >= 24:
|
||||||
|
temp2 = self.hour - 24
|
||||||
|
self.day += 1
|
||||||
|
self.hour = temp2
|
||||||
|
self.minute = temp
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'Day {self.day}, {self.hour}:{self.minute}'
|
34
survival/enums.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
|
||||||
|
class Direction(IntEnum):
|
||||||
|
DOWN = 0
|
||||||
|
LEFT = 1
|
||||||
|
UP = 2
|
||||||
|
RIGHT = 3
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rotate_left(direction):
|
||||||
|
return Direction((direction - 1) % 4)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rotate_right(direction):
|
||||||
|
return Direction((direction + 1) % 4)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_vector(direction):
|
||||||
|
if direction == Direction.UP:
|
||||||
|
return 0, -1
|
||||||
|
elif direction == Direction.DOWN:
|
||||||
|
return 0, 1
|
||||||
|
elif direction == Direction.LEFT:
|
||||||
|
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
|
@ -1,6 +1,4 @@
|
|||||||
from survival.components.position_component import PositionComponent
|
|
||||||
from survival.entity_layer import EntityLayer
|
from survival.entity_layer import EntityLayer
|
||||||
from survival.player import Player
|
|
||||||
from survival.tile_layer import TileLayer
|
from survival.tile_layer import TileLayer
|
||||||
|
|
||||||
|
|
||||||
@ -25,4 +23,4 @@ class GameMap:
|
|||||||
self.entity_layer.remove_entity(pos)
|
self.entity_layer.remove_entity(pos)
|
||||||
|
|
||||||
def is_colliding(self, pos):
|
def is_colliding(self, pos):
|
||||||
return self.entity_layer.is_colliding(pos)
|
return pos[0] < 0 or pos[0] >= self.width or pos[1] < 0 or pos[1] >= self.height or self.entity_layer.is_colliding(pos)
|
||||||
|
88
survival/graph_search.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from survival import GameMap
|
||||||
|
from survival.components.position_component import PositionComponent
|
||||||
|
from survival.enums import Direction
|
||||||
|
|
||||||
|
|
||||||
|
class Action(Enum):
|
||||||
|
ROTATE_LEFT = 0
|
||||||
|
ROTATE_RIGHT = 1
|
||||||
|
MOVE = 2
|
||||||
|
|
||||||
|
|
||||||
|
class State:
|
||||||
|
def __init__(self, position, direction):
|
||||||
|
self.position = position
|
||||||
|
self.direction = direction
|
||||||
|
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
def __init__(self, state: State, parent=None, action=None):
|
||||||
|
self.state = state
|
||||||
|
self.parent = parent
|
||||||
|
self.action = action
|
||||||
|
|
||||||
|
|
||||||
|
def get_moved_position(position, direction):
|
||||||
|
vector = Direction.get_vector(direction)
|
||||||
|
return position[0] + vector[0], position[1] + vector[1]
|
||||||
|
|
||||||
|
|
||||||
|
def get_states(state: State, game_map: GameMap):
|
||||||
|
states = list()
|
||||||
|
|
||||||
|
states.append((Action.ROTATE_LEFT, State(state.position, state.direction.rotate_left(state.direction))))
|
||||||
|
states.append((Action.ROTATE_RIGHT, State(state.position, state.direction.rotate_right(state.direction))))
|
||||||
|
|
||||||
|
target_state = get_moved_position(state.position, state.direction)
|
||||||
|
if not game_map.is_colliding(target_state):
|
||||||
|
states.append((Action.MOVE, State(target_state, state.direction)))
|
||||||
|
|
||||||
|
return states
|
||||||
|
|
||||||
|
|
||||||
|
def graph_search(game_map: GameMap, start: PositionComponent, goal: tuple):
|
||||||
|
fringe = list()
|
||||||
|
explored = list()
|
||||||
|
|
||||||
|
explored_states = set()
|
||||||
|
fringe_states = set()
|
||||||
|
|
||||||
|
start = State(start.grid_position, start.direction)
|
||||||
|
fringe.append(Node(start))
|
||||||
|
fringe_states.add((tuple(start.position), start.direction))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# No solutions found
|
||||||
|
if not any(fringe):
|
||||||
|
return []
|
||||||
|
|
||||||
|
node = fringe.pop(0)
|
||||||
|
fringe_states.remove((tuple(node.state.position), node.state.direction))
|
||||||
|
|
||||||
|
# Check goal
|
||||||
|
if node.state.position == goal:
|
||||||
|
actions = [node.action]
|
||||||
|
parent = node.parent
|
||||||
|
|
||||||
|
while parent is not None:
|
||||||
|
if parent.action is not None:
|
||||||
|
actions.append(parent.action)
|
||||||
|
parent = parent.parent
|
||||||
|
|
||||||
|
actions.reverse()
|
||||||
|
return actions
|
||||||
|
|
||||||
|
explored.append(node)
|
||||||
|
explored_states.add((tuple(node.state.position), node.state.direction))
|
||||||
|
|
||||||
|
# Get all possible states
|
||||||
|
for state in get_states(node.state, game_map):
|
||||||
|
sub_state = (tuple(state[1].position), state[1].direction)
|
||||||
|
if sub_state not in fringe_states and sub_state not in explored_states:
|
||||||
|
new_node = Node(state=state[1],
|
||||||
|
parent=node,
|
||||||
|
action=state[0])
|
||||||
|
fringe.append(new_node)
|
||||||
|
fringe_states.add((tuple(new_node.state.position), new_node.state.direction))
|
58
survival/pathfinding.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
from collections import deque as Queue
|
||||||
|
|
||||||
|
|
||||||
|
def valid_neighbor(n, game_map, visited):
|
||||||
|
if n[0] < 0 or n[1] < 0 or n[0] >= game_map.width or n[1] >= game_map.height:
|
||||||
|
return False
|
||||||
|
if visited[n[0]][n[1]]:
|
||||||
|
return False
|
||||||
|
if game_map.is_colliding(n):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def breadth_first_search(game_map, start, target):
|
||||||
|
visited = [[False for _ in range(game_map.height)] for _ in range(game_map.width)]
|
||||||
|
q = Queue()
|
||||||
|
came_from = dict()
|
||||||
|
start = tuple(start)
|
||||||
|
target = tuple(target)
|
||||||
|
|
||||||
|
came_from[start] = None
|
||||||
|
|
||||||
|
q.append(start)
|
||||||
|
visited[start[0]][start[1]] = True
|
||||||
|
|
||||||
|
while len(q) > 0:
|
||||||
|
cell = q.popleft()
|
||||||
|
|
||||||
|
if cell == target:
|
||||||
|
break
|
||||||
|
|
||||||
|
neighbors = [
|
||||||
|
(cell[0] - 1, cell[1]),
|
||||||
|
(cell[0], cell[1] + 1),
|
||||||
|
(cell[0] + 1, cell[1]),
|
||||||
|
(cell[0], cell[1] - 1),
|
||||||
|
]
|
||||||
|
|
||||||
|
for neighbor in neighbors:
|
||||||
|
if valid_neighbor(neighbor, game_map, visited):
|
||||||
|
q.append(neighbor)
|
||||||
|
visited[neighbor[0]][neighbor[1]] = True
|
||||||
|
came_from[neighbor] = cell
|
||||||
|
|
||||||
|
path = list()
|
||||||
|
current = target
|
||||||
|
|
||||||
|
while current != start:
|
||||||
|
path.append(current)
|
||||||
|
if current not in came_from:
|
||||||
|
path.clear()
|
||||||
|
return path
|
||||||
|
|
||||||
|
current = came_from[current]
|
||||||
|
|
||||||
|
path.reverse()
|
||||||
|
return path
|
@ -2,8 +2,6 @@ from random import randint
|
|||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from survival.image import Image
|
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -3,6 +3,7 @@ from survival.components.input_component import InputComponent
|
|||||||
from survival.components.movement_component import MovementComponent
|
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
|
||||||
|
|
||||||
|
|
||||||
class PlayerGenerator:
|
class PlayerGenerator:
|
||||||
@ -19,5 +20,6 @@ class PlayerGenerator:
|
|||||||
sprite = SpriteComponent('stevenson.png')
|
sprite = SpriteComponent('stevenson.png')
|
||||||
sprite.set_scale(1)
|
sprite.set_scale(1)
|
||||||
world.add_component(player, sprite)
|
world.add_component(player, sprite)
|
||||||
|
world.add_component(player, TimeComponent(0, 0, 0, 0))
|
||||||
|
|
||||||
return player
|
return player
|
||||||
|
@ -13,7 +13,7 @@ class ResourceGenerator:
|
|||||||
def generate_resources(self):
|
def generate_resources(self):
|
||||||
for x in range(RESOURCES_AMOUNT):
|
for x in range(RESOURCES_AMOUNT):
|
||||||
obj = self.world.create_entity()
|
obj = self.world.create_entity()
|
||||||
sprites = ['apple.png', 'water.png', 'wood.png', 'stone.png']
|
sprites = ['apple.png', 'water.png', 'wood.png']
|
||||||
|
|
||||||
empty_grid_pos = self.get_empty_grid_position()
|
empty_grid_pos = self.get_empty_grid_position()
|
||||||
empty_pos = [empty_grid_pos[0] * 32, empty_grid_pos[1] * 32]
|
empty_pos = [empty_grid_pos[0] * 32, empty_grid_pos[1] * 32]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
SCREEN_WIDTH = 1920
|
SCREEN_WIDTH = 1920
|
||||||
SCREEN_HEIGHT = 1080
|
SCREEN_HEIGHT = 1080
|
||||||
RESOURCES_AMOUNT = 300
|
RESOURCES_AMOUNT = 300
|
||||||
|
DIRECTION_CHANGE_DELAY = 200
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import operator
|
||||||
|
|
||||||
from survival import esper
|
from survival import esper
|
||||||
from survival.components.moving_component import MovingComponent
|
from survival.components.moving_component import MovingComponent
|
||||||
from survival.components.position_component import PositionComponent
|
from survival.components.position_component import PositionComponent
|
||||||
|
from survival.enums import Direction
|
||||||
|
|
||||||
|
|
||||||
class CollisionSystem(esper.Processor):
|
class CollisionSystem(esper.Processor):
|
||||||
@ -9,17 +12,19 @@ class CollisionSystem(esper.Processor):
|
|||||||
|
|
||||||
def process(self, dt):
|
def process(self, dt):
|
||||||
for ent, (pos, moving) in self.world.get_components(PositionComponent, MovingComponent):
|
for ent, (pos, moving) in self.world.get_components(PositionComponent, MovingComponent):
|
||||||
if moving.checked_collision:
|
if moving.target is not None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
moving.checked_collision = True
|
moving.checked_collision = True
|
||||||
|
|
||||||
if self.check_collision(moving.movement_target):
|
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)
|
self.world.remove_component(ent, MovingComponent)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.map.move_entity(pos.grid_position, moving.movement_target)
|
self.map.move_entity(pos.grid_position, moving.target)
|
||||||
pos.grid_position = moving.movement_target
|
pos.grid_position = moving.target
|
||||||
|
|
||||||
def check_collision(self, pos):
|
def check_collision(self, pos):
|
||||||
return self.map.is_colliding(pos)
|
return self.map.is_colliding(pos)
|
||||||
|
27
survival/systems/direction_system.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from survival import esper
|
||||||
|
from survival.components.direction_component import DirectionChangeComponent
|
||||||
|
from survival.components.position_component import PositionComponent
|
||||||
|
from survival.settings import DIRECTION_CHANGE_DELAY
|
||||||
|
|
||||||
|
|
||||||
|
class DirectionSystem(esper.Processor):
|
||||||
|
def process(self, dt):
|
||||||
|
for ent, (pos, direction) in self.world.get_components(PositionComponent, DirectionChangeComponent):
|
||||||
|
if pos.direction_change_timer > 0:
|
||||||
|
pos.direction_change_timer -= dt
|
||||||
|
continue
|
||||||
|
|
||||||
|
dir_left = pos.rotate_left()
|
||||||
|
dir_right = pos.rotate_right()
|
||||||
|
|
||||||
|
pos.direction_change_timer = DIRECTION_CHANGE_DELAY
|
||||||
|
|
||||||
|
if dir_left == direction.direction:
|
||||||
|
pos.direction = dir_left
|
||||||
|
elif dir_right == direction.direction:
|
||||||
|
pos.direction = dir_right
|
||||||
|
else:
|
||||||
|
pos.direction = dir_left
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.world.remove_component(ent, DirectionChangeComponent)
|
@ -10,4 +10,5 @@ class DrawSystem(esper.Processor):
|
|||||||
def process(self, dt):
|
def process(self, dt):
|
||||||
for ent, (sprite, pos) in self.world.get_components(SpriteComponent, PositionComponent):
|
for ent, (sprite, pos) in self.world.get_components(SpriteComponent, PositionComponent):
|
||||||
sprite.image.pos = pos.position
|
sprite.image.pos = pos.position
|
||||||
|
sprite.image.origin = (32 * pos.direction.value, 0)
|
||||||
self.camera.draw(sprite.image)
|
self.camera.draw(sprite.image)
|
||||||
|
@ -1,26 +1,34 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from survival import esper
|
from survival import esper
|
||||||
|
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.position_component import PositionComponent
|
from survival.components.position_component import PositionComponent
|
||||||
|
|
||||||
|
|
||||||
class InputSystem(esper.Processor):
|
class InputSystem(esper.Processor):
|
||||||
def __init__(self):
|
def __init__(self, camera):
|
||||||
self.map = None
|
self.camera = camera
|
||||||
|
|
||||||
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):
|
||||||
keys = pygame.key.get_pressed()
|
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 not self.world.has_component(ent, PathfindingComponent):
|
||||||
|
self.world.add_component(ent, PathfindingComponent(pos))
|
||||||
|
|
||||||
if self.world.has_component(ent, MovingComponent):
|
if self.world.has_component(ent, MovingComponent):
|
||||||
continue
|
continue
|
||||||
if keys[pygame.K_LEFT]:
|
if keys[pygame.K_LEFT]:
|
||||||
self.world.add_component(ent, MovingComponent([-1, 0], [pos.grid_position[0] - 1, pos.grid_position[1]]))
|
if not self.world.has_component(ent, DirectionChangeComponent):
|
||||||
|
self.world.add_component(ent, DirectionChangeComponent(pos.rotate_left()))
|
||||||
elif keys[pygame.K_RIGHT]:
|
elif keys[pygame.K_RIGHT]:
|
||||||
self.world.add_component(ent, MovingComponent([1, 0], [pos.grid_position[0] + 1, pos.grid_position[1]]))
|
if not self.world.has_component(ent, DirectionChangeComponent):
|
||||||
elif keys[pygame.K_DOWN]:
|
self.world.add_component(ent, DirectionChangeComponent(pos.rotate_right()))
|
||||||
self.world.add_component(ent, MovingComponent([0, 1], [pos.grid_position[0], pos.grid_position[1] + 1]))
|
|
||||||
elif keys[pygame.K_UP]:
|
elif keys[pygame.K_UP]:
|
||||||
self.world.add_component(ent, MovingComponent([0, -1], [pos.grid_position[0], pos.grid_position[1] - 1]))
|
self.world.add_component(ent, MovingComponent())
|
||||||
|
@ -13,23 +13,22 @@ class MovementSystem(esper.Processor):
|
|||||||
for ent, (mov, pos, moving, sprite) in self.world.get_components(MovementComponent, PositionComponent,
|
for ent, (mov, pos, moving, sprite) in self.world.get_components(MovementComponent, PositionComponent,
|
||||||
MovingComponent,
|
MovingComponent,
|
||||||
SpriteComponent):
|
SpriteComponent):
|
||||||
if moving.direction[0] != 0:
|
|
||||||
pos.position[0] += moving.direction[0] * mov.speed * dt / 100
|
|
||||||
if abs(moving.movement_target[0] * 32 - pos.position[0]) < 0.1 * mov.speed:
|
|
||||||
pos.position = [moving.movement_target[0] * 32, moving.movement_target[1] * 32]
|
|
||||||
self.world.remove_component(ent, MovingComponent)
|
|
||||||
else:
|
|
||||||
pos.position[1] += moving.direction[1] * mov.speed * dt / 100
|
|
||||||
if abs(pos.position[1] - moving.movement_target[1] * 32) < 0.1 * mov.speed:
|
|
||||||
pos.position = [moving.movement_target[0] * 32, moving.movement_target[1] * 32]
|
|
||||||
self.world.remove_component(ent, MovingComponent)
|
|
||||||
|
|
||||||
if moving.direction[0] == 1:
|
pos.position[0] += moving.direction_vector[0] * mov.speed * dt / 100
|
||||||
sprite.image.origin = (96, 0)
|
pos.position[1] += moving.direction_vector[1] * mov.speed * dt / 100
|
||||||
elif moving.direction[0] == -1:
|
|
||||||
sprite.image.origin = (64, 0)
|
|
||||||
elif moving.direction[1] == 1:
|
|
||||||
sprite.image.origin = (0, 0)
|
|
||||||
else:
|
|
||||||
sprite.image.origin = (32, 0)
|
|
||||||
|
|
||||||
|
if abs(moving.target[0] * 32 - pos.position[0]) < 0.1 * mov.speed and abs(
|
||||||
|
pos.position[1] - moving.target[1] * 32) < 0.1 * mov.speed:
|
||||||
|
pos.position = [moving.target[0] * 32, moving.target[1] * 32]
|
||||||
|
self.world.remove_component(ent, MovingComponent)
|
||||||
|
|
||||||
|
# if moving.direction[0] != 0:
|
||||||
|
# pos.position[0] += moving.direction[0] * mov.speed * dt / 100
|
||||||
|
# if abs(moving.movement_target[0] * 32 - pos.position[0]) < 0.1 * mov.speed:
|
||||||
|
# pos.position = [moving.movement_target[0] * 32, moving.movement_target[1] * 32]
|
||||||
|
# self.world.remove_component(ent, MovingComponent)
|
||||||
|
# else:
|
||||||
|
# pos.position[1] += moving.direction[1] * mov.speed * dt / 100
|
||||||
|
# if abs(pos.position[1] - moving.movement_target[1] * 32) < 0.1 * mov.speed:
|
||||||
|
# pos.position = [moving.movement_target[0] * 32, moving.movement_target[1] * 32]
|
||||||
|
# self.world.remove_component(ent, MovingComponent)
|
||||||
|
62
survival/systems/pathfinding_movement_system.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
from survival import esper
|
||||||
|
from survival.components.direction_component import DirectionChangeComponent
|
||||||
|
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.graph_search import graph_search, Action
|
||||||
|
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 = graph_search(self.game_map, pos, pathfinding.target_grid_pos)
|
||||||
|
|
||||||
|
if len(pathfinding.path) < 1:
|
||||||
|
self.world.remove_component(ent, PathfindingComponent)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self.world.has_component(ent, MovingComponent) or self.world.has_component(ent, DirectionChangeComponent):
|
||||||
|
continue
|
||||||
|
|
||||||
|
action = pathfinding.path.pop(0)
|
||||||
|
|
||||||
|
if action == Action.ROTATE_LEFT:
|
||||||
|
self.world.add_component(ent, DirectionChangeComponent(Direction.rotate_left(pos.direction)))
|
||||||
|
elif action == Action.ROTATE_RIGHT:
|
||||||
|
self.world.add_component(ent, DirectionChangeComponent(Direction.rotate_right(pos.direction)))
|
||||||
|
else:
|
||||||
|
self.world.add_component(ent, MovingComponent())
|
||||||
|
|
||||||
|
# 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 and pathfinding.current_target is None:
|
||||||
|
# self.world.remove_component(ent, PathfindingComponent)
|
||||||
|
# continue
|
||||||
|
#
|
||||||
|
# if self.world.has_component(ent, MovingComponent):
|
||||||
|
# continue
|
||||||
|
#
|
||||||
|
# if pathfinding.current_target is None:
|
||||||
|
# target = pathfinding.path.pop(0)
|
||||||
|
# else:
|
||||||
|
# target = pathfinding.current_target
|
||||||
|
#
|
||||||
|
# vector = (target[0] - pos.grid_position[0], target[1] - pos.grid_position[1])
|
||||||
|
# direction = Direction.from_vector(vector)
|
||||||
|
# if direction != pos.direction:
|
||||||
|
# pathfinding.current_target = target
|
||||||
|
# self.world.add_component(ent, DirectionChangeComponent(direction))
|
||||||
|
# continue
|
||||||
|
#
|
||||||
|
# pathfinding.current_target = None
|
||||||
|
# self.world.add_component(ent, MovingComponent())
|
12
survival/systems/time_system.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from survival import esper
|
||||||
|
from survival.components.time_component import TimeComponent
|
||||||
|
|
||||||
|
|
||||||
|
class TimeSystem(esper.Processor):
|
||||||
|
def process(self, dt):
|
||||||
|
for ent, time in self.world.get_component(TimeComponent):
|
||||||
|
time.timer += dt
|
||||||
|
if time.timer > 1000:
|
||||||
|
time.add_time(1)
|
||||||
|
time.timer = 0
|
||||||
|
print(time)
|
@ -1,19 +1,25 @@
|
|||||||
from survival import esper
|
from survival import esper
|
||||||
from survival.systems.camera_system import CameraSystem
|
from survival.systems.camera_system import CameraSystem
|
||||||
from survival.systems.collision_system import CollisionSystem
|
from survival.systems.collision_system import CollisionSystem
|
||||||
|
from survival.systems.direction_system import DirectionSystem
|
||||||
from survival.systems.draw_system import DrawSystem
|
from survival.systems.draw_system import DrawSystem
|
||||||
from survival.systems.input_system import InputSystem
|
from survival.systems.input_system import InputSystem
|
||||||
from survival.systems.movement_system import MovementSystem
|
from survival.systems.movement_system import MovementSystem
|
||||||
|
from survival.systems.pathfinding_movement_system import PathfindingMovementSystem
|
||||||
|
from survival.systems.time_system import TimeSystem
|
||||||
|
|
||||||
|
|
||||||
class WorldGenerator:
|
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())
|
world.add_processor(InputSystem(camera))
|
||||||
world.add_processor(CameraSystem(camera))
|
world.add_processor(CameraSystem(camera))
|
||||||
world.add_processor(MovementSystem(), priority=1)
|
world.add_processor(MovementSystem(), priority=1)
|
||||||
world.add_processor(CollisionSystem(game_map), priority=2)
|
world.add_processor(CollisionSystem(game_map), priority=2)
|
||||||
world.add_processor(DrawSystem(camera))
|
world.add_processor(DrawSystem(camera))
|
||||||
|
world.add_processor(TimeSystem())
|
||||||
|
world.add_processor(PathfindingMovementSystem(game_map), priority=3)
|
||||||
|
world.add_processor(DirectionSystem())
|
||||||
|
|
||||||
return world
|
return world
|
||||||
|