/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Animal class var Animal = Container.expand(function () { var self = Container.call(this); self.type = null; self.asset = null; self.setType = function (type) { self.type = type; if (self.asset) { self.removeChild(self.asset); } self.asset = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); // Snake Segment (body or head) var SnakeSegment = Container.expand(function () { var self = Container.call(this); self.asset = null; self.setType = function (type) { if (self.asset) { self.removeChild(self.asset); } var assetId = type === 'head' ? 'snakeHead' : 'snakeBody'; self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; self.setType('body'); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Animal assets: pig, cat, bee, frog (box/ellipse with different colors) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var SNAKE_START_LENGTH = 3; var SNAKE_START_SPEED = 8; // pixels per tick var SNAKE_SPEED_INCREMENT = 1.5; // speed up per sequence var SNAKE_MAX_SPEED = 32; var SEGMENT_SPACING = 90; // px between segments var ANIMAL_TYPES = ['pig', 'cat', 'bee', 'frog']; var ANIMAL_NAMES = { pig: "Pig", cat: "Cat", bee: "Bee", frog: "Frog" }; // Game state var snake = []; var snakeDir = { x: 0, y: -1 }; // start moving up var snakeNextDir = { x: 0, y: -1 }; var snakeSpeed = SNAKE_START_SPEED; var snakePositions = []; // for body following var animals = []; var currentTargetIndex = 0; // which animal in sequence to eat next var score = 0; var sequenceCount = 0; var isGameOver = false; var moveCooldown = 0; // for swipe input var dragStart = null; // GUI var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var orderTxt = new Text2('', { size: 70, fill: "#fff" }); orderTxt.anchor.set(0.5, 0); LK.gui.top.addChild(orderTxt); orderTxt.y = 130; // Helper: get random position for animal, not too close to snake head function getRandomAnimalPos() { var margin = 180; var tries = 0; while (tries < 20) { var x = margin + Math.random() * (GAME_WIDTH - 2 * margin); var y = margin + Math.random() * (GAME_HEIGHT - 2 * margin); // Avoid spawning too close to snake head var dx = x - snake[0].x; var dy = y - snake[0].y; if (dx * dx + dy * dy > 400 * 400) { return { x: x, y: y }; } tries++; } // fallback return { x: margin + Math.random() * (GAME_WIDTH - 2 * margin), y: margin + Math.random() * (GAME_HEIGHT - 2 * margin) }; } // Helper: update order text function updateOrderText() { var s = ''; for (var i = 0; i < ANIMAL_TYPES.length; i++) { if (i === currentTargetIndex) { s += '[b]' + ANIMAL_NAMES[ANIMAL_TYPES[i]] + '[/b] '; } else { s += ANIMAL_NAMES[ANIMAL_TYPES[i]] + ' '; } } orderTxt.setText(s.trim()); } // Helper: spawn all animals function spawnAnimals() { // Remove old for (var i = 0; i < animals.length; i++) { animals[i].destroy(); } animals = []; for (var i = 0; i < ANIMAL_TYPES.length; i++) { var animal = new Animal(); animal.setType(ANIMAL_TYPES[i]); var pos = getRandomAnimalPos(); animal.x = pos.x; animal.y = pos.y; animals.push(animal); game.addChild(animal); } } // Helper: reset snake function resetSnake() { for (var i = 0; i < snake.length; i++) { snake[i].destroy(); } snake = []; snakePositions = []; var startX = GAME_WIDTH / 2; var startY = GAME_HEIGHT / 2 + 300; for (var i = 0; i < SNAKE_START_LENGTH; i++) { var seg = new SnakeSegment(); seg.setType(i === 0 ? 'head' : 'body'); seg.x = startX; seg.y = startY + i * SEGMENT_SPACING; snake.push(seg); game.addChild(seg); snakePositions.push({ x: seg.x, y: seg.y }); } snakeDir = { x: 0, y: -1 }; snakeNextDir = { x: 0, y: -1 }; } // Helper: grow snake function growSnake() { var last = snake[snake.length - 1]; var seg = new SnakeSegment(); seg.setType('body'); seg.x = last.x; seg.y = last.y; snake.push(seg); game.addChild(seg); snakePositions.push({ x: seg.x, y: seg.y }); } // Helper: check self collision function checkSelfCollision() { var head = snake[0]; for (var i = 2; i < snake.length; i++) { var seg = snake[i]; var dx = head.x - seg.x; var dy = head.y - seg.y; if (dx * dx + dy * dy < 60 * 60) { return true; } } return false; } // Helper: check wall collision function checkWallCollision() { var head = snake[0]; var margin = 40; if (head.x < margin || head.x > GAME_WIDTH - margin || head.y < margin || head.y > GAME_HEIGHT - margin) { return true; } return false; } // Helper: check animal collision function checkAnimalCollision() { var head = snake[0]; for (var i = 0; i < animals.length; i++) { var animal = animals[i]; var dx = head.x - animal.x; var dy = head.y - animal.y; if (dx * dx + dy * dy < 80 * 80) { return i; } } return -1; } // Helper: handle eating animal function eatAnimal(idx) { var animal = animals[idx]; if (animal.type === ANIMAL_TYPES[currentTargetIndex]) { // Correct animal growSnake(); score++; scoreTxt.setText(score); // Remove and respawn this animal animal.destroy(); animals.splice(idx, 1); // Next in sequence currentTargetIndex++; if (currentTargetIndex >= ANIMAL_TYPES.length) { // Sequence complete sequenceCount++; currentTargetIndex = 0; // Speed up snakeSpeed = Math.min(snakeSpeed + SNAKE_SPEED_INCREMENT, SNAKE_MAX_SPEED); // Respawn all animals spawnAnimals(); // Flash green LK.effects.flashScreen(0x00ff00, 400); } else { // Only respawn this animal var newAnimal = new Animal(); newAnimal.setType(animal.type); var pos = getRandomAnimalPos(); newAnimal.x = pos.x; newAnimal.y = pos.y; animals.push(newAnimal); game.addChild(newAnimal); } updateOrderText(); } else { // Wrong animal: game over LK.effects.flashScreen(0xff0000, 800); isGameOver = true; LK.showGameOver(); } } // Helper: handle game over function handleGameOver() { isGameOver = true; // LK.showGameOver() already called } // Input: swipe to change direction function getSwipeDir(dx, dy) { if (Math.abs(dx) > Math.abs(dy)) { return { x: dx > 0 ? 1 : -1, y: 0 }; } else { return { x: 0, y: dy > 0 ? 1 : -1 }; } } // Input: touch/drag game.down = function (x, y, obj) { dragStart = { x: x, y: y }; }; game.up = function (x, y, obj) { dragStart = null; }; game.move = function (x, y, obj) { if (dragStart && !isGameOver) { var dx = x - dragStart.x; var dy = y - dragStart.y; if (dx * dx + dy * dy > 80 * 80) { var dir = getSwipeDir(dx, dy); // Prevent reversing if (!(dir.x === -snakeDir.x && dir.y === -snakeDir.y)) { snakeNextDir = dir; } dragStart = null; } } }; // Main update loop game.update = function () { if (isGameOver) return; // Move snake // Update direction if (snakeNextDir.x !== snakeDir.x || snakeNextDir.y !== snakeDir.y) { snakeDir = { x: snakeNextDir.x, y: snakeNextDir.y }; } // Calculate new head position var head = snake[0]; var newX = head.x + snakeDir.x * snakeSpeed; var newY = head.y + snakeDir.y * snakeSpeed; // Store previous positions snakePositions.unshift({ x: newX, y: newY }); if (snakePositions.length > snake.length * SEGMENT_SPACING / snakeSpeed + 2) { snakePositions.pop(); } // Move segments for (var i = 0; i < snake.length; i++) { var posIdx = Math.min(i * Math.floor(SEGMENT_SPACING / snakeSpeed), snakePositions.length - 1); var pos = snakePositions[posIdx]; snake[i].x = pos.x; snake[i].y = pos.y; } // Check wall collision if (checkWallCollision()) { LK.effects.flashScreen(0xff0000, 800); handleGameOver(); LK.showGameOver(); return; } // Check self collision if (checkSelfCollision()) { LK.effects.flashScreen(0xff0000, 800); handleGameOver(); LK.showGameOver(); return; } // Check animal collision var animalIdx = checkAnimalCollision(); if (animalIdx !== -1) { eatAnimal(animalIdx); } }; // Game start/reset function startGame() { isGameOver = false; score = 0; sequenceCount = 0; snakeSpeed = SNAKE_START_SPEED; currentTargetIndex = 0; scoreTxt.setText(score); updateOrderText(); resetSnake(); spawnAnimals(); } startGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,381 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Animal class
+var Animal = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = null;
+ self.asset = null;
+ self.setType = function (type) {
+ self.type = type;
+ if (self.asset) {
+ self.removeChild(self.asset);
+ }
+ self.asset = self.attachAsset(type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ };
+ return self;
+});
+// Snake Segment (body or head)
+var SnakeSegment = Container.expand(function () {
+ var self = Container.call(this);
+ self.asset = null;
+ self.setType = function (type) {
+ if (self.asset) {
+ self.removeChild(self.asset);
+ }
+ var assetId = type === 'head' ? 'snakeHead' : 'snakeBody';
+ self.asset = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ };
+ self.setType('body');
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Animal assets: pig, cat, bee, frog (box/ellipse with different colors)
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var SNAKE_START_LENGTH = 3;
+var SNAKE_START_SPEED = 8; // pixels per tick
+var SNAKE_SPEED_INCREMENT = 1.5; // speed up per sequence
+var SNAKE_MAX_SPEED = 32;
+var SEGMENT_SPACING = 90; // px between segments
+var ANIMAL_TYPES = ['pig', 'cat', 'bee', 'frog'];
+var ANIMAL_NAMES = {
+ pig: "Pig",
+ cat: "Cat",
+ bee: "Bee",
+ frog: "Frog"
+};
+// Game state
+var snake = [];
+var snakeDir = {
+ x: 0,
+ y: -1
+}; // start moving up
+var snakeNextDir = {
+ x: 0,
+ y: -1
+};
+var snakeSpeed = SNAKE_START_SPEED;
+var snakePositions = []; // for body following
+var animals = [];
+var currentTargetIndex = 0; // which animal in sequence to eat next
+var score = 0;
+var sequenceCount = 0;
+var isGameOver = false;
+var moveCooldown = 0; // for swipe input
+var dragStart = null;
+// GUI
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var orderTxt = new Text2('', {
+ size: 70,
+ fill: "#fff"
+});
+orderTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(orderTxt);
+orderTxt.y = 130;
+// Helper: get random position for animal, not too close to snake head
+function getRandomAnimalPos() {
+ var margin = 180;
+ var tries = 0;
+ while (tries < 20) {
+ var x = margin + Math.random() * (GAME_WIDTH - 2 * margin);
+ var y = margin + Math.random() * (GAME_HEIGHT - 2 * margin);
+ // Avoid spawning too close to snake head
+ var dx = x - snake[0].x;
+ var dy = y - snake[0].y;
+ if (dx * dx + dy * dy > 400 * 400) {
+ return {
+ x: x,
+ y: y
+ };
+ }
+ tries++;
+ }
+ // fallback
+ return {
+ x: margin + Math.random() * (GAME_WIDTH - 2 * margin),
+ y: margin + Math.random() * (GAME_HEIGHT - 2 * margin)
+ };
+}
+// Helper: update order text
+function updateOrderText() {
+ var s = '';
+ for (var i = 0; i < ANIMAL_TYPES.length; i++) {
+ if (i === currentTargetIndex) {
+ s += '[b]' + ANIMAL_NAMES[ANIMAL_TYPES[i]] + '[/b] ';
+ } else {
+ s += ANIMAL_NAMES[ANIMAL_TYPES[i]] + ' ';
+ }
+ }
+ orderTxt.setText(s.trim());
+}
+// Helper: spawn all animals
+function spawnAnimals() {
+ // Remove old
+ for (var i = 0; i < animals.length; i++) {
+ animals[i].destroy();
+ }
+ animals = [];
+ for (var i = 0; i < ANIMAL_TYPES.length; i++) {
+ var animal = new Animal();
+ animal.setType(ANIMAL_TYPES[i]);
+ var pos = getRandomAnimalPos();
+ animal.x = pos.x;
+ animal.y = pos.y;
+ animals.push(animal);
+ game.addChild(animal);
+ }
+}
+// Helper: reset snake
+function resetSnake() {
+ for (var i = 0; i < snake.length; i++) {
+ snake[i].destroy();
+ }
+ snake = [];
+ snakePositions = [];
+ var startX = GAME_WIDTH / 2;
+ var startY = GAME_HEIGHT / 2 + 300;
+ for (var i = 0; i < SNAKE_START_LENGTH; i++) {
+ var seg = new SnakeSegment();
+ seg.setType(i === 0 ? 'head' : 'body');
+ seg.x = startX;
+ seg.y = startY + i * SEGMENT_SPACING;
+ snake.push(seg);
+ game.addChild(seg);
+ snakePositions.push({
+ x: seg.x,
+ y: seg.y
+ });
+ }
+ snakeDir = {
+ x: 0,
+ y: -1
+ };
+ snakeNextDir = {
+ x: 0,
+ y: -1
+ };
+}
+// Helper: grow snake
+function growSnake() {
+ var last = snake[snake.length - 1];
+ var seg = new SnakeSegment();
+ seg.setType('body');
+ seg.x = last.x;
+ seg.y = last.y;
+ snake.push(seg);
+ game.addChild(seg);
+ snakePositions.push({
+ x: seg.x,
+ y: seg.y
+ });
+}
+// Helper: check self collision
+function checkSelfCollision() {
+ var head = snake[0];
+ for (var i = 2; i < snake.length; i++) {
+ var seg = snake[i];
+ var dx = head.x - seg.x;
+ var dy = head.y - seg.y;
+ if (dx * dx + dy * dy < 60 * 60) {
+ return true;
+ }
+ }
+ return false;
+}
+// Helper: check wall collision
+function checkWallCollision() {
+ var head = snake[0];
+ var margin = 40;
+ if (head.x < margin || head.x > GAME_WIDTH - margin || head.y < margin || head.y > GAME_HEIGHT - margin) {
+ return true;
+ }
+ return false;
+}
+// Helper: check animal collision
+function checkAnimalCollision() {
+ var head = snake[0];
+ for (var i = 0; i < animals.length; i++) {
+ var animal = animals[i];
+ var dx = head.x - animal.x;
+ var dy = head.y - animal.y;
+ if (dx * dx + dy * dy < 80 * 80) {
+ return i;
+ }
+ }
+ return -1;
+}
+// Helper: handle eating animal
+function eatAnimal(idx) {
+ var animal = animals[idx];
+ if (animal.type === ANIMAL_TYPES[currentTargetIndex]) {
+ // Correct animal
+ growSnake();
+ score++;
+ scoreTxt.setText(score);
+ // Remove and respawn this animal
+ animal.destroy();
+ animals.splice(idx, 1);
+ // Next in sequence
+ currentTargetIndex++;
+ if (currentTargetIndex >= ANIMAL_TYPES.length) {
+ // Sequence complete
+ sequenceCount++;
+ currentTargetIndex = 0;
+ // Speed up
+ snakeSpeed = Math.min(snakeSpeed + SNAKE_SPEED_INCREMENT, SNAKE_MAX_SPEED);
+ // Respawn all animals
+ spawnAnimals();
+ // Flash green
+ LK.effects.flashScreen(0x00ff00, 400);
+ } else {
+ // Only respawn this animal
+ var newAnimal = new Animal();
+ newAnimal.setType(animal.type);
+ var pos = getRandomAnimalPos();
+ newAnimal.x = pos.x;
+ newAnimal.y = pos.y;
+ animals.push(newAnimal);
+ game.addChild(newAnimal);
+ }
+ updateOrderText();
+ } else {
+ // Wrong animal: game over
+ LK.effects.flashScreen(0xff0000, 800);
+ isGameOver = true;
+ LK.showGameOver();
+ }
+}
+// Helper: handle game over
+function handleGameOver() {
+ isGameOver = true;
+ // LK.showGameOver() already called
+}
+// Input: swipe to change direction
+function getSwipeDir(dx, dy) {
+ if (Math.abs(dx) > Math.abs(dy)) {
+ return {
+ x: dx > 0 ? 1 : -1,
+ y: 0
+ };
+ } else {
+ return {
+ x: 0,
+ y: dy > 0 ? 1 : -1
+ };
+ }
+}
+// Input: touch/drag
+game.down = function (x, y, obj) {
+ dragStart = {
+ x: x,
+ y: y
+ };
+};
+game.up = function (x, y, obj) {
+ dragStart = null;
+};
+game.move = function (x, y, obj) {
+ if (dragStart && !isGameOver) {
+ var dx = x - dragStart.x;
+ var dy = y - dragStart.y;
+ if (dx * dx + dy * dy > 80 * 80) {
+ var dir = getSwipeDir(dx, dy);
+ // Prevent reversing
+ if (!(dir.x === -snakeDir.x && dir.y === -snakeDir.y)) {
+ snakeNextDir = dir;
+ }
+ dragStart = null;
+ }
+ }
+};
+// Main update loop
+game.update = function () {
+ if (isGameOver) return;
+ // Move snake
+ // Update direction
+ if (snakeNextDir.x !== snakeDir.x || snakeNextDir.y !== snakeDir.y) {
+ snakeDir = {
+ x: snakeNextDir.x,
+ y: snakeNextDir.y
+ };
+ }
+ // Calculate new head position
+ var head = snake[0];
+ var newX = head.x + snakeDir.x * snakeSpeed;
+ var newY = head.y + snakeDir.y * snakeSpeed;
+ // Store previous positions
+ snakePositions.unshift({
+ x: newX,
+ y: newY
+ });
+ if (snakePositions.length > snake.length * SEGMENT_SPACING / snakeSpeed + 2) {
+ snakePositions.pop();
+ }
+ // Move segments
+ for (var i = 0; i < snake.length; i++) {
+ var posIdx = Math.min(i * Math.floor(SEGMENT_SPACING / snakeSpeed), snakePositions.length - 1);
+ var pos = snakePositions[posIdx];
+ snake[i].x = pos.x;
+ snake[i].y = pos.y;
+ }
+ // Check wall collision
+ if (checkWallCollision()) {
+ LK.effects.flashScreen(0xff0000, 800);
+ handleGameOver();
+ LK.showGameOver();
+ return;
+ }
+ // Check self collision
+ if (checkSelfCollision()) {
+ LK.effects.flashScreen(0xff0000, 800);
+ handleGameOver();
+ LK.showGameOver();
+ return;
+ }
+ // Check animal collision
+ var animalIdx = checkAnimalCollision();
+ if (animalIdx !== -1) {
+ eatAnimal(animalIdx);
+ }
+};
+// Game start/reset
+function startGame() {
+ isGameOver = false;
+ score = 0;
+ sequenceCount = 0;
+ snakeSpeed = SNAKE_START_SPEED;
+ currentTargetIndex = 0;
+ scoreTxt.setText(score);
+ updateOrderText();
+ resetSnake();
+ spawnAnimals();
+}
+startGame();
\ No newline at end of file