Mon systeme ne prend en compte que deux dimensions mais on peut tres bien lui appliquer un rendu 3D ^^
Voila de quel code j'ai démarré, c'est un de mes codes DarkBasic que j'ai codé pour faire du raycasting ^_^
Code : Tout sélectionner
InitSprite()
InitKeyboard()
OpenWindow(0, 0, 0, 800, 600, #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered, "DarkBasic rules ??")
OpenWindowedScreen(WindowID(), 0, 0, 800, 600, 0, 0, 0)
Declare fov(camera_x, camera_z, camera_a, camera_fov)
Global screen_w, screen_h, wall_w, wall_h, wall_d, maze_w, maze_d, column_a.f
screen_w = 320
screen_h = 240
wall_w = 64/2
wall_h = 256
wall_d = 64/2
maze_w = 7
maze_d = 5
Dim maze(maze_w-1, maze_d-1)
camera_x = 78
camera_y = wall_h/2
camera_z = 171/2
camera_a = 25
camera_fov = 60 ;field of view/champ de vision
camera_speed = 5
Dim grid_x(screen_w - 1)
Dim grid_z(screen_w - 1)
Dim distance.f(screen_w - 1)
column_a.f = (camera_fov + 0.0) / screen_w
distance.f = screen_w / (2 * Tan(0.01745329*camera_fov/2))
Restore maze
For z=1 To maze_d
For x=1 To maze_w
Read maze(x-1, z-1)
Next x
Next z
;screen = 0
;buffer = 1
;create bitmap buffer, screen_w, screen_h*2
;**********************************************************************************************
Repeat
ClearScreen(0, 0, 0)
ExamineKeyboard()
old_x = camera_x
old_z = camera_z
h_dir = 0
If KeyboardPushed(#PB_Key_Right) : h_dir + 1 : EndIf
If KeyboardPushed(#PB_Key_Left ) : h_dir - 1 : EndIf
v_dir = 0
If KeyboardPushed(#PB_Key_Up ) : v_dir + 1 : EndIf
If KeyboardPushed(#PB_Key_Down ) : v_dir - 1 : EndIf
h_dir * camera_speed
v_dir * camera_speed
camera_x + v_dir * Cos(0.01745329*camera_a)
camera_z + v_dir * Sin(0.01745329*camera_a)
camera_a + h_dir
mx = camera_x/wall_w
mz = camera_z/wall_d
If mx<0 Or mx>=maze_w Or mz<0 Or mz>=maze_d
camera_x = old_x
camera_z = old_z
EndIf
mx = camera_x/wall_w
mz = camera_z/wall_d
If maze(mx, mz)=1
camera_x = old_x
camera_z = old_z
EndIf
If StartDrawing( ScreenOutput() )
fov(camera_x, camera_z, camera_a, camera_fov)
FrontColor(0, 0, 255)
Locate(240, 0) : DrawText("x : " + Str(camera_x) + " px")
Locate(240, 16) : DrawText("z : " + Str(camera_z) + " pz")
Locate(240, 32) : DrawText("angle : " + Str(camera_a) + "°")
StopDrawing()
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
;**********************************************************************************************
Procedure.f min(a.f, b.f)
If b < a : a = b : EndIf
ProcedureReturn a
EndProcedure
Procedure.f max(a.f, b.f)
If b > a : a = b : EndIf
ProcedureReturn a
EndProcedure
Procedure.f WrapValue(Angle.f)
Angle - Int(Angle / 360) * 360
If Angle < 0
Angle + 360
EndIf
ProcedureReturn Angle
EndProcedure
Procedure draw_maze(mw, md, ww, wd)
Box(0, 0, mw*ww, md*wd, $FFFFFF)
For z=0 To md-1
For x=0 To mw-1
Box(x*ww+1, z*wd+1, ww-2, wd-2, maze(x, z)*$00FFFF)
Next x
Next z
EndProcedure
Procedure fov(camera_x, camera_z, camera_a, camera_fov)
draw_maze(maze_w, maze_d, wall_w, wall_d)
alpha.f = wrapvalue(camera_a - camera_fov / 2)
For x=0 To screen_w-1
;initialisation
tan_alpha.f = 0
v_distance.f = 0
h_distance.f = 0
;Recherche verticale
If Sin(0.01745329*alpha) <> 0
If alpha<180
If alpha <> 90 : tan_alpha = Tan(0.01745329*alpha) : EndIf
v_dz = wall_d
v_grid_z = camera_z / wall_d * wall_d + wall_d + 1
Else
If alpha <> 270 : tan_alpha = Tan(0.01745329*alpha) : EndIf
v_dz = 0-wall_d
v_grid_z = camera_z / wall_d * wall_d - 1
EndIf
If tan_alpha = 0
v_dx = 0
v_grid_x = camera_x
Else
v_dx = v_dz / tan_alpha
v_grid_x = camera_x + (v_grid_z - camera_z) / tan_alpha
EndIf
gx = v_grid_x / wall_w
gz = v_grid_z / wall_d
If gx>=0 And gx<maze_w And gz>=0 And gz<maze_d
If maze(gx, gz) = 0
Repeat
v_grid_x + v_dx
v_grid_z + v_dz
gx = v_grid_x / wall_w
gz = v_grid_z / wall_d
If gx<0 Or gx>=maze_w Or gz<0 Or gz>=maze_d : Break : EndIf
If maze(gx, gz) : v_distance = Sqr((camera_x - v_grid_x)*(camera_x - v_grid_x) + (camera_z - v_grid_z)*(camera_z - v_grid_z)) : EndIf
Until v_distance <> 0
Else
v_distance = Sqr((camera_x - v_grid_x)*(camera_x - v_grid_x) + (camera_z - v_grid_z)*(camera_z - v_grid_z))
EndIf
EndIf
EndIf
;Recherche horizontale
If tan_alpha <> 0 Or Sin(0.01745329*alpha) = 0
If alpha>=90 And alpha<270
h_dx = 0-wall_w
h_grid_x = camera_x / wall_w * wall_w - 1
Else
h_dx = wall_w
h_grid_x = camera_x / wall_w * wall_w + wall_w + 1
EndIf
h_dz = h_dx * tan_alpha
h_grid_z = camera_z + (h_grid_x - camera_x) * tan_alpha
gx = h_grid_x / wall_w
gz = h_grid_z / wall_d
If gx>=0 And gx<maze_w And gz>=0 And gz<maze_d
If maze(gx, gz) = 0
Repeat
h_grid_x + h_dx
h_grid_z + h_dz
gx = h_grid_x / wall_w
gz = h_grid_z / wall_d
If gx<0 Or gx>=maze_w Or gz<0 Or gz>=maze_d : Break : EndIf
If maze(gx, gz) : h_distance = Sqr((camera_x - h_grid_x)*(camera_x - h_grid_x) + (camera_z - h_grid_z)*(camera_z - h_grid_z)) : EndIf
Until h_distance <> 0
Else
h_distance = Sqr((camera_x - h_grid_x)*(camera_x - h_grid_x) + (camera_z - h_grid_z)*(camera_z - h_grid_z))
EndIf
EndIf
EndIf
alpha = wrapvalue(alpha + column_a)
If v_distance <> 0 And h_distance <> 0
distance(x) = min(v_distance, h_distance)
Else
distance(x) = max(v_distance, h_distance)
EndIf
If distance(x) = v_distance
grid_x(x) = v_grid_x
grid_z(x) = v_grid_z
Else
grid_x(x) = h_grid_x
grid_z(x) = h_grid_z
EndIf
;**********************************log**********************************
If x > 0
LineXY(camera_x, camera_z, grid_x(x), grid_z(x), $0000FF)
EndIf
;**********************************log**********************************
Next x
EndProcedure
DataSection
maze:
Data.l 1,1,1,1,1,1,1
Data.l 1,0,0,0,0,0,1
Data.l 1,0,0,0,1,0,1
Data.l 1,0,0,0,0,0,1
Data.l 1,1,1,0,1,1,1
EndDataSection
Je reprend ce principe en y ajoutant la possibilité d'une portée limitée (comme dans metal gear solid =)
La différence c'est qu'au lieu de me servir des rayons, je me sers du contour du champ de vision, ca me permet de savoir tres facilement si aux coordonées X, Z on se trouve dans le champ de vision sous windows