External Exam Download Resources Web Applications Games Recycle Bin

platform collision correction | gml

 TypeDesc
sign(), returns 1, -1, or 0, based on parameter being positive or negative (or zero):
sign(-15)functionreturns -1
sign(7)functionreturns 1
sign(0)functionreturns 0
friction - done manually (i.e. not using in-built friction variable):
anySpeedVal = anySpeedVal * 0.95statementslowly decays value of anySpeedVal over time (when used in Step event)
x and y - built-in GML variables:
x = x + anyMovementValstatementchanges location of object to the position x + anyMovementVal. we calculate x and y values manually in our platformer, which gives us better control over our positioning, as it allows us to prevent collisions before they occur, which helps us not to "stick" to floors or walls.

Both objBlock and objPlayer are default sizes (64px x 64px, origin 0,0) and default properties (Visible, and not Solid)

objPlayer Create

grav = 1;
horiz = 0;
vert = 0;
move_speed = 7;
jump_speed = -15;
frict = 0.9;

objPlayer Step

if (keyboard_check(vk_right)){ horiz = move_speed; };
if (keyboard_check(vk_left)){ horiz = -move_speed; };
if (keyboard_check(vk_nokey)){ horiz = horiz * frict; };
vert = vert + grav;

if (place_meeting(x, y+1, objBlock)) and (keyboard_check(vk_up)) { vert = jump_speed; }
  
if (place_meeting(x+horiz, y, objBlock)) { 
  while (!place_meeting(x+sign(horiz), y, objBlock)) { 
    x = x + sign(horiz); 
  }
  horiz = 0;
}
x = x + horiz;

if (place_meeting(x, y+vert, objBlock)) {
  while (!place_meeting(x, y+sign(vert), objBlock)) {
    y = y + sign(vert);
  }
  vert = 0;
}
y = y + vert;

Challenges

1. Implement the above code

2. Lay out your level with some jumps and drops. Test these to check they are feasible.

3. Adjust grav, move_speed, jump_speed and frict values in the Create event. Explain what each do and how it changes the "feel" of your game.

4. Read the following commented version of objPlayer.step()

objPlayer Step

// left and right movement inputs:
if (keyboard_check(vk_right)){ horiz = move_speed; };
if (keyboard_check(vk_left)){ horiz = -move_speed; };
if (keyboard_check(vk_nokey)){ horiz = horiz * frict; }; //friction
	
// add constant force of gravity to our desired vert speed:
vert = vert + grav;
	
// only ALLOW jump IF the objBlock is 1 pixel BELOW the player,
// or in other words, if the player is EXACTLY standing on floor:
if (place_meeting(x, y+1, objBlock)) and (keyboard_check(vk_up)) { vert = jump_speed; }
	
// check for a HORIZONTAL collision:
if (place_meeting(x+horiz, y, objBlock)) { 
  // move AS CLOSE AS WE CAN to the HORIZONTAL collision object:
  // sign() can only return 1, -1, or 0.
  // sign(-7) == -1 (i.e. negative 1)
  // sign(7) == 1 (or +1 or positive 1)
  // sign(0) == 0
  while (!place_meeting(x+sign(horiz), y, objBlock)) { 
    x = x + sign(horiz); // move 1 pixel at a time towards object
  }
  horiz = 0; // no left right movement on HORIZONTAL collisions
}
x = x + horiz; // affect calculated horizontal changes by APPLYING to x co-ord
    
// check for a VERTICAL collision:
if (place_meeting(x, y+vert, objBlock)) {
  // move AS CLOSE AS WE CAN to the VERTICAL collision object:
  while (!place_meeting(x, y+sign(vert), objBlock)) {
  // remember, sign() can only return 1, -1, or 0:
    y = y + sign(vert);
  }
  vert = 0; // no up down movement on VERTICAL collisions
}
y = y + vert; // affect calculated vertical changes by APPLYING to x co-ord