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 ... {
...
} */