platform | putting it all together so far | gml
refining what we have done in the previous tutorials, this brings together all the elements into one game level. Please note the following important notes:
- Only the objPlayer code is shown. Nothing has changed from any other objects that was completed previously.
- To make life easier when re-defining key inputs, variables were created to store the keys for the game in the player create event. This way re-defining keys is easy in the future - it can all be done 'in this one place'.
- This time i have used mostly centred origins. This may help with appearance, flipping sprites and using external sprite animations (in following activities).
Sprite | Specifics |
---|---|
sprBlock | 64x64px, Origin: Middle Centre (32,32). |
sprPlayer | 64x64px, Origin: Middle Centre (32,32). |
sprRope | 200(W)x20(H)px, Origin: Middle Left (0,10). |
sprLadder | 64x64px, Origin: Middle Centre (32,32). |
sprProjectile | 200(W)x20(H)px, Origin: Middle Left (0,10). |
sprPortalA / sprPortalB | 20(W)x64(H)px, Origin: Middle Centre (10,32). |
All objects default properties: Visible, but not Solid. Moving platforms (all directions) have objBlock set as parent object, and use the same sprBlock sprite.
objPlayer Create
grav = 1; horiz = 0; vert = 0; move_speed = 7; jump_speed = -15; frict = 0.9; //make life easier to re-define keys: key_for_up = ord("W") key_for_left = ord("A") key_for_down = ord("S") key_for_right = ord("D") key_for_projectile = mb_any; //new variables for adding ladders: on_ladder = false; ladder_climb_speed = move_speed div 2; //new variables for adding ropes: on_rope = false; attach_timer = room_speed div 4; //quarter of a second to hold on let_go_timer = 0; //new variables for portals: teleported = false; portal_deactivate_timer = room_speed div 2; //half sec
objPlayer Step
// all regular movement applies when i'm not on a rope // AND not on a ladder: if not(on_rope) and not(on_ladder) { // left and right movement inputs: if (keyboard_check(key_for_right)){ horiz = move_speed; }; if (keyboard_check(key_for_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(key_for_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 } //---------------------------- CLIMB LADDERS: // if i am on a ladder: if place_meeting(x,y,objLadder) and not // ... and im not going to go through the ground // that the ladder has been placed on top of: place_meeting(x,bbox_bottom+1,objBlock) { on_ladder = true; vert = 0; horiz = 0; if keyboard_check(key_for_up) y -= ladder_climb_speed; if keyboard_check(key_for_down) y += ladder_climb_speed; if keyboard_check(key_for_left) x -= ladder_climb_speed; if keyboard_check(key_for_right) x += ladder_climb_speed; } else { on_ladder = false; } //---------------------------- SWING ON ROPES: if let_go_timer > 0 let_go_timer -= 1; var rope = instance_place(x,y,objRope); if (rope != noone and let_go_timer < 1) { attach_timer -= 1; if attach_timer < 1 attach_timer = 0; on_rope = true; /*------------------------------------------------------------------------ If objPlayer sprite origins were Top Left then use the following: ------------------------------------------------------------------------*/ // x = rope.x+lengthdir_x(rope.sprite_width,rope.direction) - sprite_width/2; // y = rope.bbox_bottom-sprite_height/2; /*-------------------------------------------------------------------- Because my objPlayer sprite origins are Middle Centre i am using the following: --------------------------------------------------------------------*/ x = rope.x+lengthdir_x(rope.sprite_width,rope.direction); y = rope.bbox_bottom; if attach_timer < 1 { //getting off rope: if keyboard_check(key_for_up) { let_go_timer = room_speed div 2; //half a sec to get off rope vert = jump_speed; } if keyboard_check(key_for_left) { let_go_timer = room_speed div 2; horiz = -(move_speed); } if keyboard_check(key_for_right) { let_go_timer = room_speed div 2; horiz = move_speed; } } } else { on_rope = false; attach_timer = room_speed div 4; } //---------------------------- PROECTILES: if mouse_check_button(key_for_projectile){ var inst = instance_create_layer(x,y,"Instances",objProjectile); with(inst){ inst.direction = point_direction(x,y,mouse_x,mouse_y); inst.image_angle = direction; inst.speed = 10; } } //---------------------------- PORTALS: if place_meeting(x, y, objPortalA) and !(teleported) { teleported = true; y = objPortalB.y; x = objPortalB.x + (x-xprevious); } if place_meeting(x, y, objPortalB) and !(teleported) { teleported = true; y = objPortalA.y; x = objPortalA.x + (x-xprevious); } if (teleported) portal_deactivate_timer -= 1; if (portal_deactivate_timer < 1){ teleported = false; portal_deactivate_timer = room_speed div 2; //half sec }
test game so far here in the Games link above