GameMaker Stuff

This page shows to create terrain using the midpoint displacement algorithm with GameMaker.



Script to generate terain (scr_midpoint_disp)
var wk = instance_create(0,0,work);
wk.left = 0;
wk.right = 1023;
wk.amount = 100;

ds_list_add(obj_controller.worklist, wk);

while (ds_list_size(obj_controller.worklist) > 0)
{
    var w = ds_list_find_value(obj_controller.worklist,0);

    ds_list_delete(obj_controller.worklist,0);
    
    if (w.right > w.left+1)    
    {
        var mid = int64((w.right + w.left)/2);
        show_debug_message("left=" + string(w.left) + " mid=" + string(mid) + " right=" + string(w.right))
        var leftHght =  obj_controller.heights[w.left];
        var rightHght = obj_controller.heights[w.right];
        
        var newHeight = (rightHght+leftHght)/2 - w.amount;
        obj_controller.heights[mid] = newHeight;
           
        var w1 = instance_create(0,0,work);
        w1.left = w.left;
        w1.right= mid;
        w1.amount = w.amount *.6 * choose(-1,1);
        ds_list_add(obj_controller.worklist,w1);   
        
        var w2 = instance_create(0,0,work);
        w2.left = mid;
        w2.right= w.right;
        w2.amount = w.amount *.7 * choose(-1,1);
        ds_list_add(obj_controller.worklist,w2);   
    }       
    else
    {
        show_debug_message("done");
    }   
}

Script to smooth terrain (scr_smooth)
for (var i=0; i < 1021; i+=1)
{
    obj_controller.heights[i+1] = 
        (obj_controller.heights[i] + 
        obj_controller.heights[i+1])/2; 
}

Now call the scripts from a controller
worklist = ds_list_create();
heights = ds_list_create();
 
//create 1024 slots for terrain heights
repeat (1024) 
{
    ds_list_add(heights,window_get_height()-100);
}

heights[0] = 400;
heights[1023] = 400;

scr_midpoint_disp(0,1023,100);

repeat(5)
    scr_smooth();


Drawing
To draw the terrain, loop over the height values in the list. This is done in a draw event on the controller.
for (var i=0; i < 1024; i++)
{   
    //draw line from height to bottom of screen
    draw_line(i,heights[i],i,window_get_height());
}