Advanced Platformer Physics

Материал из Поле цифровой дидактики
Описание Как мы имитируем физические свойства внутри Scratch
Область знаний Физика, Game design
Область использования (ISTE)
Возрастная категория 14


Поясняющее видео
Близкие рецепту понятия
Среды и средства для приготовления рецепта: Scratch

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