Files
scrumfun/src/main.ts
2026-02-21 13:53:08 +01:00

164 lines
3.5 KiB
TypeScript

import { crew } from "@kaplayjs/crew";
import kaplay from "kaplay";
import { createCards } from "./card";
import { WOBBLE_ANGLE, SPEED } from "./constants";
import "kaplay/global"; // uncomment if you want to use without the prefix
import { initWebRTC } from "./multiplayer";
export const k = kaplay({
plugins: [crew],
background: "#4e495f",
scale: 2,
debugKey: "r",
});
loadRoot("./"); // A good idea for Itch.io publishing later
loadSprite("card", "sprites/card.png");
loadSprite("octo", "sprites/octo.png");
loadSprite("dead", "sprites/dead.png");
loadSprite("triboi", "sprites/triboi.png");
loadSprite("wolfi", "sprites/wolfi.png");
loadSprite("bubble", "sprites/bubble.png");
k.loadCrew("sprite", "cursor");
k.loadCrew("sprite", "pointer");
k.loadCrew("sprite", "kat");
k.loadCrew("sprite", "pineapple");
k.loadCrew("sprite", "been");
k.loadCrew("font", "happy");
setLayers(["game", "hover", "ui"], "game");
const createPlayer = (scravatar: string) => {
const player = add([
sprite(scravatar),
pos(outerWidth / 4, outerWidth / 4),
anchor("center"),
area({
isSensor: true,
}),
rotate(),
animate(),
named("player"),
"player",
]);
player.animate("angle", [WOBBLE_ANGLE, -WOBBLE_ANGLE], {
easing: easings.easeInOutCubic,
direction: "ping-pong",
duration: 1,
});
const bubble = player.add([sprite("bubble"), anchor("center"), pos(30, -50)]);
const bubbleText = bubble.add([
text("9", { font: "happy", size: 24 }),
pos(-5, -24),
color(Color.BLACK),
timer(),
]);
bubble.hidden = true;
player.on("countdown", () => {
bubble.hidden = false;
let time = 9;
bubbleText.loop(
1,
() => {
if (time === -1) {
bubble.hidden = true;
}
bubbleText.text = time.toString();
time--;
},
11,
);
});
return player;
};
scene("menu", () => {
add([text("Choose your Scravatar", { font: "happy" })]);
["wolfi", "octo", "dead", "triboi"].forEach((image, i) => {
const selection = add([
pos(88 * i + 100, 100),
anchor("center"),
circle(32, { fill: true }),
opacity(0.1),
z(-1),
area(),
]);
selection.add([
text(image.toUpperCase(), { font: "happy", size: 14 }),
anchor("center"),
pos(0, 40),
]);
const avatar = selection.add([
sprite(image),
rotate(),
animate(),
anchor("center"),
]);
selection.onHover(() => {
selection.opacity = 1;
setCursor("pointer");
});
selection.onHoverEnd(() => {
selection.opacity = 0.1;
setCursor("default");
});
selection.onClick(() => {
pushScene("game", image);
}, "left");
avatar.animate("angle", [WOBBLE_ANGLE, -WOBBLE_ANGLE], {
easing: easings.easeInOutCubic,
direction: "ping-pong",
duration: 1,
});
});
const peerIDToConnect = location.pathname.replace("/", "");
initWebRTC(peerIDToConnect);
});
scene("game", (scravatar: string) => {
createCards();
const player = createPlayer(scravatar);
onUpdate(() => {
setCamPos(lerp(getCamPos(), player.pos, 0.1));
});
onKeyDown(["w", "up"], () => {
player.moveBy(0, -SPEED);
});
onKeyDown(["a", "left"], () => {
player.moveBy(-SPEED, 0);
});
onKeyDown(["s", "down"], () => {
player.moveBy(0, SPEED);
});
onKeyDown(["d", "right"], () => {
player.moveBy(SPEED, 0);
});
onKeyDown("u", () => {
player.trigger("countdown");
});
});
pushScene("menu");
// pushScene("game", "wolfi");