Patrick's push block

a nice push block i hope.

 Info

/*

- The object should be solid and have the block as its parent.

- You'll need to replace all occurrences of "player", "block", "global.leftbutton", "global.rightbutton", "killPlayer" with the names your game uses.

- Tested in yuuutu's engine (8.1) and yoyo's engine (studio)

- No author credit necessary.

*/

 Create


/// Patrick's push block
// GM snippet link (may have updated version): http://klazen.com/gm/eEq

// parameters you can tweak
pushSpeed = 2 // can only be 1, 2, or 3
fallGravity = 0.2
fallInitialSpeed = 0 // note that you can set the fall gravity to 0 and fall speed to a number for no gravity effect.
maxFallSpeed = 4 // set to -1 for unlimited fall speed. 4 is an okay value
allowPlayerMidair = true // if true, player can push while they are midair (usually set to true)
allowFallingPush = false // if true, the block can be pushed while it's falling (usually set to false) warning: can be buggy if set to true
squashPlayer = false // if true, kill the player if fallen on them

// for reference: the yuuutu push block has no gravity, fall speed and max speed of 4.

// used internally
xMoved = 0
yMoved = 0

 Step

// set h to 1 or -1 if the player is pushing the block
var h;
h = 0
if place_meeting(x-1, y, player) and keyboard_check_direct(global.rightbutton) {
    h = 1
}
if place_meeting(x+1, y, player) and keyboard_check_direct(global.leftbutton) {
    h = -1
}

var playerOnGround;
with player playerOnGround = place_meeting(x, y+1, block)
if not allowPlayerMidair and not playerOnGround {
    h = 0
}
var startOnGround;
startOnGround = place_meeting(x, y+1, block)
if not allowFallingPush and not startOnGround {
    h = 0
}

// move the block 1 pixel at a time, checking for running into blocks and falling over edges
if h != 0 {
    repeat pushSpeed {
        x += h
        if place_meeting(x, y, block) {
            x -= h
            break
        }
        if startOnGround and not place_meeting(x, y+1, block) {
            y += 1
            gravity = fallGravity
            vspeed = fallInitialSpeed
            break
        }
    }
}

// start falling if randomly midair for whatever reason
if not place_meeting(x, y+1, block) {
    gravity = fallGravity
    if vspeed == 0 vspeed = fallInitialSpeed
}

if maxFallSpeed != -1 and vspeed > maxFallSpeed {
    vspeed = maxFallSpeed
}

if squashPlayer and place_meeting(x, y+vspeed, player) {
    with player killPlayer()
}

// used for resetting this block's position in the player-block collision event
xMoved = x
yMoved = y

  Collision with block

move_contact_solid(direction, speed)
speed = 0
gravity = 0

// fix for drawing bug in studio when y has ~0.50 remainder.
// this is probably not the right way to fix it, just FYI.
if floor((y - floor(y))*100)/100 == 0.50 y += 0.01

  PLAYER'S collision with block

// add this section at the very beginning of the player's block collision event.
// change "oPatPushBlock" to your object's name

// since this collision event may have moved a push block back,
// put all push blocks back in their positions before this collision event occurred.
with oPatPushBlock {
    x = xMoved
    y = yMoved
    y += vspeed
}

/* the standard block collision code should still be down here
if !place_free ... {
  ...
  ...
  ...
}
if !place_free ... {
  ...
  ...
  ...
}
if !place_free ... {
  ...
} */