Advanced Platformer Script

Instructions: Arrow keys or WASD to move.\n\nSupports varying gravities, frictions, air resistance, restitution forces, stairs, slopes, and custom physics events.

@Stage\n\n@player_collider\n\nwhen flag clicked\ngo to x: (36) y: (28)\nshow\nset [ghost v] effect to (100)\nset [player_xvel v] to [0]\nset [player_yvel v] to [0]\nset [player_is_grounded v] to [0]\nforever\n    set [player_input_x v] to [0]\n    set [player_input_y v] to [0]\n    if <<<key (right arrow v) pressed?> or <key (d v) pressed?>> and <(player_is_sliding) = [0]>> then\n        change [player_input_x v] by (1)\n    end\n    if <<<key (left arrow v) pressed?> or <key (a v) pressed?>> and <(player_is_sliding) = [0]>> then\n        change [player_input_x v] by (-1)\n    end\n    if <<<<<key (up arrow v) pressed?> or <key (w v) pressed?>> or <key (space v) pressed?>> and <(player_is_grounded) = [1]>> and <(player_is_sliding) = [0]>> then\n        set [player_yvel v] to (player_jump_height)\n    end\n    change [player_xvel v] by ((player_input_x) * (player_speed))\n    HandleMovement\n    DetectSlopes\n    CheckGrounded\n    DetectCustomEvents\n    if <(player_is_grounded) = [1]> then\n        set [player_xvel v] to ((player_xvel) * (FRICTION))\n    end\n    set [player_xvel v] to ((player_xvel) * (AIR_RESISTANCE))\n    change [player_yvel v] by (GRAVITY)\nend\n\ndefine HandleMovement\nset [i v] to [1]\nset [player_speed_x v] to ([abs v] of (player_xvel) )\nset [player_speed_y v] to ([abs v] of (player_yvel) )\nset [did_step_down v] to [0]\nset [player_did_step v] to [0]\nset [dx v] to ((player_speed_x) / (player_xvel))\nrepeat until <not <(i) < ([floor v] of (player_speed_x) )>>\n    change x by ((player_speed_x) / (player_xvel))\n    change [i v] by (1)\n    if <<touching (scene v)?> or <touching (_edge_ v)?>> then\n        change y by (2)\n        if <<touching (scene v)?> or <touching (_edge_ v)?>> then\n            change y by (-2)\n            set [i v] to ([floor v] of (player_speed_x) )\n            change x by ((-1) * ((player_speed_x) / (player_xvel)))\n            set [player_xvel v] to ((player_xvel) * ((0) - (WALL_RESTITUTION)))\n        else\n            set [player_did_step v] to [1]\n        end\n    end\nend\nset [i v] to [1]\nrepeat until <not <(i) < ([floor v] of (player_speed_y) )>>\n    change y by ((player_speed_y) / (player_yvel))\n    change [i v] by (1)\n    if <<touching (scene v)?> or <touching (_edge_ v)?>> then\n        set [i v] to ([floor v] of (player_speed_y) )\n        change y by ((-1) * ((player_speed_y) / (player_yvel)))\n        if <(player_yvel) > [0]> then\n            set [player_yvel v] to ((player_yvel) * ((0) - (WALL_RESTITUTION)))\n        else\n            set [player_yvel v] to [0]\n        end\n    end\nend\nrepeat until <not <<touching (scene v)?> or <touching (_edge_ v)?>>>\n    change y by (1)\nend\nchange y by (-1)\n\nset [friction v] to [0.8]\nset [gravity v] to [-3]\nset [air_resistance v] to [0.74]\nset [wall_restitution v] to [0.22]\nset [player_speed v] to [4]\nset [player_jump_height v] to [22]\n\ndefine CheckGrounded\nchange y by (GRAVITY)\nif <<touching (scene v)?> or <touching (_edge_ v)?>> then\n    set [player_is_grounded v] to [1]\nelse\n    set [player_is_grounded v] to [0]\nend\nchange y by ((0) - (GRAVITY))\n\ndefine DetectSlopes\nset [player_is_sliding v] to [0]\nif <(player_did_step) = [0]> then\n    change x by (1)\n    if <<touching (scene v)?> or <touching (_edge_ v)?>> then\n        change x by (-2)\n        if <not <<touching (scene v)?> or <touching (_edge_ v)?>>> then\n            change x by (-1)\n            set [player_is_sliding v] to [1]\n        end\n        change x by (2)\n    end\n    change x by (-1)\n    change x by (-1)\n    if <<touching (scene v)?> or <touching (_edge_ v)?>> then\n        change x by (2)\n        if <not <<touching (scene v)?> or <touching (_edge_ v)?>>> then\n            change x by (1)\n            set [player_is_sliding v] to [1]\n        end\n        change x by (-2)\n    end\n    change x by (1)\nend\n\ndefine DetectCustomEvents\nif <touching (bouncy_pad v)?> then\n    set [player_xvel v] to [-100]\n    broadcast (BouncePadHit v)\nend\nif <<(last_yvel) < [-9]> and <<(player_is_grounded) = [1]> and <(last_grounded) = [0]>>> then\n    broadcast (OnLand v)\nend\nif <<touching (glass v)?> and <(glass_is_broken) = [0]>> then\n    set [glass_is_broken v] to [1]\n    broadcast (OnGlassHit v)\nend\nset [last_yvel v] to (player_yvel)\nset [last_grounded v] to (player_is_grounded)\n\n@player_model\n\nwhen flag clicked\nforever\n    go to (player_collider v)\n    point in direction ((90) + (player_xvel))\nend\n\n@scene\n\nwhen flag clicked\nset [ghost v] effect to (100)\n\n@scene_mg\n\n@scene_fg\n\n@bouncy_pad\n\nwhen I receive [bouncepadhit v]\nset [brightness v] effect to (90)\nrepeat (10)\n    change [brightness v] effect by (-9)\nend\n\nwhen flag clicked\nclear graphic effects\n\n@trail\n\nwhen flag clicked\nhide\nforever\n    if <<<(player_is_grounded) = [1]> and <([abs v] of (player_xvel) ) > [2]>> or <(player_is_sliding) = [1]>> then\n        create clone of (_myself_ v)\n    end\nend\n\nwhen I start as a clone\nset size to (100) %\ngo to (player_collider v)\nchange x by (pick random (-3) to (3))\nchange y by (pick random (0) to (3))\nshow\nrepeat (10)\n    change [ghost v] effect by (10)\n    change size by (10)\n    change y by (2)\n    turn left (5) degrees\nend\ndelete this clone\n\n@impact\n\nwhen flag clicked\nhide\n\nwhen I start as a clone\nset size to (100) %\ngo to (player_collider v)\nchange x by (pick random (-5) to (5))\nchange y by (pick random (0) to (5))\nset [particle_x_vel v] to (pick random (-5) to (5))\nshow\nrepeat (10)\n    change [ghost v] effect by (10)\n    change size by (10)\n    turn left ((particle_x_vel) * (-10)) degrees\n    change y by (1)\n    change x by (particle_x_vel)\nend\ndelete this clone\n\nwhen I receive [onland v]\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\ncreate clone of (_myself_ v)\n\n@Platformer_Script\n\nwhen flag clicked\nhide\n\nshow\ngo to [front v] layer\n\n@glass\n\nwhen flag clicked\nset [ghost v] effect to (50)\ngo to x: (-129) y: (77)\npoint in direction (90)\nset size to (100) %\nswitch costume to (glass v)\nset [glass_is_broken v] to [0]\nshow\n\nwhen I receive [onglasshit v]\nhide\nSpawnParticles\n\nwhen I start as a clone\nif <not <(recursion) < [2]>> then\n    wait until <(collided) = [1]>\n    wait (1) seconds\n    repeat (10)\n        change [ghost v] effect by (5)\n    end\n    delete this clone\nend\n\nwhen I start as a clone\nshow\nif <(recursion) = [1]> then\n    wait (([abs v] of ((x position) - ([x position v] of [player_collider v])) ) / (100)) seconds\nend\nset [collided v] to [0]\nrepeat until <(collided) = [1]>\n    UpdateForces\n    HandleMovement\nend\nif <(recursion) < [2]> then\n    Recurse\n    delete this clone\nend\nforever\n    UpdateForces\n    HandleMovement\nend\n\ndefine SpawnParticles\ngo to x: ((-129) - (17)) y: (77)\nset [xvel v] to (player_xvel)\nset [yvel v] to (player_yvel)\nset [recursion v] to [1]\nrepeat (9)\n    switch costume to (particle v)\n    create clone of (_myself_ v)\n    change x by (4)\nend\n\ndefine HandleMovement\nset [xspeed v] to ([abs v] of (xvel) )\nset [yspeed v] to ([abs v] of (yvel) )\nset [i v] to [0]\nrepeat until <not <(i) < ([floor v] of (xvel) )>>\n    change x by ((xvel) / (xspeed))\n    change [i v] by (1)\n    if <touching (scene v)?> then\n        change x by ((0) - ((xvel) / (xspeed)))\n        set [i v] to ([floor v] of (xvel) )\n        set [xvel v] to ((0) - ((WALL_RESTITUTION) * (xvel)))\n    end\nend\nset [i v] to [0]\nrepeat until <not <(i) < ([floor v] of (yspeed) )>>\n    change y by ((yvel) / (yspeed))\n    change [i v] by (1)\n    if <touching (scene v)?> then\n        change y by ((0) - ((yvel) / (yspeed)))\n        set [i v] to ([floor v] of (yspeed) )\n        set [collided v] to [1]\n        set [yvel v] to ((0) - ((0.5) * (yvel)))\n    end\nend\n\ndefine UpdateForces\nturn right (xvel) degrees\nset [xvel v] to ((xvel) * (AIR_RESISTANCE))\nchange [yvel v] by ((GRAVITY) / (2))\n\ndefine Recurse\nnext costume\nchange [recursion v] by (1)\nchange [xvel v] by (-20)\ncreate clone of (_myself_ v)\nchange [xvel v] by (20)\ncreate clone of (_myself_ v)\nchange [xvel v] by (20)\ncreate clone of (_myself_ v)\n\n