215 lines
5.4 KiB
JavaScript
215 lines
5.4 KiB
JavaScript
// Eryn Wells <eryn@erynwells.me>
|
|
|
|
class Player {
|
|
name;
|
|
|
|
#color;
|
|
|
|
constructor(name, color) {
|
|
this.name = name;
|
|
this.#color = color;
|
|
}
|
|
|
|
get color() {
|
|
|
|
}
|
|
}
|
|
|
|
class Point {
|
|
static fromEventCoordinates(x, y) {
|
|
return new Point(x - marginSize, y - marginSize);
|
|
}
|
|
|
|
x = 0;
|
|
y = 0;
|
|
|
|
constructor(x = 0, y = 0) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
/// Return a value that uniquely identifies this Point.
|
|
get identifier() {
|
|
return `x:${this.x},y:${this.y}`;
|
|
}
|
|
|
|
/// Convert this point to an array of coordinates.
|
|
get coordinates() {
|
|
return [this.x, this.y];
|
|
}
|
|
|
|
/// Convert a Point in grid space to pixel space.
|
|
toPixelPoint() {
|
|
return [marginSize + this.x * cellSize, marginSize + this.y * cellSize];
|
|
}
|
|
|
|
convertPixelPointToGridPointWithRemainder() {
|
|
let clickCol = Math.floor(this.x / cellSize);
|
|
let clickRow = Math.floor(this.y / cellSize);
|
|
|
|
let clickColRemainder = this.x - (clickCol * cellSize);
|
|
let clickRowRemainder = this.y - (clickRow * cellSize);
|
|
|
|
if (clickColRemainder >= (cellSize - hitBoxMargin)) {
|
|
clickCol += 1;
|
|
clickColRemainder = clickColRemainder - cellSize;
|
|
}
|
|
|
|
if (clickRowRemainder >= (cellSize - hitBoxMargin)) {
|
|
clickRow += 1;
|
|
clickRowRemainder = clickRowRemainder - cellSize;
|
|
}
|
|
|
|
return [new Point(clickCol, clickRow), new Point(clickColRemainder, clickRowRemainder)];
|
|
}
|
|
|
|
/// Return a string that's nice to read.
|
|
toString() {
|
|
return `(${this.x}, ${this.y})`;
|
|
}
|
|
}
|
|
|
|
class Line {
|
|
player;
|
|
from;
|
|
to;
|
|
|
|
constructor(player, from, to) {
|
|
this.player = player;
|
|
this.from = from;
|
|
this.to = to;
|
|
}
|
|
|
|
get identifier() {
|
|
return `from:[${this.from.identifier}],to:[${this.to.identifier}]`;
|
|
}
|
|
}
|
|
|
|
const sketch = p => {
|
|
const marginSize = 10;
|
|
const cellSize = 40;
|
|
const gridSize = 20;
|
|
const hitBoxMargin = 7;
|
|
|
|
let player = 1;
|
|
let lines = new Map();
|
|
|
|
p.setup = () => {
|
|
const canvasSize = [
|
|
cellSize * (gridSize - 1) + marginSize * 2,
|
|
cellSize * (gridSize - 1) + marginSize * 2
|
|
];
|
|
createCanvas(...canvasSize);
|
|
};
|
|
|
|
let mouseBoundingBoxRect;
|
|
let debugNeighboringBoxA;
|
|
let debugNeighboringBoxB;
|
|
|
|
p.draw = () => {
|
|
background(220);
|
|
|
|
for (const l of lines.values()) {
|
|
const strokeColor = l.player === 1 ? color(255, 0, 0) : color(0, 0, 255);
|
|
p.stroke(strokeColor);
|
|
p.strokeWeight(2);
|
|
p.line(
|
|
...l.from.toPixelPoint(),
|
|
...l.to.toPixelPoint()
|
|
);
|
|
}
|
|
|
|
drawGrid();
|
|
|
|
debugDrawMouseBoundingBoxRect();
|
|
debugDrawNeighboringBoxes();
|
|
|
|
p.noLoop();
|
|
};
|
|
|
|
function drawGrid() {
|
|
for (let i = 0; i < gridSize; i++) {
|
|
for (let j = 0; j < gridSize; j++) {
|
|
const [x, y] = [marginSize + cellSize * j, marginSize + cellSize * i];
|
|
p.noStroke();
|
|
p.fill(128);
|
|
p.circle(x, y, 6);
|
|
}
|
|
}
|
|
}
|
|
|
|
function debugDrawMouseBoundingBoxRect() {
|
|
if (!mouseBoundingBoxRect) {
|
|
return;
|
|
}
|
|
|
|
p.stroke(255, 0, 0);
|
|
p.strokeWeight(1);
|
|
p.noFill();
|
|
p.rect(...mouseBoundingBoxRect);
|
|
}
|
|
|
|
function debugDrawNeighboringBoxes() {
|
|
|
|
}
|
|
|
|
p.mouseMoved = (event) => {
|
|
mouseBoundingBoxRect = findHitBox(event);
|
|
|
|
if (mouseBoundingBoxRect) {
|
|
loop();
|
|
}
|
|
};
|
|
|
|
p.mouseClicked = (event) => {
|
|
const clickPoint = Point.fromEventCoordinates(event.x, event.y);
|
|
|
|
const [gridPoint, gridPointRemainder] = clickPoint.convertPixelPointToGridPointWithRemainder();
|
|
|
|
const isVertical = gridPointRemainder.x > -hitBoxMargin && gridPointRemainder.x < hitBoxMargin;
|
|
|
|
const from = gridPoint;
|
|
const to = isVertical ? new Point(gridPoint.x, gridPoint.y + 1) : new Point(gridPoint.x + 1, gridPoint.y);
|
|
|
|
console.log(
|
|
"Mouse clicked.",
|
|
clickPoint.toString(),
|
|
gridPoint.toString(),
|
|
gridPointRemainder.toString(),
|
|
from.toString(),
|
|
to.toString(),
|
|
event
|
|
);
|
|
|
|
const newLine = new Line(player, from, to);
|
|
|
|
const newLineId = newLine.identifier;
|
|
if (!lines.has(newLineId)) {
|
|
lines.set(newLineId, newLine);
|
|
|
|
player = (player === 1 ? 2 : 1);
|
|
|
|
loop();
|
|
}
|
|
};
|
|
|
|
function findHitBox(mouseEvent) {
|
|
const clickPoint = Point.fromEventCoordinates(mouseEvent.x, mouseEvent.y);
|
|
|
|
const [gridPoint, gridPointRemainder] = clickPoint.convertPixelPointToGridPointWithRemainder();
|
|
|
|
const isHorizontal = gridPointRemainder.y > -hitBoxMargin && gridPointRemainder.y < hitBoxMargin;
|
|
const isVertical = gridPointRemainder.x > -hitBoxMargin && gridPointRemainder.x < hitBoxMargin;
|
|
|
|
if (isHorizontal === isVertical) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
marginSize + gridPoint.x * cellSize + (isVertical ? -hitBoxMargin : 0),
|
|
marginSize + gridPoint.y * cellSize + (!isVertical ? -hitBoxMargin : 0),
|
|
isVertical ? 2 * hitBoxMargin : cellSize,
|
|
isVertical ? cellSize : 2 * hitBoxMargin,
|
|
];
|
|
}
|
|
};
|