Compare commits
10 commits
495fd68fed
...
32fd1dde91
Author | SHA1 | Date | |
---|---|---|---|
|
32fd1dde91 | ||
|
a39a119ad8 | ||
|
e511b3bae4 | ||
|
9c7251f607 | ||
|
ecefe02aa2 | ||
|
8e0a25325b | ||
|
a12db0db5d | ||
|
c366ce804a | ||
|
c60e064852 | ||
|
9d4f05a8f2 |
4 changed files with 127 additions and 42 deletions
59
data.js
59
data.js
|
@ -1,4 +1,6 @@
|
|||
// the game data
|
||||
export default {
|
||||
// the platforms
|
||||
parts: [
|
||||
// x, y, width, height, type
|
||||
[100, 100, 200, 50],
|
||||
|
@ -23,37 +25,74 @@ export default {
|
|||
[1000, -1500, 50, 50],
|
||||
[1400, -1400, 50, 50],
|
||||
[1800, -1350, 50, 50],
|
||||
[2100, -1350, 50, 50],
|
||||
[2150, -1350, 50, 50],
|
||||
[2150, -1450, 50, 50],
|
||||
[2150, -1550, 50, 50],
|
||||
[2150, -1650, 50, 50],
|
||||
[2150, -1750, 50, 50, "checkpoint"],
|
||||
[2125, -1850, 100, 50],
|
||||
[2100, -1950, 150, 50],
|
||||
[2075, -2050, 200, 50],
|
||||
[2050, -2150, 100, 50],
|
||||
[2200, -2150, 100, 50],
|
||||
[2150, -2250, 50, 50, "checkpoint"],
|
||||
[2000, -2350, 50, 50],
|
||||
[1850, -2450, 50, 50],
|
||||
[1600, -2500, 50, 50],
|
||||
[1350, -2550, 50, 50],
|
||||
[1050, -2600, 50, 50],
|
||||
[775, -2650, 50, 50],
|
||||
[400, -2650, 50, 50],
|
||||
[25, -2650, 50, 50],
|
||||
[-350, -2650, 50, 50, "checkpoint"],
|
||||
[-750, -2650, 50, 50],
|
||||
[-1200, -2500, 50, 50],
|
||||
[-1500, -2200, 50, 50],
|
||||
[-1900, -1900, 50, 50],
|
||||
[-2100, -2000, 50, 50, "final"],
|
||||
],
|
||||
|
||||
// the player
|
||||
player: {
|
||||
x: 200,
|
||||
y: 0,
|
||||
velx: 0,
|
||||
vely: 0,
|
||||
// savex: 200,
|
||||
// savey: 85,
|
||||
savex: 850,
|
||||
savey: -1600,
|
||||
savex: 200,
|
||||
savey: 85,
|
||||
size: 15,
|
||||
canJump: false,
|
||||
},
|
||||
|
||||
// inputs - done this way so you can press multiple keys at once
|
||||
input: {
|
||||
up: false,
|
||||
down: false,
|
||||
left: false,
|
||||
right: false,
|
||||
},
|
||||
|
||||
// colors for each thing
|
||||
color: {
|
||||
player: "#f92a38",
|
||||
platforms: "#222222",
|
||||
shadow: "#dddddd",
|
||||
background: "#ffffff",
|
||||
dots: "#f6f6f6",
|
||||
platforms: "#222222",
|
||||
shadow: "#dddddd",
|
||||
checkpoint: "#4feab4",
|
||||
active: "#52e5a5",
|
||||
final: "#52e5cd",
|
||||
win: "#6befd9",
|
||||
},
|
||||
|
||||
camera: [0, 0],
|
||||
size: [0, 0],
|
||||
anim: [0, 0, 1],
|
||||
// rendering stuff
|
||||
camera: [0, 0], // camera position
|
||||
size: [0, 0], // window/canvas size
|
||||
anim: [0, 0, 1], // checkpoint animation details
|
||||
|
||||
// performance
|
||||
cache: {
|
||||
background: null,
|
||||
dirty: true,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<title>heya world</title>
|
||||
<title>canvas testing</title>
|
||||
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<script src="/script.js" type="module" defer></script>
|
||||
|
|
104
script.js
104
script.js
|
@ -1,9 +1,10 @@
|
|||
import game from "/data.js";
|
||||
import game from "/data.js"; // import the game data
|
||||
|
||||
// import elements from html
|
||||
const canvas = document.getElementById("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// resize the canvas to full screen
|
||||
function resize() {
|
||||
const w = window.innerWidth;
|
||||
const h = window.innerHeight;
|
||||
|
@ -14,6 +15,7 @@ function resize() {
|
|||
game.size = [w, h];
|
||||
}
|
||||
|
||||
// reset the player to the last checkpoint (or start)
|
||||
function die() {
|
||||
game.player.x = game.player.savex;
|
||||
game.player.y = game.player.savey;
|
||||
|
@ -22,8 +24,10 @@ function die() {
|
|||
}
|
||||
|
||||
function draw() {
|
||||
requestAnimationFrame(draw);
|
||||
|
||||
if (!game.cache.dirty) return;
|
||||
|
||||
requestAnimationFrame(draw); // to continuously animate
|
||||
|
||||
const offx = game.camera[0] - game.size[0] / 2;
|
||||
const offy = game.camera[1] - game.size[1] / 2;
|
||||
const c = game.color;
|
||||
|
@ -36,8 +40,9 @@ function draw() {
|
|||
color("background");
|
||||
ctx.fillRect(0, 0, game.size[0], game.size[1]);
|
||||
color("dots");
|
||||
for (let i = 0; i < 40; i++) {
|
||||
for (let j = 0; j < 30; j++) {
|
||||
|
||||
for (let i = 0; i < 30; i++) {
|
||||
for (let j = 0; j < 40; j++) {
|
||||
const spacing = 60;
|
||||
const depth = 0.5;
|
||||
ctx.beginPath();
|
||||
|
@ -52,7 +57,7 @@ function draw() {
|
|||
}
|
||||
}
|
||||
|
||||
// draw animation
|
||||
// draw checkpoint animation (if there is one)
|
||||
if (game.anim[2] < 1) {
|
||||
color("shadow");
|
||||
ctx.globalAlpha = 1 - game.anim[2];
|
||||
|
@ -65,7 +70,6 @@ function draw() {
|
|||
);
|
||||
ctx.fill();
|
||||
ctx.globalAlpha = 1;
|
||||
game.anim[2] += 0.04;
|
||||
}
|
||||
|
||||
// draw platforms
|
||||
|
@ -81,6 +85,8 @@ function draw() {
|
|||
// draw player
|
||||
color("player");
|
||||
rect(game.player.x, game.player.y, game.player.size, game.player.size);
|
||||
|
||||
game.cache.dirty = true;
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
@ -95,34 +101,61 @@ function update() {
|
|||
if (i.left) p.velx -= speed;
|
||||
if (i.right) p.velx += speed;
|
||||
|
||||
// update position
|
||||
if (move("x", p.velx, p.velx < 0 ? -1 : 1)) {
|
||||
p.velx = 0;
|
||||
// update x position
|
||||
for (let i = 0; i < Math.abs(p.velx) - 1; i++) {
|
||||
p.x += p.velx < 0 ? -1 : 1;
|
||||
const c = collision();
|
||||
if (c) {
|
||||
p.x -= p.velx < 0 ? -1 : 1;
|
||||
p.velx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// reset jump if they're falling or already jumping (there's a small grace period though)
|
||||
if (Math.abs(p.vely) > 3) p.canJump = false;
|
||||
|
||||
// update y position
|
||||
const collided = move("y", p.vely, p.vely < 0 ? -1 : 1);
|
||||
if (collided) {
|
||||
if (p.vely >= 0) p.canJump = true;
|
||||
if (p.vely >= 0) {
|
||||
// if they fell onto a platform then let them jump
|
||||
p.canJump = true;
|
||||
|
||||
// if they hit a checkpoint
|
||||
if (collided[4] === "checkpoint") {
|
||||
for (let part of game.parts.filter((i) => i[4] === "active")) {
|
||||
part[4] = "checkpoint";
|
||||
// if they hit a checkpoint
|
||||
if (collided[4] === "checkpoint" || collided[4] === "final") {
|
||||
// unset the other checkpoints
|
||||
for (let part of game.parts.filter((i) => i[4] === "active")) {
|
||||
part[4] = "checkpoint";
|
||||
}
|
||||
|
||||
const x = collided[0] + collided[2] / 2;
|
||||
const y = collided[1] + collided[3] / 2;
|
||||
|
||||
// play the checkpoint animation
|
||||
game.anim = [x, y, 0];
|
||||
game.player.savex = x - game.player.size / 2;
|
||||
game.player.savey = y - collided[3] / 2 - game.player.size;
|
||||
|
||||
// they won!
|
||||
if (collided[4] === "final") {
|
||||
alert("ayo you win");
|
||||
|
||||
// reset the inputs, `alert()` does weird things
|
||||
input.up = false;
|
||||
input.down = false;
|
||||
input.left = false;
|
||||
input.right = false;
|
||||
}
|
||||
|
||||
// don't spam animation; change platform color
|
||||
collided[4] = collided[4] === "final" ? "win" : "active";
|
||||
}
|
||||
|
||||
const x = collided[0] + collided[2] / 2;
|
||||
const y = collided[1] + collided[3] / 2;
|
||||
|
||||
game.anim = [x, y, 0];
|
||||
game.player.savex = x - game.player.size / 2;
|
||||
game.player.savey = y - collided[3] / 2 - game.player.size;
|
||||
|
||||
collided[4] = "active";
|
||||
}
|
||||
|
||||
p.vely = 0;
|
||||
}
|
||||
|
||||
// they fell out of the world
|
||||
if (p.y > 1000) die();
|
||||
|
||||
// update velocity
|
||||
|
@ -130,9 +163,15 @@ function update() {
|
|||
p.vely = Math.min(30, p.vely + 0.8);
|
||||
|
||||
// update camera
|
||||
c[0] = (c[0] * 9 + p.x) / 10;
|
||||
c[1] = (c[1] * 9 + p.y) / 10;
|
||||
const camx = (c[0] * 9 + p.x) / 10;
|
||||
const camy = (c[1] * 9 + p.y) / 10;
|
||||
if (c[0] !== camx || c[1] !== camy) game.cache.dirty = true;
|
||||
c[0] = camx;
|
||||
c[1] = camy;
|
||||
|
||||
if (game.anim[2] < 1) game.anim[2] += 0.04;
|
||||
|
||||
// move, and return the platform the player collided with if any
|
||||
function move(key, amt, speed) {
|
||||
for (let i = 0; i < Math.abs(amt) - 1; i++) {
|
||||
p[key] += speed;
|
||||
|
@ -142,9 +181,10 @@ function update() {
|
|||
return c;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
// check if there was a collision
|
||||
function collision() {
|
||||
const s = game.player.size;
|
||||
for (let part of game.parts) {
|
||||
|
@ -159,25 +199,29 @@ function update() {
|
|||
}
|
||||
}
|
||||
|
||||
// handle input
|
||||
function input(e) {
|
||||
const i = game.input;
|
||||
const down = e.type === "keydown";
|
||||
switch (e.key) {
|
||||
switch (e.code) {
|
||||
case "ArrowUp":
|
||||
case "KeyW":
|
||||
return (i.up = down);
|
||||
case "ArrowDown":
|
||||
case "KeyS":
|
||||
return (i.down = down);
|
||||
case "ArrowLeft":
|
||||
case "KeyA":
|
||||
return (i.left = down);
|
||||
case "ArrowRight":
|
||||
case "KeyD":
|
||||
return (i.right = down);
|
||||
case "r":
|
||||
case "KeyR":
|
||||
return die();
|
||||
}
|
||||
}
|
||||
|
||||
// run the game!
|
||||
|
||||
resize();
|
||||
draw();
|
||||
setInterval(update, 1000 / 60);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* mmmm css */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue