News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Infinite Floor

Started by kevin, January 09, 2025, 07:17:50 AM

Previous topic - Next topic

kevin

Infinite Floor


  This code was originally written by ScottyBro.  The original source code came with a huge (2 colour) bitmap as the ground texture, which I've replaced with a function to generate texture so it can posted as source code snippet. 

    What does this code do ?  It's creates some of a Mario Cart / Mode 7 perspective that you've no doubt seen in classic racing games.  The player can move the camera around the world using the arrow keys. 


PlayBASIC Code: [Select]
; PROJECT : infinitefloor01
; AUTHOR : Scottie Bro
; CREATED : 3/08/2011
; EDITED : 10/01/2025
; ---------------------------------------------------------------------

//OpenScreen 800,600,32,1

// Render a check pattern to a texture for the floor
IMage=Make_Check_Pattern_Floor(2048,64)

drawimage Image,0,0,0
;sync
;waitkey


xres = 800
yres = 600

depth = 255

xcell = 16
zcell = 8

xsize = xres / xcell
zsize = depth / zcell

ang = 0

xeye = 1024
yeye = 1024

xspeed = 1
yspeed = 1

anginc = 1

dim x2d(xsize,zsize)
dim y2d(xsize,zsize)

dim xf(xsize,zsize)
dim yf(xsize,zsize)

do

x3d = -xres / 2
y3d = 50
z3d = 0

x1 = xeye + xres / 2
y1 = yeye - depth

cls rgb(0,0,255)

for j = 0 to zsize
for i = 0 to xsize

x2d(i,j) = ((x3d * 255) / (255 - z3d)) + (xres / 2)
y2d(i,j) = ((y3d * 255) / (255 - z3d)) + (yres / 2)

; dot x2d(i,j),y2d(i,j)

xf(i,j) = xeye + (xeye - x1) * cos(ang) + (yeye - y1) * sin(ang)
yf(i,j) = yeye - (yeye - y1) * cos(ang) + (xeye - x1) * sin(ang)

;dot xf(,j),yf(i,j)

;xf(i,j) = wrapvalue(xf(i,j),1,2047)
;yf(i,j) = wrapvalue(yf(i,j),1,2047)

x3d = x3d + xcell

x1 = x1 - xcell

next i

x3d = -xres / 2
z3d = z3d + zcell

x1 = xeye + xres / 2
y1 = y1 + zcell

next j

lockbuffer

for j = 0 to zsize - 1
for i = 0 to xsize - 1
texturequad Image,x2d(i,j),y2d(i,j),xf(i,j),yf(i,j),x2d(i+1,j),y2d(i+1,j),xf(i+1,j),yf(i+1,j),x2d(i+1,j+1),y2d(i+1,j+1),xf(i+1,j+1),yf(i+1,j+1),x2d(i,j+1),y2d(i,j+1),xf(i,j+1),yf(i,j+1),0
;texturequad 1,xf(i,j),yf(i,j),xf(i,j),yf(i,j),xf(i+1,j),yf(i+1,j),xf(i+1,j),yf(i+1,j),xf(i+1,j+1),yf(i+1,j+1),xf(i+1,j+1),yf(i+1,j+1),xf(i,j+1),yf(i,j+1),xf(i,j+1),yf(i,j+1),0

next i
next j

unlockbuffer

sync

if upkey() = 1 then xeye = xeye + xspeed * cos(270+ang):yeye = yeye + yspeed * sin(270+ang)
if downkey() = 1 then xeye = xeye + xspeed * cos(90+ang):yeye = yeye + yspeed * sin(90+ang)

xeye = wrapvalue(xeye,255,2047-255)
yeye = wrapvalue(yeye,255,2047-255)

if leftkey() = 1 then ang = ang - anginc
if rightkey() = 1 then ang = ang + anginc

if ang < 0 then ang = 360
if ang > 360 then ang = 0

loop spacekey()


end



Function Make_Check_Pattern_Floor(Size,TileSize)
if Size>0 and TileSize>0
oldsurface=GetSurface()
Image=NewFXImage(Size,Size)
RenderToImage Image
dim Palette(1)
Palette(0)=rgb(255,255,255)
Palette(1)=rgb(0,0,0)

lockbuffer
ThisRGB=point(0,0)
// Draw two rows and copy the rest.
For Ylp=0 to (TileSize*2)-1 Step TileSize
CurrentColour = (Ylp/TileSize) and 1
For Xlp=0 to Size-1 Step TileSize
X1=Xlp
X2=X1+TileSize
Y1=Ylp
Y2=Y1+TileSize
boxc X1,Y1,X2,Y2,true,palette(CurrentColour)
CurrentColour = 1-CurrentColour
Next
Next
unlockbuffer

// Copy the chunks down the frame
For Ylp=(TileSize*2) to Size -1 Step TileSize*2
CopyRect IMage,0,0,Size,TileSize*2,IMage,0,Ylp
next

rendertoimage oldsurface
Login required to view complete source code



    This source code was original written way back 2011.  Since then there's been various similar conversation about creating a classic carting game / mode 7 style perspective in classic PlayBASIC.. 

    Links: 

    - Mode 7 - Part one
    - PB Racing / PB Karting
    - Pseudo 3D / Mode 7 in PLAYBASICc.