Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Binary file modified bun.lockb
Binary file not shown.
21 changes: 12 additions & 9 deletions src/menu.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { updateAndDraw as pongUpdateAndDraw } from "./pong";
import { updateAndDraw as bulletHellUpdateAndDraw } from "./bullet-hell";
import { updateAndDraw as setUpdateAndDraw } from "./set";

const games = {
pong: pongUpdateAndDraw,
"bullet hell": bulletHellUpdateAndDraw,
};
const gameNames = Object.keys(games);
const games = [
Copy link
Copy Markdown
Author

@sebastiansandqvist sebastiansandqvist Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious to get your take on using tuples instead of an object for this. it was the easiest way I could think of to fix the type error on line 95

["pong", pongUpdateAndDraw],
["bullet hell", bulletHellUpdateAndDraw],
["set", setUpdateAndDraw],
] as const;

let game = null as null | keyof typeof games;
// let game = null as null | (typeof games)[number];
let game = games[2] as null | (typeof games)[number];
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporarily just launching straight into Set

let index = 0;
let animatedIndex = 0;

Expand Down Expand Up @@ -44,7 +46,7 @@ export function updateAndDraw(
ctx.fillStyle = "white";
ctx.font = `${fontSize}px Arial`;
ctx.textAlign = "center";
const gameNames = Object.keys(games);
const gameNames = games.map(([name]) => name);
const canvasRect = canvas.getBoundingClientRect();
const numberToDrawAboveAndBelow = 4;
const spacing = 10;
Expand Down Expand Up @@ -74,7 +76,8 @@ export function updateAndDraw(
return;
}

games[game](canvas, ctx, dt);
const [_gameName, updateAndDraw] = game;
updateAndDraw(canvas, ctx, dt);
}

function modulusThatHandlesNegatives(n: number, m: number) {
Expand All @@ -89,6 +92,6 @@ document.addEventListener("keydown", (e) => {
if (e.key === "ArrowDown") index++;
if (e.key === "ArrowUp") index--;
if (e.key === "Enter") {
game = gameNames[modulusThatHandlesNegatives(index, gameNames.length)];
game = games[modulusThatHandlesNegatives(index, games.length)];
}
});
167 changes: 167 additions & 0 deletions src/set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
const gameResolution = { width: 400, height: 300 };
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is all throwaway code at this point! just trying to render something to the screen as a start. includes some experiments with the dashed fill and attempting (unsuccessfully) to render an S shape.


// attributes:
// - color: [red, green, blue]
// - fill: [solid, dashed, outline]
// - count: [1, 2, 3]
// - shape: [S, O, diamond]

type Shape = "S" | "O" | "diamond";
type Color = "red" | "green" | "blue";
type Fill = "solid" | "dashed" | "outline";
type Count = 1 | 2 | 3;

type Card = {
color: Color;
fill: Fill;
count: Count;
shape: Shape;
};

function isSet(cards: [Card, Card, Card]) {
const colors = new Set(cards.map((card) => card.color));
const fills = new Set(cards.map((card) => card.fill));
const counts = new Set(cards.map((card) => card.count));
const shapes = new Set(cards.map((card) => card.shape));

return (
(colors.size === 1 || colors.size === 3) &&
(fills.size === 1 || fills.size === 3) &&
(counts.size === 1 || counts.size === 3) &&
(shapes.size === 1 || shapes.size === 3)
);
}

export function updateAndDraw(
canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D,
dt: number,
) {
// make letterboxed area
const gameArea = (() => {
const drawingRect = canvas.getBoundingClientRect();
const drawingRectRatio = drawingRect.width / drawingRect.height;
const targetRatio = gameResolution.width / gameResolution.height;
const drawingRectWidth =
drawingRectRatio > targetRatio
? drawingRect.height * targetRatio
: drawingRect.width;
const drawingRectHeight =
drawingRectRatio > targetRatio
? drawingRect.height
: drawingRect.width / targetRatio;
return {
x: drawingRect.width / 2 - drawingRectWidth / 2,
y: drawingRect.height / 2 - drawingRectHeight / 2,
width: drawingRectWidth,
height: drawingRectHeight,
};
})();

ctx.fillStyle = "#333";
ctx.save();

ctx.translate(gameArea.x, gameArea.y);
ctx.scale(
gameArea.width / gameResolution.width,
gameArea.height / gameResolution.height,
);
ctx.fillRect(0, 0, gameResolution.width, gameResolution.height);

drawO(ctx, "red", "solid", 3, 50);
drawO(ctx, "blue", "dashed", 2, 100);
drawO(ctx, "green", "outline", 1, 150);

ctx.restore();
}

function drawS(ctx: CanvasRenderingContext2D) {
const s = {
curviness: 60,
width: 300,
height: 100,
strokeColor: "blue",
fillColor: "red",
};

ctx.beginPath();
ctx.moveTo(s.width / 2, 0);

ctx.bezierCurveTo(
s.width / 2 + s.curviness,
s.height / 4,
s.width / 2 - s.curviness,
(s.height / 4) * 3,
s.width / 2,
s.height,
);

ctx.moveTo(s.width / 2, s.height);

ctx.bezierCurveTo(
s.width / 2 - s.curviness,
(s.height / 4) * 3,
s.width / 2 + s.curviness,
s.height / 4,
s.width / 2,
0,
);

ctx.fillStyle = s.fillColor;
ctx.fill();

ctx.strokeStyle = s.strokeColor;
ctx.stroke();
}

// TODO: function to draw a card.
// then pass the card coords to the shape function.

function drawO(
ctx: CanvasRenderingContext2D,
color: Color,
fill: Fill,
count: Count,
y: number,
) {
const shapeWidth = 20;
const shapeHeight = 32;
for (let i = 0; i < count; i++) {
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.beginPath();
ctx.roundRect(
20 + (shapeWidth + 10) * i,
y,
shapeWidth,
shapeHeight,
shapeHeight,
);
ctx.closePath();
if (fill === "outline") ctx.stroke();
if (fill === "solid") {
ctx.stroke();
ctx.fill();
}
if (fill === "dashed") {
ctx.save();
ctx.stroke();
ctx.clip();
const dashGap = 1.5;
const startX = 20 + (shapeWidth + 10) * i;
const endX = startX + shapeWidth;
const startY = y;
const endY = y + shapeHeight;

for (let lineY = startY; lineY <= endY; lineY += 2 + dashGap) {
ctx.beginPath();
ctx.moveTo(startX, lineY);
ctx.lineTo(Math.min(startX + 32, endX), lineY);
ctx.stroke();
}
ctx.restore();
}
}
}

function drawDiamond() {}