Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cache optimised update 1 #8

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions boom.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import pygame
import math
import functools

wall_texture_path = 'wall.png'
floor_texture_path = 'floor.png'
sky_texture_path = 'sky.png'

# 3 functions to cache the calculated trig values
cached_sin = functools.cache(math.sin)
cached_cos = functools.cache(math.cos)
cached_tan = functools.cache(math.tan)

world = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
Expand Down Expand Up @@ -40,8 +46,8 @@ def lighting(screen, doomguy_pos, doomguy_vector):

main_vector = doomguy_vector - (math.pi / 3) / 2 + 0.1
for ray in range(800):
sin_a = math.sin(main_vector)
cos_a = math.cos(main_vector)
sin_a = cached_sin(main_vector)
cos_a = cached_cos(main_vector)

y_hor, dy = (y_map + 1, 1) if sin_a > 0 else (y_map - 1e-6, -1)

Expand Down Expand Up @@ -80,9 +86,9 @@ def lighting(screen, doomguy_pos, doomguy_vector):
else:
depth = depth_hor

depth *= math.cos(doomguy_vector - main_vector)
depth *= cached_cos(doomguy_vector - main_vector)

proj_height = 800 / math.tan((math.pi / 3) / 2) / (depth + 0.0001)
proj_height = 800 / cached_tan((math.pi / 3) / 2) / (depth + 0.0001)

color = [255 / (1 + depth ** 5 * 0.00002)] * 3
pygame.draw.rect(screen, color, (ray * scale, 540 - proj_height // 2, scale, proj_height))
Expand All @@ -108,8 +114,8 @@ def check_wall_collision(x, y):
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_q):
pygame.quit()

sin_a = math.sin(doomguy_vector)
cos_a = math.cos(doomguy_vector)
sin_a = cached_sin(doomguy_vector)
cos_a = cached_cos(doomguy_vector)
dx, dy = 0, 0
speed = doomguy_speed * dt
speed_sin = speed * sin_a
Expand Down
158 changes: 158 additions & 0 deletions boom_test_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import pygame
import math
import timeit

wall_texture_path = 'wall.png'
floor_texture_path = 'floor.png'
sky_texture_path = 'sky.png'

world = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
]

walls = {}

for l, row in enumerate(world):
for n, value in enumerate(row):
if value:
walls[(n, l)] = value


doomguy_pos = 1.5, 5
doomguy_vector = 0
doomguy_speed = 2
doomguy_sens = 2
fov = math.pi / 3
scale = 1600 // 600

code_without_cache = """
def lighting(screen, doomguy_pos, doomguy_vector):
ox, oy = doomguy_pos
x_map, y_map = int(ox), int(oy)

main_vector = doomguy_vector - (math.pi / 3) / 2 + 0.1
for ray in range(800):
sin_a = math.sin(main_vector)
cos_a = math.cos(main_vector)

y_hor, dy = (y_map + 1, 1) if sin_a > 0 else (y_map - 1e-6, -1)

depth_hor = (y_hor - oy) / sin_a
x_hor = ox + depth_hor * cos_a

delta_depth = dy / sin_a
dx = delta_depth * cos_a

for i in range(20):
tile_hor = int(x_hor), int(y_hor)
if tile_hor in walls:
break
x_hor += dx
y_hor += dy
depth_hor += delta_depth

x_vert, dx = (x_map + 1, 1) if cos_a > 0 else (x_map - 1e-6, -1)

depth_vert = (x_vert - ox) / cos_a
y_vert = oy + depth_vert * sin_a

delta_depth = dx / cos_a
dy = delta_depth * sin_a

for i in range(20):
tile_vert = int(x_vert), int(y_vert)
if tile_vert in walls:
break
x_vert += dx
y_vert += dy
depth_vert += delta_depth

if depth_vert < depth_hor:
depth = depth_vert
else:
depth = depth_hor

depth *= math.cos(doomguy_vector - main_vector)

proj_height = 800 / math.tan((math.pi / 3) / 2) / (depth + 0.0001)

color = [255 / (1 + depth ** 5 * 0.00002)] * 3
pygame.draw.rect(screen, color, (ray * scale, 540 - proj_height // 2, scale, proj_height))

main_vector += (math.pi / 3) / 800
"""

code_with_cache = """
def lighting(screen, doomguy_pos, doomguy_vector):
ox, oy = doomguy_pos
x_map, y_map = int(ox), int(oy)

main_vector = doomguy_vector - (math.pi / 3) / 2 + 0.1
for ray in range(800):
sin_a = cached_sin(main_vector)
cos_a = cached_cos(main_vector)

y_hor, dy = (y_map + 1, 1) if sin_a > 0 else (y_map - 1e-6, -1)

depth_hor = (y_hor - oy) / sin_a
x_hor = ox + depth_hor * cos_a

delta_depth = dy / sin_a
dx = delta_depth * cos_a

for i in range(20):
tile_hor = int(x_hor), int(y_hor)
if tile_hor in walls:
break
x_hor += dx
y_hor += dy
depth_hor += delta_depth

x_vert, dx = (x_map + 1, 1) if cos_a > 0 else (x_map - 1e-6, -1)

depth_vert = (x_vert - ox) / cos_a
y_vert = oy + depth_vert * sin_a

delta_depth = dx / cos_a
dy = delta_depth * sin_a

for i in range(20):
tile_vert = int(x_vert), int(y_vert)
if tile_vert in walls:
break
x_vert += dx
y_vert += dy
depth_vert += delta_depth

if depth_vert < depth_hor:
depth = depth_vert
else:
depth = depth_hor

depth *= cached_cos(doomguy_vector - main_vector)

proj_height = 800 / cached_tan((math.pi / 3) / 2) / (depth + 0.0001)

color = [255 / (1 + depth ** 5 * 0.00002)] * 3
pygame.draw.rect(screen, color, (ray * scale, 540 - proj_height // 2, scale, proj_height))

main_vector += (math.pi / 3) / 800
"""


# performance before cache implementation
print("\nperformance before cache implementation:")
print(timeit.timeit(stmt=code_without_cache, number=1))
# performance after cache implementation
print("\nperformance after cache implementation:")
print(timeit.timeit(stmt=code_with_cache, number=1))