Описание Как мы имитируем физические свойства внутри Scratch Физика, Game design 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.

define Platforming Scripts: Jump Height (J.H) max speed: (M.S) Acceleration: (A) friction: (F) Wall Jump X: (W.J.X) Wall Jump Y: (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 :

(Yvel)//This stores the speed the player will move down by.
define Platforming Scripts: Jump Height (J.H) max speed: (M.S) Acceleration: (A) friction: (F) Wall Jump X: (W.J.X) Wall Jump Y: (W.J.Y)
change y by (Yvel)
change [Yvel v] by (-2)
if <(Yvel)<[-22]> then
set [Yvel v] to (-22) // this caps the player's max speed to -22
end


### 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:

define Platforming Scripts: Jump Height (J.H) max speed: (M.S) Acceleration: (A) friction: (F) Wall Jump X: (W.J.X) Wall Jump Y: (W.J.Y)
change y by (Yvel)
change [Yvel v] by (-2)
if <(Yvel)<[-22]> then
set [Yvel v] to (-22)
end
if <touching [level v]> then
repeat until <not<touching [level v]>>
change y by ((([abs v] of (Yvel))/(Yvel))*(-1)) // this slowly pushes the player out of the collision on the y-axis.
end
set [Yvel v] to (0) // Sets the speed back to 0


### 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.

define Platforming Scripts: Jump Height (J.H) max speed: (M.S) Acceleration: (A) friction: (F) Wall Jump X: (W.J.X) Wall Jump Y: (W.J.Y)
change y by (Yvel)
change [Yvel v] by (-2)
if <(Yvel)<[-22]> then
set [Yvel v] to (-22)
end
if <touching [level v]> then
repeat until <not<touching [level v]>>
change y by ((([abs v] of (Yvel))/(Yvel))*(-1)) // this slowly pushes the player out of the collision on the y-axis.
end
set [Yvel v] to (0)
if <<key [up arrow v] pressed?> or <key [w v] pressed?> > then
set [Yvel v] to (J.H) // Jump height can be set to any positive value
end


### 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:

define Platforming Scripts: Jump Height (J.H) max speed: (M.S) Acceleration: (A) friction: (F) Wall Jump X: (W.J.X) Wall Jump Y: (W.J.Y)
change y by (Yvel)
change [Yvel v] by (-2)
set [Ydir v] to (([abs v] of (Yvel))/(Yvel)) // this quantifies the direction the player is moving on the y-axis
if <(Yvel)<[-22]> then
set [Yvel v] to (-22)
end
if <touching [level v]> then
repeat until <not<touching [level v]>>
change y by ((([abs v] of (Yvel))/(Yvel))*(-1)) // this slowly pushes the player out of the collision on the y-axis.
end
set [Yvel v] to (0)
if <<<key [up arrow v] pressed?> or <key [w v] pressed?>> and <(Ydir)<> > then // Checks if the player is moving down when jumping
set [Yvel v] to (J.H) // Jump height can be set to any positive value
end

## 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

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:

when gf clicked
forever
switch costume to (hitbox v)
... //other scripts
switch costume to (regular v)
end

## 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

define move (dist)
change [speed x v] by (dist) //replace with this
... //the other scripts

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

when gf clicked
forever
switch costume to (hitbox v)
change [speed y v] by [-1]
change y by (speed y)
check ground touch::custom
set [speed x v] to ((speed x)*(0.8)) //add this!
change x by (speed x) //and this!
...
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.