platform collision correction | gml
Type | Desc | |
---|---|---|
sign(), returns 1, -1, or 0, based on parameter being positive or negative (or zero): | ||
sign(-15) | function | returns -1 |
sign(7) | function | returns 1 |
sign(0) | function | returns 0 |
friction - done manually (i.e. not using in-built friction variable): |
||
anySpeedVal = anySpeedVal * 0.95 | statement | slowly decays value of anySpeedVal over time (when used in Step event) |
x and y - built-in GML variables: | ||
x = x + anyMovementVal | statement | changes 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 code2. 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