External Exam Download Resources Web Applications Games Recycle Bin

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:

  1. Only the objPlayer code is shown. Nothing has changed from any other objects that was completed previously.
  2. 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'.
  3. This time i have used mostly centred origins. This may help with appearance, flipping sprites and using external sprite animations (in following activities).
SpriteSpecifics
sprBlock64x64px, Origin: Middle Centre (32,32).
sprPlayer64x64px, Origin: Middle Centre (32,32).
sprRope200(W)x20(H)px, Origin: Middle Left (0,10).
sprLadder64x64px, Origin: Middle Centre (32,32).
sprProjectile200(W)x20(H)px, Origin: Middle Left (0,10).
sprPortalA / sprPortalB20(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