diff --git a/assets/atlas.png b/assets/atlas.png new file mode 100644 index 0000000..25b0add Binary files /dev/null and b/assets/atlas.png differ diff --git a/assets/stevenson.png b/assets/stevenson.png new file mode 100644 index 0000000..00e57c8 Binary files /dev/null and b/assets/stevenson.png differ diff --git a/survival/__init__.py b/survival/__init__.py index ad64f01..c457f84 100644 --- a/survival/__init__.py +++ b/survival/__init__.py @@ -1,36 +1,36 @@ import pygame +from settings import SCREEN_WIDTH, SCREEN_HEIGHT +from survival.camera import Camera from survival.game_map import GameMap -window_width = 1280 -window_height = 720 - -def draw_game(): - game_map.draw(win) +def draw_game(delta): + win.fill((0, 0, 0)) + game_map.draw(camera) pygame.display.update() -def update_game(pressed_keys): - game_map.update(pressed_keys) +def update_game(delta, pressed_keys): + game_map.update(camera, delta, pressed_keys) pass if __name__ == '__main__': pygame.init() - win = pygame.display.set_mode((window_width, window_height)) + win = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("AI Project") clock = pygame.time.Clock() - game_map = GameMap(int(window_width/32), int(window_height/32) + 1) - + 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) run = True while run: # Set the framerate - clock.tick(60) + ms = clock.tick(60) events = pygame.event.get() @@ -40,5 +40,5 @@ if __name__ == '__main__': keys = pygame.key.get_pressed() - draw_game() - update_game(keys) + draw_game(ms) + update_game(ms, keys) diff --git a/survival/camera.py b/survival/camera.py index 91f4129..bc6348b 100644 --- a/survival/camera.py +++ b/survival/camera.py @@ -1,16 +1,31 @@ from pygame.rect import Rect +from survival import SCREEN_WIDTH, SCREEN_HEIGHT + class Camera: - def __init__(self, width, height): + def __init__(self, width, height, window): self.camera = Rect(0, 0, width, height) self.width = width self.height = height + self.window = window - def apply(self, game_object): - return game_object.get_rect().move(self.camera.topleft) + def draw(self, image): + image.draw(self.window, self) - def update(self, target_object): - x = -target_object.get_rect().x + int(self.width / 2) - y = -target_object.get_rect().y + int(self.height / 2) + def apply(self, pos): + return pos[0] + self.camera.left, pos[1] + self.camera.top + + def get_visible_area(self): + return Rect(-self.camera.left, -self.camera.top, + 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 = min(0, x) + y = min(0, y) + x = max(-(self.width - SCREEN_WIDTH), x) + y = max(-(self.height - SCREEN_HEIGHT), y) self.camera = Rect(x, y, self.width, self.height) diff --git a/survival/game_map.py b/survival/game_map.py index a0c68c0..3fc9937 100644 --- a/survival/game_map.py +++ b/survival/game_map.py @@ -1,50 +1,21 @@ -import os - -import pygame -from pygame.rect import Rect - from survival.player import Player -from survival.quad_tree import QuadTree -from survival.stone import Stone -from survival.tile import Tile +from survival.tile_layer import TileLayer class GameMap: - def __init__(self, width, height): self.width = width self.height = height - self.game_objects = [] self.player = Player() - self.game_objects.append(self.player) - self.tiles = [[Tile() for x in range(width)] for y in range(height)] - self.textures = [pygame.image.load(os.path.join('..', 'assets', 'map1.png')), - pygame.image.load(os.path.join('..', 'assets', 'map2.png')), - pygame.image.load(os.path.join('..', 'assets', 'map3.png')), - pygame.image.load(os.path.join('..', 'assets', 'map4.png'))] - self.game_objects.append(Stone([100, 200])) - self.quad_tree = QuadTree(0, Rect(0, 0, width * 32, height * 32)) + self.layers = [] + self.layers.append(TileLayer(width, height)) - def draw(self, window): - for y in range(self.height): - for x in range(self.width): - window.blit(self.textures[self.tiles[y][x].background_id], (x * 32, y * 32)) + def draw(self, camera): + visible_area = camera.get_visible_area() + for layer in self.layers: + layer.draw(camera, visible_area) + self.player.draw(camera) - for game_object in self.game_objects: - game_object.draw(window) - - def update(self, pressed_keys): - self.quad_tree.clear() - - for game_object in self.game_objects: - self.quad_tree.insert(game_object) - - self.player.update(pressed_keys) - - for game_object in self.game_objects: - possible_colliders = [] - self.quad_tree.retrieve(possible_colliders, game_object) - for collider in possible_colliders: - if game_object.get_rect().colliderect(collider.get_rect()) and game_object != collider: - game_object.velocity = [0, 0] - game_object.pos = game_object.last_pos + def update(self, camera, delta, pressed_keys): + self.player.update(delta, pressed_keys) + camera.update(self.player) diff --git a/survival/image.py b/survival/image.py new file mode 100644 index 0000000..3c93b9c --- /dev/null +++ b/survival/image.py @@ -0,0 +1,22 @@ +import os + +import pygame + + +class Image: + def __init__(self, filename): + self.texture = pygame.image.load(os.path.join('..', 'assets', filename)).convert_alpha() + self.image = self.texture + self.origin = (0, 0) + self.pos = (0, 0) + self.scale = 1 + + def set_scale(self, scale): + self.image = pygame.transform.scale(self.texture, + (self.texture.get_width() * scale, self.texture.get_height() * scale)) + self.scale = scale + + def draw(self, window, camera): + window.blit(self.image, camera.apply(self.pos), + pygame.Rect(self.origin[0] * self.scale, self.origin[1] * self.scale, 32 * self.scale, + 32 * self.scale)) diff --git a/survival/player.py b/survival/player.py index bd4cf58..57d1a97 100644 --- a/survival/player.py +++ b/survival/player.py @@ -1,34 +1,88 @@ -import os +from random import randint import pygame -from survival.game_object import GameObject +from survival.image import Image -class Player(GameObject): +class Player: def __init__(self): - super().__init__([0, 0], os.path.join('..', 'assets', 'player.png')) + 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 - def draw(self, window): - super().draw(window) + 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) + + def is_moving(self): + return self.pos != self.movement_target + + def move_in_random_direction(self): + value = randint(0, 3) + random_movement = { + 0: self.move_up, + 1: self.move_down, + 2: self.move_left, + 3: self.move_right + } + random_movement[value]() + + def update(self, delta, pressed_keys): + if self.is_moving(): + if self.velocity[0] != 0: + self.pos[0] += self.velocity[0] * self.speed * delta / 100 + if abs(self.movement_target[0] - self.pos[0]) < 0.1 * self.speed: + self.velocity = [0, 0] + self.pos = self.movement_target + else: + self.pos[1] += self.velocity[1] * self.speed * delta / 100 + if abs(self.pos[1] - self.movement_target[1]) < 0.1 * self.speed: + self.velocity = [0, 0] + self.pos = self.movement_target + return + + self.timer += delta + + if self.timer > 1000: + #self.move_in_random_direction() + self.timer = 0 - def update(self, pressed_keys): if pressed_keys[pygame.K_LEFT]: - self.velocity[0] = -1 + self.move_left() elif pressed_keys[pygame.K_RIGHT]: - self.velocity[0] = 1 - else: - self.velocity[0] = 0 - - if pressed_keys[pygame.K_DOWN]: - self.velocity[1] = 1 + self.move_right() + elif pressed_keys[pygame.K_DOWN]: + self.move_down() elif pressed_keys[pygame.K_UP]: - self.velocity[1] = -1 - else: - self.velocity[1] = 0 + self.move_up() - self.last_pos = [self.pos[0], self.pos[1]] + def move_left(self): + self.velocity = [-1, 0] + self.movement_target = [self.pos[0] - 32, self.pos[1]] - self.pos[0] += self.velocity[0] - self.pos[1] += self.velocity[1] + def move_right(self): + self.velocity = [1, 0] + self.movement_target = [self.pos[0] + 32, self.pos[1]] + def move_up(self): + self.velocity = [0, -1] + self.movement_target = [self.pos[0], self.pos[1] - 32] + + def move_down(self): + self.velocity = [0, 1] + self.movement_target = [self.pos[0], self.pos[1] + 32] diff --git a/survival/settings.py b/survival/settings.py new file mode 100644 index 0000000..30e3c68 --- /dev/null +++ b/survival/settings.py @@ -0,0 +1,2 @@ +SCREEN_WIDTH = 1920 +SCREEN_HEIGHT = 1080 diff --git a/survival/stone.py b/survival/stone.py deleted file mode 100644 index f72dab2..0000000 --- a/survival/stone.py +++ /dev/null @@ -1,9 +0,0 @@ -import os - -from survival.game_object import GameObject - - -class Stone(GameObject): - - def __init__(self, pos): - super().__init__(pos, os.path.join('..', 'assets', 'stone.png')) diff --git a/survival/textureatlas.py b/survival/textureatlas.py deleted file mode 100644 index 4628c60..0000000 --- a/survival/textureatlas.py +++ /dev/null @@ -1,24 +0,0 @@ -import pygame - - -class TextureAtlas(object): - def __init__(self, filename): - self.atlas = pygame.image.load(filename).convert() - - def image_at(self, rectangle, color_key=None): - rect = pygame.Rect(rectangle) - image = pygame.Surface(rect.size).convert() - image.blit(self.atlas, (0, 0), rect) - if color_key is not None: - if color_key is -1: - color_key = image.get_at((0, 0)) - image.set_colorkey(color_key, pygame.RLEACCEL) - return image - - def images_at(self, rects, color_key=None): - return [self.image_at(rect, color_key) for rect in rects] - - def load_row(self, rect, image_count, color_key=None): - images = [(rect[0] + rect[2] * x, rect[1], rect[2], rect[3]) - for x in range(image_count)] - return self.images_at(images, color_key) diff --git a/survival/tile.py b/survival/tile.py index bff4aab..590eb26 100644 --- a/survival/tile.py +++ b/survival/tile.py @@ -1,7 +1,9 @@ -import pygame -from random import randrange +import random class Tile: - def __init__(self): - self.background_id = randrange(4) + origins = [(0, 0), (32, 0), (64, 0), (96, 0)] + + def __init__(self, origin=(0, 0)): + self.origin = random.choice(Tile.origins) + self.image = None diff --git a/survival/tile_layer.py b/survival/tile_layer.py new file mode 100644 index 0000000..b07465a --- /dev/null +++ b/survival/tile_layer.py @@ -0,0 +1,17 @@ +from survival.image import Image +from survival.tile import Tile + + +class TileLayer: + def __init__(self, width, height): + self.width = width + self.height = height + self.tiles = [[Tile() for x in range(self.width)] for y in range(self.height)] + 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): + self.image.pos = (x * 32, y * 32) + self.image.origin = self.tiles[y][x].origin + camera.draw(self.image)