feat(settings/user/snake): improve snake design
This commit is contained in:
@@ -289,29 +289,99 @@ onRender((ctx) => {
|
||||
}
|
||||
} else {
|
||||
// food
|
||||
const foodPos = cellToBoardPos(food);
|
||||
ctx.fillStyle = "#ff2020";
|
||||
ctx.fillRect(
|
||||
cellToBoardPos(food).x + 1,
|
||||
cellToBoardPos(food).y + 1,
|
||||
CELL_SIZE,
|
||||
CELL_SIZE,
|
||||
);
|
||||
ctx.fillRect(foodPos.x + 1, foodPos.y + 1, CELL_SIZE, CELL_SIZE);
|
||||
|
||||
// snake
|
||||
for (const part of tail) {
|
||||
ctx.fillStyle = state.value === "dead" ? "#991010" : "#20ff20";
|
||||
ctx.fillRect(
|
||||
cellToBoardPos(part).x + 1,
|
||||
cellToBoardPos(part).y + 1,
|
||||
CELL_SIZE,
|
||||
CELL_SIZE,
|
||||
);
|
||||
const snakeParts = [...tail, position];
|
||||
const dead = state.value === "dead";
|
||||
const FILL = dead ? "#b84800" : "#ff8c00";
|
||||
const FILL_DIM = dead ? "#8c3600" : "#cc7000";
|
||||
|
||||
const connectedTo = (i: number, dx: number, dy: number) => {
|
||||
const part = snakeParts[i]!;
|
||||
const neighbor = new THREE.Vector2(part.x + dx, part.y + dy);
|
||||
const prev = snakeParts[i - 1];
|
||||
const next = snakeParts[i + 1];
|
||||
return (prev && prev.equals(neighbor)) || (next && next.equals(neighbor));
|
||||
};
|
||||
|
||||
// fills
|
||||
for (let i = 0; i < snakeParts.length; i++) {
|
||||
const part = snakeParts[i]!;
|
||||
const { x, y } = cellToBoardPos(part);
|
||||
const px = x + 1;
|
||||
const py = y + 1;
|
||||
|
||||
ctx.fillStyle = i === snakeParts.length - 1 ? FILL : FILL_DIM;
|
||||
ctx.fillRect(px, py, CELL_SIZE, CELL_SIZE);
|
||||
|
||||
if (connectedTo(i, 1, 0)) {
|
||||
ctx.fillRect(px + CELL_SIZE, py, CELL_PADDING, CELL_SIZE);
|
||||
}
|
||||
if (connectedTo(i, 0, 1)) {
|
||||
ctx.fillRect(px, py + CELL_SIZE, CELL_SIZE, CELL_PADDING);
|
||||
}
|
||||
}
|
||||
assets.user.snakeHead.draw(
|
||||
ctx,
|
||||
cellToBoardPos(position).x + 1,
|
||||
cellToBoardPos(position).y,
|
||||
);
|
||||
|
||||
// outlines
|
||||
ctx.fillStyle = "#ffffff";
|
||||
for (let i = 0; i < snakeParts.length; i++) {
|
||||
const part = snakeParts[i]!;
|
||||
const { x, y } = cellToBoardPos(part);
|
||||
const px = x + 1;
|
||||
const py = y + 1;
|
||||
|
||||
if (!connectedTo(i, 0, -1)) {
|
||||
ctx.fillRect(px, py, CELL_SIZE, 1);
|
||||
}
|
||||
if (!connectedTo(i, 0, 1)) {
|
||||
ctx.fillRect(px, py + CELL_SIZE - 1, CELL_SIZE, 1);
|
||||
}
|
||||
if (!connectedTo(i, -1, 0)) {
|
||||
ctx.fillRect(px, py, 1, CELL_SIZE);
|
||||
}
|
||||
if (!connectedTo(i, 1, 0)) {
|
||||
ctx.fillRect(px + CELL_SIZE - 1, py, 1, CELL_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
const EYE_SIZE = 2;
|
||||
const EYE_MARGIN = 3;
|
||||
const eyeFar = CELL_SIZE - EYE_MARGIN - EYE_SIZE;
|
||||
|
||||
const head = snakeParts[snakeParts.length - 1]!;
|
||||
const { x: headCellX, y: headCellY } = cellToBoardPos(head);
|
||||
const headX = headCellX + 1;
|
||||
const headY = headCellY + 1;
|
||||
|
||||
let eye1x: number, eye1y: number, eye2x: number, eye2y: number;
|
||||
if (direction.x === 1) {
|
||||
eye1x = headX + eyeFar;
|
||||
eye1y = headY + EYE_MARGIN;
|
||||
eye2x = headX + eyeFar;
|
||||
eye2y = headY + eyeFar;
|
||||
} else if (direction.x === -1) {
|
||||
eye1x = headX + EYE_MARGIN;
|
||||
eye1y = headY + EYE_MARGIN;
|
||||
eye2x = headX + EYE_MARGIN;
|
||||
eye2y = headY + eyeFar;
|
||||
} else if (direction.y === 1) {
|
||||
eye1x = headX + EYE_MARGIN;
|
||||
eye1y = headY + eyeFar;
|
||||
eye2x = headX + eyeFar;
|
||||
eye2y = headY + eyeFar;
|
||||
} else {
|
||||
eye1x = headX + EYE_MARGIN;
|
||||
eye1y = headY + EYE_MARGIN;
|
||||
eye2x = headX + eyeFar;
|
||||
eye2y = headY + EYE_MARGIN;
|
||||
}
|
||||
|
||||
ctx.fillStyle = dead ? "#3d1500" : "#7a3800";
|
||||
ctx.fillRect(eye1x, eye1y, EYE_SIZE, EYE_SIZE);
|
||||
ctx.fillRect(eye2x, eye2y, EYE_SIZE, EYE_SIZE);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
@@ -353,7 +423,7 @@ useKeyDown(({ key }) => {
|
||||
break;
|
||||
}
|
||||
|
||||
if (newDirection.clone().dot(direction) === 0) {
|
||||
if (newDirection.dot(direction) === 0) {
|
||||
nextDirection.copy(newDirection);
|
||||
atlas.audio.type.play(0.35);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user