# [PHP] Generating Random Terrain Fractal

0 favourites
• 3 posts
From the Asset Store
Best car suspension with spring effect and very cool terrain generation.
• PHP script (and eventually Construct 2) that generates fractal terrain using Diamond Square Algorithm. The three links below show (in order), implementation inside Construct 2, Fractal Terrain with Gradient, Raw Fractal

In Action Inside Construct

Terrain Example

Raw Example

``````<?

\$DATA_SIZE = 513;
\$SEED = 0.0;
\$data = array();
\$maxY = -1E32;
\$minY = 1E32;
mt_srand(\$DATA_SIZE);
\$RAND_MAX = mt_getrandmax();
\$data[0][0] = \$data[0][\$DATA_SIZE-1] = \$data[\$DATA_SIZE-1][0] = \$data[\$DATA_SIZE-1][\$DATA_SIZE-1] = \$SEED;
\$h = 200.0;

for (\$sideLength = \$DATA_SIZE-1; \$sideLength >= 2; \$sideLength /= 2, \$h /= 2.0)     {
\$halfSide = \$sideLength/2;
for(\$x=0; \$x<\$DATA_SIZE-1;\$x+=\$sideLength) {
?for(\$y=0; \$y<\$DATA_SIZE-1; \$y+=\$sideLength) {

//x,y is upper left corner of the square
//calculate average of existing corners
\$avg = \$data[\$x][\$y] +                     //top left
\$data[\$x+\$sideLength][\$y]   +                    //top right
\$data[\$x][\$y+\$sideLength]   +                     //lower left
\$data[\$x+\$sideLength][\$y+\$sideLength];      //lower right

\$avg = \$avg / 4.0;

//center is average plus random offset in the range (-h, h)
\$offset = (-\$h) + rand() * (\$h - (-\$h)) / \$RAND_MAX;
\$data[\$x+\$halfSide][\$y+\$halfSide] = \$avg + \$offset;

?} //for y
} // for x

//Generate the diamond values
//Since diamonds are staggered, we only move x by half side
//NOTE: if the data shouldn't wrap the x < DATA_SIZE and y < DATA_SIZE
for (\$x=0; \$x<\$DATA_SIZE; \$x+=\$halfSide) {
for (\$y=(\$x+\$halfSide)%\$sideLength; \$y<\$DATA_SIZE; \$y+=\$sideLength) {

//x,y is center of diamond
//we must use mod and add DATA_SIZE for subtraction
//so that we can wrap around the array to find the corners

\$avg =
\$data[(\$x-\$halfSide+\$DATA_SIZE)%\$DATA_SIZE][\$y] +     //left of center
\$data[(\$x+\$halfSide)%\$DATA_SIZE][\$y]                    +     //right of center
\$data[\$x][(\$y+\$halfSide)%\$DATA_SIZE]                    +     //below center
\$data[\$x][(\$y-\$halfSide+\$DATA_SIZE)%\$DATA_SIZE];     //above center

\$avg = \$avg / 4.0;

//new value = average plus random offset
//calc random value in the range (-h,+h)
\$offset = (-\$h) + rand() * (\$h - (-\$h)) / \$RAND_MAX;
\$avg = \$avg + \$offset;

//update value for center of diamond
\$data[\$x][\$y] = \$avg;

//wrap values on the edges
//remove this and adjust loop condition above
//for non-wrapping values
//if (\$x == 0) \$data[\$DATA_SIZE-1][\$y] = \$avg;
//if (\$y == 0) \$data[\$x][\$DATA_SIZE-1] = \$avg;
} //for y
?} //for x
} //for sideLength

//Calculate minY and maxY values
for (\$i = 0; \$i<\$DATA_SIZE-1; \$i++){
for(\$j=0; \$j<\$DATA_SIZE-1; \$j++) {
?if (\$data[\$i][\$j] > \$maxY){
\$maxY = \$data[\$i][\$j];
?}
?if (\$data[\$i][\$j] < \$minY){
\$minY = \$data[\$i][\$j];
?}
}
}

createTerrain();

// start of functions
function createTerrain(){
global \$DATA_SIZE, \$data, \$maxY, \$minY;
\$px = 0;
\$py = 0;
\$pz = 0;
\$pallete = array();
// I use a 256px wide image gradient here to represent the colors for elevation
\$im = imagecreatefrompng("map.png");
for(\$a = 0;\$a<= 256;\$a++){
?\$rgb = imagecolorat(\$im, \$a+1, 1);
?\$r = (\$rgb >> 16) & 0xFF;
?\$g = (\$rgb >> 8) & 0xFF;
?\$b = \$rgb & 0xFF;
?\$pallete[\$a][r] =  \$r;
?\$pallete[\$a][g] =  \$g;
?\$pallete[\$a][b] =  \$b;
}
\$gd = imagecreatetruecolor(\$DATA_SIZE, \$DATA_SIZE);
for(\$x=0; \$x < \$DATA_SIZE-1; \$x++){
for(\$y=0; \$y < \$DATA_SIZE-1; \$y++){
??//populate the point struct
\$px = \$x;
\$py = \$data[\$x][\$y]; // color || height
\$pz = \$y;
??//change range to 0..1
??\$py = (\$py - \$minY) / (\$maxY - \$minY);
??\$py  = floor(\$py * 255);
\$c[0] = \$pallete[\$py][r];
\$c[1] = \$pallete[\$py][g];
\$c[2] = \$pallete[\$py][b];
??\$color = imagecolorallocate(\$gd, \$c[0], \$c[1], \$c[2]);
??imagesetpixel(\$gd, round(\$y),round(\$x), \$color);
}
}
header('Content-Type: image/png');
imagepng(\$gd);
imagedestroy(\$gd);

}

function html2rgb(\$color){
if (\$color[0] == '#')
\$color = substr(\$color, 1);

if (strlen(\$color) == 6)
list(\$r, \$g, \$b) = array(\$color[0].\$color[1],
\$color[2].\$color[3],
\$color[4].\$color[5]);
elseif (strlen(\$color) == 3)
list(\$r, \$g, \$b) = array(\$color[0].\$color[0], \$color[1].\$color[1], \$color[2].\$color[2]);
else
return false;

\$r = hexdec(\$r); \$g = hexdec(\$g); \$b = hexdec(\$b);

return array(\$r, \$g, \$b);
}

?>``````
• well that's very interesting!

Think you could bias certain terrain areas to create stuff like biomes and other terrain features?

• ## Try Construct 3

Develop games in your browser. Powerful, performant & highly capable.

Construct 3 users don't see these ads
• Think you could bias certain terrain areas to create stuff like biomes and other terrain features?

I could.

• 3 posts
Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)