feat(settings/user/snake): improve snake design
This commit is contained in:
@@ -289,29 +289,99 @@ onRender((ctx) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// food
|
// food
|
||||||
|
const foodPos = cellToBoardPos(food);
|
||||||
ctx.fillStyle = "#ff2020";
|
ctx.fillStyle = "#ff2020";
|
||||||
ctx.fillRect(
|
ctx.fillRect(foodPos.x + 1, foodPos.y + 1, CELL_SIZE, CELL_SIZE);
|
||||||
cellToBoardPos(food).x + 1,
|
|
||||||
cellToBoardPos(food).y + 1,
|
|
||||||
CELL_SIZE,
|
|
||||||
CELL_SIZE,
|
|
||||||
);
|
|
||||||
|
|
||||||
// snake
|
// snake
|
||||||
for (const part of tail) {
|
const snakeParts = [...tail, position];
|
||||||
ctx.fillStyle = state.value === "dead" ? "#991010" : "#20ff20";
|
const dead = state.value === "dead";
|
||||||
ctx.fillRect(
|
const FILL = dead ? "#b84800" : "#ff8c00";
|
||||||
cellToBoardPos(part).x + 1,
|
const FILL_DIM = dead ? "#8c3600" : "#cc7000";
|
||||||
cellToBoardPos(part).y + 1,
|
|
||||||
CELL_SIZE,
|
const connectedTo = (i: number, dx: number, dy: number) => {
|
||||||
CELL_SIZE,
|
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,
|
// outlines
|
||||||
cellToBoardPos(position).x + 1,
|
ctx.fillStyle = "#ffffff";
|
||||||
cellToBoardPos(position).y,
|
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();
|
ctx.restore();
|
||||||
@@ -353,7 +423,7 @@ useKeyDown(({ key }) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newDirection.clone().dot(direction) === 0) {
|
if (newDirection.dot(direction) === 0) {
|
||||||
nextDirection.copy(newDirection);
|
nextDirection.copy(newDirection);
|
||||||
atlas.audio.type.play(0.35);
|
atlas.audio.type.play(0.35);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user