Last active 1693212965

A mini 2.5D engine in python

cubEngine.py Raw
1import math
2from kandinsky import *
3
4
5def shade_color(intensity, dist, way, color):
6 if color >= 255 - 20:
7 color = 255 - 20
8 if way:
9 ret = ((color / 255.0) + 0.1) * (intensity * (dist / 255.0))
10 else:
11 ret = ((color / 255.0) + 0.1) * (intensity * (255.0 / dist))
12
13 ret = color + 20 if ret > color + 20 else ret
14 ret = 0 if ret < 0 else ret
15
16 return int(ret)
17
18
19class CubColor:
20 def __init__(self, r, g, b):
21 self.r = r
22 self.g = g
23 self.b = b
24 self.shadedR = 0
25 self.shadedG = 0
26 self.shadedB = 0
27
28 def shade(self, intensity, dist, way):
29 self.shadedR = shade_color(intensity, dist, way, self.r)
30 self.shadedG = shade_color(intensity, dist, way, self.g)
31 self.shadedB = shade_color(intensity, dist, way, self.b)
32 return [self.shadedR, self.shadedG, self.shadedB]
33
34 def get_color(self):
35 return [self.r, self.g, self.b]
36
37
38class CubVector:
39 def __init__(self, x, y):
40 self.x = x
41 self.y = y
42
43 def translate(self, x, y):
44 self.x += x
45 self.y += y
46
47 def rotate(self, angle):
48 old = CubVector(self.x, self.y)
49 self.x = old.x * math.cos(math.radians(angle)) - old.y * math.sin(math.radians(angle))
50 self.y = old.x * math.sin(math.radians(angle)) + old.y * math.cos(math.radians(angle))
51
52
53class CubPlayer:
54 def __init__(self, pos, prov_dir):
55 self.pos = pos
56 self.dir = prov_dir
57 self.plan = CubVector(0, 0.66)
58 self.view_offset = 0
59
60 def move(self, angle, speed, prov_map):
61 dire = CubVector(self.dir.x, self.dir.y)
62
63 dire.rotate(angle)
64 n_pos = CubVector(
65 self.pos.x + dire.x / speed,
66 self.pos.y + dire.y / speed
67 )
68
69 if prov_map[int(n_pos.y + dire.y / (speed / 2))][int(n_pos.x + dire.x / (speed / 2))] == 1:
70 return
71 self.pos.x = n_pos.x
72 self.pos.y = n_pos.y
73
74 def look_sides(self, angle):
75 self.dir.rotate(angle)
76 self.plan.rotate(angle)
77
78 def look_up(self, speed):
79 if self.view_offset < 100:
80 self.view_offset += speed
81
82 def look_down(self, speed):
83 if self.view_offset > -100:
84 self.view_offset -= speed
85
86
87class CubRay:
88 def __init__(self, cam):
89 self.origin = CubVector(player.pos.x, player.pos.y)
90 self.dir = CubVector(
91 player.dir.x + player.plan.x * cam,
92 player.dir.y + player.plan.y * cam
93 )
94 self.mpos = CubVector(int(player.pos.x), int(player.pos.y))
95 self.dist = CubVector(
96 1 if self.dir.x == 0 else 0,
97 1 if self.dir.y == 0 else 0
98 )
99 if self.dir.x != 0 and self.dir.y != 0:
100 self.dist.x = abs(1 / self.dir.x)
101 self.dist.y = abs(1 / self.dir.y)
102 self.step = CubVector(1, 1)
103 self.sdist = CubVector(
104 (self.mpos.x + 1.0 - player.pos.x) * self.dist.x,
105 (self.mpos.y + 1.0 - player.pos.y) * self.dist.y
106 )
107 if self.dir.x < 0:
108 self.step.x = -1
109 self.sdist.x = (player.pos.x - self.mpos.x) * self.dist.x
110 if self.dir.y < 0:
111 self.step.y = -1
112 self.sdist.y = (player.pos.y - self.mpos.y) * self.dist.y
113 self.hit = 0
114 self.side = 0
115
116 def cast(self):
117 while self.hit == 0:
118 if self.sdist.x < self.sdist.y:
119 self.side = 0
120 self.sdist.x += self.dist.x
121 self.mpos.x += self.step.x
122 else:
123 self.side = 1
124 self.sdist.y += self.dist.y
125 self.mpos.y += self.step.y
126 if prov_map[int(self.mpos.y)][int(self.mpos.x)] == 1:
127 self.hit = 1
128
129 def calc(self, x):
130 wall = CubColor(255, 55, 0)
131
132 if self.side == 0:
133 dist = (self.mpos.x - player.pos.x + (1 - self.step.x) / 2) / self.dir.x
134 else:
135 dist = (self.mpos.y - player.pos.y + (1 - self.step.y) / 2) / self.dir.y
136
137 if dist == 0:
138 line_height = 0
139 else:
140 line_height = int(height / dist)
141
142 start = int(-line_height / 2 + height / 2 + player.view_offset)
143 end = int(line_height / 2 + height / 2 + player.view_offset)
144
145 return [wall.shade(5, dist, False), x, start, end]
146
147
148prov_map = [
149 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
150 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
151 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
152 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
153 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
154 [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
155 [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1],
156 [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
157 [1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
158 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
159 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
160 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
161 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
162 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
163 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
164 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
165 [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
166 [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
167 [1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
168 [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
169 [1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
170 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
171 [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
172 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
173]
174
175width = 320
176height = 222
177
178player = CubPlayer(CubVector(12.5, 10.5), CubVector(1, 0))
179ceil = CubColor(50, 50, 50)
180floor = CubColor(20, 20, 20)
181running = True
182
183
184def draw_line(sc_x, sc_y, color):
185 for i in range(sc_y[0], sc_y[1]):
186 set_pixel(sc_x, i, color)
187
188
189def render():
190 ceil = CubColor(50, 50, 50)
191 floor = CubColor(20, 20, 20)
192
193 #for x in range(width):
194 # draw_line(x, (0, height), (0,0,0))
195
196 for x in range(width):
197 cam = 2 * x / width - 1
198 ray = CubRay(cam)
199 ray.cast()
200 lst = ray.calc(x)
201 draw_line(lst[1], (0, lst[2]), ceil.get_color())
202 draw_line(lst[1], (lst[2], lst[3]), lst[0])
203 draw_line(lst[1], (lst[3], height), floor.get_color())
204
205
206def update(keys):
207 global running
208
209 tm = 4
210 if "right" in keys:
211 player.move(90, int(10 / tm), prov_map)
212 elif "left" in keys:
213 player.move(-90, int(10 / tm), prov_map)
214 if "down" in keys:
215 player.move(180, int(10 / tm), prov_map)
216 elif "up" in keys:
217 player.move(0, int(10 / tm), prov_map)
218 if "8" in keys:
219 player.look_up(int((height / 100)) * tm)
220 elif "5" in keys:
221 player.look_down(int((height / 100)) * tm)
222 if "4" in keys:
223 player.look_sides(int(width / -200) * tm)
224 elif "6" in keys:
225 player.look_sides(int(width / 200) * tm)
226 if "0" in keys:
227 running = False
228
229
230def game():
231 global running
232
233 #render()
234 running = True
235 while running:
236 keys = get_keys()
237 if keys != set():
238 update(keys)
239 render()

Powered by Opengist ⋅ Load: 135ms