World is recognizable
This commit is contained in:
parent
5942305f15
commit
f79b8bdb3e
113
game.py
113
game.py
|
|
@ -1,46 +1,74 @@
|
||||||
import pygame
|
import pygame
|
||||||
import maze
|
import maze
|
||||||
|
|
||||||
|
class Maze(maze.Maze):
|
||||||
|
|
||||||
|
def __init__(self, m: maze.Maze, s: int = 1):
|
||||||
|
self.__maze = m
|
||||||
|
self.__scale = s
|
||||||
|
|
||||||
|
@property
|
||||||
|
def width(self) -> int: return self.__maze.width * self.__scale
|
||||||
|
|
||||||
|
@property
|
||||||
|
def height(self) -> int: return self.__maze.height * self.__scale
|
||||||
|
|
||||||
|
@property
|
||||||
|
def highlighted(self) -> tuple[int,int] | None:
|
||||||
|
if self.__maze.highlighted is None: return None
|
||||||
|
return (
|
||||||
|
self.__maze.highlighted[0] * self.__scale,
|
||||||
|
self.__maze.highlighted[1] * self.__scale
|
||||||
|
)
|
||||||
|
|
||||||
|
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||||
|
return self.__maze[index[0] // self.__scale, index[1] // self.__scale]
|
||||||
|
|
||||||
|
def step(self) -> bool: return self.__maze.step()
|
||||||
|
|
||||||
|
def run(self, i=1_000_000) -> bool: return self.__maze.run(i)
|
||||||
|
|
||||||
def draw_map(
|
def draw_map(
|
||||||
screen: pygame.Surface,
|
screen: pygame.Surface,
|
||||||
player_pos: pygame.Vector2,
|
player_pos: pygame.Vector2,
|
||||||
player_dir: pygame.Vector2,
|
player_dir: pygame.Vector2,
|
||||||
world_map: maze.Maze,
|
world_map: maze.Maze,
|
||||||
):
|
):
|
||||||
cell_size = 10
|
|
||||||
screen.fill(pygame.Color(64,64,64))
|
screen.fill(pygame.Color(64,64,64))
|
||||||
|
|
||||||
pygame.draw.rect(screen, "blue", pygame.Rect(
|
pygame.draw.rect(screen, "blue", pygame.Rect(
|
||||||
(player_pos/cell_size)-(2.5,2.5) + (pygame.Vector2(screen.size) // 2),(5,5)))
|
(player_pos)-(2.5,2.5) + (pygame.Vector2(screen.size) // 2),(5,5)))
|
||||||
pygame.draw.line(
|
pygame.draw.line(
|
||||||
screen,
|
screen,
|
||||||
"blue",
|
"blue",
|
||||||
(player_pos/cell_size) + (pygame.Vector2(screen.size) // 2),
|
(player_pos) + (pygame.Vector2(screen.size) // 2),
|
||||||
(player_pos/cell_size) + (player_dir) + (pygame.Vector2(screen.size) // 2),
|
(player_pos) + (player_dir) + (pygame.Vector2(screen.size) // 2),
|
||||||
)
|
)
|
||||||
|
|
||||||
plane = pygame.Vector2(0,0.66)
|
plane = pygame.Vector2(0,0.66).rotate(player_dir.as_polar()[1])
|
||||||
|
|
||||||
for x in range(0, screen.width, 50):
|
for x in range(0, screen.width, 50):
|
||||||
camera = 2 * x / screen.width - 1
|
camera = 2 * x / screen.width - 1
|
||||||
|
# if True:
|
||||||
|
# camera = 0
|
||||||
ray_dir = player_dir.normalize() + (plane * camera)
|
ray_dir = player_dir.normalize() + (plane * camera)
|
||||||
|
|
||||||
wall_dist, side = ray(player_pos, ray_dir, world_map)
|
wall_dist, side = ray(player_pos, ray_dir, world_map, debug=True)
|
||||||
pygame.draw.line(
|
if side is not None:
|
||||||
screen,
|
pygame.draw.line(
|
||||||
pygame.Color(192,192,192) if side else pygame.Color(255,255,255),
|
screen,
|
||||||
(player_pos/cell_size) + (pygame.Vector2(screen.size) // 2),
|
pygame.Color(0,255,0) if side else pygame.Color(255,0,0),
|
||||||
(player_pos/cell_size) + (ray_dir * wall_dist) + (pygame.Vector2(screen.size) // 2),
|
(player_pos) + (pygame.Vector2(screen.size) // 2),
|
||||||
)
|
(player_pos) + (ray_dir * wall_dist) +
|
||||||
|
(pygame.Vector2(screen.size) // 2),
|
||||||
|
)
|
||||||
|
|
||||||
for y in range(world_map.height):
|
for y in range(world_map.height):
|
||||||
for x in range(world_map.width):
|
for x in range(world_map.width):
|
||||||
if not world_map[x, y]:
|
if not world_map[x, y]:
|
||||||
pygame.draw.rect(screen, pygame.Color(255,255,255), pygame.Rect(
|
pygame.draw.rect(screen, pygame.Color(255,255,255), pygame.Rect(
|
||||||
(pygame.Vector2(x, y) * cell_size) +
|
(pygame.Vector2(x, y)) +
|
||||||
(pygame.Vector2(screen.size) // 2),
|
(pygame.Vector2(screen.size) // 2), (1, 1)))
|
||||||
(cell_size, cell_size),
|
|
||||||
))
|
|
||||||
|
|
||||||
def draw_game(
|
def draw_game(
|
||||||
screen: pygame.Surface,
|
screen: pygame.Surface,
|
||||||
|
|
@ -50,7 +78,7 @@ def draw_game(
|
||||||
):
|
):
|
||||||
screen.fill(pygame.Color(0,0,0))
|
screen.fill(pygame.Color(0,0,0))
|
||||||
|
|
||||||
plane = pygame.Vector2(0,0.66)
|
plane = pygame.Vector2(0,0.66).rotate(player_dir.as_polar()[1])
|
||||||
|
|
||||||
for x in range(screen.width):
|
for x in range(screen.width):
|
||||||
camera = 2 * x / screen.width - 1
|
camera = 2 * x / screen.width - 1
|
||||||
|
|
@ -58,31 +86,35 @@ def draw_game(
|
||||||
|
|
||||||
wall_dist, side = ray(player_pos, ray_dir, world_map)
|
wall_dist, side = ray(player_pos, ray_dir, world_map)
|
||||||
|
|
||||||
lineHeight = int(screen.height / wall_dist)
|
if side is not None:
|
||||||
|
lineHeight = int(screen.height / max(wall_dist, 1e-3))
|
||||||
|
|
||||||
draw_start = -lineHeight / 2 + screen.height / 2
|
draw_start = -lineHeight / 2 + screen.height / 2
|
||||||
if draw_start < 0: draw_start = 0
|
if draw_start < 0: draw_start = 0
|
||||||
draw_end = lineHeight / 2 + screen.height / 2
|
draw_end = lineHeight / 2 + screen.height / 2
|
||||||
if draw_end >= screen.height: draw_end = screen.height - 1
|
if draw_end >= screen.height: draw_end = screen.height - 1
|
||||||
|
|
||||||
pygame.draw.line(
|
pygame.draw.line(
|
||||||
screen,
|
screen,
|
||||||
pygame.Color(192,192,192) if side else pygame.Color(255,255,255),
|
pygame.Color(192,192,192) if side else pygame.Color(255,255,255),
|
||||||
(x, draw_start),
|
(x, draw_start),
|
||||||
(x, draw_end),
|
(x, draw_end),
|
||||||
)
|
)
|
||||||
|
|
||||||
def ray(
|
def ray(
|
||||||
ray_pos: pygame.Vector2,
|
ray_pos: pygame.Vector2,
|
||||||
ray_dir: pygame.Vector2,
|
ray_dir: pygame.Vector2,
|
||||||
world_map: maze.Maze,
|
world_map: maze.Maze,
|
||||||
max_dis_squared: int = 100,
|
max_dis_squared: int = 10_000,
|
||||||
) -> tuple[float, int]:
|
debug: bool = False
|
||||||
|
) -> tuple[float, int | None]:
|
||||||
delta = pygame.Vector2(1/max(abs(ray_dir.x),1e-3),1/max(abs(ray_dir.y),1e-3))
|
delta = pygame.Vector2(1/max(abs(ray_dir.x),1e-3),1/max(abs(ray_dir.y),1e-3))
|
||||||
map_pos = pygame.Vector2(int(ray_dir.x),int(ray_dir.y))
|
map_pos = pygame.Vector2(int(ray_pos.x),int(ray_pos.y))
|
||||||
step = pygame.Vector2(0,0)
|
step = pygame.Vector2(0,0)
|
||||||
side_dis = pygame.Vector2(0,0)
|
side_dis = pygame.Vector2(0,0)
|
||||||
|
|
||||||
|
# if debug: print(map_pos)
|
||||||
|
|
||||||
if ray_dir.x < 0:
|
if ray_dir.x < 0:
|
||||||
step.x = -1
|
step.x = -1
|
||||||
side_dis.x = (ray_pos.x - map_pos.x) * delta.x
|
side_dis.x = (ray_pos.x - map_pos.x) * delta.x
|
||||||
|
|
@ -114,8 +146,17 @@ def ray(
|
||||||
map_pos.x < world_map.width and
|
map_pos.x < world_map.width and
|
||||||
map_pos.y < world_map.height and
|
map_pos.y < world_map.height and
|
||||||
world_map[int(map_pos.x),int(map_pos.y)]
|
world_map[int(map_pos.x),int(map_pos.y)]
|
||||||
) or side_dis.length_squared() > max_dis_squared:
|
): break
|
||||||
break
|
|
||||||
|
if (
|
||||||
|
map_pos.x < 0 or
|
||||||
|
map_pos.y < 0 or
|
||||||
|
map_pos.x > world_map.width or
|
||||||
|
map_pos.y > world_map.height or
|
||||||
|
side_dis.length_squared() > max_dis_squared
|
||||||
|
): return 0, None
|
||||||
|
|
||||||
|
# if debug: print(map_pos, side_dis)
|
||||||
|
|
||||||
if side == 0: perp_wall_dist = side_dis.x - delta.x
|
if side == 0: perp_wall_dist = side_dis.x - delta.x
|
||||||
else: perp_wall_dist = side_dis.y - delta.y
|
else: perp_wall_dist = side_dis.y - delta.y
|
||||||
|
|
@ -137,10 +178,10 @@ def game_loop():
|
||||||
running = True
|
running = True
|
||||||
dt = 0
|
dt = 0
|
||||||
|
|
||||||
player_pos = pygame.Vector2(10, 10)
|
player_pos = pygame.Vector2(6, 6)
|
||||||
player_dir = pygame.Vector2(-10, 0)
|
player_dir = pygame.Vector2(-4, 0)
|
||||||
|
|
||||||
world_map = maze.RecursiveBacktracker(15)
|
world_map = Maze(maze.RecursiveBacktracker(63), 4)
|
||||||
world_map.run()
|
world_map.run()
|
||||||
|
|
||||||
while running:
|
while running:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue