smoothretro82

Controllable snake (update 4.1) toggle riding in the HUD update

Nov 21st, 2025 (edited)
206
0
Never
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.69 KB | None | 0 0
  1. // --- Snake Game with Riding (Cycling Beads + HUD Controls) ---
  2.  
  3. let body = []; // snake
  4. let length = 5;
  5. let alive = true;
  6. let dx = 1;
  7. let dy = 0;
  8.  
  9. let x = cursor.x; // spawn snake at cursor
  10. let y = cursor.y;
  11.  
  12. // Traveling bead list
  13. let beads = [];
  14.  
  15. // NEW — ride toggle
  16. let rideEnabled = true;
  17.  
  18. // --- HUD SETUP ---
  19. let hud;
  20.  
  21. // Create HUD
  22. function createHUD() {
  23. hud = document.createElement("div");
  24. hud.style.position = "fixed";
  25. hud.style.bottom = "20px";
  26. hud.style.right = "20px";
  27. hud.style.display = "grid";
  28. hud.style.gridTemplateColumns = "50px 50px 50px";
  29. hud.style.gridTemplateRows = "50px 50px 50px";
  30. hud.style.gap = "5px";
  31. hud.style.zIndex = "9999";
  32.  
  33. const mkBtn = (symbol, onClick) => {
  34. const b = document.createElement("div");
  35. b.textContent = symbol;
  36. b.style.width = "50px";
  37. b.style.height = "50px";
  38. b.style.display = "flex";
  39. b.style.alignItems = "center";
  40. b.style.justifyContent = "center";
  41. b.style.border = "2px solid #aaa";
  42. b.style.borderRadius = "10px";
  43. b.style.background = "rgba(0,0,0,0.4)";
  44. b.style.color = "white";
  45. b.style.fontSize = "24px";
  46. b.style.cursor = "pointer";
  47. b.addEventListener("click", onClick);
  48. return b;
  49. };
  50.  
  51. hud.appendChild(document.createElement("div")); // blank
  52. hud.appendChild(mkBtn("▲", () => changeDirection(0, -1))); // up
  53. hud.appendChild(document.createElement("div")); // blank
  54.  
  55. hud.appendChild(mkBtn("◀", () => changeDirection(-1, 0))); // left
  56.  
  57. // NEW — center ride toggle button
  58. const rideBtn = mkBtn("R", () => {
  59. rideEnabled = !rideEnabled;
  60. rideBtn.style.background = rideEnabled
  61. ? "rgba(0,150,0,0.6)"
  62. : "rgba(150,0,0,0.6)";
  63. });
  64. rideBtn.style.background = "rgba(0,150,0,0.6)"; // start ON
  65. hud.appendChild(rideBtn);
  66.  
  67. hud.appendChild(mkBtn("▶", () => changeDirection(1, 0))); // right
  68.  
  69. hud.appendChild(document.createElement("div")); // blank
  70. hud.appendChild(mkBtn("▼", () => changeDirection(0, 1))); // down
  71. hud.appendChild(document.createElement("div")); // blank
  72.  
  73. document.body.appendChild(hud);
  74. }
  75.  
  76. createHUD();
  77.  
  78. // --- Particle Explode (unchanged) ---
  79. function explodeSegment(seg) {
  80. const particles = ".";
  81. const count = 0;
  82.  
  83. for (let i = 0; i < count; i++) {
  84. const angle = Math.random() * Math.PI * 2;
  85. const dist = Math.random() * 2 + 1;
  86. const px = Math.round(seg.x + Math.cos(angle) * dist);
  87. const py = Math.round(seg.y + Math.sin(angle) * dist);
  88.  
  89. const char = particles[Math.floor(Math.random() * particles.length)];
  90.  
  91. writeCharAt(char, seg.color, px, py);
  92.  
  93. setTimeout(() => {
  94. writeCharAt(" ", 0, px, py);
  95. }, 200 + Math.random() * 300);
  96. }
  97. }
  98.  
  99. // --- GAME LOOP ---
  100. function gameLoop() {
  101. if (!alive) return;
  102.  
  103. // Move head
  104. x += dx;
  105. y += dy;
  106.  
  107. // NEW — Riding toggle
  108. if (rideEnabled && typeof cursor !== "undefined") {
  109. const behind = body.at(-2) || body.at(-1);
  110. if (behind) {
  111. cursor.x = behind.x;
  112. cursor.y = behind.y;
  113. }
  114. }
  115.  
  116. // Self-collision
  117. for (let cell of body) {
  118. if (cell.x === x && cell.y === y) {
  119. death();
  120. return;
  121. }
  122. }
  123.  
  124. // Read tile
  125. const cellInfo = getCharInfoXY(x, y);
  126.  
  127. // Eating = add a bead (store color + character)
  128. if (cellInfo.char !== " ") {
  129. length++;
  130. beads.push({
  131. index: body.length,
  132. color: cellInfo.color,
  133. char: cellInfo.char // NEW
  134. });
  135. }
  136.  
  137. // Always add neutral head segment
  138. const baseColor = 16;
  139.  
  140. if (body.push({ x, y, color: baseColor, char: "█" }) > length) {
  141. const end = body.shift();
  142. writeCharAt(" ", 0, end.x, end.y);
  143.  
  144. // Move beads and wrap around
  145. for (let bead of beads) {
  146. bead.index = (bead.index - 1 + body.length) % body.length;
  147. }
  148. }
  149.  
  150. // Reset snake segment visuals
  151. for (let i = 0; i < body.length; i++) {
  152. body[i].color = 16;
  153. body[i].char = "█";
  154. }
  155.  
  156. // Apply beads (color + character)
  157. for (let bead of beads) {
  158. body[bead.index].color = bead.color;
  159. body[bead.index].char = bead.char;
  160. }
  161.  
  162. // Draw head segment
  163. const head = body.at(-1);
  164. const drawChar = head.char || "█";
  165. writeCharAt(drawChar, head.color, head.x, head.y);
  166.  
  167. setTimeout(gameLoop, 150);
  168. }
  169.  
  170. // --- DEATH ---
  171. function death() {
  172. alive = false;
  173.  
  174. if (typeof joystickContainer !== "undefined" && joystickContainer)
  175. joystickContainer.remove();
  176.  
  177. if (hud) hud.remove();
  178.  
  179. const dying = setInterval(() => {
  180. if (body.length === 0) {
  181. clearInterval(dying);
  182. return;
  183. }
  184.  
  185. const current = Math.min(10, body.length);
  186. for (let i = 0; i < current; i++) {
  187. const end = body.shift();
  188. explodeSegment(end);
  189. writeCharAt(" ", 0, end.x, end.y);
  190. }
  191. }, 150);
  192. }
  193.  
  194. // --- DIRECTION CONTROL ---
  195. function changeDirection(new_dx, new_dy) {
  196. if (!alive) return;
  197.  
  198. if (dx === 0 && new_dx !== 0) {
  199. dx = new_dx;
  200. dy = 0;
  201. } else if (dy === 0 && new_dy !== 0) {
  202. dx = 0;
  203. dy = new_dy;
  204. }
  205. }
  206.  
  207. // --- KEYBOARD INPUT ---
  208. window.addEventListener("keydown", event => {
  209. if (!alive) return;
  210.  
  211. switch (event.key) {
  212. case "w":
  213. case "ArrowUp":
  214. changeDirection(0, -1);
  215. break;
  216. case "s":
  217. case "ArrowDown":
  218. changeDirection(0, 1);
  219. break;
  220. case "d":
  221. case "ArrowRight":
  222. changeDirection(1, 0);
  223. break;
  224. case "a":
  225. case "ArrowLeft":
  226. changeDirection(-1, 0);
  227. break;
  228.  
  229. // NEW — keyboard ride toggle
  230. case "r":
  231. case "R":
  232. rideEnabled = !rideEnabled;
  233. break;
  234.  
  235. case "Alt":
  236. death();
  237. break;
  238. }
  239. });
  240.  
  241. gameLoop();
  242.  
Advertisement
Comments
  • smoothretro82
    252 days
    # text 0.04 KB | 0 0
    1. Update #1: Removed the HUD that had arrows
  • smoothretro82
    251 days
    # text 0.28 KB | 0 0
    1. To not ride the snake, but still control it, remove this bit of code:
    2.  
    3. // Riding behavior: place cursor BEHIND the snake head
    4. if (typeof cursor !== "undefined") {
    5. const behind = body.at(-2) || body.at(-1);
    6. if (behind) {
    7. cursor.x = behind.x;
    8. cursor.y = behind.y;
    9. }
    10. }
  • smoothretro82
    250 days
    # text 0.08 KB | 0 0
    1. 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