Verfasst: 29.10.2006 15:36
Update! Sprites
(Framerate leider nur ~45 bei 320x240
)

(Framerate leider nur ~45 bei 320x240

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
Structure Sprite
x.f
y.f
texture.l
EndStructure
Structure structDist
dist.f
Nb.l
EndStructure
#numSprites = 18
#mapWidth = 23
#mapHeight = 23
#texWidth = 63
#texHeight = 63
w = 320
h = 240
Global Dim worldMap.l(#mapWidth,#mapHeight)
Global Dim buffer.l(w,h)
Global Dim texture.l(11,#texWidth,#texHeight)
Restore wrldmap
For j = 0 To #mapHeight
For i = 0 To #mapWidth
Read worldMap(i,j)
Next i
Next j
Global Dim sprite.Sprite(#numSprites)
sprite(0)\x = 20.5
sprite(0)\y = 11.5
sprite(0)\texture = 10
sprite(1)\x = 18.5
sprite(1)\y = 4.5
sprite(1)\texture = 10
sprite(2)\x = 10
sprite(2)\y = 4.5
sprite(2)\texture = 10
sprite(3)\x = 10
sprite(3)\y = 12.5
sprite(3)\texture = 10
sprite(4)\x = 3.5
sprite(4)\y = 6.5
sprite(4)\texture = 10
sprite(5)\x = 3.5
sprite(5)\y = 20.5
sprite(5)\texture = 10
sprite(6)\x = 3.5
sprite(6)\y = 14.5
sprite(6)\texture = 10
sprite(7)\x = 14.5
sprite(7)\y = 20.5
sprite(7)\texture = 10
sprite(8)\x = 18.5
sprite(8)\y = 10.5
sprite(8)\texture = 9
sprite(9)\x = 18.5
sprite(9)\y = 11.5
sprite(9)\texture = 9
sprite(10)\x = 18.5
sprite(10)\y = 12.5
sprite(10)\texture = 9
sprite(11)\x = 21.5
sprite(11)\y = 1.5
sprite(11)\texture = 8
sprite(12)\x = 15.5
sprite(12)\y = 1.5
sprite(12)\texture = 8
sprite(13)\x = 16
sprite(13)\y = 1.8
sprite(13)\texture = 8
sprite(14)\x = 16.2
sprite(14)\y = 1.2
sprite(14)\texture = 8
sprite(15)\x = 3.5
sprite(15)\y = 2.5
sprite(15)\texture = 8
sprite(16)\x = 9.5
sprite(16)\y = 15.5
sprite(16)\texture = 8
sprite(17)\x = 10
sprite(17)\y = 15.1
sprite(17)\texture = 8
sprite(18)\x = 10.5
sprite(18)\y = 15.8
sprite(18)\texture = 8
Global Dim spriteDistance.structDist(#numSprites)
Global Dim Zbuffer.f(w)
posX.f = 8
posY.f = 5
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 10
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
Zbuffer(x) = perpWallDist
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
For i = 0 To #numSprites
spriteDistance(i)\Nb = i
spriteDistance(i)\dist = ((posX - sprite(i)\x) * (posX - sprite(i)\x) + (posY - sprite(i)\y) * (posY - sprite(i)\y))
Next i
SortStructuredArray(spriteDistance(),1,OffsetOf(structDist\dist),#PB_Sort_Float)
For i = 0 To #numSprites
spriteX.f = sprite(spriteDistance(i)\Nb)\x - posX
spriteY.f = sprite(spriteDistance(i)\Nb)\y - posY
invDet.f = 1.0 / (planeX * dirY - dirX * planeY)
transformX.f = invDet * (dirY * spriteX - dirX * spriteY)
transformY.f = invDet * (-planeY * spriteX + planeX * spriteY)
spriteScreenX = Int((w / 2) * (1 + transformX / transformY))
spriteHeight = Abs(Int(h / (transformY)))
drawStartY = -spriteHeight / 2 + h / 2
If drawStartY < 0
drawStartY = 0
EndIf
drawEndY = spriteHeight / 2 + h / 2
If drawEndY >= h
drawEndY = h - 1
EndIf
spriteWidth = Abs(Int(h / (transformY)))
drawStartX = -spriteWidth / 2 + spriteScreenX
If drawStartX < 0
drawStartX = 0
EndIf
drawEndX = spriteWidth / 2 + spriteScreenX
If drawEndX >= w
drawEndX = w - 1
EndIf
For stripe = drawStartX To drawEndX
texX = Int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * #texWidth / spriteWidth) / 256
If transformY > 0 And stripe > 0 And stripe < w And transformY < Zbuffer(stripe)
For y = drawStartY To drawEndY
d = y * 256 - h * 128 + spriteHeight * 128
texY = ((d * #texHeight) / spriteHeight) / 256
color = texture(sprite(spriteDistance(i)\Nb)\texture,texX,texY)
If color <> 0
buffer(stripe,y) = color
EndIf
Next y
EndIf
Next stripe
Next i
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 8,8,8,8,8,8,8,8,8,8,8,4,4,6,4,4,6,4,6,4,4,4,6,4
Data.l 8,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,4
Data.l 8,0,3,3,0,0,0,0,0,8,8,4,0,0,0,0,0,0,0,0,0,0,0,6
Data.l 8,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6
Data.l 8,0,3,3,0,0,0,0,0,8,8,4,0,0,0,0,0,0,0,0,0,0,0,4
Data.l 8,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,6,6,0,6,4,6
Data.l 8,8,8,8,0,8,8,8,8,8,8,4,4,4,4,4,4,6,0,0,0,0,0,6
Data.l 7,7,7,7,0,7,7,7,7,0,8,0,8,0,8,0,8,4,0,4,0,6,0,6
Data.l 7,7,0,0,0,0,0,0,7,8,0,8,0,8,0,8,8,6,0,0,0,0,0,6
Data.l 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,4
Data.l 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,6,0,6,0,6
Data.l 7,7,0,0,0,0,0,0,7,8,0,8,0,8,0,8,8,6,4,6,0,6,6,6
Data.l 7,7,7,7,0,7,7,7,7,8,8,4,0,6,8,4,8,3,3,3,0,3,3,3
Data.l 2,2,2,2,0,2,2,2,2,4,6,4,0,0,6,0,6,3,0,0,0,0,0,3
Data.l 2,2,0,0,0,0,0,2,2,4,0,0,0,0,0,0,4,3,0,0,0,0,0,3
Data.l 2,0,0,0,0,0,0,0,2,4,0,0,0,0,0,0,4,3,0,0,0,0,0,3
Data.l 1,0,0,0,0,0,0,0,1,4,4,4,4,4,6,0,6,3,3,0,0,0,3,3
Data.l 2,0,0,0,0,0,0,0,2,2,2,1,2,2,2,6,6,0,0,5,0,5,0,5
Data.l 2,2,0,0,0,0,0,2,2,2,0,0,0,2,2,0,5,0,5,0,0,0,5,5
Data.l 2,0,0,0,0,0,0,0,2,0,0,0,0,0,2,5,0,5,0,5,0,5,0,5
Data.l 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5
Data.l 2,0,0,0,0,0,0,0,2,0,0,0,0,0,2,5,0,5,0,5,0,5,0,5
Data.l 2,2,0,0,0,0,0,2,2,2,0,0,0,2,2,0,5,0,5,0,0,0,5,5
Data.l 2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,5,5,5,5,5,5,5,5,5
EndDataSection