Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ssController #2

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions components/ssController/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# ssController() - 2D Sidescroll Platformer Controller

Apply this component to a game object for a 2D Sidescroll Platformer Controller that:

* Has player input built into the controller (can be turned off).
* Has advanced movement options using friction & acceleration.
* Implements CoyoteTime (jump after falling off a block for a short period of time).
* Implements a Jump Buffer (hitting space before landing allows you to buffer a jump that will execute as soon as you land).

## Requires

* A tag on any object you wish to be a wall.
* The object to have `["area", "body"]` components.

## Parameters

* `moveSpeed: 240`: number - how fast, in pixels/sec, the character should move.
* `accel: 8`: number - how fast, in pixels/sec/sec, the character accelerates.
* `deccel: 5`: number - how fast, in pixels/sec/sec, the character deccelerates.
* `velPower: 1`: number - extra control over how fast, in pixels/sec/sec the character changes speed.
* `friction: 0.9`: number - an extra amount the character loses speed when not having any input.
* `jumpForce: 480`: number - initial jump speed of the object (uses the built-in body() component to jump (for now)).
* `coyoteTime: 0.15`: number - how long, in seconds, the character has to jump after falling off an object.
* `jumpBufferTime: 0.2`: number - how long, in seconds, the character can press jump before being able to jump, and still have it execute.
* `blockTag: "block"`: string - what tag the character should check for when hitting a wall to reset its velocity.
* `useInput: true`: boolean - whether or not the character should use the built in controller movement inputs.

## Example Usage

```.js

"P": () => [
k.sprite("player"),
k.area(),
k.body(),
ssController({moveSpeed: 800}),
(etc.)
],

```
105 changes: 105 additions & 0 deletions components/ssController/ssController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// adds better movement && coyote time && jump buffer
export default function ssController({moveSpeed = 240, accel = 8, deccel = 5, velPower = 1, friction = 0.9, jumpForce = 480, coyoteTime = 0.15, jumpBufferTime = 0.2, blockTag = "block", useInput = true} = {}) {

// movement
var velocity = 0;
var targetSpeed = 0;
var amount;

// coyoteTime
var coyoteCount = 0;

var canJump = false;

// jump buffer
var jumpBufferCount = 0;

return {

id: "sscontroller",
require: ["pos", "body"],

add() {

this.input = 0;

onKeyPress(["space", "up"], () => {
if (canJump)
this.jump(jumpForce);
else
jumpBufferCount = jumpBufferTime;
});

this.onCollide(blockTag, (other, c) => {
if (c.isRight() && velocity > 0)
velocity = 0;
else if (c.isLeft() && velocity < 0)
velocity = 0;
});

},

update() {

// input

// should players change input themselves?

if (useInput) {
this.input = 0;

if (isKeyDown("a") || isKeyDown("left"))
this.input -= 1;

if (isKeyDown("d") || isKeyDown("right"))
this.input += 1;
}

// movement

targetSpeed = this.input * moveSpeed;

speedDif = targetSpeed - velocity;

accelRate = (Math.abs(targetSpeed) > 0.01) ? accel : deccel;

movement = Math.pow(Math.abs(speedDif) * accelRate, velPower) * Math.sign(speedDif);

velocity += movement * dt();

this.move(velocity, 0);

amount = Math.min(Math.abs(velocity), Math.abs(friction));

amount *= Math.sign(velocity);

velocity -= amount;

// coyote time
if (this.isGrounded()) {
coyoteCount = coyoteTime;
} else {
coyoteCount -= dt();
}

if ((coyoteCount > 0 && this.isFalling()) || this.isGrounded())
canJump = true;
else
canJump = false;

// jump buffer
if (jumpBufferCount > 0 && canJump)
this.jump(jumpForce);
else
jumpBufferCount -= dt();
},

draw() {},

destroy() {},

inspect() {
return "{\n\tInput: " + this.input + "\n\tVelocity: " + (Math.round(velocity*10)/10) + "\n\tCoyote: " + (Math.round(coyoteCount*10)/10) + "\n\tJump Buffer: " + (Math.round(jumpBufferCount*10)/10) + "\n\tCanJump: " + canJump + "\n}";
},
}
}