Advanced Platformer Physics

Материал из Поле цифровой дидактики

A platformer is a type of game distinguished by jumping across platforms and avoiding obstacles. In order to make the game realistic, more advanced scripting must be used.

Y movement

Because advanced simulations for platformers take more blocks of code, condensing it to a single custom block can simplify the script. A custom block, ticked run without screen refresh is needed.

definePlatformingScripts:JumpHeightJ.Hmaxspeed:M.SAcceleration:Afriction:FWallJumpX:W.J.XWallJumpY:W.J.Y

To make for realistic gravity, the amount the player moves down in will increase the longer the player is in the air. 1 variable is needed to store the value the player will move down by :

YvelThisstoresthespeedtheplayerwillmovedownby.definePlatformingScripts:JumpHeightJ.Hmaxspeed:M.SAcceleration:Afriction:FWallJumpX:W.J.XWallJumpY:W.J.YchangeybyYvelchangeYvelby-2ifYvel<-22thensetYvelto-22thiscapstheplayer'smaxspeedto-22end

Y-Collisions

In order for the player to collide with another entity like the level, the player needs to be pushed out of the level one pixel at a time until the player is out of the collision. To determine if the player collided with a ceiling, the player must check if the collision occurred during a jump, or when the "Yvel" variable is positive. If it is a ceiling collision, the player will be pushed out of the level downwards:

definePlatformingScripts:JumpHeightJ.Hmaxspeed:M.SAcceleration:Afriction:FWallJumpX:W.J.XWallJumpY:W.J.YchangeybyYvelchangeYvelby-2ifYvel<-22thensetYvelto-22endiftouchinglevelthenrepeatuntilnottouchinglevelchangeybyabsofYvel/Yvel*-1thisslowlypushestheplayeroutofthecollisiononthey-axis.endsetYvelto0Setsthespeedbackto0

Jumping

Coding Jumping for the player requires the Yvel variable to be set to a positive value. However, the player must only jump when it collides the level.

definePlatformingScripts:JumpHeightJ.Hmaxspeed:M.SAcceleration:Afriction:FWallJumpX:W.J.XWallJumpY:W.J.YchangeybyYvelchangeYvelby-2ifYvel<-22thensetYvelto-22endiftouchinglevelthenrepeatuntilnottouchinglevelchangeybyabsofYvel/Yvel*-1thisslowlypushestheplayeroutofthecollisiononthey-axis.endsetYvelto0ifkeyuparrowpressed?orkeywpressed?thensetYveltoJ.HJumpheightcanbesettoanypositivevalueend

Fixing the stick to the ceiling bug

When the player collides with the ceiling and is still jumping, the player has a tendency to stick to the ceiling. To fix this, the player must only jump when the player is falling. A variable is needed to describe the direction the player is moving on the y-axis:

Ydir

Integrate the "Ydir" variable in the platforming script:

definePlatformingScripts:JumpHeightJ.Hmaxspeed:M.SAcceleration:Afriction:FWallJumpX:W.J.XWallJumpY:W.J.YchangeybyYvelchangeYvelby-2setYdirtoabsofYvel/Yvelthisquantifiesthedirectiontheplayerismovingonthey-axisifYvel<-22thensetYvelto-22endiftouchinglevelthenrepeatuntilnottouchinglevelchangeybyabsofYvel/Yvel*-1thisslowlypushestheplayeroutofthecollisiononthey-axis.endsetYvelto0ifkeyuparrowpressed?orkeywpressed?andYdir<0thenChecksiftheplayerismovingdownwhenjumpingsetYveltoJ.HJumpheightcanbesettoanypositivevalueend

X movement

The movement along the x-axis requires more code, as acceleration, friction, and side collisions are needed. The velocity of the player moving on the x-axis will be stored as a variable, called "Xvel":

Hitboxes

Шаблон:Main

If your player, avatar, etc. has arms, they will catch on the platforms (if your player is a smooth rectangle you can skip this). The answer to that is a hitbox. Create a new costume for your sprite and make it a filled rectangle about the size of your normal costume (the one it's showing). Then update your scripts like this:

whenclickedforeverswitchcostumetohitbox...otherscriptsswitchcostumetoregularend

Walking Momentum

To simulate momentum, it needs a gliding effect - after you stop pressing the left/right key, it "glides" to a stop instead of stopping right away. First, update the "move" block - replace the "change x" block with a "change speed x" block

definemovedistchangespeedxbydistreplacewiththis...theotherscripts

Then, after the "check ground touch" block, add:

whenclickedforeverswitchcostumetohitboxchangespeedyby-1changeybyspeedycheckgroundtouchsetspeedxtospeedx*0.8addthis!changexbyspeedxandthis!...end

What this does is slowly (but not too slowly) speed up when you are pressing the key, and slowly lose speed when you let go.

See Also