Raycasting engine
Author: Jonhux
Added: 27. elokuuta 2011 kello 9.30
Edited: 27. elokuuta 2011 kello 9.30
Category: Sovellukset
Description
Teksturoimaton raycasting engine vuoden takaa
Toimii itsellä moitteetta
Quality 1 => fps 30
Quality 2 => fps 60
Code
Select all1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | // Jonhu
// 31.7.2010
SCREEN 640, 480
Const Map_Width = 20
Const Map_Height = 20
Dim Map( Map_Width, Map_Height )
LoadMap1()
// alkusijanti
posX# = 10.0
posY# = 2.0
// alku suuntavektorit (katsoo alussa "taaksepäin")
dirX# = -1.0
dirY# = 0.0
// tason sijainti kameralla
planeX# = 0.00
planeY# = 0.66
// nopeudet
MoveSpeed# = 0.1
RotSpeed# = 3.0
//taustan teko
background = MakeBackGroundImg()
Repeat
// taustalle liikkumaton kuva, joka tuo vähän tunnelmaa :D
DrawImage background,0,0
// piirretään kenttä
DrawRays( posX#, posY#, dirX#, dirY#, planeX#, planeY# )
// Liikkuminen eteen ja taakse
kerroin = KeyDown(cbkeyW) - KeyDown(cbkeyS) + UpKey() - DownKey()
If kerroin <> 0 Then
// tutkitaan uudet sijainnit x- ja y-suunnassa
collision_map1 = Map( RoundDown(posX + dirX * moveSpeed*kerroin), RoundDown(posY) )
collision_map2 = Map( RoundDown(posX), RoundDown(posY + dirY * moveSpeed*kerroin) )
// jos kartalla uusi sijainti ei ole seinän päällä sallitaan siirto
If collision_map1 + collision_map2 = 0 Then
posX# = posX# + dirX * moveSpeed * kerroin
posY# = posY# + dirY * moveSpeed * kerroin
EndIf
EndIf
// kääntyminen oikealle ja vasemmalle
kerroin = KeyDown(cbkeyA) - KeyDown(cbkeyD) + LeftKey() - RightKey()
If kerroin <> 0 Then
oldDirX# = dirX
oldPlaneX# = planeX
dirX# = dirX * Cos(rotSpeed*kerroin) - dirY * Sin(rotSpeed*kerroin)
dirY# = oldDirX * Sin(rotSpeed*kerroin) + dirY * Cos(rotSpeed*kerroin)
planeX# = planeX * Cos(rotSpeed*kerroin) - planeY * Sin(rotSpeed*kerroin)
planeY# = oldPlaneX * Sin(rotSpeed*kerroin) + planeY * Cos(rotSpeed*kerroin)
EndIf
Color cbwhite
Text 10,10,"FPS: "+FPS()
Text 10,30,posx+" : "+ posy
DrawScreen
Forever
Function DrawRays( posX#, posY#, dirX#, dirY#, planeX#, planeY#, quality = 2 )
// määritetään raycasting alueen koko
ProjectionPlane_w = ScreenWidth()
ProjectionPlane_h = ScreenHeight()
x% = 0
// käy läpi koko ProjectionPlane_w leveyden quality välein...
While ( x < ProjectionPlane_w )
// kameran x-sijainti
Camera_X# = 2.0 * Float(x%) / Float(ProjectionPlane_w) - 1.0 //x-coordinate in camera space
rayPosX# = posX
rayPosY# = posY
// rayn suuntavektori = nykyinen suunta + taso
rayDirX# = dirX + planeX * Camera_X
rayDirY# = dirY + planeY * Camera_X
// sijainti 2d-mapilla
mapx = RoundDown( rayPosX )
mapy = RoundDown( rayPosY )
// rayn pituus
deltaDistX# = Sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
deltaDistY# = Sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
If rayDirX < 0 Then
stepX% = -1
sideDistX# = (rayPosX# - mapX) * deltaDistX#
Else
stepX% = 1
sideDistX# = (mapX + 1.0 - rayPosX#) * deltaDistX#
EndIf
If rayDirY < 0 Then
stepY% = -1
sideDistY# = (rayPosY - mapY) * deltaDistY
Else
stepY% = 1
sideDistY# = (mapY + 1.0 - rayPosY) * deltaDistY
EndIf
// siirrytään seuraavaan tileen, kunnes törmätään seinään --> etsitään törmäys kohta
While Map( mapX, mapY ) = 0
If sideDistX# < sideDistY# Then
sideDistX + deltaDistX
mapX + stepX
side% = 0
Else
sideDistY + deltaDistY
mapY + stepY
side% = 1
EndIf
Wend
// kun ollaan törmätty seinään, niin side-muuttuja
// kertoo tapahtuiko törmäys x- vai y-suunnassa.
// side = 0 vaakataso
// side = 1 pystytaso
// kohtisuoran rayn etäisyys
If side = 0 Then
perpWallDist# = Abs((mapX - rayPosX# + (1.0 - Float(stepX)) / 2.0) / rayDirX#)
Else
perpWallDist# = Abs((mapY - rayPosY# + (1.0 - Float(stepY)) / 2.0) / rayDirY#)
EndIf
LineHeight# = Abs( ProjectionPlane_h / perpWallDist )
//viivan lähtökohta y-suunnassa
drawStartY% = ProjectionPlane_h / 2.0 - lineHeight / 2.0
If drawStartY < 0 Then drawStartY% = 0 // jos ulkona ruudulta, niin asetetaan nollaksi lähtökohta
// eri variset tilet seinassa:
If Map( mapX, mapY ) = 1 Then r = 120 : g = 120 : b = 120
If Map( mapX, mapY ) = 2 Then r = 220 : g = 120 : b = 120
If Map( mapX, mapY ) = 3 Then r = 120 : g = 120 : b = 220
// x- ja y-suuntaisille tileille eri kirkkaudet
If side = 1 Then v# = 0.7 Else v# = 1.0
Color r*v,g*v,b*v
// piirretään boksi..
Box x, drawstartY , quality, lineHeight
// lisätään x:sää tarkkuuden verran
x + quality
Wend
EndFunction
Function LoadMap1()
Dim map1(20) As String
map1(0) = " 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 1 1 1 1 1 "
map1(1) = " 1 0 0 1 0 0 3 0 0 0 0 0 0 0 3 0 0 1 1 1 "
map1(2) = " 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 "
map1(3) = " 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 "
map1(4) = " 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 "
map1(5) = " 1 1 1 1 1 2 1 0 0 0 1 1 1 1 1 1 1 0 0 1 "
map1(6) = " 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 "
map1(7) = " 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 "
map1(8) = " 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 "
map1(9) = " 1 0 0 0 0 0 0 0 0 0 3 1 1 0 0 0 0 0 0 1 "
map1(10) = " 1 0 0 0 1 1 1 0 0 0 2 1 1 0 0 0 0 0 0 1 "
map1(11) = " 1 0 0 0 0 0 3 0 0 0 1 1 1 0 0 0 0 0 0 1 "
map1(12) = " 1 0 0 1 1 0 2 0 0 0 0 0 0 0 0 0 1 1 1 1 "
map1(13) = " 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 "
map1(14) = " 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 "
map1(15) = " 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 "
map1(16) = " 1 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 1 "
map1(17) = " 1 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 "
map1(18) = " 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 "
map1(19) = " 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "
For y = 0 To 19
For x = 0 To 19
w$ = GetWord( map1(y), x+1 )
Map( x , y ) = Int(w)
Next x
Next y
EndFunction
// tekee taustan piirtämällä erivärisiä viivoja vaakatasoon taustaksi
Function MakeBackGroundImg()
img = MakeImage( ScreenWidth(),ScreenHeight())
DrawToImage img
For y=0 To ImageHeight(img)/2
Color 20,20,205-y/2
Line 0,y,ImageWidth(img),y
Next y
For y=ImageHeight(img) To ImageHeight(img)/2 Step -1
l = (y-ImageHeight(img)/2.0)
Color 20,20+l/2,10
Line 0,y,ImageWidth(img),y
Next y
DrawToScreen
Return img
EndFunction
|
Comments
#22 Sent by: MaGetzUb, 14. syyskuuta 2011 kello 1.15
Eteenpäin liikkeessä*
Leave a comment
You must be logged in to comment.
#21 Sent by: MaGetzUb, 14. syyskuuta 2011 kello 1.14
Nätti, mutta osa koodista hämmentää... Samaa kerroin muuttujaa käytetään että eteenpäin, sekä kääntymisessä. Miksi näin?