not bad!
it is kind of slow for 320 x 200. isn't it?
anyway..
just did a quick glance at your code and I think I fixed a couple of your errors:
Const MAPSIZE = 16
Const GRIDSIZE = 64
Const GRIDSHIFTS = 6
Const GWIDTH = 320
Const GHEIGHT = 200
Const ANGLEOFVIEW = 60
Const CASTINGSTEP# = ANGLEOFVIEW/Float( GWIDTH )
Const TILES = 2
Const TEXTURESIZE = 64
Const SCALEFACTOR# = TEXTURESIZE/GRIDSIZE
Const FLOORTILE = 2
Const CEILINGTILE = 2
Const HD = ( SCALEFACTOR# <> 1 )
Const CEILING = True
Graphics GWIDTH, GHEIGHT, 32, 2
Global CamX# = 5*GRIDSIZE + GRIDSIZE/2, CamY# = 5*GRIDSIZE + GRIDSIZE/2, ProjectionDistance# = ( GWIDTH/2 )/Tan( ANGLEOFVIEW/2 )
Global CameraAngle = 270, PlayerHeight = 32, PlaneDisplacement
Dim MapData( MAPSIZE - 1, MAPSIZE - 1 )
Dim TextureData( TILES*( TEXTURESIZE)*( TEXTURESIZE ) )
Dim Distances#( GWIDTH - 1 )
For i = 0 To Tiles - 1
Texture = LoadImage( "Tile" + ( i + 1 ) + ".png" )
SetBuffer ImageBuffer( Texture )
LockBuffer ImageBuffer( Texture )
For x = 0 To TEXTURESIZE - 1
For y = 0 To TEXTURESIZE - 1
TextureData( i*TEXTURESIZE*TEXTURESIZE + ( x*TEXTURESIZE + y ) ) = ReadPixelFast( x, y )
Next
Next
FreeImage Texture
Next
Type Sprite
Field X#
Field Y#
Field Height
Field Width
Field ImageData[ 256*256 ]
End Type
Dummy = LoadImage( "Alien.png" )
LockBuffer ImageBuffer( Dummy )
For i = 1 To 10
Drink.Sprite = New Sprite
Drink\X# = Rnd( 0, MAPSIZE*GRIDSIZE )
Drink\Y# = Rnd( 0, MAPSIZE*GRIDSIZE )
Drink\Height = ImageHeight( Dummy )
Drink\Width = ImageWidth( Dummy )
For x = 0 To Drink\Width - 1
For y = 0 To Drink\Height - 1
Drink\ImageData[ x*Drink\Width + y ] = ReadPixelFast( x, y, ImageBuffer( Dummy ) )
Next
Next
If MapData( Drink\X# Shr GRIDSHIFTS, Drink\Y# Shr GRIDSHIFTS ) Then i = i - 1
Next
FreeImage( Dummy )
SetBuffer BackBuffer()
Restore MapData
For i = 0 To MAPSIZE - 1
For t = 0 To MAPSIZE - 1
Read MapData( t, i )
Next
Next
Timer = CreateTimer( 60 )
DisplayFPS = 0
FPS = 0
Counter = MilliSecs()
While Not KeyHit( 1 )
Cls
LockBuffer BackBuffer()
RenderScreen()
RenderSprites()
UnlockBuffer BackBuffer()
MoveCamera()
If MilliSecs() - Counter > 1000 Then
DisplayFPS = FPS
Counter = MilliSecs()
FPS = 0
EndIf
Text 0, 0, DisplayFPS
Flip 0
WaitTimer Timer
FPS = FPS + 1
Wend
End
Function MoveCamera()
XSpeed# = -Sgn( KeyDown( 208 ) - KeyDown( 200 ) )*Cos( CameraAngle )
YSpeed# = Sgn( KeyDown( 208 ) - KeyDown( 200 ) )*Sin( CameraAngle )
TileX = ( CamX# + XSpeed# + Sgn( XSpeed# ) ) Shr GRIDSHIFTS
TileY = ( CamY# + YSpeed# + Sgn( YSpeed# ) ) Shr GRIDSHIFTS
OldTileX = CamX# Shr GRIDSHIFTS
OldTileY = CamY# Shr GRIDSHIFTS
If Not MapData( OldTileX, TileY ) Then CamY# = CamY# + YSpeed#
If Not MapData( TileX, OldTileY ) Then CamX# = CamX# + XSpeed#
CameraAngle = CameraAngle - KeyDown( 203 ) + KeyDown( 205 )
PlaneDisplacement = PlaneDisplacement - KeyDown( 74 ) + KeyDown( 78 )
End Function
Function RenderScreen()
For i = 0 To GWIDTH - 2
Angle# = ( CameraAngle - ANGLEOFVIEW/2 + CASTINGSTEP#*i ) Mod 360
Angle# = ( 360 + Angle# ) Mod 360
;Wird der Strahl nach oben oder unten geschickt?
YDirection = 1 - ( Angle# < 180 )*2
;Wird der Strahl nach links oder rechts geschickt?
XDirection = -1 + ( Angle# > 270 Or Angle# < 90 )*2
;Horizontale Kollision
Ya# = CamY# Mod GRIDSIZE
If YDirection = 1 Then Ya# = GRIDSIZE - Ya#
Xa# = Ya#/Tan( Angle# )
IntersectionY# = CamY# + YDirection*Ya#
IntersectionX# = CamX# - YDirection*Xa#
TileY = ( IntersectionY# + YDirection ) Shr GRIDSHIFTS
TileX = IntersectionX# Shr GRIDSHIFTS
If TileX >= 0 And TileX < MAPSIZE And TileY >= 0 And TileY < MAPSIZE Then
If MapData( TileX, TileY ) Then
WallTile = MapData( TileX, TileY )
Else
Ya# = YDirection Shl GRIDSHIFTS
Xa# = Ya#/Tan( Angle# )
Repeat
IntersectionX# = IntersectionX# - Xa#
IntersectionY# = IntersectionY# + Ya#
TileY = ( IntersectionY# + YDirection ) Shr GRIDSHIFTS
TileX = IntersectionX# Shr GRIDSHIFTS
If TileX >= 0 And TileX < MAPSIZE And TileY >= 0 And TileY < MAPSIZE Then
If MapData( TileX, TileY ) Then
WallTile = MapData( TileX, TileY )
Exit
EndIf
Else
Exit
EndIf
Forever
EndIf
EndIf
WallX# = IntersectionX#
WallY# = IntersectionY#
;Vertikale Kollision
Xa# = CamX# Mod GRIDSIZE
If XDirection = 1 Then Xa# = GRIDSIZE - Xa#
Ya# = Xa#*Tan( Angle# )
IntersectionX# = CamX# + XDirection*Xa#
IntersectionY# = CamY# - XDirection*Ya#
TileY = IntersectionY# Shr GRIDSHIFTS
TileX = ( IntersectionX# + XDirection ) Shr GRIDSHIFTS
If TileX >= 0 And TileX < MAPSIZE And TileY >= 0 And TileY < MAPSIZE Then
If MapData( TileX, TileY ) Then
IntersectionTile = MapData( TileX, TileY )
Else
Xa# = XDirection Shl GRIDSHIFTS
Ya# = Xa#*Tan( Angle# )
Repeat
IntersectionX# = IntersectionX# + Xa#
IntersectionY# = IntersectionY# - Ya#
TileY = IntersectionY# Shr GRIDSHIFTS
TileX = ( IntersectionX# + XDirection ) Shr GRIDSHIFTS
If TileX >= 0 And TileX < MAPSIZE And TileY >= 0 And TileY < MAPSIZE Then
If MapData( TileX, TileY ) Then
IntersectionTile = MapData( TileX, TileY )
Exit
EndIf
Else
Exit
EndIf
Forever
EndIf
EndIf
DistanceVertically# = Abs( ( WallY# - CamY# )/Sin( Angle# ) )
DistanceHorizontally# = Abs( ( IntersectionX# - CamX# )/Cos( Angle# ) )
If DistanceHorizontally# < DistanceVertically# Then
SmallerDistance# = DistanceHorizontally#
If WallTile > 0 Then
If HD Then
TextureRow = Floor( ( WallX# Mod GRIDSIZE )*SCALEFACTOR# )
Else
TextureRow = Floor( WallX# ) Mod GRIDSIZE
EndIf
EndIf
If HD Then
TextureRow = Floor( ( IntersectionY# Mod GRIDSIZE )*SCALEFACTOR# )
Else
TextureRow = Floor( IntersectionY# ) Mod GRIDSIZE
EndIf
Else
SmallerDistance# = DistanceVertically#
If IntersectionTile > 0 Then
If HD Then
TextureRow = Floor( ( IntersectionY# Mod GRIDSIZE )*SCALEFACTOR# )
Else
TextureRow = Floor( IntersectionY# ) Mod GRIDSIZE
EndIf
EndIf
If HD Then
TextureRow = Floor( ( WallX# Mod GRIDSIZE )*SCALEFACTOR# )
Else
TextureRow = Floor( WallX# ) Mod GRIDSIZE
EndIf
EndIf
WallHeight = ( GRIDSIZE/( SmallerDistance#*Cos( CASTINGSTEP#*i - ANGLEOFVIEW/2 ) ) )*ProjectionDistance#
If WallTile = 0 And IntersectionTile > 0 Then WallTile = IntersectionTile
TStart = ( GHEIGHT/2 + PlaneDisplacement ) - WallHeight/2
TEnd = ( GHEIGHT/2 + PlaneDisplacement ) + WallHeight/2
If TStart < 0 Then YCorrection = Abs( TStart )
If TEnd >= GHEIGHT Then YCorrection2 = TEnd - GHEIGHT + 1
For t = TStart + YCorrection To TEnd - YCorrection2
If WallTile = 1 Then
WritePixelFast i, t, $FFFFFFFF
Else
ARGB = TextureData( ( WallTile - 2 )*TEXTURESIZE*TEXTURESIZE + ( TextureRow*TEXTURESIZE + ( t - GHEIGHT/2 + WallHeight/2 - PlaneDisplacement )*( TEXTURESIZE/Float( WallHeight ) ) ) )
WritePixelFast i, t, ARGB
EndIf
Next
;Floor - Casting
TStart = ( GHEIGHT/2 + PlaneDisplacement ) + WallHeight/2
TStart = TStart*( TStart >= 0 )
TEnd = GHEIGHT
;********************************
For t = TStart To TEnd-1 ;fixed
;********************************
Length# = ( ( GRIDSIZE/2 )/( ( t - GHEIGHT/2 - PlaneDisplacement )/ProjectionDistance# ) )/Cos( CASTINGSTEP#*i - ANGLEOFVIEW/2 )
FloorX = CamX# + Cos( Angle# )*Length#
FloorY = CamY# - Sin( Angle# )*Length#
TextureColumn = FloorY Mod TEXTURESIZE
TextureRow = FloorX Mod TEXTURESIZE
ARGB = TextureData( ( FLOORTILE - 1 )*TEXTURESIZE*TEXTURESIZE + ( TextureRow*TEXTURESIZE + TextureColumn ) )
If i >= 320 Or t >= 200 Then Print i+" "+t+" third"
WritePixelFast i, t, ARGB
Next
If CEILING Then
;Ceil - Casting
TStart = 0
TEnd = ( GHEIGHT/2 + PlaneDisplacement ) - WallHeight/2
TEnd = TEnd*( TEnd < GHEIGHT ) + ( GHEIGHT - 1 )*( TEnd >= GHEIGHT )
;*************************************
For t = TStart To TEnd-1 ;fixed
;*************************************
Length# = ( ( GRIDSIZE/2 )/( ( GHEIGHT/2 - t + PlaneDisplacement )/ProjectionDistance# ) )/Cos( CASTINGSTEP#*i - ANGLEOFVIEW/2 )
CeilingX = CamX# + Cos( Angle# )*Length#
CeilingY = CamY# - Sin( Angle# )*Length#
TextureRow = CeilingX Mod TEXTURESIZE
TextureColumn = CeilingY Mod TEXTURESIZE
ARGB = TextureData( ( CEILINGTILE - 1 )*TEXTURESIZE*TEXTURESIZE + ( TextureRow*TEXTURESIZE + TextureColumn ) )
WritePixelFast i, t, ARGB
Next
EndIf
Distances#( i ) = SmallerDistance#
TextureRow = 0
IntersectionTile = 0
WallTile = 0
Saviour = 0
YCorrection = 0
YCorrection2 = 0
Next
End Function
Function RenderSprites()
;Sprites
For Drink.Sprite = Each Sprite
Distance# = Sqr( ( CamX# - Drink\X# )*( CamX# - Drink\X# ) + ( CamY# - Drink\Y# )*( CamY# - Drink\Y# ) )
Height = Drink\Height - 1
Width = Drink\Width
SpriteHeight = ( Height/Distance# )*ProjectionDistance#
SpriteWidth = Width*( SpriteHeight/Float( Height ) )
Difference# = ATan( ( Drink\Y# - CamY# )/( Drink\X# - CamX# ) )
If Drink\X# - CamX# < 0 Then Difference# = 180 + Difference#
Angle# = ( -Difference# - CameraAngle + 360 ) Mod 360
StartSlice = ( Angle# + ANGLEOFVIEW/2 )/CASTINGSTEP# - SpriteWidth/2
If ( StartSlice < 0 Or StartSlice > GWIDTH ) And Abs( Angle# ) > 360 - ANGLEOFVIEW/2 - SpriteWidth/2 Then
Angle# = Angle# - Sgn( Angle# )*360
StartSlice = ( Angle# + ANGLEOFVIEW/2 )/CASTINGSTEP# - SpriteWidth/2
EndIf
XStart = StartSlice*( StartSlice >= 0 )
XEnd = StartSlice + SpriteWidth - 1
XEnd = XEnd*( XEnd < GWIDTH ) + ( GWIDTH - 1 )*( XEnd > GWIDTH )
YStart = ( GHEIGHT/2 - Spriteheight/2 + PlaneDisplacement )*( GHEIGHT/2 - SpriteHeight/2 + PlaneDisplacement >= 0 )
YEnd = GHEIGHT/2 + SpriteHeight/2 - 1 + PlaneDisplacement
YEnd = YEnd*( YEnd <= GHEIGHT ) + GHEIGHT*( YEnd > GHEIGHT )
;**************************************
For x = XStart To XEnd-1 ;fixed maybe?
For y = YStart To YEnd-1 ;fixed maybe?
;*****************************************
If Distances#( x ) > Distance# Then
ARGB = Drink\ImageData[ Floor( ( x - StartSlice )*( Width/Float( SpriteWidth ) ) )*Drink\Width + ( y - GHEIGHT/2 + SpriteHeight/2 - PlaneDisplacement )*( Height/Float( SpriteHeight ) ) ]
If ARGB - $FF000000 <> 0 Then
If x >= 320 Or y >= 200 Then Print x+" "+y+" fifth"
WritePixelFast x, y, ARGB
EndIf
EndIf
Next
Next
Next
End Function
.MapData
Data 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
Data 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2
Data 1, 0, 2, 0, 2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 0, 2
Data 2, 2, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2
Data 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2
Data 2, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2
Data 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 2
Data 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 0, 2
Data 2, 2, 2, 0, 2, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2
Data 2, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2
Data 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, 0, 2
Data 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2
Data 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2
Data 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2
Data 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
Data 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2