diff --git a/.gitignore b/.gitignore index 38da6d9..bc6fd9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__/ .vscode/ +*.xcf diff --git a/assets/character.png b/assets/character.png index a6fa6a5..f8956d5 100644 Binary files a/assets/character.png and b/assets/character.png differ diff --git a/assets/wall_3.png b/assets/wall_3.png index b91c928..ae5de6d 100644 Binary files a/assets/wall_3.png and b/assets/wall_3.png differ diff --git a/palette.png b/palette.png index c1cdad6..a405d36 100644 Binary files a/palette.png and b/palette.png differ diff --git a/src/game.py b/src/game.py index 043fbb1..b02eb15 100644 --- a/src/game.py +++ b/src/game.py @@ -31,8 +31,8 @@ map.generate() # Player player = Player() -player.sprite.texture = spritesheet.SpriteSheet(assets.get("character.png"), 16, 24) -player.sprite.set_rect((0, 8, 16, 24)) +player.sprite.texture = spritesheet.SpriteSheet(assets.get("character.png"), 32, 48) +player.sprite.set_rect((8, 32, 16, 16)) # TODO: Scale character up x2 (1.5m) # TODO: Use asset loader for spritesheets player.sprite.texture.set_animation(0, 0, 0) @@ -64,15 +64,13 @@ while 1: # Move the map based on player position psize = player.sprite.rect.size - camera = [CENTER[0] - (psize[0] / 2 * SCALE), CENTER[1] - (psize[1] / 2 * SCALE)] + camera = [int(CENTER[0] - (psize[0] / 2 * SCALE)), int(CENTER[1] - (psize[1] / 2 * SCALE))] + + player_rendered = False for z in range(len(map.map)): for y in range(len(map.map[z])): for x in range(len(map.map[z][y])): - if z == 1 and y == round(player.pos.y) and x == round(player.pos.x): - # Draw player - screen.blit(pygame.transform.scale(player.sprite.texture.frame, [round(SCALE * player.sprite.texture.width), round(SCALE * player.sprite.texture.height)]), camera) - tile = map.get_tile(x, y, z) if tile: # NOTE: Rotations are clockwise due to Y+ down rendering @@ -101,5 +99,10 @@ while 1: # text = arial.render(str(int(x)) + ", " + str(int(y)), False, (255, 255, 255)) # screen.blit(text, [x * 64 - (player.pos.x * round(SCALE * METER)) + camera[0], y * 64 - (player.pos.y * round(SCALE * METER)) + camera[1]]) + if not player_rendered and z == 1 and y == round(player.pos.y + player.sprite.get_rect()[3] / METER): + # Draw player + screen.blit(pygame.transform.scale(player.sprite.texture.frame, [round(SCALE * player.sprite.texture.width), round(SCALE * player.sprite.texture.height)]), camera) + player_rendered = True + pygame.display.update() # pygame.display.flip() diff --git a/src/generator.py b/src/generator.py new file mode 100644 index 0000000..2e2da8f --- /dev/null +++ b/src/generator.py @@ -0,0 +1,208 @@ +import random +import time +import math + +MSIZE = 80 + +def rand(*args): + random.seed(time.clock()) + return random.randint(*args) + +class Room(): + def __init__(self, x, y, width, height): + self.x = x + self.y = y + self.width = width + self.height = height + + self.left = x + self.right = x + width + self.top = y + self.bottom = y + height + + self.cx = math.floor(self.x + (width / 2)) + self.cy = math.floor(self.y + (height / 2)) + + def intersects(self, other): + return self.left <= other.right and self.right >= other.left and self.top <= other.bottom and self.bottom >= other.top + +class Generator(): + rooms = [] + board = [] + + def __init__(self, width, height = None): + self.width = width + self.height = height or width + + for y in range(self.height): + self.board.append([]) + for _ in range(self.width): + self.board[y].append(0) + + self.place_rooms() + self.place_corridors() + + def place_rooms(self): + for _ in range(rand(10, 30)): + width = rand(4, 10) + height = rand(4, 10) + x = rand(0, 60) + y = rand(0, 60) + + if x + width > self.width: + x = self.width - width + + if y + height > self.height: + y = self.height - height + + collides = False + room = Room(x, y, width, height) + + for other_room in self.rooms: + if room.intersects(other_room): + collides = True + break + + if not collides: + self.place_room(room) + + def place_room(self, room): + for row in range(room.height): + for col in range(room.width): + y = room.y + row + x = room.x + col + + self.board[y][x] = 1 + + self.rooms.append(room) + + def place_corridors(self): + for i in range(0, len(self.rooms) - 1): + room1 = self.rooms[i] + room2 = self.rooms[i + 1] + + if rand(0, 2) == 0: + if room1.cx <= room2.cx: + self.horiz_corridor(room1.cx, room2.cx, room1.cy) + else: + self.horiz_corridor(room2.cx, room1.cx, room1.cy) + if room1.cy <= room2.cy: + self.vert_corridor(room1.cy, room2.cy, room2.cx) + else: + self.vert_corridor(room2.cy, room1.cy, room2.cx) + else: + if room1.cy <= room2.cy: + self.vert_corridor(room1.cy, room2.cy, room2.cx) + else: + self.vert_corridor(room2.cy, room1.cy, room2.cx) + if room1.cx <= room2.cx: + self.horiz_corridor(room1.cx, room2.cx, room1.cy) + else: + self.horiz_corridor(room2.cx, room1.cx, room1.cy) + + def horiz_corridor(self, x1, x2, y): + for row in range(y - 1, y + 2): + for col in range(x1 - 1, x2 + 2): + self.board[row][col] = 1 + + def vert_corridor(self, y1, y2, x): + for row in range(y1, y2 + 2): + for col in range(x - 1, x + 2): + self.board[row][col] = 1 + + def get_map(self): + # Map object + map = { + "tiles": [ + "floor_cobble.png", + "wall_cobble_down.png", + "wall_cobble_right.png", + "wall_cobble_up.png", + "wall_cobble_left.png", + "wall_cobble_corner_nw_inner.png", + "wall_cobble_corner_ne_inner.png", + "wall_cobble_corner_se_inner.png", + "wall_cobble_corner_sw_inner.png", + "wall_cobble_corner_nw_outer.png", + "wall_cobble_corner_ne_outer.png", + "wall_cobble_corner_se_outer.png", + "wall_cobble_corner_sw_outer.png" + ], + "renderLayers": [] + } + + # Generate walls + bounds = [] + for y in range(self.height): + bounds.append([]) + for x in range(self.width): + wall = 0 + if self.board[y][x] > 0: + for x2 in range(x - 1, x + 2): + for y2 in range(y - 1, y + 2): + if self.board[y2][x2] == 0: + wall += 1 + bounds[y].append(wall) + map["boundaries"] = bounds + + # Floor layer + layer1 = self.board.copy() + map["renderLayers"].append(layer1) + + # Wall layer + layer2 = [] + for y in range(self.height): + layer2.append([]) + for _ in range(self.width): + layer2[y].append(0) + + # Straight walls + for y in range(self.height): + for x in range(self.width): + if self.board[y][x] == 1: + tile = 0 + if x > 0 and x < self.width and self.board[y][x - 1] == 1 and self.board[y][x + 1] == 1: + if y == 0 or self.board[y - 1][x] == 0: + tile = 2 + elif y == self.height or self.board[y + 1][x] == 0: + tile = 4 + + if y > 0 and y < self.height and self.board[y - 1][x] == 1 and self.board[y + 1][x] == 1: + if x == 0 or self.board[y][x - 1] == 0: + tile = 3 + elif x == self.width or self.board[y][x + 1] == 0: + tile = 5 + + layer2[y][x] = tile + + # Corner walls (Im not sure how some of it works but whatever) + for y in range(self.height): + for x in range(self.width): + if bounds[y][x] > 0 and layer2[y][x] == 0: + tile = 0 + if (y > self.height or bounds[y + 1][x] > 0) and (x > self.width or bounds[y][x + 1] > 0): + if bounds[y][x] > 1: + tile = 6 + else: + tile = 10 + elif (y > self.height or bounds[y + 1][x] > 0) and (x < 1 or bounds[y][x - 1] > 0): + if bounds[y][x] > 1: + tile = 7 + else: + tile = 11 + elif (y < 1 or bounds[y - 1][x] > 0) and (bounds[y][x - 1] > 0): + if bounds[y][x] > 1: + tile = 8 + else: + tile = 12 + elif (y < 1 or bounds[y - 1][x] > 0) and (x >= self.width or bounds[y][x + 1] > 0): + if bounds[y][x] > 1: + tile = 9 + else: + tile = 13 + + layer2[y][x] = tile + + map["renderLayers"].append(layer2) + + return map diff --git a/src/map.py b/src/map.py index 916e47c..8b15d1d 100644 --- a/src/map.py +++ b/src/map.py @@ -21,15 +21,19 @@ class Map: # self.map = self.placer.populate(self.map) def collides(self, pos, rect): - px = int(math.floor(pos.x)) - py = int(math.floor(pos.y)) - for y in range(py - 1, py + 2): + METER = self.METER + cx = pos.x + (rect[0] / METER) + cy = pos.y + (rect[1] / METER) + px = int(math.floor(cx)) + py = int(math.floor(cy)) + cw = cx + (rect[2] / METER) + ch = cy + (rect[3] / METER) + for y in range(py - 1, py + 1 + math.ceil(rect[3] / METER)): for x in range(px - 1, px + 2): - if y >= 0 and y < len(self.map[1]) and x >=0 and x < len(self.map[1][y]): + if y >= 0 and y < len(self.map[1]) and x >= 0 and x < len(self.map[1][y]): tile = self.map[1][y][x] if tile and tile.is_solid(): - if pos.x + (rect[2] / self.METER) >= x and pos.x + (rect[0] / self.METER) <= (x + 1) and \ - pos.y + (rect[3] / self.METER) >= y and pos.y + (rect[1] / self.METER) <= (y + 1): + if cw >= x and cx <= (x + 1) and ch >= y and cy <= (y + 1): return True return False diff --git a/src/player.py b/src/player.py index deb700b..f2a940e 100644 --- a/src/player.py +++ b/src/player.py @@ -59,6 +59,6 @@ class Player: if controller.is_down("up") or controller.is_down("down") or \ controller.is_down("left") or controller.is_down("right"): - self.sprite.texture.set_animation(self.dir * 4, (self.dir * 4) + 3, self.speed * 3) + self.sprite.texture.set_animation(self.dir * 4, (self.dir * 4) + 3, self.speed * 2) else: self.sprite.texture.set_animation(self.dir * 4, self.dir * 4, 0) diff --git a/src/sprite.py b/src/sprite.py index 13cd91d..916812d 100644 --- a/src/sprite.py +++ b/src/sprite.py @@ -13,3 +13,6 @@ class Sprite: def set_rect(self, rect): self.rect = pygame.Rect(*rect) + + def get_rect(self): + return self.rect