3D Modifying a mesh height in real time with some help from puzzler
https://forum.thegamecreators.com/thread/221994+ Code Snippet// Project: coordinate
// Created: 2018-04-06
// show all errors
SetErrorMode(2)
#constant screenWidth=1024
#constant screenHeight=768
#constant perlinw = 200
#constant perlinh = 200
#constant perlinz = 200
#constant mapX=2048
#constant mapY=50
#constant mapZ=1024
SetWindowSize(screenWidth,screenHeight,0)
Setvirtualresolution(screenWidth,screenHeight)
SetScissor(0,0,0,0)
SetCameraRange( 1, 0.1, 900000 )
SetGlobal3DDepth(10000)
type _heights
meshposition
height
endtype
global heights as _heights[]
global TerrainImageID
// start perlin map data
NoiseInit()
TerrainImageID=generatePerlinImages()
mapsprite = CreateSprite(TerrainImageID)
SetSpriteSize(mapsprite,100,100)
SetSpritePosition(mapsprite,screenWidth-100,0)
HeightMapTextureMemblock = CreateMemblockFromImage(TerrainImageID)
HeightMapTextureWidthMemblock = GetMemblockInt(HeightMapTextureMemblock, 0)
HeightMapTextureHeightMemblock = GetMemblockInt(HeightMapTextureMemblock, 4)
TerrainImageID =CreateImageFromMemblock(HeightMapTextureMemblock)
//the following three lines only used if not updating on fly
//HeightImageMemblock=CreateMemblockFromImage(HeightImage)
//HeightImageWidthMemblock=GetMemblockInt(HeightImageMemblock, 0)
//HeightImageHeightMemblock=GetMemblockInt(HeightImageMemblock, 4)
global TerrainObjectID
// create the terrain object from a height map
TerrainObjectID=CreateObjectFromHeightMap( "height.png", mapX,mapY, mapZ, 0, 0 )
SetObjectCollisionMode( TerrainObjectID, 1 ) //On needed for object raycasting
SetObjectImage( TerrainObjectID, TerrainImageID, 0 )
SetObjectTransparency(TerrainObjectID,0)
TerrainMemblock=createMapMemblock(TerrainObjectID)
//DeleteObject(TerrainObjectID)
//createObjectFromMeshMemblock(TerrainObjectID,TerrainMemblock)
//SetObjectPosition(TerrainObjectID,x,y,z)
//SetObjectCollisionMode( TerrainObjectID, 1 )
//SetObjectImage( TerrainObjectID, TerrainImageID, 0 )
//SetObjectTransparency(TerrainObjectID,0)
//SetCameraRange(1,1,2000 )
SetCameraPosition(1, 805, 378, -41)
//SetObjectMeshNormalMapScale( TerrainObjectID, 0, 1.0, 1.0 )
do
checkCameraMovement()
pointerState=GetRawMouseLeftState()
if pointerState = 1
pointer_x = GetPointerX()
pointer_y = GetPointerY()
//pointer_y2 =screenHeight-GetPointerY()
// get the x, y and z unit vectors based on the pointer position
unit_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
unit_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
unit_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
// calculate the start of the ray cast, which is the unit vector + the camera position
start_x# = unit_x# + GetCameraX(1)
start_y# = unit_y# + GetCameraY(1)
start_z# = unit_z# - GetCameraZ(1)
// calculate the end of the vector, which is the unit vector multiplied by the length of the ray cast and then add the camera position to it
end_x# = 1000*unit_x# + GetCameraX(1)
end_y# = 1000*unit_y# + GetCameraY(1)
end_z# = 1000*unit_z# - GetCameraZ(1)
// determine which object has been hit
object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
Print ("objhit" + str(object_hit)+"="+str(TerrainObjectID))
if object_hit = TerrainObjectID
xPixel# = GetObjectRayCastX(0)
yPixel# = GetObjectRayCastZ(0)
for y = -5 to 5 step 1
for x = -5 to 5 step 1
writePixelMemblock(HeightMapTextureMemblock,HeightMapTextureWidthMemblock,HeightMapTextureHeightMemblock,xPixel#+x,yPixel#+y,1,1,1,255)
//i=xpixel#+x
//SetMeshMemblockVertexPosition(TerrainMemblock,i,GetMeshMemblockVertexX(TerrainMemblock,i),GetMeshMemblockVertexY(TerrainMemblock,i)+1,GetMeshMemblockVertexZ(TerrainMemblock,i)) //make it flat
//i=i+ypixel#+y
//SetMeshMemblockVertexPosition(TerrainMemblock,i,GetMeshMemblockVertexX(TerrainMemblock,i),GetMeshMemblockVertexY(TerrainMemblock,i)+1,GetMeshMemblockVertexZ(TerrainMemblock,i)) //make it flat
next x
next y
// index of this vertex is (Vertices start back left and go right then down to next line etc....
yPixel#=screenHeight-yPixel#/1.2
maxX=(SQRT(GetMemblockInt(TerrainMemblock,0)))*1.5
maxZ=(SQRT(GetMemblockInt(TerrainMemblock,0)))*.95
x=xPixel#/(mapX/maxX):z=(yPixel#)/(mapZ/MaxZ)
x=xPixel#/(mapX/perlinw):z=(yPixel#)/(mapZ/perlinz)
i=floor((x) + (z*maxX))
if i>0 and i<=GetMemblockInt(terrainMemblock,0)
// i = floor(xPixel# + (yPixel#*MapX)*GetMemblockInt(TerrainMemblock,0))
print (i)
posy=1
// for posy=-1 to 1
for posx=-1 to 1
if (i+posx)*posy >0 or (i+posx) * posy<GetMemblockSize(TerrainMemBlock)
SetMeshMemblockVertexPosition(TerrainMemblock,heights[(i+posx) * posy].meshposition,GetMeshMemblockVertexX(TerrainMemblock,(i+posx)*posy),GetMeshMemblockVertexY(TerrainMemblock,(i+posx)*posy)+heights[i].height/10,GetMeshMemblockVertexZ(TerrainMemblock,(i+posx)*posy))
dec heights[(i+posx) * posy].height,1
endif
// next
next
SetObjectMeshFromMemblock(TerrainObjectID,1,TerrainMemblock)
endif
endif
// update the image from the memblock
CreateImageFromMemblock(TerrainImageID,HeightMapTextureMemblock)
endif
if GetRawMouseRightPressed()
resetTerrain(TerrainMemblock)
endif
// show some information
Print( "FPS: " + str(ScreenFPS(),1) )
Print("MsxX="+str(GetObjectSizeMaxX(terrainObjectID)))
Print( "Polygons: " + str(GetPolygonsDrawn()))
print( "CameraPos: " + str(GetCameraX(1)) + ", " + str(GetCameraY(1)) +", " + str(GetCameraZ(1)))
print("vertices="+str(GetMemblockInt(terrainMemblock,0)))
print("maxX="+str(maxX))
print("maxZ="+str(maxZ))
print("X="+str(X))
print("Z="+str(z))
print("i ="+str(i))
sync()
loop
function createMapMemblock(newobj as integer)
chk = CreateMemblockFromObjectMesh(newobj,1)
endfunction chk
function checkCameraMovement()
if GetRawKeyState(37) then MoveCameraLocalX(1,-5) //Left
if GetRawKeyState(39) then MoveCameraLocalX(1,5) //Right
if GetRawKeyState(38) then MoveCameraLocalZ(1,5) //Forward
if GetRawKeyState(40) then MoveCameraLocalZ(1,-5) //Backward
if GetRawKeyState(87) then MoveCameraLocalY(1,-5) //87 W
if GetRawKeyState(83) then MoveCameraLocalY(1,5) //87 S
//if GetRawKeyState(65) then RotateCameraLocalY(1,1)
//if GetRawKeyState(68) then RotateCameraLocalY(1,-1)
// if cameray#<(blocksizey*10) then cameray#=(blocksizey*10)
if GetRawKeyPressed(27) then end
/*
// rotate the camera
if ( GetPointerPressed()=1 )
startMouseX# = GetPointerX()
startMouseY# = GetPointerY()
angx# = GetCameraAngleX(1)
angy# = GetCameraAngleY(1)
endif
if ( GetPointerState() = 1 )
fDiffX# = (GetPointerX() - startMouseX#)/4.0
fDiffY# = (GetPointerY() - startMouseY#)/4.0
newX# = angx# + fDiffY#
if ( newX# > 89 ) then newX# = 89
if ( newX# < -89 ) then newX# = -89
SetCameraRotation( 1, newX#, angy# + fDiffX#, 0 )
endif
*/
endfunction
function writePixelMemblock(memblockId as integer,memblockWidth,memblockHeight,x as integer,y as integer,R as integer, G as integer, B as integer, A as integer)
if (mapX/perlinw)>1 and (mapZ/perlinz)>1
x=x/(mapX/perlinw):y=y/(mapZ/perlinz)
else
x=x/perlinw:y=y/perlinz
endif
if x<0 then exitfunction
if y<0 then exitfunction
R =R+ GetMemblockByte(memblockId,12+(x*4)+((memblockHeight-y)*4*memblockWidth))
G =G+ GetMemblockByte(memblockId,13+(x*4)+((memblockHeight-y)*4*memblockWidth))
B =B+ GetMemblockByte(memblockId,14+(x*4)+((memblockHeight-y)*4*memblockWidth))
A =A+ GetMemblockByte(memblockId,15+(x*4)+((memblockHeight-y)*4*memblockWidth))
if R>255 then R=255
if G>255 then G=255
if B>255 then B=255
if A>255 then A=255
SetMemblockByte(memblockId,12+(x*4)+((memblockHeight-y)*4*memblockWidth),R) // Write Red
SetMemblockByte(memblockId,13+(x*4)+((memblockHeight-y)*4*memblockWidth),G) // Write Green
SetMemblockByte(memblockId,14+(x*4)+((memblockHeight-y)*4*memblockWidth),B) // Write Blue
SetMemblockByte(memblockId,15+(x*4)+((memblockHeight-y)*4*memblockWidth),A) // Write Alpha full opaque (255)
endfunction
function resetTerrain (msblk as integer)
count = GetMemblockInt( msblk ,0 )
for i = 0 to count
SetMeshMemblockVertexPosition(msblk,i,GetMeshMemblockVertexX(msblk,i),0,GetMeshMemblockVertexZ(msblk,i)) //make it flat
next
SetObjectMeshFromMemblock(TerrainObjectID,1,msblk)
Endfunction
function generatePerlinImages()
// Generate image from memblock
size = perlinw * perlinh * 4 + 12
mem = CreateMemblock(size) //the colour texture image
SetMemblockInt(mem,0,perlinw)
SetMemblockInt(mem,4,perlinh)
SetMemblockInt(mem,8,32)
mem2 = CreateMemblock(size) //the black and white height image
SetMemblockInt(mem2,0,perlinw)
SetMemblockInt(mem2,4,perlinh)
SetMemblockInt(mem2,8,32)
offset as integer = 12
a as float, b as float
a = 5.0
b = 2.0
meshposition=0
for y = 0 to perlinh - 1
for x = 0 to perlinw - 1
a = a + 0.0001
b = b + 0.002
// Try out these two noise methods
//noise = 255.0*Noise2D(x/10.0,y/10.0)
noise = 255.0*Noise2D(x/255.0,y/255.0)
noise = abs(noise)
// add to array
height as _heights
height.meshposition=meshposition
height.height = noise
heights.insert(height)
// end of adding to array
inc meshposition
//clouds
if noise>255
SetMemblockByte(mem, offset, noise)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, noise)
SetMemblockByte(mem, offset+3, 255)
endif
//greenary
if noise>100 and noise<=255
SetMemblockByte(mem, offset, 0)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, 0)
SetMemblockByte(mem, offset+3, 255)
endif
//sand
if noise>50 and noise<=100
SetMemblockByte(mem, offset, noise)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, 0)
SetMemblockByte(mem, offset+3, 255)
endif
// water
if noise<=50
SetMemblockByte(mem, offset, noise/2)
SetMemblockByte(mem, offset+1, 0)
SetMemblockByte(mem, offset+2, noise)
SetMemblockByte(mem, offset+3, 255)
endif
//mem2 is the black and white image
SetMemblockByte(mem2, offset, noise)
SetMemblockByte(mem2, offset+1, noise)
SetMemblockByte(mem2, offset+2, noise)
SetMemblockByte(mem2, offset+3, 255)
offset = offset + 4
next
next
map=CreateImageFromMemblock(mem)
//heightImage=CreateImageFromMemblock(heightImage)
saveImage(mem,"height.png")
DeleteObject(mem):DeleteObject(mem2)
endfunction map
// ***************************************************************************************************
// Ken Perlin's Simplex Noise 2D. AGK Version.
// Ported from Stefan Gustavson's Java implementation
// (http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf)
// 2015.02.03
// AGK reference https://forum.thegamecreators.com/thread/213532
// Thank you Thank you
#constant PN3DF2 = 0.5*(sqrt(3.0)-1.0)
#constant PN3DG2 = (3.0-sqrt(3.0))/6.0
Type sPNVECTOR
x as float
y as float
z as float
endtype
Global PNHash as integer[512]
Global PNGrad3 as sPNVECTOR[256]
Function NoiseInit()
Local n as integer, rn as integer
For n=0 To 255
PNHash[n] = n
Next n
For n=0 To 255
rn=Random(0, 255)
PNHash.swap(n,rn)
Next n
For n=0 To 255
PNHash[256 + n] = PNHash[n]
Next n
PNHash[511] = PNHash[0]
For n=0 To 15
PNGrad3[n * 16 + 0].x = 1 : PNGrad3[n * 16 + 0].y = 1 : PNGrad3[n * 16 + 0].z = 0
PNGrad3[n * 16 + 1].x = -1 : PNGrad3[n * 16 + 1].y = 1 : PNGrad3[n * 16 + 1].z = 0
PNGrad3[n * 16 + 2].x = 1 : PNGrad3[n * 16 + 2].y = -1 : PNGrad3[n * 16 + 2].z = 0
PNGrad3[n * 16 + 3].x = -1 : PNGrad3[n * 16 + 3].y = -1 : PNGrad3[n * 16 + 3].z = 0
PNGrad3[n * 16 + 4].x = 1 : PNGrad3[n * 16 + 4].y = 0 : PNGrad3[n * 16 + 4].z = 1
PNGrad3[n * 16 + 5].x = -1 : PNGrad3[n * 16 + 5].y = 0 : PNGrad3[n * 16 + 5].z = 1
PNGrad3[n * 16 + 6].x = 1 : PNGrad3[n * 16 + 6].y = 0 : PNGrad3[n * 16 + 6].z = -1
PNGrad3[n * 16 + 7].x = -1 : PNGrad3[n * 16 + 7].y = 0 : PNGrad3[n * 16 + 7].z = -1
PNGrad3[n * 16 + 8].x = 0 : PNGrad3[n * 16 + 8].y = 1 : PNGrad3[n * 16 + 8].z = 1
PNGrad3[n * 16 + 9].x = 0 : PNGrad3[n * 16 + 9].y = -1 : PNGrad3[n * 16 + 9].z = 1
PNGrad3[n * 16 + 10].x = 0 : PNGrad3[n * 16 + 10].y = 1 : PNGrad3[n * 16 + 10].z = -1
PNGrad3[n * 16 + 11].x = 0 : PNGrad3[n * 16 + 11].y = -1 : PNGrad3[n * 16 + 11].z = -1
PNGrad3[n * 16 + 12].x = 1 : PNGrad3[n * 16 + 12].y = 1 : PNGrad3[n * 16 + 12].z = 0
PNGrad3[n * 16 + 13].x = -1 : PNGrad3[n * 16 + 13].y = 1 : PNGrad3[n * 16 + 13].z = 0
PNGrad3[n * 16 + 14].x = 0 : PNGrad3[n * 16 + 14].y = -1 : PNGrad3[n * 16 + 14].z = 1
PNGrad3[n * 16 + 15].x = 0 : PNGrad3[n * 16 + 15].y = -1 : PNGrad3[n * 16 + 15].z = -1
Next n
endfunction
function Noise2D(xin as float, yin as float)
local n0 as float, n1 as float, n2 as float, s as float, t as float, x0 as float, y0 as float, xs as float, ys as float
local i as integer, j as integer, i1 as integer, j1 as integer, i2 as integer, j2 as integer, gi0 as integer, gi1 as integer, gi2 as integer
local x1 as float, y1 as float, x2 as float, y2 as float, x3 as float, y3 as float, t0 as float, t1 as float, t2 as float
s = (xin + yin) * PN3DF2
xs = xin + s
i = floor(xs)
ys = yin + s
j = floor(ys)
t = (i + j) * PN3DG2
x0 = xin - (i - t)
y0 = yin - (j - t)
if x0>y0
i1=1
j1=0
else
i1=0
j1=1
endif
x1 = x0 - i1 + PN3DG2
y1 = y0 - j1 + PN3DG2
x2 = x0 - 1.0 + 2.0 * PN3DG2
y2 = y0 - 1.0 + 2.0 * PN3DG2
i = i && 255
j = j && 255
gi0 = PNHash[i + PNHash[j]] && 15
gi1 = PNHash[i + i1 + PNHash[j + j1]] && 15
gi2 = PNHash[i + 1 + PNHash[j+ 1]] && 15
t0 = 0.5 - x0*x0-y0*y0
if t0<0
n0 = 0.0
else
t0 = t0 * t0
n0 = t0 * t0 * (PNGrad3[gi0].x * x0 + PNGrad3[gi0].y * y0)
endif
t1 = 0.5 - x1*x1-y1*y1
if t1<0
n1 = 0.0
else
t1 = t1 * t1
n1 = t1 * t1 * (PNGrad3[gi1].x * x1 + PNGrad3[gi1].y * y1)
endif
t2 = 0.5 - x2*x2-y2*y2
if t2<0
n2 = 0.0
else
t2 = t2 * t2
n2 = t2 * t2 * (PNGrad3[gi2].x * x2 + PNGrad3[gi2].y * y2)
endif
endfunction 70.0 * (n0 + n1 + n2)
An
easier way to modify mesh great for building a terrain but not for real time
+ Code Snippet//3D Modifying a mesh height by modifying texture and re loading
// Project: coordinate
// Created: 2018-04-06
// show all errors
SetErrorMode(2)
#constant screenWidth=1024
#constant screenHeight=768
#constant perlinw = 200
#constant perlinh = 200
#constant perlinz = 200
#constant mapX=2048
#constant mapY=100
#constant mapZ=1024
SetWindowSize(screenWidth,screenHeight,0)
Setvirtualresolution(screenWidth,screenHeight)
SetScissor(0,0,0,0)
SetCameraRange( 1, 0.1, 900000 )
SetGlobal3DDepth(10000)
type _heights
meshposition
height
endtype
global heights as _heights[]
global TerrainImageID
// start perlin map data
NoiseInit()
TerrainImageID=generatePerlinImages()
mapsprite = CreateSprite(TerrainImageID)
SetSpriteSize(mapsprite,100,100)
SetSpritePosition(mapsprite,screenWidth-100,0)
HeightMapTextureMemblock = CreateMemblockFromImage(TerrainImageID)
HeightMapTextureWidthMemblock = GetMemblockInt(HeightMapTextureMemblock, 0)
HeightMapTextureHeightMemblock = GetMemblockInt(HeightMapTextureMemblock, 4)
TerrainImageID =CreateImageFromMemblock(HeightMapTextureMemblock)
//the following three lines only used if not updating on fly
//createBlankTexture(heightImage,200,200,makecolor(0,0,0))
HeightImage=loadImage("height.png")
HeightImageMemblock=CreateMemblockFromImage(HeightImage)
HeightImageWidthMemblock=GetMemblockInt(HeightImageMemblock, 0)
HeightImageHeightMemblock=GetMemblockInt(HeightImageMemblock, 4)
Local TerrainObjectID
// create the terrain object from a height map
TerrainObjectID=CreateObjectFromHeightMap( "height.png", mapX,mapY, mapZ, 0, 0 )
SetObjectCollisionMode( TerrainObjectID, 1 ) //On needed for object raycasting
SetObjectImage( TerrainObjectID, TerrainImageID, 0 )
SetObjectTransparency(TerrainObjectID,0)
//TerrainMemblock=CreateMemblockFromObjectMesh(TerrainObjectID,1)
//SetCameraRange(1,1,2000 )
SetCameraPosition(1, 805, 378, -41)
do
checkCameraMovement()
if GetPointerState()=1
pointer_x = GetPointerX()
pointer_y = GetPointerY()
//pointer_y2 =screenHeight-GetPointerY()
// get the x, y and z unit vectors based on the pointer position
unit_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
unit_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
unit_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
// calculate the start of the ray cast, which is the unit vector + the camera position
start_x# = unit_x# + GetCameraX(1)
start_y# = unit_y# + GetCameraY(1)
start_z# = unit_z# - GetCameraZ(1)
// calculate the end of the vector, which is the unit vector multiplied by the length of the ray cast and then add the camera position to it
end_x# = 1000*unit_x# + GetCameraX(1)
end_y# = 1000*unit_y# + GetCameraY(1)
end_z# = 1000*unit_z# - GetCameraZ(1)
// determine which object has been hit
object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
Print ("objhit=" + str(object_hit))
if object_hit = TerrainObjectID
xPixel# = GetObjectRayCastX(0)
yPixel# = GetObjectRayCastZ(0)
for y = -5 to 5 step 1
for x = -5 to 5 step 1
writePixelMemblock(HeightImageMemblock,HeightImageWidthMemblock,HeightImageHeightMemblock,xPixel#+x,yPixel#+y,1,1,1,255)
next x
next y
DeleteImage(HeightImage)
HeightImage=CreateImageFromMemblock(HeightImageMemblock)
saveImage(HeightImage,"height.png")
DeleteObject(TerrainObjectID)
TerrainObjectID=CreateObjectFromHeightMap( "height.png", mapX,mapY, mapZ, 0, 0 )
SetObjectCollisionMode( TerrainObjectID, 1 )
SetObjectImage( TerrainObjectID, TerrainImageID, 0 )
endif
endif
sync()
loop
function checkCameraMovement()
if GetRawKeyState(37) then MoveCameraLocalX(1,-5) //Left
if GetRawKeyState(39) then MoveCameraLocalX(1,5) //Right
if GetRawKeyState(38) then MoveCameraLocalZ(1,5) //Forward
if GetRawKeyState(40) then MoveCameraLocalZ(1,-5) //Backward
if GetRawKeyState(87) then MoveCameraLocalY(1,-5) //87 W
if GetRawKeyState(83) then MoveCameraLocalY(1,5) //87 S
if GetRawKeyPressed(27) then end
endfunction
function writePixelMemblock(memblockId as integer,memblockWidth,memblockHeight,x as integer,y as integer,R as integer, G as integer, B as integer, A as integer)
if (mapX/perlinw)>1 and (mapZ/perlinz)>1
x=x/(mapX/perlinw):y=y/(mapZ/perlinz)
else
x=x/perlinw:y=y/perlinz
endif
if x<0 then exitfunction
if y<0 then exitfunction
R =R+ GetMemblockByte(memblockId,12+(x*4)+((memblockHeight-y)*4*memblockWidth))
G =G+ GetMemblockByte(memblockId,13+(x*4)+((memblockHeight-y)*4*memblockWidth))
B =B+ GetMemblockByte(memblockId,14+(x*4)+((memblockHeight-y)*4*memblockWidth))
A =A+ GetMemblockByte(memblockId,15+(x*4)+((memblockHeight-y)*4*memblockWidth))
if R>255 then R=255
if G>255 then G=255
if B>255 then B=255
if A>255 then A=255
SetMemblockByte(memblockId,12+(x*4)+((memblockHeight-y)*4*memblockWidth),R) // Write Red
SetMemblockByte(memblockId,13+(x*4)+((memblockHeight-y)*4*memblockWidth),G) // Write Green
SetMemblockByte(memblockId,14+(x*4)+((memblockHeight-y)*4*memblockWidth),B) // Write Blue
SetMemblockByte(memblockId,15+(x*4)+((memblockHeight-y)*4*memblockWidth),A) // Write Alpha full opaque (255)
endfunction
function generatePerlinImages()
// Generate image from memblock
size = perlinw * perlinh * 4 + 12
mem = CreateMemblock(size) //the colour texture image
SetMemblockInt(mem,0,perlinw)
SetMemblockInt(mem,4,perlinh)
SetMemblockInt(mem,8,32)
mem2 = CreateMemblock(size) //the black and white height image
SetMemblockInt(mem2,0,perlinw)
SetMemblockInt(mem2,4,perlinh)
SetMemblockInt(mem2,8,32)
offset as integer = 12
a as float, b as float
a = 5.0
b = 2.0
meshposition=0
for y = 0 to perlinh - 1
for x = 0 to perlinw - 1
a = a + 0.0001
b = b + 0.002
// Try out these two noise methods
//noise = 255.0*Noise2D(x/10.0,y/10.0)
noise = 255.0*Noise2D(x/255.0,y/255.0)
noise = abs(noise)
// add to array
height as _heights
height.meshposition=meshposition
height.height = noise
heights.insert(height)
// end of adding to array
inc meshposition
//clouds
if noise>255
SetMemblockByte(mem, offset, noise)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, noise)
SetMemblockByte(mem, offset+3, 255)
endif
//greenary
if noise>100 and noise<=255
SetMemblockByte(mem, offset, 0)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, 0)
SetMemblockByte(mem, offset+3, 255)
endif
//sand
if noise>50 and noise<=100
SetMemblockByte(mem, offset, noise)
SetMemblockByte(mem, offset+1, noise)
SetMemblockByte(mem, offset+2, 0)
SetMemblockByte(mem, offset+3, 255)
endif
// water
if noise<=50
SetMemblockByte(mem, offset, noise/2)
SetMemblockByte(mem, offset+1, 0)
SetMemblockByte(mem, offset+2, noise)
SetMemblockByte(mem, offset+3, 255)
endif
//mem2 is the black and white image
SetMemblockByte(mem2, offset, noise)
SetMemblockByte(mem2, offset+1, noise)
SetMemblockByte(mem2, offset+2, noise)
SetMemblockByte(mem2, offset+3, 255)
offset = offset + 4
next
next
map=CreateImageFromMemblock(mem)
heightImg=CreateImageFromMemblock(mem2)
saveImage(heightImg,"height.png")
DeleteObject(mem):DeleteObject(mem2)
endfunction map
// ***************************************************************************************************
// Ken Perlin's Simplex Noise 2D. AGK Version.
// Ported from Stefan Gustavson's Java implementation
// (http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf)
// 2015.02.03
// AGK reference https://forum.thegamecreators.com/thread/213532
// Thank you Thank you
#constant PN3DF2 = 0.5*(sqrt(3.0)-1.0)
#constant PN3DG2 = (3.0-sqrt(3.0))/6.0
Type sPNVECTOR
x as float
y as float
z as float
endtype
Global PNHash as integer[512]
Global PNGrad3 as sPNVECTOR[256]
Function NoiseInit()
Local n as integer, rn as integer
For n=0 To 255
PNHash[n] = n
Next n
For n=0 To 255
rn=Random(0, 255)
PNHash.swap(n,rn)
Next n
For n=0 To 255
PNHash[256 + n] = PNHash[n]
Next n
PNHash[511] = PNHash[0]
For n=0 To 15
PNGrad3[n * 16 + 0].x = 1 : PNGrad3[n * 16 + 0].y = 1 : PNGrad3[n * 16 + 0].z = 0
PNGrad3[n * 16 + 1].x = -1 : PNGrad3[n * 16 + 1].y = 1 : PNGrad3[n * 16 + 1].z = 0
PNGrad3[n * 16 + 2].x = 1 : PNGrad3[n * 16 + 2].y = -1 : PNGrad3[n * 16 + 2].z = 0
PNGrad3[n * 16 + 3].x = -1 : PNGrad3[n * 16 + 3].y = -1 : PNGrad3[n * 16 + 3].z = 0
PNGrad3[n * 16 + 4].x = 1 : PNGrad3[n * 16 + 4].y = 0 : PNGrad3[n * 16 + 4].z = 1
PNGrad3[n * 16 + 5].x = -1 : PNGrad3[n * 16 + 5].y = 0 : PNGrad3[n * 16 + 5].z = 1
PNGrad3[n * 16 + 6].x = 1 : PNGrad3[n * 16 + 6].y = 0 : PNGrad3[n * 16 + 6].z = -1
PNGrad3[n * 16 + 7].x = -1 : PNGrad3[n * 16 + 7].y = 0 : PNGrad3[n * 16 + 7].z = -1
PNGrad3[n * 16 + 8].x = 0 : PNGrad3[n * 16 + 8].y = 1 : PNGrad3[n * 16 + 8].z = 1
PNGrad3[n * 16 + 9].x = 0 : PNGrad3[n * 16 + 9].y = -1 : PNGrad3[n * 16 + 9].z = 1
PNGrad3[n * 16 + 10].x = 0 : PNGrad3[n * 16 + 10].y = 1 : PNGrad3[n * 16 + 10].z = -1
PNGrad3[n * 16 + 11].x = 0 : PNGrad3[n * 16 + 11].y = -1 : PNGrad3[n * 16 + 11].z = -1
PNGrad3[n * 16 + 12].x = 1 : PNGrad3[n * 16 + 12].y = 1 : PNGrad3[n * 16 + 12].z = 0
PNGrad3[n * 16 + 13].x = -1 : PNGrad3[n * 16 + 13].y = 1 : PNGrad3[n * 16 + 13].z = 0
PNGrad3[n * 16 + 14].x = 0 : PNGrad3[n * 16 + 14].y = -1 : PNGrad3[n * 16 + 14].z = 1
PNGrad3[n * 16 + 15].x = 0 : PNGrad3[n * 16 + 15].y = -1 : PNGrad3[n * 16 + 15].z = -1
Next n
endfunction
function Noise2D(xin as float, yin as float)
local n0 as float, n1 as float, n2 as float, s as float, t as float, x0 as float, y0 as float, xs as float, ys as float
local i as integer, j as integer, i1 as integer, j1 as integer, i2 as integer, j2 as integer, gi0 as integer, gi1 as integer, gi2 as integer
local x1 as float, y1 as float, x2 as float, y2 as float, x3 as float, y3 as float, t0 as float, t1 as float, t2 as float
s = (xin + yin) * PN3DF2
xs = xin + s
i = floor(xs)
ys = yin + s
j = floor(ys)
t = (i + j) * PN3DG2
x0 = xin - (i - t)
y0 = yin - (j - t)
if x0>y0
i1=1
j1=0
else
i1=0
j1=1
endif
x1 = x0 - i1 + PN3DG2
y1 = y0 - j1 + PN3DG2
x2 = x0 - 1.0 + 2.0 * PN3DG2
y2 = y0 - 1.0 + 2.0 * PN3DG2
i = i && 255
j = j && 255
gi0 = PNHash[i + PNHash[j]] && 15
gi1 = PNHash[i + i1 + PNHash[j + j1]] && 15
gi2 = PNHash[i + 1 + PNHash[j+ 1]] && 15
t0 = 0.5 - x0*x0-y0*y0
if t0<0
n0 = 0.0
else
t0 = t0 * t0
n0 = t0 * t0 * (PNGrad3[gi0].x * x0 + PNGrad3[gi0].y * y0)
endif
t1 = 0.5 - x1*x1-y1*y1
if t1<0
n1 = 0.0
else
t1 = t1 * t1
n1 = t1 * t1 * (PNGrad3[gi1].x * x1 + PNGrad3[gi1].y * y1)
endif
t2 = 0.5 - x2*x2-y2*y2
if t2<0
n2 = 0.0
else
t2 = t2 * t2
n2 = t2 * t2 * (PNGrad3[gi2].x * x2 + PNGrad3[gi2].y * y2)
endif
endfunction 70.0 * (n0 + n1 + n2)
function createBlankTexture(ImgId as integer,sizex as integer, sizey as integer, color)
SetClearColor(0,0,0)
ClearScreen()
Render()
drawbox(0,0,sizex-1, sizey-1, color, color,color,color, 0)
Render()
//img = getimage(0,0,sizex, sizey)
getimage(ImgId,0,0,sizex, sizey)
Swap()
saveImage(imgId,"height.png")
endfunction
Complete 3D minigame showing a never ending world by wrapping objects in a predefined workspace
https://forum.thegamecreators.com/thread/222010+ Code Snippet//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=40 //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=40 //maximum blocks on z plane
#constant raiseAmmount=8 //the ammount to raise or lower each blocks vertexs
#constant speed# = 10.0 //the following for a sine curve to repesent hils on the yplane
#constant xMaxResolution=1024
#constant yMaxResolution=768
#constant acceleration#=.025 //used to calclate the carSpeed#
#constant maxCarSpeed#=2.0 //The Maximum speed the carBlock will move
#constant minRand=50 // the minimum the randmoness# can get hence and create more obstacles
#constant maxRand=350 // the maximum the randmoness# can get hence and create less obstacles
#constant decRand=1 // the degree the radomness decreased by to create more obstacle
#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 randomness = maxRand //the lower this value the harder it gets its decreased over time automatically
global blockCount
global carBlock=10000 //carblock and carMem have the same referrence
global carMem=10000 //the 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 texture1 //the detailed texture
global texture2 //the texture without detail
global texture3 //the checkpoint Image
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( "Mini 3d driving game with blocks" )
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
colorFlag as integer
yPos as integer
checkpointFlag 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:texture1=createtexture(32,32, makecolor(255,255,255),155):texture2=createtexture(32,32,makecolor(255,255,255),5)
for y = 1 to mapY
for x = 1 to mapX
for z = 1 to mapZ
CreateObjectBox(num,1,1,1)
c=random(100,150)
SetObjectColor(num,c,c,c,255)
SetObjectImage(num,texture1,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].yPos=y
blocksChanged[num].xPosStart=x
blocksChanged[num].yPosStart=y
blocksChanged[num].zPosStart=z
blocksChanged[num].colorFlag=0
blocksChanged[num].checkpointFlag=0
//SetObjectImage( num, random(1,20), 0)
SetObjectPosition(num,x,y,z)
inc num
next z
next x
next y
blockCount=num-1
CreateObjectBox(carBlock,1,1,2)
CreateMemblockFromObjectMesh(carBlock,carMem,1)
SetObjectCastShadow(carBlock, 1 ) //set shadows on for the carBlock
setObjectPosition(carBlock,mapX/2,mapY+3,10)
SetObjectColor(carBlock,200,0,0,255) //red cars go faster
SetObjectCollisionMode(carBlock,1) //on is set or raycasting wont work
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)
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:randomness = maxRand
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():yAngle=0
x=xMaxResolution/2
repeat
if GetDirectionX()<-.25 //uses gyroscope for movement
moveBlocks(abs(GetDirectionX()*2.5),0,0)
yAngle=-abs(GetDirectionX()*20)
SetObjectRotation( carBlock,0,yAngle,0 )
elseif GetDirectionX()>.25 //uses gyroscope for movement
moveBlocks(-abs(GetDirectionX()*2.5),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 first raycast is used to set the height of the carBlock
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#+1.0
end_y# = y#-6.0
end_z# = z#+2
hit=ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
if hit>0
rem move car according to hill height
SetObjectPosition(carBlock,GetObjectX(carBlock),GetObjectY(hit)+2,GetObjectZ(carBlock))
SetObjectCastShadow(carBlock, 1 )
endif
//the second raycasting is used for crashes
x#=getObjectX(carBlock)
y#=GetObjectY(carBlock)+2
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#+1.0
end_y# = y#-2.0
end_z# = z#+2
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
//randomness is used to determine if blocks should be raised and colored or not increases with time
if randomness>minRand then randomness=randomness-decRand //increase the probability of getting an obstacle
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
sync()
until GetRawKeyPressed(27) or lives <1
SetTextVisible(textGameOver,1)
SetTextVisible(textPlayAgain,1)
SetTextVisible(textHowFar,1)
endfunction
function setupText()
x=xMaxResolution/2
CreateText(textTitle,"Mini 3D Driving Game")
SetTextSize(textTitle,50)
SetTextPosition(textTitle,x-180,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
if GetObjectWorldX(num)<xMin#
SetObjectPosition(num,getObjectX(num)+(xNum+x),getObjectY(num),getObjectZ(num))
else
SetObjectPosition(num,getObjectX(num)+x,getObjectY(num),getObjectZ(num))
endif
endif
if x>0 //move blocks Left
if GetObjectWorldX(num)>xMax#
SetObjectPosition(num,getObjectX(num)-(xNum-x),getObjectY(num),getObjectZ(num))
else
SetObjectPosition(num,getObjectX(num)+x,getObjectY(num),getObjectZ(num))
endif
endif
if z>0 //move blocks toward screen
if GetObjectWorldZ(num)<zMin
SetObjectPosition(num,getObjectX(num),blocksChanged[num].yPos,getObjectZ(num)+zNum)
//x# = sin(timer()*speed#)*200
y# = sin(timer()*speed#*2)*100.0 // ranges from -100 to 100
y#=y#/50.0 //if this division is set to low the raycasting needs changing 50 and 75 both work well
moveBlockYDirection(num,y#)
//if blocksChanged[num].checkpointFlag=0 and
if getObjectWorldz(1)<=zMin //for white checkpoint line
//SetObjectColor(num,255,255,255,255)
SetObjectColor(num,myRed,myGreen,myBlue,255)
SetObjectImage(num,texture2,0)
blocksChanged[num].checkpointFlag=1
if blocksChanged[num].colorflag=1 //do not allow raised blocks at check points
blocksChanged[num].colorFlag=0
modifyBlock(num,-raiseAmmount) //lower block
SetObjectCastShadow(num,0)
endif
else
c=random(100,150)
SetObjectColor(num,c,c,c,255)
SetObjectImage(num,texture1,0)
blocksChanged[num].checkpointFlag=0
//if blocksChanged[num].colorflag=1 //
// blocksChanged[num].colorFlag=0
// modifyBlock(num,-raiseAmmount) //lower block
// SetObjectCastShadow(num,0)
//endif
endif
if blocksChanged[num].colorflag=0 //random color then raise block
if Random(0,randomness)<1
modifyBlock(num,raiseAmmount)
blocksChanged[num].colorFlag=1
blocksChanged[num].checkpointFlag=0
SetObjectCastShadow(num,1)
SetObjectColor(num,random(1,255),random(1,255),random(1,255),255)
SetObjectImage(num,texture2,0)
endif
else
modifyBlock(num,-raiseAmmount) //lower block
blocksChanged[num].colorFlag=0
blocksChanged[num].checkpointFlag=0
SetObjectCastShadow(num,0)
c=random(100,150):SetObjectColor(num,c,c,c,255)
SetObjectImage(num,texture1,0)
endif
else
SetObjectPosition(num,getObjectX(num),getObjectY(num),getObjectZ(num)-z)
rem block 40 is off the screen so increment score
if num=40 then inc score
endif
endif
next num
endfunction
function moveBlockYDirection(num,y as float)
//move blocks on the yplane as set by the sine curve
blocksChanged[num].yPos=y
SetObjectPosition(num,getObjectX(num),blocksChanged[num].yPos,getObjectZ(num))
endfunction
function blocksExplode()
//vertexFront as integer[4] = [0,1,2,3] rem front face
//vertexRight as integer[4] = [4,5,6,7] rem right face
//vertexTop as integer[4] = [8,9,10,11] rem top face
//vertexLeft as integer[4] = [12,13,14,15] rem left face
//vertexBottom as integer[4] = [20,21,22,23] rem bottom face
//vertexBack as integer[4] = [16,17,18,19] rem back face
//if you just want to seperate each face from the car set the same directions for each face as described above
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
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)
next index
SetObjectMeshFromMemblock(carBlock,1,carMem)
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)
SetObjectCastShadow(num,0) //set all blocks to no shadows
rem the blocks that have been raised return them back to how they started
if blocksChanged[num].colorflag=1
modifyBlock(num,-raiseAmmount)
c=random(100,150)
SetObjectColor(num,c,c,c,255)
SetObjectImage(num,texture1,0)
endif
blocksChanged[num].colorFlag=0
blocksChanged[num].checkpointFlag=0
next num
randomness = maxRand //restore the obstacles randomness back to easy after a crash
rem because the cars vertexs are destroyed delete the car and memblock and recreate them
DeleteObject(carBlock)
DeleteMemblock(carMem)
CreateObjectBox(carBlock,1,1,2)
CreateMemblockFromObjectMesh(carBlock,carMem,1)
SetObjectCastShadow(carBlock, 1 )
setObjectPosition(carBlock,mapX/2,mapY+3,10)
SetObjectRotation(carBlock,0,0,0)
SetObjectColor(carBlock,200,0,0,255) //red cars go faster
SetObjectCollisionMode(carBlock,1)
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
// 102, 51, 0
// Function to create a texture
// by Puzzler
// Inputs - Sizex - size of the texture to create - width
// Sizey - size of the texture to create - height
// Color - is the main color of the image
// Denisity - is a the depth of the texture - the lower the value, the more detail. higher value = no detail
//
// Returns the image for the resulting texture
//
// EG. CreateTexture ( 100, 100, makecolor(0,0,255), 100)
// This could create a DEEP water effect texture?
function createtexture(sizex# as float, sizey# as float, color, density as integer)
swap()
drawbox(0,0,sizex#, sizey#, color, color,color,color, 1)
render()
img = getimage(0,0,sizex#, sizey#)
memblockid = CreateMemblockFromImage (img)
imgwidth = GetMemblockInt(memblockid, 0)
imgheight = GetMemblockInt(memblockid, 4)
size=GetMemblockSize(memblockid)
for offset=12 to size-4 step 4
r=GetMemblockByte(memblockid, offset)
g=GetMemblockByte(memblockid, offset+1)
b=GetMemblockByte(memblockid, offset+2)
a=GetMemblockByte(memblockid, offset+3)
strength=random(1,density)
SetMemblockByte (memblockid, offset, r-strength)
SetMemblockByte (memblockid, offset+1, g-strength)
SetMemblockByte (memblockid, offset+2, b-strength )
SetMemblockByte (memblockid, offset+3, a-strength)
next
deleteimage (img)
img = CreateImageFromMemblock(memblockid)
DeleteMemblock(memblockid)
endfunction img