Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // --- Snake Game with Riding (Cycling Beads + HUD Controls) ---
- let body = []; // snake
- let length = 5;
- let alive = true;
- let dx = 1;
- let dy = 0;
- let x = cursor.x; // spawn snake at cursor
- let y = cursor.y;
- // Traveling bead list
- let beads = [];
- // NEW — ride toggle
- let rideEnabled = true;
- // --- HUD SETUP ---
- let hud;
- // Create HUD
- function createHUD() {
- hud = document.createElement("div");
- hud.style.position = "fixed";
- hud.style.bottom = "20px";
- hud.style.right = "20px";
- hud.style.display = "grid";
- hud.style.gridTemplateColumns = "50px 50px 50px";
- hud.style.gridTemplateRows = "50px 50px 50px";
- hud.style.gap = "5px";
- hud.style.zIndex = "9999";
- const mkBtn = (symbol, onClick) => {
- const b = document.createElement("div");
- b.textContent = symbol;
- b.style.width = "50px";
- b.style.height = "50px";
- b.style.display = "flex";
- b.style.alignItems = "center";
- b.style.justifyContent = "center";
- b.style.border = "2px solid #aaa";
- b.style.borderRadius = "10px";
- b.style.background = "rgba(0,0,0,0.4)";
- b.style.color = "white";
- b.style.fontSize = "24px";
- b.style.cursor = "pointer";
- b.addEventListener("click", onClick);
- return b;
- };
- hud.appendChild(document.createElement("div")); // blank
- hud.appendChild(mkBtn("▲", () => changeDirection(0, -1))); // up
- hud.appendChild(document.createElement("div")); // blank
- hud.appendChild(mkBtn("◀", () => changeDirection(-1, 0))); // left
- // NEW — center ride toggle button
- const rideBtn = mkBtn("R", () => {
- rideEnabled = !rideEnabled;
- rideBtn.style.background = rideEnabled
- ? "rgba(0,150,0,0.6)"
- : "rgba(150,0,0,0.6)";
- });
- rideBtn.style.background = "rgba(0,150,0,0.6)"; // start ON
- hud.appendChild(rideBtn);
- hud.appendChild(mkBtn("▶", () => changeDirection(1, 0))); // right
- hud.appendChild(document.createElement("div")); // blank
- hud.appendChild(mkBtn("▼", () => changeDirection(0, 1))); // down
- hud.appendChild(document.createElement("div")); // blank
- document.body.appendChild(hud);
- }
- createHUD();
- // --- Particle Explode (unchanged) ---
- function explodeSegment(seg) {
- const particles = ".";
- const count = 0;
- for (let i = 0; i < count; i++) {
- const angle = Math.random() * Math.PI * 2;
- const dist = Math.random() * 2 + 1;
- const px = Math.round(seg.x + Math.cos(angle) * dist);
- const py = Math.round(seg.y + Math.sin(angle) * dist);
- const char = particles[Math.floor(Math.random() * particles.length)];
- writeCharAt(char, seg.color, px, py);
- setTimeout(() => {
- writeCharAt(" ", 0, px, py);
- }, 200 + Math.random() * 300);
- }
- }
- // --- GAME LOOP ---
- function gameLoop() {
- if (!alive) return;
- // Move head
- x += dx;
- y += dy;
- // NEW — Riding toggle
- if (rideEnabled && typeof cursor !== "undefined") {
- const behind = body.at(-2) || body.at(-1);
- if (behind) {
- cursor.x = behind.x;
- cursor.y = behind.y;
- }
- }
- // Self-collision
- for (let cell of body) {
- if (cell.x === x && cell.y === y) {
- death();
- return;
- }
- }
- // Read tile
- const cellInfo = getCharInfoXY(x, y);
- // Eating = add a bead (store color + character)
- if (cellInfo.char !== " ") {
- length++;
- beads.push({
- index: body.length,
- color: cellInfo.color,
- char: cellInfo.char // NEW
- });
- }
- // Always add neutral head segment
- const baseColor = 16;
- if (body.push({ x, y, color: baseColor, char: "█" }) > length) {
- const end = body.shift();
- writeCharAt(" ", 0, end.x, end.y);
- // Move beads and wrap around
- for (let bead of beads) {
- bead.index = (bead.index - 1 + body.length) % body.length;
- }
- }
- // Reset snake segment visuals
- for (let i = 0; i < body.length; i++) {
- body[i].color = 16;
- body[i].char = "█";
- }
- // Apply beads (color + character)
- for (let bead of beads) {
- body[bead.index].color = bead.color;
- body[bead.index].char = bead.char;
- }
- // Draw head segment
- const head = body.at(-1);
- const drawChar = head.char || "█";
- writeCharAt(drawChar, head.color, head.x, head.y);
- setTimeout(gameLoop, 150);
- }
- // --- DEATH ---
- function death() {
- alive = false;
- if (typeof joystickContainer !== "undefined" && joystickContainer)
- joystickContainer.remove();
- if (hud) hud.remove();
- const dying = setInterval(() => {
- if (body.length === 0) {
- clearInterval(dying);
- return;
- }
- const current = Math.min(10, body.length);
- for (let i = 0; i < current; i++) {
- const end = body.shift();
- explodeSegment(end);
- writeCharAt(" ", 0, end.x, end.y);
- }
- }, 150);
- }
- // --- DIRECTION CONTROL ---
- function changeDirection(new_dx, new_dy) {
- if (!alive) return;
- if (dx === 0 && new_dx !== 0) {
- dx = new_dx;
- dy = 0;
- } else if (dy === 0 && new_dy !== 0) {
- dx = 0;
- dy = new_dy;
- }
- }
- // --- KEYBOARD INPUT ---
- window.addEventListener("keydown", event => {
- if (!alive) return;
- switch (event.key) {
- case "w":
- case "ArrowUp":
- changeDirection(0, -1);
- break;
- case "s":
- case "ArrowDown":
- changeDirection(0, 1);
- break;
- case "d":
- case "ArrowRight":
- changeDirection(1, 0);
- break;
- case "a":
- case "ArrowLeft":
- changeDirection(-1, 0);
- break;
- // NEW — keyboard ride toggle
- case "r":
- case "R":
- rideEnabled = !rideEnabled;
- break;
- case "Alt":
- death();
- break;
- }
- });
- gameLoop();
Advertisement
Comments
-
- Update #1: Removed the HUD that had arrows
-
- To not ride the snake, but still control it, remove this bit of code:
- // Riding behavior: place cursor BEHIND the snake head
- if (typeof cursor !== "undefined") {
- const behind = body.at(-2) || body.at(-1);
- if (behind) {
- cursor.x = behind.x;
- cursor.y = behind.y;
- }
- }
-
- update #4: The snake also takes the character it ate with it along with it's color.
Add Comment
Please, Sign In to add comment