Seite 1 von 3

Raycasting

Verfasst: 26.10.2006 21:05
von AndyX
Hab den C++-Source aus diesem Tutorial nach PB übersetzt. Für alle die so Dinge mögen ^_^ hat sicherlich noch Platz für Optimierungen, aber er funktioniert auf jeden Fall.

Code: Alles auswählen

;eine kleine Raycasting Engine (Flat shaded)
;Controls: Pfeiltasten (gehen/drehen)
;  A,D: strafen

#mapWidth = 24
#mapHeight = 24

Global Dim worldMap.l(#mapWidth,#mapHeight)
For j = 0 To 24
  For i = 0 To 24
    If j = 0 Or j = 24 Or i = 0 Or i = 24
      worldMap(i,j) = 1
    EndIf
    If i = 12 And j = 12
      worldMap(i,j) = 2
    EndIf
  Next i
Next j

posX.f = 22
posY.f = 12
dirX.f = -1
dirY.f = 0
planeX.f = 0
planeY.f = 0.66
time = 0
oldTime = 0

InitKeyboard()
InitSprite()
OpenScreen(512,384,32,"3D")

Repeat
  Delay(0)
  ClearScreen(0)
  StartDrawing(ScreenOutput())
  Box(0,0,512,192,RGB(90,150,220))
  Box(0,192,512,192,RGB(160,160,160))
  For x = 0 To 512
    cameraX.f = 2 * x / 512 - 1
    rayPosX.f = posX
    rayPosY.f = posY
    rayDirX.f = dirX + planeX * cameraX
    rayDirY.f = dirY + planeY * cameraX
    mapx = Int(rayPosX)
    mapy = Int(rayPosY)
    sideDistX.f
    sideDistY.f
    deltaDistX.f = Sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
    deltaDistY.f = Sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
    perpWallDist.f
    stepX.l
    stepY.l
    hit.l = 0
    side.l
    If rayDirX < 0
      stepX = -1
      sideDistX = (rayPosX - mapx) * deltaDistX
    Else
      stepX = 1
      sideDistX = (mapx + 1.0 - rayPosX) * deltaDistX
    EndIf
    If rayDirY < 0
      stepY = -1
      sideDistY = (rayPosY - mapy) * deltaDistY
    Else
      stepY = 1
      sideDistY = (mapy + 1.0 - rayPosY) * deltaDistY
    EndIf
    While hit = 0 
      If sideDistX < sideDistY
        sideDistX + deltaDistX
        mapx + stepX
        side = 0
      Else
        sideDistY + deltaDistY
        mapy + stepY
        side = 1
      EndIf               
      If worldMap(mapx,mapy) > 0
        hit = 1
      EndIf
    Wend
    If side = 0
      perpWallDist = Abs((mapx - rayPosX + (1 - stepX) / 2) / rayDirX)
    Else
      perpWallDist = Abs((mapy - rayPosY + (1 - stepY) / 2) / rayDirY)
    EndIf
    lineHeight = Abs(Int(384 / perpWallDist))
    drawStart = -lineHeight / 2 + 384 / 2
    If drawStart < 0
      drawStart = 0
    EndIf
    drawEnd = lineHeight / 2 + 384 / 2
    If drawEnd >= 384
      drawEnd = 384 - 1
    EndIf
    If worldMap(mapx,mapy) = 1
      color = RGB(255,0,0)
    ElseIf worldMap(mapx,mapy) = 2
      color = RGB(0,255,0)
    Else
      color = RGB(0,0,255)
    EndIf
    If side = 1
      color = RGB(Red(color)/2,Green(color)/2,Blue(color)/2)
    EndIf
    LineXY(x,drawStart,x,drawEnd,color)
  Next x
  oldTime = time
  time = ElapsedMilliseconds()
  frameTime.f = (time - oldTime) / 1000.0
  DrawingMode(1)
  DrawText(0,0,StrF(1.0 / frameTime),RGB(255,255,255))
  StopDrawing()
  FlipBuffers()
  moveSpeed.f = frameTime * 5.0
  rotSpeed.f = frameTime * 3.0 
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)
    If(worldMap(Int(posX + dirX * moveSpeed),Int(posY)) = #False)
      posX + dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + dirY * moveSpeed)) = #False)
      posY + dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Down)
    If(worldMap(Int(posX - dirX * moveSpeed),Int(posY)) = #False)
      posX - dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - dirY * moveSpeed)) = #False)
      posY - dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_A)
    If(worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = #False)
      posX - planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = #False)
      posY - planeY * moveSpeed
    EndIf
  ElseIf KeyboardPushed(#PB_Key_D)
    If(worldMap(Int(posX + planeX * moveSpeed),Int(posY)) = #False)
      posX + planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + planeY * moveSpeed)) = #False)
      posY + planeY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Right)
    oldDirX.f = dirX
    dirX = dirX * Cos(-rotSpeed) - dirY * Sin(-rotSpeed)
    dirY = oldDirX * Sin(-rotSpeed) + dirY * Cos(-rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(-rotSpeed) - planeY * Sin(-rotSpeed)
    planeY = oldPlaneX * Sin(-rotSpeed) + planeY * Cos(-rotSpeed)
  EndIf
  If KeyboardPushed(#PB_Key_Left)
    oldDirX.f = dirX
    dirX = dirX * Cos(rotSpeed) - dirY * Sin(rotSpeed)
    dirY = oldDirX * Sin(rotSpeed) + dirY * Cos(rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(rotSpeed) - planeY * Sin(rotSpeed)
    planeY = oldPlaneX * Sin(rotSpeed) + planeY * Cos(rotSpeed)
  EndIf
Until KeyboardPushed(1)
viel Spaß :D

Verfasst: 26.10.2006 22:31
von Kekskiller
Nett. Ich hatte auch von dem Tutorial gelernt. Aber leider hab ich dann mit fortschreitender selfmade-Engine nur noch Spaghetticode fabriziert :) . Versuch dich dochmal an Texturen oder gar an Wänden auf Vektorbasis. Bei mir hat das fast Jahr gedauert, bis ich alles hinbekommen habe.

Verfasst: 26.10.2006 22:51
von Zaphod
Wände auf Vektorbasis würde man mit einem etwas anderen Algorithmus Raycasten, es macht deswegen keinen Sinn einen Blockbasierten algorithmus zu schreiben mit der Absicht ihn zu erweitern.

Das einfügen von Texturen ist aber kein großes Problem, ich hab dafür ohne Tutorial etwa 3 Stunden gebraucht und ich bin alles andere als ein Matheass.

Verfasst: 27.10.2006 18:28
von Kekskiller
Ich selber habe meinen Raycaster von Block auf Vektor umgebaut. Es war nur ein Vorschlag, was es anderes probieren könnte. Sei nicht so grantig.

Verfasst: 27.10.2006 18:28
von Kekskiller
Bitte löschen, Board nölt.

Verfasst: 28.10.2006 16:52
von AndyX
Texturen :)

Code: Alles auswählen

Procedure floor(x.f)
  ProcedureReturn Round(x,0)
EndProcedure

#mapWidth = 23
#mapHeight = 23
#texWidth = 128
#texHeight = 128
w = 800
h = 600

Global Dim worldMap.l(#mapWidth,#mapHeight)
Global Dim buffer.l(w,h)
Global Dim texture.l(8,#texWidth,#texHeight)

Restore wrldmap
For j = 0 To #mapHeight
  For i = 0 To #mapWidth
    Read worldMap(i,j)
  Next i
Next j

posX.f = 22
posY.f = 12
dirX.f = -1
dirY.f = 0
planeX.f = 0
planeY.f = 0.66
time = 0
oldTime = 0

For x = 0 To #texWidth
  For y = 0 To #texHeight
    xorcolor = (x * 256 / #texWidth) ! (y * 256 / #texHeight)
    xcolor = x * 256 / #texWidth
    ycolor = y * 256 / #texHeight
    xycolor = y * 128 / #texHeight + x * 128 / #texWidth
    texture(0,x,y) = (65536 * 254 * (x <> y And x <> #texWidth - y))
    texture(1,x,y) = (xycolor + 256 * xycolor + 65536 * xycolor)
    texture(2,x,y) = (256 * xycolor + 65536 * xycolor)
    texture(3,x,y) = (xorcolor + 256 * xorcolor + 65536 * xorcolor)
    texture(4,x,y) = (256 * xorcolor)
    texture(5,x,y) = (65536 * 192 * (x % 16 And y % 16))
    texture(6,x,y) = (65536 * ycolor)
    texture(7,x,y) = (128 + 256 * 128 + 65536 * 128)
  Next y
Next x

InitKeyboard()
InitSprite()
OpenScreen(w,h,32,"3D")

Repeat
  Delay(0)
  ClearScreen(0)
  For x = 0 To w
    cameraX.f = 2 * x / w - 1
    rayPosX.f = posX
    rayPosY.f = posY
    rayDirX.f = dirX + planeX * cameraX
    rayDirY.f = dirY + planeY * cameraX
    mapx = Int(rayPosX)
    mapy = Int(rayPosY)
    sideDistX.f
    sideDistY.f
    deltaDistX.f = Sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
    deltaDistY.f = Sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
    perpWallDist.f
    stepX.l
    stepY.l
    hit.l = 0
    side.l
    If rayDirX < 0
      stepX = -1
      sideDistX = (rayPosX - mapx) * deltaDistX
    Else
      stepX = 1
      sideDistX = (mapx + 1.0 - rayPosX) * deltaDistX
    EndIf
    If rayDirY < 0
      stepY = -1
      sideDistY = (rayPosY - mapy) * deltaDistY
    Else
      stepY = 1
      sideDistY = (mapy + 1.0 - rayPosY) * deltaDistY
    EndIf
    While hit = 0 
      If sideDistX < sideDistY
        sideDistX + deltaDistX
        mapx + stepX
        side = 0
      Else
        sideDistY + deltaDistY
        mapy + stepY
        side = 1
      EndIf               
      If worldMap(mapx,mapy) > 0
        hit = 1
      EndIf
    Wend
    If side = 0
      perpWallDist = Abs((mapx - rayPosX + (1 - stepX) / 2) / rayDirX)
    Else
      perpWallDist = Abs((mapy - rayPosY + (1 - stepY) / 2) / rayDirY)
    EndIf
    lineHeight = Abs(Int(h / perpWallDist))
    drawStart = -lineHeight / 2 + h / 2
    If drawStart < 0
      drawStart = 0
    EndIf
    drawEnd = lineHeight / 2 + h / 2
    If drawEnd >= h
      drawEnd = h - 1
    EndIf
    texNum = worldMap(mapx,mapy) - 1
    wallX.f
    If side = 1
      wallX = rayPosX + ((mapy - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
    Else
      wallX = rayPosY + ((mapx - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
    EndIf
    wallX - floor(wallX)
    texX = Int(wallX * #texWidth)
    If(side = 0 And rayDirX > 0)
      texX = #texWidth - texX - 1
    EndIf
    If(side = 1 And rayDirY < 0)
      texX = #texWidth - texX - 1
    EndIf
    For y = drawStart To drawEnd 
      d = y * 256 - h * 128 + lineHeight * 128
      texY = ((d * #texHeight) / lineHeight) / 256
      color = texture(texNum,texX,texY)
      If side = 1
        color = (color >> 1) & 8355711
      EndIf
      buffer(x,y) = color            
    Next y
  Next x
  StartDrawing(ScreenOutput())
  For x = 0 To w-1
    For y = 0 To h-1
      Plot(x,y,buffer(x,y))
      buffer(x,y) = 0
    Next y
  Next x
  oldTime = time
  time = ElapsedMilliseconds()
  frameTime.f = (time - oldTime) / 1000.0
  DrawingMode(1)
  DrawText(0,0,StrF(1.0 / frameTime),RGB(255,255,255))
  StopDrawing()
  FlipBuffers()
  moveSpeed.f = frameTime * 5.0
  rotSpeed.f = frameTime * 3.0 
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)
    If(worldMap(Int(posX + dirX * moveSpeed),Int(posY)) = #False)
      posX + dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + dirY * moveSpeed)) = #False)
      posY + dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Down)
    If(worldMap(Int(posX - dirX * moveSpeed),Int(posY)) = #False)
      posX - dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - dirY * moveSpeed)) = #False)
      posY - dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_A)
    If(worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = #False)
      posX - planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = #False)
      posY - planeY * moveSpeed
    EndIf
  ElseIf KeyboardPushed(#PB_Key_D)
    If(worldMap(Int(posX + planeX * moveSpeed),Int(posY)) = #False)
      posX + planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + planeY * moveSpeed)) = #False)
      posY + planeY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Right)
    oldDirX.f = dirX
    dirX = dirX * Cos(-rotSpeed) - dirY * Sin(-rotSpeed)
    dirY = oldDirX * Sin(-rotSpeed) + dirY * Cos(-rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(-rotSpeed) - planeY * Sin(-rotSpeed)
    planeY = oldPlaneX * Sin(-rotSpeed) + planeY * Cos(-rotSpeed)
  EndIf
  If KeyboardPushed(#PB_Key_Left)
    oldDirX.f = dirX
    dirX = dirX * Cos(rotSpeed) - dirY * Sin(rotSpeed)
    dirY = oldDirX * Sin(rotSpeed) + dirY * Cos(rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(rotSpeed) - planeY * Sin(rotSpeed)
    planeY = oldPlaneX * Sin(rotSpeed) + planeY * Cos(rotSpeed)
  EndIf
Until KeyboardPushed(1)

End
DataSection
wrldmap:
Data.l 4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,3,0,0,0,5,8,0,5,8,0,5,8,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,7,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,6,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,5,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,4,4,4,4,4,0,4,4,4,0,0,0,2,2,2,2,2,2,2,3,3,3,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,2,0,2,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,2,0,2,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
EndDataSection

Verfasst: 28.10.2006 17:15
von Zaphod
Garnicht übel ;)

Verfasst: 28.10.2006 18:04
von Fluid Byte
Danke AndyX, das ist exzellenter code! Ich wollte ähnliches auch schon mal schreiben bin aber nie dazu gekommen bzw. hatte keinen Bock mich damit zu befassen. :mrgreen:

PS: Woher kenn ich diese graue Textur bloß? Ach ja! Das ist das "Xor Checker" preset für den "Expression" Generator in TextureMaker! :wink:

Verfasst: 28.10.2006 23:40
von AndyX
Texturiert mit Boden u. Decke:

(benötigt das Texturpaket von hier -> Paket)

Code: Alles auswählen

Macro floor(x)
  Round(x,0)
EndMacro
Macro ColorRGB(r,g,b)
  ((r&$FF)+((g&$FF)<<8)+((b&$FF)<<16))
EndMacro

#mapWidth = 23
#mapHeight = 23
#texWidth = 63
#texHeight = 63
w = 512
h = 384

Global Dim worldMap.l(#mapWidth,#mapHeight)
Global Dim buffer.l(w,h)
Global Dim texture.l(8,#texWidth,#texHeight)

Restore wrldmap
For j = 0 To #mapHeight
  For i = 0 To #mapWidth
    Read worldMap(i,j)
  Next i
Next j

posX.f = 20
posY.f = 12
dirX.f = -1
dirY.f = 0
planeX.f = 0
planeY.f = 0.66
time = 0
oldTime = 0

InitKeyboard()
InitSprite()
OpenScreen(w,h,32,"3D")
StartDrawing(ScreenOutput())
DrawingMode(1)
DrawText(10,10,"wird geladen...",RGB(0,255,0))
StopDrawing()
FlipBuffers()

LoadSprite(8,"barrel.bmp")
LoadSprite(0,"bluestone.bmp")
LoadSprite(1,"colorstone.bmp")
LoadSprite(2,"eagle.bmp")
LoadSprite(9,"greenlight.bmp")
LoadSprite(3,"greystone.bmp")
LoadSprite(4,"mossy.bmp")
LoadSprite(10,"pillar.bmp")
LoadSprite(5,"purplestone.bmp")
LoadSprite(6,"redbrick.bmp")
LoadSprite(7,"wood.bmp")

For i = 0 To 7
  StartDrawing(SpriteOutput(i))
  For x = 0 To #texWidth
    For y = 0 To #texHeight
      c = Point(x,y)
      texture(i,x,y) = c
    Next y
  Next x
  StopDrawing()
Next i

Repeat
  For x = 0 To w
    cameraX.f = 2 * x / w - 1
    rayPosX.f = posX
    rayPosY.f = posY
    rayDirX.f = dirX + planeX * cameraX
    rayDirY.f = dirY + planeY * cameraX
    mapx = Int(rayPosX)
    mapy = Int(rayPosY)
    sideDistX.f
    sideDistY.f
    deltaDistX.f = Sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
    deltaDistY.f = Sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
    perpWallDist.f
    stepX.l
    stepY.l
    hit.l = 0
    side.l
    If rayDirX < 0
      stepX = -1
      sideDistX = (rayPosX - mapx) * deltaDistX
    Else
      stepX = 1
      sideDistX = (mapx + 1.0 - rayPosX) * deltaDistX
    EndIf
    If rayDirY < 0
      stepY = -1
      sideDistY = (rayPosY - mapy) * deltaDistY
    Else
      stepY = 1
      sideDistY = (mapy + 1.0 - rayPosY) * deltaDistY
    EndIf
    While hit = 0 
      If sideDistX < sideDistY
        sideDistX + deltaDistX
        mapx + stepX
        side = 0
      Else
        sideDistY + deltaDistY
        mapy + stepY
        side = 1
      EndIf               
      If worldMap(mapx,mapy) > 0
        hit = 1
      EndIf
    Wend
    If side = 0
      perpWallDist = Abs((mapx - rayPosX + (1 - stepX) / 2) / rayDirX)
    Else
      perpWallDist = Abs((mapy - rayPosY + (1 - stepY) / 2) / rayDirY)
    EndIf
    lineHeight = Abs(Int(h / perpWallDist))
    drawStart = -lineHeight / 2 + h / 2
    If drawStart < 0
      drawStart = 0
    EndIf
    drawEnd = lineHeight / 2 + h / 2
    If drawEnd >= h
      drawEnd = h - 1
    EndIf
    texNum = worldMap(mapx,mapy) - 1
    wallX.f
    If side = 1
      wallX = rayPosX + ((mapy - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
    Else
      wallX = rayPosY + ((mapx - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
    EndIf
    wallX - floor(wallX)
    texX = Int(wallX * #texWidth)
    If(side = 0 And rayDirX > 0)
      texX = #texWidth - texX - 1
    EndIf
    If(side = 1 And rayDirY < 0)
      texX = #texWidth - texX - 1
    EndIf
    For y = drawStart To drawEnd 
      d = y * 256 - h * 128 + lineHeight * 128
      texY = ((d * #texHeight) / lineHeight) / 256
      color = texture(texNum,texX,texY)
      If side = 1
        color = (color >> 1) & 8355711
      EndIf
      buffer(x,y) = color            
    Next y
    floorXWall.f
    floorYWall.f
    If side = 0 And rayDirX > 0
      floorXWall = mapx
      floorYWall = mapy + wallX
    ElseIf side = 0 And rayDirX < 0
      floorXWall = mapx + 1.0
      floorYWall = mapy + wallX
    ElseIf side = 1 And rayDirY > 0
      floorXWall = mapx + wallX
      floorYWall = mapy
    Else
      floorXWall = mapx + wallX
      floorYWall = mapy + 1.0
    EndIf
    distWall.f
    distPlayer.f
    currentDist.f  
    distWall = perpWallDist
    distPlayer = 0.0
    If drawEnd < 0
      drawEnd = h
    EndIf
    For y = drawEnd + 1 To h
      currentDist = h / (2.0 * y - h)
      weight.f = (currentDist - distPlayer) / (distWall - distPlayer)
      currentFloorX.f = weight * floorXWall + (1.0 - weight) * posX
      currentFloorY.f = weight * floorYWall + (1.0 - weight) * posY
      floorTexX.l
      floorTexY.l
      floorTexX = Int(currentFloorX * #texWidth) % #texWidth
      floorTexY = Int(currentFloorY * #texHeight) % #texHeight
      buffer(x,y) = (texture(3,floorTexX,floorTexY) >> 1) & 8355711
      buffer(x,h - y) = texture(7,floorTexX,floorTexY)
    Next y
  Next x
  StartDrawing(ScreenOutput())
  For x = 0 To w-1
    For y = 0 To h-1
      Plot(x,y,buffer(x,y))
      buffer(x,y) = 0
    Next y
  Next x
  oldTime = time
  time = ElapsedMilliseconds()
  frameTime.f = (time - oldTime) / 1000.0
  DrawingMode(1)
  DrawText(0,0,StrF(1.0 / frameTime),RGB(255,255,255))
  StopDrawing()
  FlipBuffers()
  moveSpeed.f = frameTime * 5.0
  rotSpeed.f = frameTime * 3.0 
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)
    If(worldMap(Int(posX + dirX * moveSpeed),Int(posY)) = #False)
      posX + dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + dirY * moveSpeed)) = #False)
      posY + dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Down)
    If(worldMap(Int(posX - dirX * moveSpeed),Int(posY)) = #False)
      posX - dirX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - dirY * moveSpeed)) = #False)
      posY - dirY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_A)
    If(worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = #False)
      posX - planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = #False)
      posY - planeY * moveSpeed
    EndIf
  ElseIf KeyboardPushed(#PB_Key_D)
    If(worldMap(Int(posX + planeX * moveSpeed),Int(posY)) = #False)
      posX + planeX * moveSpeed
    EndIf
    If(worldMap(Int(posX),Int(posY + planeY * moveSpeed)) = #False)
      posY + planeY * moveSpeed
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Right)
    oldDirX.f = dirX
    dirX = dirX * Cos(-rotSpeed) - dirY * Sin(-rotSpeed)
    dirY = oldDirX * Sin(-rotSpeed) + dirY * Cos(-rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(-rotSpeed) - planeY * Sin(-rotSpeed)
    planeY = oldPlaneX * Sin(-rotSpeed) + planeY * Cos(-rotSpeed)
  EndIf
  If KeyboardPushed(#PB_Key_Left)
    oldDirX.f = dirX
    dirX = dirX * Cos(rotSpeed) - dirY * Sin(rotSpeed)
    dirY = oldDirX * Sin(rotSpeed) + dirY * Cos(rotSpeed)
    oldPlaneX.f = planeX
    planeX = planeX * Cos(rotSpeed) - planeY * Sin(rotSpeed)
    planeY = oldPlaneX * Sin(rotSpeed) + planeY * Cos(rotSpeed)
  EndIf
Until KeyboardPushed(1)

End
DataSection
wrldmap:
Data.l 4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,3,0,0,0,5,8,0,5,8,0,5,8,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,7,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,6,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,5,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,4,4,4,4,4,0,4,4,4,0,0,0,2,2,2,2,2,2,2,3,3,3,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,2,0,2,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,2,0,2,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 4,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,0,0,2,0,0,0,2
Data.l 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
EndDataSection

Verfasst: 29.10.2006 11:19
von Kekskiller
Coole Sache, aber wie bei allen Raycastern leider nur mit halber Framerate. Zu blöde, dass man diese Alghos nur bedingt optimieren kann.