diff --git a/survival/__init__.py b/survival/__init__.py index c457f84..27a0251 100644 --- a/survival/__init__.py +++ b/survival/__init__.py @@ -1,21 +1,28 @@ import pygame from settings import SCREEN_WIDTH, SCREEN_HEIGHT +from survival import esper 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.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 def draw_game(delta): win.fill((0, 0, 0)) game_map.draw(camera) + world.process(delta) pygame.display.update() -def update_game(delta, pressed_keys): - game_map.update(camera, delta, pressed_keys) - pass - - if __name__ == '__main__': pygame.init() @@ -26,6 +33,37 @@ if __name__ == '__main__': game_map = GameMap(int(SCREEN_WIDTH / 32) * 2, 2 * int(SCREEN_HEIGHT / 32) + 1) camera = Camera(game_map.width * 32, game_map.height * 32, win) + + world = esper.World() + world.add_processor(InputSystem()) + world.add_processor(CameraSystem(camera)) + world.add_processor(MovementSystem(), priority=1) + world.add_processor(CollisionSystem(game_map), priority=2) + world.add_processor(DrawSystem(win, camera)) + + player = world.create_entity() + pos = PositionComponent([0, 0], [0, 0]) + world.add_component(player, pos) + world.add_component(player, MovementComponent()) + world.add_component(player, InputComponent()) + camera_target = CameraTargetComponent(pos) + world.add_component(player, camera_target) + game_map.add_entity(player, pos) + sprite = SpriteComponent('stevenson.png') + sprite.set_scale(1) + world.add_component(player, sprite) + + apple = world.create_entity() + pos = PositionComponent([96, 96], [3, 3]) + world.add_component(apple, pos) + world.add_component(apple, SpriteComponent('apple.png')) + game_map.add_entity(apple, pos) + apple = world.create_entity() + pos = PositionComponent([128, 128], [4, 4]) + world.add_component(apple, pos) + world.add_component(apple, SpriteComponent('apple.png')) + game_map.add_entity(apple, pos) + run = True while run: @@ -41,4 +79,3 @@ if __name__ == '__main__': keys = pygame.key.get_pressed() draw_game(ms) - update_game(ms, keys) diff --git a/survival/camera.py b/survival/camera.py index bc6348b..d03769b 100644 --- a/survival/camera.py +++ b/survival/camera.py @@ -21,8 +21,8 @@ class Camera: SCREEN_WIDTH - self.camera.left, SCREEN_HEIGHT - self.camera.top) def update(self, target): - x = -target.pos[0] + int(SCREEN_WIDTH / 2) - y = -target.pos[1] + int(SCREEN_HEIGHT / 2) + x = -target.position[0] + int(SCREEN_WIDTH / 2) + y = -target.position[1] + int(SCREEN_HEIGHT / 2) x = min(0, x) y = min(0, y) diff --git a/survival/components/camera_target_component.py b/survival/components/camera_target_component.py new file mode 100644 index 0000000..6ca95f8 --- /dev/null +++ b/survival/components/camera_target_component.py @@ -0,0 +1,3 @@ +class CameraTargetComponent: + def __init__(self, target): + self.target = target diff --git a/survival/components/collision_component.py b/survival/components/collision_component.py new file mode 100644 index 0000000..6a4bc16 --- /dev/null +++ b/survival/components/collision_component.py @@ -0,0 +1,3 @@ +class CollisionComponent: + def __init__(self): + pass diff --git a/survival/components/input_component.py b/survival/components/input_component.py new file mode 100644 index 0000000..c2e1300 --- /dev/null +++ b/survival/components/input_component.py @@ -0,0 +1,3 @@ +class InputComponent: + def __init__(self): + self.input_data = None diff --git a/survival/components/movement_component.py b/survival/components/movement_component.py new file mode 100644 index 0000000..92a7896 --- /dev/null +++ b/survival/components/movement_component.py @@ -0,0 +1,4 @@ +class MovementComponent: + def __init__(self): + self.speed = 30 + self.timer = 0 diff --git a/survival/components/moving_component.py b/survival/components/moving_component.py new file mode 100644 index 0000000..0de446e --- /dev/null +++ b/survival/components/moving_component.py @@ -0,0 +1,5 @@ +class MovingComponent: + def __init__(self, direction, target): + self.direction = direction + self.movement_target = target + self.checked_collision = False diff --git a/survival/components/position_component.py b/survival/components/position_component.py new file mode 100644 index 0000000..5164100 --- /dev/null +++ b/survival/components/position_component.py @@ -0,0 +1,4 @@ +class PositionComponent: + def __init__(self, pos, grid_pos): + self.position = pos + self.grid_position = grid_pos diff --git a/survival/components/sprite_component.py b/survival/components/sprite_component.py new file mode 100644 index 0000000..9d6ef95 --- /dev/null +++ b/survival/components/sprite_component.py @@ -0,0 +1,9 @@ +from survival.image import Image + + +class SpriteComponent: + def __init__(self, path): + self.image = Image(path) + + def set_scale(self, scale): + self.image.set_scale(scale) diff --git a/survival/entity_layer.py b/survival/entity_layer.py new file mode 100644 index 0000000..d934b6f --- /dev/null +++ b/survival/entity_layer.py @@ -0,0 +1,22 @@ +class EntityLayer: + def __init__(self, width, height): + self.width = width + self.height = height + self.tiles = [[None for x in range(self.width)] for y in range(self.height)] + + def draw(self, camera, visible_area): + pass + + def add_entity(self, entity, pos): + self.tiles[pos[1]][pos[0]] = entity + + def move_entity(self, from_pos, to_pos): + ent = self.tiles[from_pos[1]][from_pos[0]] + self.tiles[from_pos[1]][from_pos[0]] = None + self.tiles[to_pos[1]][to_pos[0]] = ent + + def remove_entity(self, pos): + self.tiles[pos[1]][pos[0]] = None + + def is_colliding(self, pos): + return self.tiles[pos[1]][pos[0]] is not None diff --git a/survival/game_map.py b/survival/game_map.py index 3fc9937..dfc0365 100644 --- a/survival/game_map.py +++ b/survival/game_map.py @@ -1,3 +1,5 @@ +from survival.components.position_component import PositionComponent +from survival.entity_layer import EntityLayer from survival.player import Player from survival.tile_layer import TileLayer @@ -6,16 +8,21 @@ class GameMap: def __init__(self, width, height): self.width = width self.height = height - self.player = Player() - self.layers = [] - self.layers.append(TileLayer(width, height)) + self.tile_layer = TileLayer(width, height) + self.entity_layer = EntityLayer(width, height) def draw(self, camera): visible_area = camera.get_visible_area() - for layer in self.layers: - layer.draw(camera, visible_area) - self.player.draw(camera) + self.tile_layer.draw(camera, visible_area) - def update(self, camera, delta, pressed_keys): - self.player.update(delta, pressed_keys) - camera.update(self.player) + def add_entity(self, entity, pos): + self.entity_layer.add_entity(entity, pos.grid_position) + + def move_entity(self, from_pos, to_pos): + self.entity_layer.move_entity(from_pos, to_pos) + + def remove_entity(self, pos): + self.entity_layer.remove_entity(pos) + + def is_colliding(self, pos): + return self.entity_layer.is_colliding(pos) diff --git a/survival/game_object.py b/survival/game_object.py deleted file mode 100644 index dd27093..0000000 --- a/survival/game_object.py +++ /dev/null @@ -1,20 +0,0 @@ -import pygame -from pygame.rect import Rect - - -class GameObject: - - def __init__(self, pos, texture): - self.pos = pos - self.last_pos = pos - self.texture = pygame.image.load(texture) - self.texture = pygame.transform.scale(self.texture, (64, 64)) - self.width = self.texture.get_width() - self.height = self.texture.get_height() - self.velocity = [0, 0] - - def draw(self, window): - window.blit(self.texture, self.pos) - - def get_rect(self): - return Rect(self.pos[0], self.pos[1], self.width, self.height) diff --git a/survival/player.py b/survival/player.py index 57d1a97..a689663 100644 --- a/survival/player.py +++ b/survival/player.py @@ -7,25 +7,17 @@ from survival.image import Image class Player: def __init__(self): - self.pos = [0, 0] - self.velocity = [0, 0] - self.image = Image('stevenson.png') - self.image.set_scale(2) - self.origin = (0, 0) - self.speed = 30 - self.movement_target = [self.pos[0], self.pos[1]] - self.timer = 0 + # self.pos = [1024, 512] + # self.velocity = [0, 0] + # self.image = Image('stevenson.png') + # self.image.set_scale(2) + # self.speed = 30 + # self.movement_target = [self.pos[0], self.pos[1]] + # self.timer = 0 + pass def draw(self, camera): - if self.is_moving(): - if self.velocity[0] == 1: - self.image.origin = (96, 0) - elif self.velocity[0] == -1: - self.image.origin = (64, 0) - elif self.velocity[1] == 1: - self.image.origin = (0, 0) - else: - self.image.origin = (32, 0) + self.image.pos = self.pos camera.draw(self.image) @@ -59,7 +51,7 @@ class Player: self.timer += delta if self.timer > 1000: - #self.move_in_random_direction() + self.move_in_random_direction() self.timer = 0 if pressed_keys[pygame.K_LEFT]: diff --git a/survival/systems/camera_system.py b/survival/systems/camera_system.py new file mode 100644 index 0000000..e553f92 --- /dev/null +++ b/survival/systems/camera_system.py @@ -0,0 +1,12 @@ +from survival import esper +from survival.components.camera_target_component import CameraTargetComponent +from survival.components.position_component import PositionComponent + + +class CameraSystem(esper.Processor): + def __init__(self, camera): + self.camera = camera + + def process(self, dt): + for ent, (camera_target, pos) in self.world.get_components(CameraTargetComponent, PositionComponent): + self.camera.update(pos) diff --git a/survival/systems/collision_system.py b/survival/systems/collision_system.py new file mode 100644 index 0000000..5a7055e --- /dev/null +++ b/survival/systems/collision_system.py @@ -0,0 +1,25 @@ +from survival import esper +from survival.components.moving_component import MovingComponent +from survival.components.position_component import PositionComponent + + +class CollisionSystem(esper.Processor): + def __init__(self, game_map): + self.map = game_map + + def process(self, dt): + for ent, (pos, moving) in self.world.get_components(PositionComponent, MovingComponent): + if moving.checked_collision: + continue + + moving.checked_collision = True + + if self.check_collision(moving.movement_target): + self.world.remove_component(ent, MovingComponent) + + else: + self.map.move_entity(pos.grid_position, moving.movement_target) + pos.grid_position = moving.movement_target + + def check_collision(self, pos): + return self.map.is_colliding(pos) diff --git a/survival/systems/draw_system.py b/survival/systems/draw_system.py new file mode 100644 index 0000000..84fca83 --- /dev/null +++ b/survival/systems/draw_system.py @@ -0,0 +1,14 @@ +from survival import esper +from survival.components.position_component import PositionComponent +from survival.components.sprite_component import SpriteComponent + + +class DrawSystem(esper.Processor): + def __init__(self, window, camera): + self.window = window + self.camera = camera + + def process(self, dt): + for ent, (sprite, pos) in self.world.get_components(SpriteComponent, PositionComponent): + sprite.image.pos = pos.position + self.camera.draw(sprite.image) diff --git a/survival/systems/input_system.py b/survival/systems/input_system.py new file mode 100644 index 0000000..c8d7cc8 --- /dev/null +++ b/survival/systems/input_system.py @@ -0,0 +1,26 @@ +import pygame + +from survival import esper +from survival.components.input_component import InputComponent +from survival.components.moving_component import MovingComponent +from survival.components.position_component import PositionComponent + + +class InputSystem(esper.Processor): + def __init__(self): + self.map = None + + def process(self, dt): + for ent, (inp, pos) in self.world.get_components(InputComponent, PositionComponent): + keys = pygame.key.get_pressed() + + if self.world.has_component(ent, MovingComponent): + continue + if keys[pygame.K_LEFT]: + self.world.add_component(ent, MovingComponent([-1, 0], [pos.grid_position[0] - 1, pos.grid_position[1]])) + elif keys[pygame.K_RIGHT]: + self.world.add_component(ent, MovingComponent([1, 0], [pos.grid_position[0] + 1, pos.grid_position[1]])) + elif keys[pygame.K_DOWN]: + self.world.add_component(ent, MovingComponent([0, 1], [pos.grid_position[0], pos.grid_position[1] + 1])) + elif keys[pygame.K_UP]: + self.world.add_component(ent, MovingComponent([0, -1], [pos.grid_position[0], pos.grid_position[1] - 1])) diff --git a/survival/systems/movement_system.py b/survival/systems/movement_system.py new file mode 100644 index 0000000..70ad744 --- /dev/null +++ b/survival/systems/movement_system.py @@ -0,0 +1,35 @@ +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.components.sprite_component import SpriteComponent + + +class MovementSystem(esper.Processor): + def __init__(self): + self.map = None + + def process(self, dt): + for ent, (mov, pos, moving, sprite) in self.world.get_components(MovementComponent, PositionComponent, + MovingComponent, + 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: + sprite.image.origin = (96, 0) + 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) + diff --git a/survival/tile_layer.py b/survival/tile_layer.py index b07465a..ee701c4 100644 --- a/survival/tile_layer.py +++ b/survival/tile_layer.py @@ -10,8 +10,8 @@ class TileLayer: self.image = Image('atlas.png') def draw(self, camera, visible_area): - for y in range(int(visible_area.top/32), int(visible_area.height/32) + 1): - for x in range(int(visible_area.left/32), int(visible_area.width/32) + 1): + for y in range(int(visible_area.top / 32), int(visible_area.height / 32) + 1): + for x in range(int(visible_area.left / 32), int(visible_area.width / 32) + 1): self.image.pos = (x * 32, y * 32) self.image.origin = self.tiles[y][x].origin camera.draw(self.image)