A player that runs and jumps between platforms. It's a good one to read if you want to see how collisions with SquareKickbox work, and how to move things a set amount every tick.
Use the left and right arrow keys to move, and the up arrow or space to jump.
Make a project like in Getting Started, and put this in game.js. It doesn't need any assets.
import MDog from "https://cdn.jsdelivr.net/gh/MiloKesteloot/MDogEngine@v1.4.0/MDogModules/MDogMain.js";
const Vector = MDog.Math.Vector;
const SquareKickbox = MDog.Basics.SquareKickbox;
const Keyboard = MDog.Input.Keyboard;
// The player is 12 by 16 pixels. Its kickbox is attached to its position, so it moves with it.
const player = new Vector(40, 300);
const velocity = new Vector(0, 0);
const playerBox = new SquareKickbox(player, 0, 0, 12, 16);
const platforms = [
makePlatform(0, 352, 512, 32),
makePlatform(110, 300, 90, 12),
makePlatform(240, 250, 90, 12),
makePlatform(370, 200, 90, 12),
makePlatform(210, 150, 60, 12),
];
function makePlatform(x, y, width, height) {
return new SquareKickbox(new Vector(x, y), 0, 0, width, height);
}
function main() {
const onGround = isOnGround();
if (onGround && velocity.y > 0) {
velocity.y = 0;
}
// Walk
velocity.x = 0;
if (Keyboard.isDown("ArrowLeft")) {
velocity.x = -0.8;
}
if (Keyboard.isDown("ArrowRight")) {
velocity.x = 0.8;
}
// Jump
if (onGround && (Keyboard.isClicked("ArrowUp") || Keyboard.isClicked(" "))) {
velocity.y = -2.2;
}
// Gravity, with a top falling speed
velocity.y = Math.min(velocity.y + 0.03, 3);
moveX(velocity.x);
moveY(velocity.y);
draw();
}
// Moves sideways, and stops at walls
function moveX(amount) {
player.x += amount;
for (const platform of platforms) {
if (playerBox.colliding(platform)) {
if (amount > 0) {
player.x = platform.getLeftX() - playerBox.getWidth();
} else {
player.x = platform.getRightX() + 1;
}
}
}
// Stay on the screen
player.x = Math.max(0, Math.min(player.x, MDog.Draw.getScreenWidthInArtPixels() - playerBox.getWidth()));
}
// Moves up or down, and stops at floors and ceilings
function moveY(amount) {
player.y += amount;
for (const platform of platforms) {
if (playerBox.colliding(platform)) {
if (amount > 0) {
player.y = platform.getTopY() - playerBox.getHeight();
} else {
player.y = platform.getBottomY() + 1;
}
velocity.y = 0;
}
}
}
// Checks if there's a platform one pixel below the player
function isOnGround() {
player.y += 1;
const touching = platforms.some(platform => playerBox.colliding(platform));
player.y -= 1;
return touching;
}
function draw() {
MDog.Draw.clear({color: "#1d2b3a"});
for (const platform of platforms) {
MDog.Draw.rectangleFill(platform.getLeftX(), platform.getTopY(), platform.getWidth(), platform.getHeight(), "#5e8c4a");
}
MDog.Draw.rectangleFill(playerBox.getLeftX(), playerBox.getTopY(), 12, 16, "#ffcc33");
}
MDog.setActiveFunction(main);
Every platform is a SquareKickbox stuck to its own Vector. The player's kickbox is stuck to the player's position, so moving the player moves its kickbox too.
The player moves along x and y separately. After each move, if the player overlaps a platform, it gets pushed back out to the edge. Doing one direction at a time is how you can tell whether you hit a wall, a floor, or a ceiling.
isOnGround() is a little sneaky: it moves the player down one pixel, checks for platforms, and moves back up. You can only jump if that found something.
Speeds are in pixels per tick, and there are 160 ticks a second, so a walking speed of 0.8 is 128 pixels a second.