User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'head.filters = [{' Line Number: 166
User prompt
Make the snake's body and all effects more visible over the background
User prompt
Ensure that the background does not cover or interfere with the visibility of the snake's body and any particle effects.
User prompt
"Each time food is eaten, the character should grow by adding a new segment of the same character behind the head. The new segment should be positioned directly behind the head, and a trailing star-like effect should follow the growing body, like a shooting star
User prompt
Apply an animation to the body segments to give the appearance of walking or movement. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
1- Play a baby sound when the food is eaten 2- The growing body should never go in front of the head; it must always stay behind the head.
User prompt
"The head should always be in front, and the growing body should follow directly behind it, continuing right from the back of the head
User prompt
Keep the snake's tail balanced with its head, and ensure the view stays centered on the head.
User prompt
Play a baby sound when the food is eaten
Remix started
Copy Snake Xenzia 2024
/**** * Classes ****/ var BodyPart = Container.expand(function () { var self = Container.call(this); var bodyPart = self.attachAsset('head', { anchorX: 0.5, anchorY: 0.5 }); // Rotate the body part based on direction self.setDirection = function (direction) { if (direction === 'up') { bodyPart.rotation = 0; } else if (direction === 'down') { bodyPart.rotation = Math.PI; } else if (direction === 'left') { bodyPart.rotation = -Math.PI / 2; } else if (direction === 'right') { bodyPart.rotation = Math.PI / 2; } }; return self; }); var BonusFood = Container.expand(function () { var self = Container.call(this); // Create the bonus food var bonusFood = self.attachAsset('bonusFood', { anchorX: 0.5, anchorY: 0.5 }); }); var Food = Container.expand(function () { var self = Container.call(this); // Create the food var food = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); }); var Life = Container.expand(function () { var self = Container.call(this); // Create the life var life = self.attachAsset('life', { anchorX: 0.5, anchorY: 0.5 }); }); var Pause = Container.expand(function () { var self = Container.call(this); // Create the pause button var pause = self.attachAsset('pause', { anchorX: 0.5, anchorY: 0.5 }); // Event handler called when a press happens on element. self.down = function (x, y, obj) { if (!game.paused) { game.paused = true; pause.id = 'resume'; } else { game.paused = false; pause.id = 'pause'; } }; }); var Poison = Container.expand(function () { var self = Container.call(this); // Create the poison var poison = self.attachAsset('poison', { anchorX: 0.5, anchorY: 0.5 }); }); var Snake = Container.expand(function () { var self = Container.call(this); // Create the head of the snake var head = self.attachAsset('head', { anchorX: 0.5, anchorY: 0.5 }); // Initialize the snake's direction and speed self.direction = 'up'; self.speed = 5; self.previousPositions = []; // Update the head rotation based on direction self.updateHeadRotation = function () { if (self.direction === 'up') { head.rotation = 0; } else if (self.direction === 'down') { head.rotation = Math.PI; } else if (self.direction === 'left') { head.rotation = -Math.PI / 2; } else if (self.direction === 'right') { head.rotation = Math.PI / 2; } }; self.moveHead = function (newDirection) { if (newDirection === 'up' && this.direction !== 'down') { this.direction = 'up'; self.updateHeadRotation(); } else if (newDirection === 'down' && this.direction !== 'up') { this.direction = 'down'; self.updateHeadRotation(); } else if (newDirection === 'left' && this.direction !== 'right') { this.direction = 'left'; self.updateHeadRotation(); } else if (newDirection === 'right' && this.direction !== 'left') { this.direction = 'right'; self.updateHeadRotation(); } }; // Initialize with the correct rotation self.updateHeadRotation(); return self; }); /**** * Initialize Game ****/ //<Assets used in the game will automatically appear here> var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Add a background to the game var background = game.addChild(LK.getAsset('newBackground', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Initialize pause button var pause = game.addChild(new Pause()); // Position the pause button a little to the left from the top right corner of the game pause.x = 2048 - pause.width; pause.y = 50; // Move the pause button a little down var snake = game.addChild(new Snake()); snake.body = []; // Position the snake at the center of the game snake.x = 2048 / 2; snake.y = 2732 / 2; // Initialize food var food = game.addChild(new Food()); // Position the food at a random location within the game food.x = Math.random() * 2048; food.y = Math.random() * 2732; // Initialize poison var bonusFood = game.addChild(new BonusFood()); // Hide the bonus food when the game starts bonusFood.x = -100; bonusFood.y = -100; var poison = game.addChild(new Poison()); // Initialize life var life = game.addChild(new Life()); // Hide the life when the game starts life.x = -100; life.y = -100; // Hide the poison when the game starts poison.x = -100; poison.y = -100; game.update = function () { if (game.paused) { return; } // Update the snake's position based on its direction and speed if (snake.direction === 'up') { snake.y -= snake.speed * 2.25; } else if (snake.direction === 'down') { snake.y += snake.speed * 2.25; } else if (snake.direction === 'left') { snake.x -= snake.speed * 2.25; } else if (snake.direction === 'right') { snake.x += snake.speed * 2.25; } // Store the current position of the snake head snake.previousPositions.unshift({ x: snake.x, y: snake.y, direction: snake.direction }); // Limit the previous positions array to the length of the body plus some buffer if (snake.previousPositions.length > snake.body.length + 10) { snake.previousPositions.pop(); } // Update the position of the body parts to follow the head's previous positions for (var i = 0; i < snake.body.length; i++) { if (i + 1 < snake.previousPositions.length) { snake.body[i].x = snake.previousPositions[i + 1].x; snake.body[i].y = snake.previousPositions[i + 1].y; snake.body[i].setDirection(snake.previousPositions[i + 1].direction); } } // Check if the snake's head intersects with the food if (snake.intersects(food)) { // Increase the score score += 10; // Update the score text scoreTxt.setText('Score: ' + score); // Increase the food consumed count foodConsumed += 1; // Add a new body part to the snake var newBodyPart = new BodyPart(); // Set the direction of the new body part newBodyPart.setDirection(snake.direction); // If no previous positions exist, create initial position if (snake.previousPositions.length <= snake.body.length) { var lastPos; if (snake.body.length === 0) { lastPos = { x: snake.x, y: snake.y }; } else { var lastBodyPart = snake.body[snake.body.length - 1]; lastPos = { x: lastBodyPart.x, y: lastBodyPart.y }; } // Calculate position based on direction if (snake.direction === 'up') { newBodyPart.x = lastPos.x; newBodyPart.y = lastPos.y + 50; // Use a fixed offset } else if (snake.direction === 'down') { newBodyPart.x = lastPos.x; newBodyPart.y = lastPos.y - 50; } else if (snake.direction === 'left') { newBodyPart.x = lastPos.x + 50; newBodyPart.y = lastPos.y; } else if (snake.direction === 'right') { newBodyPart.x = lastPos.x - 50; newBodyPart.y = lastPos.y; } } else { // Use the position from previous positions array var pos = snake.previousPositions[snake.body.length]; newBodyPart.x = pos.x; newBodyPart.y = pos.y; } snake.body.push(newBodyPart); game.addChild(newBodyPart); // Check if it's time to show the bonus food if (score % 150 === 0) { // Position the bonus food at a new random location within the game, ensuring it does not appear on the border do { bonusFood.x = Math.random() * (2048 - bonusFood.width) + bonusFood.width / 2; bonusFood.y = Math.random() * (2732 - bonusFood.height) + bonusFood.height / 2; } while ((bonusFood.x < 100 || bonusFood.x > 1948) && (bonusFood.y < 100 || bonusFood.y > 2632)); // Show the bonus food for 8 seconds LK.setTimeout(function () { bonusFood.x = -100; bonusFood.y = -100; }, 8000); } // Check if it's time to show the life if (score !== 0 && score % 100 === 0 && score != previousScore) { previousScore = score; // Position the life at a new random location within the game, ensuring it does not appear on the border do { life.x = Math.random() * (2048 - life.width) + life.width / 2; life.y = Math.random() * (2732 - life.height) + life.height / 2; } while ((life.x < 100 || life.x > 1948) && (life.y < 100 || life.y > 2632)); // Show the life for 10 seconds LK.setTimeout(function () { life.x = -100; life.y = -100; }, 10000); } // Check if it's time to show the poison if (foodConsumed === 8 && !poisonGenerated) { // Position the poison at a new random location within the game, ensuring it does not appear on the border do { poison.x = Math.random() * (2048 - poison.width) + poison.width / 2; poison.y = Math.random() * (2732 - poison.height) + poison.height / 2; } while ((poison.x < 100 || poison.x > 1948) && (poison.y < 100 || poison.y > 2632)); // Show the poison for 8 seconds LK.setTimeout(function () { poison.x = -100; poison.y = -100; }, 8000); poisonGenerated = true; foodConsumed = 0; // Reset the food consumed count after generating poison } // Position the food at a new random location within the game, ensuring it does not appear on the border do { food.x = Math.random() * (2048 - food.width) + food.width / 2; food.y = Math.random() * (2732 - food.height) + food.height / 2; } while ((food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632)); } // Check if the snake's head intersects with the bonus food if (snake.intersects(bonusFood)) { // Increase the score by 50 score += 50; // Update the score text scoreTxt.setText('Score: ' + score); // Play the bonus food sound LK.getSound('bonusfood').play(); // Hide the bonus food bonusFood.x = -100; bonusFood.y = -100; } // Check if the snake's head intersects with the life if (snake.intersects(life)) { // Increase the lives by 1, up to a maximum of 8 if (lives < 8) { lives += 1; // Update the lives text livesTxt.setText('Lives: ' + lives); // Play the life sound LK.getSound('life').play(); } // Hide the life life.x = -100; life.y = -100; } // Check if the snake's head intersects with the poison if (snake.intersects(poison)) { // Decrease the lives lives -= 1; // Update the lives text livesTxt.setText('Lives: ' + lives); // Play the poison sound LK.getSound('poison').play(); // Hide the poison poison.x = -100; poison.y = -100; // Reset the food consumed count after consuming poison foodConsumed = 0; // Check if the lives have hit 0 if (lives === 0) { // Show game over LK.getSound('GameOver').play(); LK.showGameOver(); } } // Check if the snake's head has moved out of the screen if (snake.x < 0) { snake.x = 2048; } else if (snake.x > 2048) { snake.x = 0; } else if (snake.y < 0) { snake.y = 2732; } else if (snake.y > 2732) { snake.y = 0; } }; // Initialize lives, score, food consumed and poison generated var lives = 3; var score = 0; var previousScore = 0; var foodConsumed = 0; var poisonGenerated = false; // Create lives text var livesTxt = new Text2('Lives: ' + lives, { size: 32, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(livesTxt); // Create score text var scoreTxt = new Text2('Score: ' + score, { size: 32, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); game.down = function (x, y, obj) { if (game.paused) { return; } // Change the snake's direction to always move in the direction of the front area of the snake head which is not connected to the snake body if (x > snake.x && snake.direction !== 'left' && snake.direction !== 'right') { snake.moveHead('right'); } else if (x < snake.x && snake.direction !== 'right' && snake.direction !== 'left') { snake.moveHead('left'); } else if (y > snake.y && snake.direction !== 'up' && snake.direction !== 'down') { snake.moveHead('down'); } else if (y < snake.y && snake.direction !== 'down' && snake.direction !== 'up') { snake.moveHead('up'); } };
===================================================================
--- original.js
+++ change.js
@@ -6,10 +6,20 @@
var bodyPart = self.attachAsset('head', {
anchorX: 0.5,
anchorY: 0.5
});
- self.lastX = 0;
- self.lastY = 0;
+ // Rotate the body part based on direction
+ self.setDirection = function (direction) {
+ if (direction === 'up') {
+ bodyPart.rotation = 0;
+ } else if (direction === 'down') {
+ bodyPart.rotation = Math.PI;
+ } else if (direction === 'left') {
+ bodyPart.rotation = -Math.PI / 2;
+ } else if (direction === 'right') {
+ bodyPart.rotation = Math.PI / 2;
+ }
+ };
return self;
});
var BonusFood = Container.expand(function () {
var self = Container.call(this);
@@ -26,21 +36,8 @@
anchorX: 0.5,
anchorY: 0.5
});
});
-var GameView = Container.expand(function () {
- var self = Container.call(this);
- // This container will hold all game elements
- self.gameContainer = new Container();
- self.addChild(self.gameContainer);
- // Method to center the view on the snake's head
- self.centerOnSnake = function (snake) {
- // Calculate how much to move the container to center the snake
- self.gameContainer.x = 2048 / 2 - snake.x;
- self.gameContainer.y = 2732 / 2 - snake.y;
- };
- return self;
-});
var Life = Container.expand(function () {
var self = Container.call(this);
// Create the life
var life = self.attachAsset('life', {
@@ -83,19 +80,39 @@
});
// Initialize the snake's direction and speed
self.direction = 'up';
self.speed = 5;
+ self.previousPositions = [];
+ // Update the head rotation based on direction
+ self.updateHeadRotation = function () {
+ if (self.direction === 'up') {
+ head.rotation = 0;
+ } else if (self.direction === 'down') {
+ head.rotation = Math.PI;
+ } else if (self.direction === 'left') {
+ head.rotation = -Math.PI / 2;
+ } else if (self.direction === 'right') {
+ head.rotation = Math.PI / 2;
+ }
+ };
self.moveHead = function (newDirection) {
if (newDirection === 'up' && this.direction !== 'down') {
this.direction = 'up';
+ self.updateHeadRotation();
} else if (newDirection === 'down' && this.direction !== 'up') {
this.direction = 'down';
+ self.updateHeadRotation();
} else if (newDirection === 'left' && this.direction !== 'right') {
this.direction = 'left';
+ self.updateHeadRotation();
} else if (newDirection === 'right' && this.direction !== 'left') {
this.direction = 'right';
+ self.updateHeadRotation();
}
};
+ // Initialize with the correct rotation
+ self.updateHeadRotation();
+ return self;
});
/****
* Initialize Game
@@ -107,12 +124,10 @@
/****
* Game Code
****/
-// Create the game view that will handle centering
-var gameView = game.addChild(new GameView());
// Add a background to the game
-var background = gameView.gameContainer.addChild(LK.getAsset('newBackground', {
+var background = game.addChild(LK.getAsset('newBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
@@ -121,26 +136,26 @@
var pause = game.addChild(new Pause());
// Position the pause button a little to the left from the top right corner of the game
pause.x = 2048 - pause.width;
pause.y = 50; // Move the pause button a little down
-var snake = gameView.gameContainer.addChild(new Snake());
+var snake = game.addChild(new Snake());
snake.body = [];
// Position the snake at the center of the game
snake.x = 2048 / 2;
snake.y = 2732 / 2;
// Initialize food
-var food = gameView.gameContainer.addChild(new Food());
+var food = game.addChild(new Food());
// Position the food at a random location within the game
food.x = Math.random() * 2048;
food.y = Math.random() * 2732;
// Initialize poison
-var bonusFood = gameView.gameContainer.addChild(new BonusFood());
+var bonusFood = game.addChild(new BonusFood());
// Hide the bonus food when the game starts
bonusFood.x = -100;
bonusFood.y = -100;
-var poison = gameView.gameContainer.addChild(new Poison());
+var poison = game.addChild(new Poison());
// Initialize life
-var life = gameView.gameContainer.addChild(new Life());
+var life = game.addChild(new Life());
// Hide the life when the game starts
life.x = -100;
life.y = -100;
// Hide the poison when the game starts
@@ -159,67 +174,72 @@
snake.x -= snake.speed * 2.25;
} else if (snake.direction === 'right') {
snake.x += snake.speed * 2.25;
}
- // Store last positions for body parts
+ // Store the current position of the snake head
+ snake.previousPositions.unshift({
+ x: snake.x,
+ y: snake.y,
+ direction: snake.direction
+ });
+ // Limit the previous positions array to the length of the body plus some buffer
+ if (snake.previousPositions.length > snake.body.length + 10) {
+ snake.previousPositions.pop();
+ }
+ // Update the position of the body parts to follow the head's previous positions
for (var i = 0; i < snake.body.length; i++) {
- snake.body[i].lastX = snake.body[i].x;
- snake.body[i].lastY = snake.body[i].y;
+ if (i + 1 < snake.previousPositions.length) {
+ snake.body[i].x = snake.previousPositions[i + 1].x;
+ snake.body[i].y = snake.previousPositions[i + 1].y;
+ snake.body[i].setDirection(snake.previousPositions[i + 1].direction);
+ }
}
- // Update the position of the body parts to follow the head
- for (var i = snake.body.length - 1; i > 0; i--) {
- snake.body[i].x = snake.body[i - 1].x;
- snake.body[i].y = snake.body[i - 1].y;
- }
- if (snake.body.length > 0) {
- snake.body[0].x = snake.x;
- snake.body[0].y = snake.y;
- }
- // Center the view on the snake head
- gameView.centerOnSnake(snake);
// Check if the snake's head intersects with the food
if (snake.intersects(food)) {
// Increase the score
score += 10;
// Update the score text
scoreTxt.setText('Score: ' + score);
- // Play baby sound when food is eaten
- LK.getSound('besin').play();
// Increase the food consumed count
foodConsumed += 1;
// Add a new body part to the snake
var newBodyPart = new BodyPart();
- if (snake.body.length === 0) {
- // Add the first body part to the edge of the head
- if (snake.direction === 'up') {
- newBodyPart.x = snake.x;
- newBodyPart.y = snake.y + snake.height;
- } else if (snake.direction === 'down') {
- newBodyPart.x = snake.x;
- newBodyPart.y = snake.y - snake.height;
- } else if (snake.direction === 'left') {
- newBodyPart.x = snake.x + snake.width;
- newBodyPart.y = snake.y;
- } else if (snake.direction === 'right') {
- newBodyPart.x = snake.x - snake.width;
- newBodyPart.y = snake.y;
+ // Set the direction of the new body part
+ newBodyPart.setDirection(snake.direction);
+ // If no previous positions exist, create initial position
+ if (snake.previousPositions.length <= snake.body.length) {
+ var lastPos;
+ if (snake.body.length === 0) {
+ lastPos = {
+ x: snake.x,
+ y: snake.y
+ };
+ } else {
+ var lastBodyPart = snake.body[snake.body.length - 1];
+ lastPos = {
+ x: lastBodyPart.x,
+ y: lastBodyPart.y
+ };
}
- } else {
- // Add subsequent body parts to the edge of the last body part
- var lastBodyPart = snake.body[snake.body.length - 1];
+ // Calculate position based on direction
if (snake.direction === 'up') {
- newBodyPart.x = lastBodyPart.x;
- newBodyPart.y = lastBodyPart.y + lastBodyPart.height;
+ newBodyPart.x = lastPos.x;
+ newBodyPart.y = lastPos.y + 50; // Use a fixed offset
} else if (snake.direction === 'down') {
- newBodyPart.x = lastBodyPart.x;
- newBodyPart.y = lastBodyPart.y - lastBodyPart.height;
+ newBodyPart.x = lastPos.x;
+ newBodyPart.y = lastPos.y - 50;
} else if (snake.direction === 'left') {
- newBodyPart.x = lastBodyPart.x + lastBodyPart.width;
- newBodyPart.y = lastBodyPart.y;
+ newBodyPart.x = lastPos.x + 50;
+ newBodyPart.y = lastPos.y;
} else if (snake.direction === 'right') {
- newBodyPart.x = lastBodyPart.x - lastBodyPart.width;
- newBodyPart.y = lastBodyPart.y;
+ newBodyPart.x = lastPos.x - 50;
+ newBodyPart.y = lastPos.y;
}
+ } else {
+ // Use the position from previous positions array
+ var pos = snake.previousPositions[snake.body.length];
+ newBodyPart.x = pos.x;
+ newBodyPart.y = pos.y;
}
snake.body.push(newBodyPart);
game.addChild(newBodyPart);
// Check if it's time to show the bonus food
@@ -325,27 +345,8 @@
snake.y = 2732;
} else if (snake.y > 2732) {
snake.y = 0;
}
- // Balance the snake's body parts to maintain proper spacing
- for (var i = 0; i < snake.body.length; i++) {
- // Calculate proper spacing between body parts
- var targetPart = i === 0 ? snake : snake.body[i - 1];
- var currentPart = snake.body[i];
- // Calculate the distance between parts
- var dx = targetPart.x - currentPart.x;
- var dy = targetPart.y - currentPart.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // If parts are too far apart, adjust position
- var idealDistance = 150; // Based on the head asset width
- if (distance > idealDistance * 1.2) {
- // Calculate angle
- var angle = Math.atan2(dy, dx);
- // Adjust position to maintain proper spacing
- currentPart.x = targetPart.x - Math.cos(angle) * idealDistance;
- currentPart.y = targetPart.y - Math.sin(angle) * idealDistance;
- }
- }
};
// Initialize lives, score, food consumed and poison generated
var lives = 3;
var score = 0;
Pause icon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
havuç. In-Game asset. 2d. High contrast. No shadows
çilek. In-Game asset. 2d. High contrast. No shadows
boynuna bir kurdele ve eline de uçan bir balon
böğürtlen ormanı. In-Game asset. 2d. High contrast. No shadows
taş. In-Game asset. 2d. High contrast. No shadows
mesaj kutusu. In-Game asset. 2d. High contrast. No shadows