• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Making Classic Snake with GameMaker 2.3 Constructors (Linked Lists)

GM Version: 2.3.0.529
Target Platform: Windows
Download: Link to drive
Links: Youtube

Summary:
Simple video tutorial in making the classic Snake game with GameMaker 2.3 Constructors and the creation of Linked List using constructors

Tutorial:
Just want to share a simple tutorial of making the classic snake game using the new constructors of GMS 2.3. They were used to make a linked list data structure which was used to program the snake efficiently. Prior to 2.3, one might use ds_list or an array but the efficiency of adding a new head and removing the tail will have a time complexity of O(N) (shift all values of the list/array) whereas a linked list will have a time complexity of O(1).

The way the Linked list is created is by first making a constructor I named block (because the body and head of the snake look like blocks :) )
GML:
block = function(_x,_y,_blk) constructor{
    x = _x;
    y = _y;
    blk = _blk;
}
x and y are the coordinates of the block while blk is the pointer to the next block in the sequence. The last block, the tail, will be pointing to noone. We only have direct access to the head of the block linked list. We will need to hop to the other blocks in the body using the block pointer to access those. fortunately, we do not need direct access any single block at except the head at any part of the game. In the beginning, when the snake is one pixel long, the head and the tail are same block.

Every step, a new head is created which points to the old head and the tail will be destroyed. If you eat the food however, the tail will not be destroyed which will increase the length of the snake by one.
GML:
head = new block(x,y,head); //creation of new block
var p = head;
var lp = noone;

while(p.blk != noone){
    if (p != head && p.x == x && p.y == y){
        game_restart();  
    }
    lp = p;
    p = p.blk;  
}

if (x == obj_food.x && y == obj_food.y){ //if you eat food, destroy the food and spawn a new one in an open space
    instance_destroy(obj_food);
    var _x = floor(random(16));
    var _y = floor(random(16));
    var pp = head;
    while (pp != noone){ //ensure that food is spawned in open space (using ds_grid to take note of occupied areas for this could speed up the process but it is not necessary)
        if (pp.x == _x && pp.y == _y){
            _x = floor(random(16));
            _y = floor(random(16));
            pp = head;
        }
        else{
            pp = pp.blk;  
        }
    }
    instance_create_depth(_x,_y,0,obj_food);
}
else{ //if you dont eat food, delete the tail
    delete lp.blk;
    lp.blk = noone;
}

The snake is drawn with a simple black pixel per block:
GML:
draw_set_color(c_black);
var p = head;
while (p != noone){
    draw_rectangle(p.x,p.y,p.x,p.y,0);
    p = p.blk;
}

It's nice to see that even a simple game like snake benefits from the new GML features. I'm sure most of you guys are not interested in creating an old game like snake so you can skip to 11:20, when I start making the linked list constructor.
 
Top