User prompt
Remove nick selection at game start ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.rankings = storageRankings;' Line Number: 378 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.rankings = storageRankings;' Line Number: 380
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.rankings = storageRankings;' Line Number: 375 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.rankings = rankings;' Line Number: 360 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Create a ranking tab. There should be a ranking button on the right side of the screen and open the ranking tab. Write the highest scores in the ranking tab. Before the game starts, ask the player for their nickname, and if this nickname has a score in the ranking list, write it next to that score. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Write the highest score made at the top of the game. Even if you exit the game and re-enter, the highest score made with that device should be written there. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Let the game have a dark gray background
User prompt
Let the game have a gray background
Code edit (2 edits merged)
Please save this source code
User prompt
Let the snake's body move more smoothly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The life number of the apples should be written under the apples.
User prompt
undo what you did last
User prompt
Let the snake's body be one piece. Let the life number of the apples be written under the apples. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the snake's body be united ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
increase the size of apples
Code edit (1 edits merged)
Please save this source code
User prompt
After the snake eats the apple, its speed remains the same
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game configuration var segmentLength = 40, startingSegments = 10, spawn = { x: 1024, y: 1366 }, snakeSpeed = 2000, baseSnakeSpeed = 2, speedIncrement = 2000, maxApples = 3, appleLife = 300, segmentsPerApple = 2, snakeWidth = 30, appleWidth = 25, cursorSize = 20, snake, target, apples, score, gameState, deathMeans, smoothMovement = true, movementQueue = []; function distance(p1, p2) { var dx = p2.x - p1.x; var dy = p2.y - p1.y; return Math.sqrt(dx * dx + dy * dy); } function lineIntersect(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) { var s1_x = p1_x - p0_x, s1_y = p1_y - p0_y, s2_x = p3_x - p2_x, s2_y = p3_y - p2_y, s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y), t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y); if (s >= 0 && s <= 1 && t >= 0 && t <= 1) { return true; } return false; } function SGM(angle, x, y) { this.x = x || 0; this.y = y || 0; this.angle = angle || 0; this.parent = null; } ; SGM.prototype.endX = function () { return this.x + Math.cos(this.angle) * segmentLength; }; SGM.prototype.endY = function () { return this.y + Math.sin(this.angle) * segmentLength; }; SGM.prototype.pointAt = function (x, y) { var dx = x - this.x, dy = y - this.y; this.angle = Math.atan2(dy, dx); }; SGM.prototype.target = function (x, y) { this.targetX = x; this.targetY = y; this.arrived = false; this.totalDist = distance({ x: this.endX(), y: this.endY() }, { x: this.targetX, y: this.targetY }); this.currentDist = parseInt(this.totalDist); }; SGM.prototype.gotoTarget = function () { if (!this.arrived) { if (this.targetX > this.x + segmentLength || this.targetX < this.x - segmentLength || this.targetY > this.y + segmentLength || this.targetY < this.y - segmentLength) { this.pointAt(this.targetX, this.targetY); } else { this.arrived = true; } this.currentDist = distance({ x: this.endX(), y: this.endY() }, { x: this.targetX, y: this.targetY }); } // Smooth movement with tweening if (smoothMovement) { var moveSpeed = snakeSpeed * 1.2; // Faster movement var newX = this.x + (this.endX() - this.x) / moveSpeed; var newY = this.y + (this.endY() - this.y) / moveSpeed; // Use tween for very smooth transitions tween(this, { x: newX, y: newY }, { duration: 15, easing: tween.easeOut }); } else { this.x += (this.endX() - this.x) / snakeSpeed; this.y += (this.endY() - this.y) / snakeSpeed; } if (this.parent) { this.parent.drag(this.x, this.y); } }; SGM.prototype.drag = function (x, y) { this.pointAt(x, y); var newX = x - Math.cos(this.angle) * segmentLength; var newY = y - Math.sin(this.angle) * segmentLength; if (smoothMovement) { // Smooth transition for body segments tween(this, { x: newX, y: newY }, { duration: 20, easing: tween.easeInOut }); } else { this.x = newX; this.y = newY; } if (this.parent) { // Delay the parent drag slightly for smoother chain movement var self = this; LK.setTimeout(function () { self.parent.drag(self.x, self.y); }, 5); } }; SGM.prototype.render = function (context) { context.lineTo(this.endX(), this.endY()); }; function IKR(x, y) { this.ix = x || 0; this.iy = y || 0; this.sgms = []; this.lastArm = null; } ; IKR.prototype.addSeg = function (angle) { var arm = new SGM(angle); if (this.lastArm !== null) { arm.x = this.lastArm.endX(); arm.y = this.lastArm.endY(); arm.parent = this.lastArm; } else { arm.x = this.ix; arm.y = this.iy; } this.sgms.push(arm); this.lastArm = arm; }; IKR.prototype.grow = function () { var tail = this.sgms[0], arm = new SGM(tail.angle); arm.x = tail.x - Math.cos(tail.angle) * segmentLength; arm.y = tail.y - Math.sin(tail.angle) * segmentLength; tail.parent = arm; this.sgms.unshift(arm); }; IKR.prototype.drag = function (x, y) { this.lastArm.drag(x, y); }; function CUR(x, y) { this.x = x; this.y = y; this.rotation = 0; } ; CUR.prototype.render = function (context) { context.save(); context.translate(this.x, this.y); context.rotate(this.rotation); context.beginPath(); context.moveTo(0, -cursorSize); context.lineTo(0, -cursorSize / 2); context.moveTo(0, cursorSize / 2); context.lineTo(0, cursorSize); context.moveTo(-cursorSize, 0); context.lineTo(-cursorSize / 2, 0); context.moveTo(cursorSize / 2, 0); context.lineTo(cursorSize, 0); context.stroke(); context.restore(); this.rotation = (this.rotation + cursorSpin) % 360; }; function Apple(x, y) { this.x = x; this.y = y; this.life = appleLife; this.rotation = 0; } Apple.prototype.update = function () { this.life--; }; Apple.prototype.render = function (context) { context.beginPath(); context.arc(this.x, this.y, appleWidth, 0, Math.PI * 2); context.fill(); if (gameState !== 'dead') { context.save(); context.fillStyle = 'white'; context.font = '8px sans-serif'; context.fillText(this.life, this.x + 10, this.y + 10); context.restore(); CUR.prototype.render.call(this, context); } }; function init() { snake = new IKR(spawn.x, spawn.y); cursor = new CUR(-20, -20); target = new CUR(spawn.x + segmentLength * (startingSegments + 5), spawn.y); apples = []; score = 0; snakeSpeed = baseSnakeSpeed; // Reset speed to base value for (var i = 0; i < startingSegments; i++) { snake.addSeg(); } snake.lastArm.target(target.x, target.y); gameState = 'play'; } init(); // Touch events handled by game object game.down = function (x, y, obj) { switch (gameState) { case 'play': target.x = x; target.y = y; snake.lastArm.target(target.x, target.y); break; case 'dead': init(); break; } }; function badPlacement(apple) { for (var s = 0; s < snake.sgms.length; s++) { var seg = snake.sgms[s]; if (Math.min(distance(apple, { x: seg.endX(), y: seg.endY() }), distance(apple, { x: seg.x, y: seg.y })) < appleWidth * 2) { return true; } } return false; } function addScoreSegments() { for (var i = 0; i < segmentsPerApple; i++) { snake.grow(); } // Increase snake speed progressively snakeSpeed = Math.max(200, snakeSpeed + speedIncrement); } function update() { if (gameState !== 'dead') { snake.lastArm.gotoTarget(); if (snake.lastArm.endX() > 2048 - 50 || snake.lastArm.endX() < 50 || snake.lastArm.endY() > 2732 - 50 || snake.lastArm.endY() < 50) { gameState = 'dead'; deathMeans = 'Hit the wall!'; LK.showGameOver(); return; } for (var s = 0; s < snake.sgms.length - 2; s++) { var seg = snake.sgms[s]; if (lineIntersect(snake.lastArm.x, snake.lastArm.y, snake.lastArm.endX(), snake.lastArm.endY(), seg.x, seg.y, seg.endX(), seg.endY())) { gameState = 'dead'; deathMeans = 'You bit yourself'; LK.showGameOver(); return; } for (var a in apples) { var apple = apples[a]; if (Math.min(distance(apple, { x: seg.endX(), y: seg.endY() }), distance(apple, { x: seg.x, y: seg.y })) < appleWidth * 2) { score += Math.round(apple.life / 2); // half score if absorbed by the tail apples.splice(a, 1); addScoreSegments(); } } } for (var a in apples) { var apple = apples[a]; apple.update(); if (apple.life <= 0) { apples.splice(a, 1); continue; } if (distance(apple, { x: snake.lastArm.endX(), y: snake.lastArm.endY() }) < appleWidth * 2) { score += apple.life; apples.splice(a, 1); addScoreSegments(); } } if (apples.length < maxApples && Math.random() < 0.02) { var offset = appleWidth * 4, apple = new Apple(offset + Math.floor(Math.random() * (2048 - offset * 2)), offset + Math.floor(Math.random() * (2732 - offset * 2))); while (badPlacement(apple)) { apple.x = offset + Math.floor(Math.random() * (2048 - offset * 2)); apple.y = offset + Math.floor(Math.random() * (2732 - offset * 2)); } apples.push(apple); // Create visual apple var appleVisual = LK.getAsset('apple', { width: appleWidth * 2, height: appleWidth * 2, color: 0x00ff00, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); appleVisual.x = apple.x; appleVisual.y = apple.y; game.addChild(appleVisual); appleObjects.push(appleVisual); } } } // LK rendering system - visual elements handled by game objects var snakeSegments = []; var appleObjects = []; var targetObject = null; var scoreText = null; // Initialize visual elements function initVisuals() { // Clear existing visuals for (var i = 0; i < snakeSegments.length; i++) { snakeSegments[i].destroy(); } for (var i = 0; i < appleObjects.length; i++) { appleObjects[i].destroy(); } if (targetObject) { targetObject.destroy(); } if (scoreText) { scoreText.destroy(); } snakeSegments = []; appleObjects = []; // Create score text scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topLeft.addChild(scoreText); scoreText.x = 120; scoreText.y = 20; // Create target indicator targetObject = LK.getAsset('target', { width: 30, height: 30, color: 0x0000ff, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); game.addChild(targetObject); } // Initialize the game init(); initVisuals(); // LK game update loop game.update = function () { if (gameState === 'play') { update(); // Update score display if (scoreText) { scoreText.setText('Score: ' + score); } // Update target position if (targetObject && !snake.lastArm.arrived) { targetObject.x = target.x; targetObject.y = target.y; targetObject.visible = true; } else if (targetObject) { targetObject.visible = false; } // Update snake visual segments updateSnakeVisuals(); // Update apple visuals updateAppleVisuals(); } }; function updateSnakeVisuals() { // Only update positions if we have existing segments, otherwise recreate if (snakeSegments.length !== snake.sgms.length + 1) { // Clear existing snake segments for (var i = 0; i < snakeSegments.length; i++) { snakeSegments[i].destroy(); } snakeSegments = []; // Create new snake segments for (var s = 0; s < snake.sgms.length; s++) { var seg = snake.sgms[s]; var segmentVisual = LK.getAsset('snakeSegment', { width: snakeWidth, height: segmentLength, color: 0x64ff64, shape: 'box', anchorX: 0.5, anchorY: 0 }); segmentVisual.x = seg.x; segmentVisual.y = seg.y; segmentVisual.rotation = seg.angle + Math.PI / 2; game.addChild(segmentVisual); snakeSegments.push(segmentVisual); } // Create snake head with proper sizing var head = LK.getAsset('snakeHead', { width: 60, height: 60, anchorX: 0.5, anchorY: 0.5 }); head.x = snake.lastArm.endX(); head.y = snake.lastArm.endY(); game.addChild(head); snakeSegments.push(head); } else { // Update existing segments smoothly for (var s = 0; s < snake.sgms.length; s++) { var seg = snake.sgms[s]; var segmentVisual = snakeSegments[s]; // Smooth visual updates with tweening tween(segmentVisual, { x: seg.x, y: seg.y, rotation: seg.angle + Math.PI / 2 }, { duration: 15, easing: tween.easeOut }); } // Update head smoothly var head = snakeSegments[snakeSegments.length - 1]; tween(head, { x: snake.lastArm.endX(), y: snake.lastArm.endY() }, { duration: 15, easing: tween.easeOut }); } } function updateAppleVisuals() { // Remove apples that no longer exist for (var i = appleObjects.length - 1; i >= 0; i--) { var found = false; for (var a = 0; a < apples.length; a++) { if (Math.abs(appleObjects[i].x - apples[a].x) < 5 && Math.abs(appleObjects[i].y - apples[a].y) < 5) { found = true; break; } } if (!found) { appleObjects[i].destroy(); appleObjects.splice(i, 1); } } } ; ;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game configuration
var segmentLength = 40,
startingSegments = 10,
spawn = {
x: 1024,
y: 1366
},
snakeSpeed = 2000,
baseSnakeSpeed = 2,
speedIncrement = 2000,
maxApples = 3,
appleLife = 300,
segmentsPerApple = 2,
snakeWidth = 30,
appleWidth = 25,
cursorSize = 20,
snake,
target,
apples,
score,
gameState,
deathMeans,
smoothMovement = true,
movementQueue = [];
function distance(p1, p2) {
var dx = p2.x - p1.x;
var dy = p2.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
}
function lineIntersect(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) {
var s1_x = p1_x - p0_x,
s1_y = p1_y - p0_y,
s2_x = p3_x - p2_x,
s2_y = p3_y - p2_y,
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y),
t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
return true;
}
return false;
}
function SGM(angle, x, y) {
this.x = x || 0;
this.y = y || 0;
this.angle = angle || 0;
this.parent = null;
}
;
SGM.prototype.endX = function () {
return this.x + Math.cos(this.angle) * segmentLength;
};
SGM.prototype.endY = function () {
return this.y + Math.sin(this.angle) * segmentLength;
};
SGM.prototype.pointAt = function (x, y) {
var dx = x - this.x,
dy = y - this.y;
this.angle = Math.atan2(dy, dx);
};
SGM.prototype.target = function (x, y) {
this.targetX = x;
this.targetY = y;
this.arrived = false;
this.totalDist = distance({
x: this.endX(),
y: this.endY()
}, {
x: this.targetX,
y: this.targetY
});
this.currentDist = parseInt(this.totalDist);
};
SGM.prototype.gotoTarget = function () {
if (!this.arrived) {
if (this.targetX > this.x + segmentLength || this.targetX < this.x - segmentLength || this.targetY > this.y + segmentLength || this.targetY < this.y - segmentLength) {
this.pointAt(this.targetX, this.targetY);
} else {
this.arrived = true;
}
this.currentDist = distance({
x: this.endX(),
y: this.endY()
}, {
x: this.targetX,
y: this.targetY
});
}
// Smooth movement with tweening
if (smoothMovement) {
var moveSpeed = snakeSpeed * 1.2; // Faster movement
var newX = this.x + (this.endX() - this.x) / moveSpeed;
var newY = this.y + (this.endY() - this.y) / moveSpeed;
// Use tween for very smooth transitions
tween(this, {
x: newX,
y: newY
}, {
duration: 15,
easing: tween.easeOut
});
} else {
this.x += (this.endX() - this.x) / snakeSpeed;
this.y += (this.endY() - this.y) / snakeSpeed;
}
if (this.parent) {
this.parent.drag(this.x, this.y);
}
};
SGM.prototype.drag = function (x, y) {
this.pointAt(x, y);
var newX = x - Math.cos(this.angle) * segmentLength;
var newY = y - Math.sin(this.angle) * segmentLength;
if (smoothMovement) {
// Smooth transition for body segments
tween(this, {
x: newX,
y: newY
}, {
duration: 20,
easing: tween.easeInOut
});
} else {
this.x = newX;
this.y = newY;
}
if (this.parent) {
// Delay the parent drag slightly for smoother chain movement
var self = this;
LK.setTimeout(function () {
self.parent.drag(self.x, self.y);
}, 5);
}
};
SGM.prototype.render = function (context) {
context.lineTo(this.endX(), this.endY());
};
function IKR(x, y) {
this.ix = x || 0;
this.iy = y || 0;
this.sgms = [];
this.lastArm = null;
}
;
IKR.prototype.addSeg = function (angle) {
var arm = new SGM(angle);
if (this.lastArm !== null) {
arm.x = this.lastArm.endX();
arm.y = this.lastArm.endY();
arm.parent = this.lastArm;
} else {
arm.x = this.ix;
arm.y = this.iy;
}
this.sgms.push(arm);
this.lastArm = arm;
};
IKR.prototype.grow = function () {
var tail = this.sgms[0],
arm = new SGM(tail.angle);
arm.x = tail.x - Math.cos(tail.angle) * segmentLength;
arm.y = tail.y - Math.sin(tail.angle) * segmentLength;
tail.parent = arm;
this.sgms.unshift(arm);
};
IKR.prototype.drag = function (x, y) {
this.lastArm.drag(x, y);
};
function CUR(x, y) {
this.x = x;
this.y = y;
this.rotation = 0;
}
;
CUR.prototype.render = function (context) {
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.beginPath();
context.moveTo(0, -cursorSize);
context.lineTo(0, -cursorSize / 2);
context.moveTo(0, cursorSize / 2);
context.lineTo(0, cursorSize);
context.moveTo(-cursorSize, 0);
context.lineTo(-cursorSize / 2, 0);
context.moveTo(cursorSize / 2, 0);
context.lineTo(cursorSize, 0);
context.stroke();
context.restore();
this.rotation = (this.rotation + cursorSpin) % 360;
};
function Apple(x, y) {
this.x = x;
this.y = y;
this.life = appleLife;
this.rotation = 0;
}
Apple.prototype.update = function () {
this.life--;
};
Apple.prototype.render = function (context) {
context.beginPath();
context.arc(this.x, this.y, appleWidth, 0, Math.PI * 2);
context.fill();
if (gameState !== 'dead') {
context.save();
context.fillStyle = 'white';
context.font = '8px sans-serif';
context.fillText(this.life, this.x + 10, this.y + 10);
context.restore();
CUR.prototype.render.call(this, context);
}
};
function init() {
snake = new IKR(spawn.x, spawn.y);
cursor = new CUR(-20, -20);
target = new CUR(spawn.x + segmentLength * (startingSegments + 5), spawn.y);
apples = [];
score = 0;
snakeSpeed = baseSnakeSpeed; // Reset speed to base value
for (var i = 0; i < startingSegments; i++) {
snake.addSeg();
}
snake.lastArm.target(target.x, target.y);
gameState = 'play';
}
init();
// Touch events handled by game object
game.down = function (x, y, obj) {
switch (gameState) {
case 'play':
target.x = x;
target.y = y;
snake.lastArm.target(target.x, target.y);
break;
case 'dead':
init();
break;
}
};
function badPlacement(apple) {
for (var s = 0; s < snake.sgms.length; s++) {
var seg = snake.sgms[s];
if (Math.min(distance(apple, {
x: seg.endX(),
y: seg.endY()
}), distance(apple, {
x: seg.x,
y: seg.y
})) < appleWidth * 2) {
return true;
}
}
return false;
}
function addScoreSegments() {
for (var i = 0; i < segmentsPerApple; i++) {
snake.grow();
}
// Increase snake speed progressively
snakeSpeed = Math.max(200, snakeSpeed + speedIncrement);
}
function update() {
if (gameState !== 'dead') {
snake.lastArm.gotoTarget();
if (snake.lastArm.endX() > 2048 - 50 || snake.lastArm.endX() < 50 || snake.lastArm.endY() > 2732 - 50 || snake.lastArm.endY() < 50) {
gameState = 'dead';
deathMeans = 'Hit the wall!';
LK.showGameOver();
return;
}
for (var s = 0; s < snake.sgms.length - 2; s++) {
var seg = snake.sgms[s];
if (lineIntersect(snake.lastArm.x, snake.lastArm.y, snake.lastArm.endX(), snake.lastArm.endY(), seg.x, seg.y, seg.endX(), seg.endY())) {
gameState = 'dead';
deathMeans = 'You bit yourself';
LK.showGameOver();
return;
}
for (var a in apples) {
var apple = apples[a];
if (Math.min(distance(apple, {
x: seg.endX(),
y: seg.endY()
}), distance(apple, {
x: seg.x,
y: seg.y
})) < appleWidth * 2) {
score += Math.round(apple.life / 2); // half score if absorbed by the tail
apples.splice(a, 1);
addScoreSegments();
}
}
}
for (var a in apples) {
var apple = apples[a];
apple.update();
if (apple.life <= 0) {
apples.splice(a, 1);
continue;
}
if (distance(apple, {
x: snake.lastArm.endX(),
y: snake.lastArm.endY()
}) < appleWidth * 2) {
score += apple.life;
apples.splice(a, 1);
addScoreSegments();
}
}
if (apples.length < maxApples && Math.random() < 0.02) {
var offset = appleWidth * 4,
apple = new Apple(offset + Math.floor(Math.random() * (2048 - offset * 2)), offset + Math.floor(Math.random() * (2732 - offset * 2)));
while (badPlacement(apple)) {
apple.x = offset + Math.floor(Math.random() * (2048 - offset * 2));
apple.y = offset + Math.floor(Math.random() * (2732 - offset * 2));
}
apples.push(apple);
// Create visual apple
var appleVisual = LK.getAsset('apple', {
width: appleWidth * 2,
height: appleWidth * 2,
color: 0x00ff00,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5
});
appleVisual.x = apple.x;
appleVisual.y = apple.y;
game.addChild(appleVisual);
appleObjects.push(appleVisual);
}
}
}
// LK rendering system - visual elements handled by game objects
var snakeSegments = [];
var appleObjects = [];
var targetObject = null;
var scoreText = null;
// Initialize visual elements
function initVisuals() {
// Clear existing visuals
for (var i = 0; i < snakeSegments.length; i++) {
snakeSegments[i].destroy();
}
for (var i = 0; i < appleObjects.length; i++) {
appleObjects[i].destroy();
}
if (targetObject) {
targetObject.destroy();
}
if (scoreText) {
scoreText.destroy();
}
snakeSegments = [];
appleObjects = [];
// Create score text
scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreText);
scoreText.x = 120;
scoreText.y = 20;
// Create target indicator
targetObject = LK.getAsset('target', {
width: 30,
height: 30,
color: 0x0000ff,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5
});
game.addChild(targetObject);
}
// Initialize the game
init();
initVisuals();
// LK game update loop
game.update = function () {
if (gameState === 'play') {
update();
// Update score display
if (scoreText) {
scoreText.setText('Score: ' + score);
}
// Update target position
if (targetObject && !snake.lastArm.arrived) {
targetObject.x = target.x;
targetObject.y = target.y;
targetObject.visible = true;
} else if (targetObject) {
targetObject.visible = false;
}
// Update snake visual segments
updateSnakeVisuals();
// Update apple visuals
updateAppleVisuals();
}
};
function updateSnakeVisuals() {
// Only update positions if we have existing segments, otherwise recreate
if (snakeSegments.length !== snake.sgms.length + 1) {
// Clear existing snake segments
for (var i = 0; i < snakeSegments.length; i++) {
snakeSegments[i].destroy();
}
snakeSegments = [];
// Create new snake segments
for (var s = 0; s < snake.sgms.length; s++) {
var seg = snake.sgms[s];
var segmentVisual = LK.getAsset('snakeSegment', {
width: snakeWidth,
height: segmentLength,
color: 0x64ff64,
shape: 'box',
anchorX: 0.5,
anchorY: 0
});
segmentVisual.x = seg.x;
segmentVisual.y = seg.y;
segmentVisual.rotation = seg.angle + Math.PI / 2;
game.addChild(segmentVisual);
snakeSegments.push(segmentVisual);
}
// Create snake head with proper sizing
var head = LK.getAsset('snakeHead', {
width: 60,
height: 60,
anchorX: 0.5,
anchorY: 0.5
});
head.x = snake.lastArm.endX();
head.y = snake.lastArm.endY();
game.addChild(head);
snakeSegments.push(head);
} else {
// Update existing segments smoothly
for (var s = 0; s < snake.sgms.length; s++) {
var seg = snake.sgms[s];
var segmentVisual = snakeSegments[s];
// Smooth visual updates with tweening
tween(segmentVisual, {
x: seg.x,
y: seg.y,
rotation: seg.angle + Math.PI / 2
}, {
duration: 15,
easing: tween.easeOut
});
}
// Update head smoothly
var head = snakeSegments[snakeSegments.length - 1];
tween(head, {
x: snake.lastArm.endX(),
y: snake.lastArm.endY()
}, {
duration: 15,
easing: tween.easeOut
});
}
}
function updateAppleVisuals() {
// Remove apples that no longer exist
for (var i = appleObjects.length - 1; i >= 0; i--) {
var found = false;
for (var a = 0; a < apples.length; a++) {
if (Math.abs(appleObjects[i].x - apples[a].x) < 5 && Math.abs(appleObjects[i].y - apples[a].y) < 5) {
found = true;
break;
}
}
if (!found) {
appleObjects[i].destroy();
appleObjects.splice(i, 1);
}
}
}
;
;