I'm thinking something like this
Night Driver
//questions and comments https://forum.thegamecreators.com/thread/222010
#constant KEY_LEFT = 37 //the left arrow key scancode
#constant KEY_UP = 38 //the up arrow key scancode
#constant KEY_RIGHT = 39 //the right arrow key scancode
#constant KEY_DOWN = 40 //the down arrow key scancode
#constant KEY_A = 65 //the scan code for the "a" key
#constant KEY_Z = 90 //the scan code for the "z" key
#constant mapX=20 //maximum blocks on x plane CHANGE THIS TO MAKE ROAD NARROWER IE 20 WHICH WILL SPEED IT UP
#constant mapY=1 //maximum blocks on y plane
#constant mapZ=100 //maximum blocks on z plane
#constant speed# = 10.0 //the following for a sine curve to repesent hils on the yplane
#constant xMaxResolution=1024
#constant yMaxResolution=768
#constant acceleration#=.25 //used to calclate the carSpeed#
#constant maxCarSpeed#=2.0 //The Maximum speed the carBlock will move
#constant textTitle=1 //the title text id
#constant textSpeed=2 //the speed text id
#constant textScore=3 //the score text id
#constant textLives=4 //the lives text id
#constant textFPS=5 // the fps text id
#constant textGameOver=6 //the game over text id
#constant textPlayAgain=7 //the Click to play again text id
#constant textHighScore=8 //the highscore text id
#constant textTopSpeed=9 //the top speed text id
#constant textHowFar=10 //the text how far can you go text id
global blockCount
global carBlock=10000 //carblock and carMem have the same referrence
global carMem=10000 //the carBlocks memblock id
global carTop=10001 //carblock and carMem have the same referrence
global carTopMem=10001 //the carBlocks memblock id
global otherCarBlock=10002 //the otherCarblock and otherCarMem have the same referrence
global otherCarMem=10002 //the other carBlocks memblock id
global lives=3 //The actual lives of a player
global score=0 //holds the player score whiched is based on progression
global highScore=0 //holds the total high score for the day
global topSpeed#=0 //the maximun speed you have reached today
time#=timer() //holds the startTime for calculations of the sineCurve with the movements and used in calculating an acceleration curve
global sound1 as integer
global sound2 as integer
//global y# as float = 0.0
dim blocksChanged[mapX*mapY*mapZ] as block
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Night Driver" )
SetWindowSize( xMaxResolution, yMaxResolution, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( xMaxResolution, yMaxResolution ) // doesn't have to match the window
SetOrientationAllowed( 0, 0, 1, 1 ) // allow only landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
type vertex
xDirection as integer
yDirection as integer
zDirection as integer
endtype
type block
id as integer
xPosStart as integer
yPosStart as integer
zPosStart as integer
//the following used for my particle effect
xDirection as float
yDirection as float
zDirection as float
endtype
num=1:texture=createBlankTexture(32,32, makecolor(255,255,255))
for y = 1 to mapY
for x = 1 to mapX step mapX-1
for z = 1 to mapZ step 10
CreateObjectBox(num,1,4,1)
c=255:SetObjectColor(num,c,c,c,255)
SetObjectImage(num,texture,0)
SetObjectCollisionMode( num, 1 ) //On is needed for raycasting
CreateMemblockFromObjectMesh(num,num,1) //there is exactly the same number of blocks as memblocks and each id is equal
//the shadow is set to off on each block as its only needed for the raised ones
//SetObjectCastShadow(num,0)
blocksChanged[num].id=num
//the directions are only used for the particle effect when you crash
blocksChanged[num].xDirection=Random2(-100,100)/50.0
blocksChanged[num].yDirection=Random2(-100,100)/50.0
blocksChanged[num].zDirection=Random2(-100,100)/50.0
blocksChanged[num].xPosStart=x
blocksChanged[num].yPosStart=y
blocksChanged[num].zPosStart=z
SetObjectPosition(num,x,y,z)
inc num
next z
next x
next y
blockCount=num-1
createCar(carBlock,carMem)
createCar(otherCarBlock,otherCarMem)
sound1=createSound(1) //creates a base rumble
sound2=createSound(2) //creates white noise
//SetSunActive(1)
//SetSunColor( 255, 255,255 )
//SetFogSunColor( 20, 20, 20 )
//Add some atmosphere
SetFogMode( 1 )
SetFogColor(20,20,20)
SetFogRange(10,100)
CreatePointLight(1, getObjectX(carBlock),getObjectY(carBlock),getObjectZ(carBlock), 120, 255, 255,255 )
//SetShadowMappingMode(3 )
//SetShadowSmoothing( 0)
//SetShadowMapSize( 512, 512 )
//SetShadowRange( -1 ) // use the full camera range
//SetShadowBias( 0.0012 ) // offset shadows slightly to avoid shadow artifacts
setCameraPosition(1,mapX/2,10,0)
setupText()
repeat
sync()
If GetPointerPressed() or GetRawKeyPressed(32)
SetTextVisible(textGameOver,0):SetTextVisible(textPlayAgain,0):SetTextVisible(textHowFar,0)
lives=3:score=0:playGame()
if score>highScore
highScore=score
SetTextString(textHighScore,"High="+Str(highScore))
endif
if carSpeed#>topSpeed#
topSpeed#=carSpeed#
SetTextString(textTopSpeed,"Top Speed="+Str(Round(topSpeed#/maxCarSpeed#*100))+"%")
endif
endif
until GetRawKeyPressed(27)
end //exitprogram
function playGame()
global carSpeed#=1.0 //car speed used for acceleration with timer
ResetTimer():time#=timer()
x=xMaxResolution/2:yAngle=0
repeat
//if GetRawKeyState (KEY_LEFT)
if GetDirectionX()<-.25 //uses gyroscope for movement
moveBlocks(abs(GetDirectionX()*2),0,0)
yAngle=-abs(GetDirectionX()*20)
SetObjectRotation( carBlock,0,yAngle,0 )
elseif GetDirectionX()>.25 //uses gyroscope for movement
moveBlocks(-abs(GetDirectionX()*2),0,0)
yAngle=abs(GetDirectionX()*20)
SetObjectRotation( carBlock,0,yAngle,0 )
else
if yAngle<0
inc yAngle
SetObjectRotation( carBlock,0,yAngle,0 )
elseif yAngle>0
dec yAngle
SetObjectRotation( carBlock,0,yAngle,0 )
endif
endif
moveBlocks(0,0,carSpeed#)
//the second raycasting is used for crashes
x#=getObjectX(carBlock)
y#=GetObjectY(carBlock)
z#=getObjectZ(carBlock)
// calculate the start of the ray cast
start_x# = x#
start_y# = y#
start_z# = z#
// calculate the end of the ray cast
end_x# = x#+2.0
end_y# = y#-2.0 //-2.0
end_z# = z#+6.0 + carSpeed#
hit=ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
if hit>0 //player crashed
dec lives
PlaySound(sound1,100,0)
PlaySound(sound2,50,0)
blocksExplode()
restoreBlocks()
carSpeed#=1.0 //Set the speed back to its default as you crashed
yAngle=0
time#=timer()
endif
if timer()>time#+1.0
carSpeed#=carSpeed#+acceleration# //increase the car speed every 1 second
time#=timer()
endif
if carSpeed#>maxCarSpeed# then carSpeed#=maxCarSpeed#
SetTextString(textSpeed,"Speed="+Str(Round(carSpeed#/maxCarSpeed#*100))+"%")
SetTextString(textScore,"Score="+Str(score))
SetTextString(textLives,"Lives="+Str(lives))
SetTextString(textFPS,"FPS="+Str(trunc(screenFPS())))
if score>highScore
highScore=score
SetTextString(textHighScore,"High="+Str(highScore))
endif
if carSpeed#>topSpeed#
topSpeed#=carSpeed#
SetTextString(textTopSpeed,"Top Speed="+Str(Round(topSpeed#/maxCarSpeed#*100))+"%")
endif
//Print("Angle..............."+str(GetObjectAngleY(otherCarBlock)))
sync()
until GetRawKeyPressed(27) or lives <1
SetTextVisible(textGameOver,1)
SetTextVisible(textPlayAgain,1)
SetTextVisible(textHowFar,1)
endfunction
function setupText()
x=xMaxResolution/2
CreateText(textTitle,"Night Driver")
SetTextSize(textTitle,50)
SetTextPosition(textTitle,x-120,5)
SetTextColor(textTitle,220,50,50,255)
CreateText(textSpeed,"Speed=")
SetTextSize(textSpeed,35)
SetTextPosition(textSpeed,5,5)
SetTextColor(textSpeed,255,255,255,255)
CreateText(textScore,"Score=")
SetTextSize(textScore,35)
SetTextPosition(textScore,13,35)
SetTextColor(textScore,255,255,255,255)
CreateText(textLives,"Lives=")
SetTextSize(textLives,35)
SetTextPosition(textLives,18,65)
SetTextColor(textLives,255,255,255,255)
CreateText(textFPS,"FPS=")
SetTextSize(textFPS,35)
SetTextPosition(textFPS,36,95)
SetTextColor(textFPS,255,255,255,255)
CreateText(textGameOver,"GameOver")
SetTextSize(textGameOver,55)
SetTextPosition(textGameOver,x-112,yMaxResolution/2-18)
SetTextColor(textGameOver,255,5,5,255)
SetTextVisible(textGameOver,0)
CreateText(textPlayAgain,"How far can you go?")
SetTextSize(textPlayAgain,55)
SetTextPosition(textPlayAgain,x-200,yMaxResolution/2+20)
SetTextColor(textPlayAgain,255,255,255,255)
SetTextVisible(textPlayAgain,1)
CreateText(textHowFar,"Click to Play")
SetTextSize(textHowFar,55)
SetTextPosition(textHowFar,x-126,yMaxResolution/2+58)
SetTextColor(textHowFar,255,255,255,255)
SetTextVisible(textHowFar,1)
CreateText(textHighScore,"High=0")
SetTextSize(textHighScore,35)
SetTextPosition(textHighScore,xMaxResolution-150,5)
SetTextColor(textHighScore,255,255,255,255)
CreateText(textTopSpeed,"Top Speed=0")
SetTextSize(textTopSpeed,35)
SetTextPosition(textTopSpeed,xMaxResolution-222,35)
SetTextColor(textTopSpeed,255,255,255,255)
endfunction
function modifyBlock(block as integer, ammount as integer)
rem there are the following 8 vertexs that we need to modify to extend in the ydirection [0,2,4,6,8,9,10,11]
vertex as integer[7] = [0,2,4,6,8,9,10,11]
maxVertex=GetMemblockInt(block,0)-1
for index = 0 to 7
if index<=maxVertex
SetMeshMemblockVertexPosition(block,vertex[index],GetMeshMemblockVertexX(block,vertex[index]),GetMeshMemblockVertexY(block,vertex[index])+ammount,GetMeshMemblockVertexZ(block,vertex[index]))
endif
next index
SetObjectMeshFromMemblock(block,1,block)
endfunction
function moveBlocks(x as float,y as float,z as float)
rem These define the maximum and minimum an object may be placed in this example all objects
rem are 1,1,1 so defing these locations was done as following but could be calculated for
rem other objects of different dimmensions
xNum=mapX-1 //number of objects placed accross the xplane-1
yNum=mapY-1 //number of objects placed accross the yplane-1
zNum=mapZ-1 //number of objects placed accross the zplane-1
rem defing the 3d window workspace
xMin#=x:xMax#=mapX+x //the minimum and maximum xlocations for wrapping blocks on x plane
yMin=1:yMax=mapY //the minimum and maximum ylocation for wrapping blocks on the y plane
zMin#=0:zMax#=mapZ //the minimum and maximum zlocations for wrapping blocks on z plane
//time#=timer()
myRed=random(0,255):myGreen=random(0,255):myBlue=random(0,255)
for num=1 to blockCount
if x<0 //move blocks right
SetObjectPosition(num,getObjectX(num)+x,getObjectY(num),getObjectZ(num))
endif
if x>0 //move blocks Left
SetObjectPosition(num,getObjectX(num)+x,getObjectY(num),getObjectZ(num))
endif
if z>0 //move blocks toward screen
if GetObjectWorldZ(num)<zMin#
x# = sin(timer()*speed#*2)*100 // ranges from -100 to 100
x#=x#/5.0 //if this division is set to low the raycasting needs changing 50 and 75 both work well
SetObjectPosition(num,x#+getObjectX(num),getObjectY(num),getObjectZ(num)+zNum)
else
SetObjectPosition(num,getObjectX(num),getObjectY(num),getObjectZ(num)-z)
rem block 20 is off the screen so increment score
if num=20 then inc score
endif
endif
next num
if GetObjectWorldZ(otherCarBlock)<zMin#
SetObjectPosition(otherCarBlock,getObjectX(blockCount)-4,getObjectY(blockCount),getObjectZ(blockCount))
SetObjectColor(otherCarBlock,random(1,100),random(1,100),random(1,100),255) //random color other car
else
SetObjectPosition(otherCarBlock,getObjectX(blockCount)-4,getObjectY(blockCount),getObjectZ(blockCount))
endif
angle# = GetAngle(getObjectX(blockCount),getObjectZ(blockCount),getObjectX(blockCount-2),getObjectZ(blockCount-2))
SetObjectRotation(otherCarBlock,0,0,0)
RotateObjectGlobalY(otherCarBlock,angle#)
endfunction
function blocksExplode()
maxVertex=GetMemblockInt(carBlock,0)-1
Dim CarVertex[maxVertex] as vertex
For index=0 to maxVertex
//set each vertex a random direction
CarVertex[index].xDirection=random2(-100,100)/50.0
CarVertex[index].yDirection=Random2(-100,100)/50.0
CarVertex[index].zDirection=Random2(-100,0)/50.0
next index
maxVertex=GetMemblockInt(carBlock+1,0)-1
Dim CarTopVertex[maxVertex] as vertex
For index=0 to maxVertex
//set each vertex a random direction
CarTopVertex[index].xDirection=random2(-100,100)/50.0
CarTopVertex[index].yDirection=Random2(-100,100)/50.0
CarTopVertex[index].zDirection=Random2(-100,0)/50.0
next index
maxVertex=GetMemblockInt(otherCarBlock,0)-1
Dim OtherCarVertex[maxVertex] as vertex
For index=0 to maxVertex
//set each vertex a random direction
OtherCarVertex[index].xDirection=random2(-100,100)/50.0
OtherCarVertex[index].yDirection=Random2(-100,100)/50.0
OtherCarVertex[index].zDirection=Random2(-100,0)/50.0
next index
maxVertex=GetMemblockInt(otherCarBlock+1,0)-1
Dim OtherCarTopVertex[maxVertex] as vertex
For index=0 to maxVertex
//set each vertex a random direction
OtherCarTopVertex[index].xDirection=random2(-100,100)/50.0
OtherCarTopVertex[index].yDirection=Random2(-100,100)/50.0
OtherCarTopVertex[index].zDirection=Random2(-100,0)/50.0
next index
startTime#=Timer()
repeat
for num=1 to blockCount
//move the ground blocks in their set random directions
SetObjectPosition(num,getObjectX(num)+blocksChanged[num].xDirection,getObjectY(num)+blocksChanged[num].yDirection,getObjectZ(num)+blocksChanged[num].zDirection)
next num
for index = 0 to maxVertex
//Tear the cars vertexs apart as set by there random direction
SetMeshMemblockVertexPosition(carMem,index,GetMeshMemblockVertexX(carMem,index)+CarVertex[index].xDirection,GetMeshMemblockVertexY(carMem,index)+CarVertex[index].yDirection,GetMeshMemblockVertexZ(carMem,index)+CarVertex[index].zDirection)
SetMeshMemblockVertexPosition(otherCarMem,index,GetMeshMemblockVertexX(OtherCarMem,index)+otherCarVertex[index].xDirection,GetMeshMemblockVertexY(otherCarMem,index)+OtherCarVertex[index].yDirection,GetMeshMemblockVertexZ(otherCarMem,index)+otherCarVertex[index].zDirection)
SetMeshMemblockVertexPosition(carMem+1,index,GetMeshMemblockVertexX(carMem+1,index)+CarTopVertex[index].xDirection,GetMeshMemblockVertexY(carMem+1,index)+CarTopVertex[index].yDirection,GetMeshMemblockVertexZ(carMem+1,index)+CarTopVertex[index].zDirection)
SetMeshMemblockVertexPosition(otherCarMem+1,index,GetMeshMemblockVertexX(OtherCarMem+1,index)+otherCarTopVertex[index].xDirection,GetMeshMemblockVertexY(otherCarMem+1,index)+OtherCarTopVertex[index].yDirection,GetMeshMemblockVertexZ(otherCarMem+1,index)+otherCarTopVertex[index].zDirection)
next index
SetObjectMeshFromMemblock(carBlock,1,carMem)
SetObjectMeshFromMemblock(carBlock+1,1,carMem+1)
SetObjectMeshFromMemblock(otherCarBlock,1,otherCarMem)
SetObjectMeshFromMemblock(otherCarBlock+1,1,otherCarMem+1)
sync()
until timer()>StartTime#+3
endfunction
function restoreBlocks()
//restore all the block properties after a collision
for num=1 to blockCount
//restore blocks to the starting positions
SetObjectPosition(blocksChanged[num].id,blocksChanged[num].xPosStart,blocksChanged[num].yPosStart,blocksChanged[num].zPosStart)
next num
createCar(carBlock,carMem)
createCar(otherCarBlock,otherCarMem)
resetTimer() //need to reset time for the road curves
endfunction
function createSound(num as integer)
//create sound wave in memory
local sound as integer
local frames as integer
local data as integer
local size as integer
local mem as integer
local sec as float
sec = .4
data = sec * (44100 * (2*2)) // 176400 bytes per second
frames = data / 4
size = 2+2+4+4 + data
mem = CreateMemblock(size)
SetMemblockByte(mem,0, 2) //The first 2 bytes of the memlbock store the number of channels (1 or 2 supported)
SetMemblockByte(mem,1, 0)
SetMemblockByte(mem,2,16) //the next 2 bytes store the bits per sample (8 (1 byte) or 16 (2 byte) supported)
SetMemblockByte(mem,3, 0)
SetMemblockint(mem,4,44100) // the next 4 bytes store the samples per second, for example 44100
SetMemblockint(mem,8,frames) // The next 4 bytes are the number of frames in the sound data, the size of the sound data in bytes can be calculated from this with the formula numFrames*(bitsPerSample/8)*channels.
local i as integer
local value as integer
local Hz as float // the hertz of the sound
local w as float
value=0
w=0
local randomize as integer[8]=[80,53,-25,73,44,0,24,80] //deep base rumble
maxW=360:if num=2 then maxW=32768 //360 is normal
for i=0 to data -1 step 4
Hz=randomize[random2(1,8)] //deep base rumble
w=w+(maxW / 44100.0) * Hz
if w > maxW then w = w -maxW
value = sin(w)*(32767.0) //Max −32768 through 32767
SetMemblockShort(mem,12+i+0 ,value) // short 2 bytes −32768 through 32767
SetMemblockShort(mem,12+i+2 ,value) // short 2 bytes −32768 through 32767
next i
sound = CreateSoundFromMemblock(mem)
DeleteMemblock(mem)
endFunction sound
function createBlankTexture(sizex# as float, sizey# as float, color)
swap()
drawbox(0,0,sizex#, sizey#, color, color,color,color, 1)
render()
img = getimage(0,0,sizex#, sizey#)
endfunction img
function getAngle(x1#, y1#, x2#, y2#)
//result# = ATanFull(x1# - x2#, y1# - y2#)
result# = ATan2(x1# - x2#,y1# - y2#)
endfunction result#
function createCar(carId as integer,carMemId as integer)
DeleteObject(carId):DeleteObject(CarId+1)
DeleteMemBlock(carMemId):DeleteMemblock(carMemId+1)
vertex as integer[7] = [17,15,7,13, 1,19,3,5]
CreateObjectBox(carId,2,2,4)
CreateMemblockFromObjectMesh(carId,carMemId,1)
setObjectPosition(carId,mapX/2,mapY,10)
SetObjectColor(carId,200,0,0,255) //red cars go faster
SetObjectCollisionMode(carId,1) //on is set or raycasting wont work
CreateObjectBox(carId+1,2,1,1) //the car top
setObjectPosition(carId+1,getObjectX(carId)-(mapX/2),getObjectY(carId)-mapY+1.5,getObjectZ(carId)-10)
CreateMemblockFromObjectMesh(carId+1,carMemId+1,1)
for i = 0 to 7
SetMeshMemblockVertexPosition(carMemId+1,vertex[i],GetMeshMemblockVertexX(carMemId,vertex[i]),GetMeshMemblockVertexY(carMemId,vertex[i])+.5,GetMeshMemblockVertexZ(carMemId,vertex[i])*.5)
next i
//SetMeshMemblockVertexPosition(carMemId+1,vertexBottom[2],GetMeshMemblockVertexX(carMemId,vertexBottom[2]),GetMeshMemblockVertexY(carMem,vertexBottom[2]),GetMeshMemblockVertexZ(carMem,vertexBottom[2])-1)
SetObjectMeshFromMemblock(carId+1,1,carMemId+1)
SetObjectColor(carId+1,0,0,200,255) //red cars go faster
SetObjectCollisionMode(carTop,1) //on is set or raycasting wont work
FixObjectToObject(carId+1,carId)
//SetObjectVisible(carId,0)
endfunction
I need to design cows etc to cross the road now lol
fubar