/**** 
* Classes
****/ 
// Replace 'custom_head_bite_image_id' with your actual image id for the bite effect
// Food Class
var Food = Container.expand(function () {
	var self = Container.call(this);
	var foodGraphics = self.attachAsset('food', {
		anchorX: 0.5,
		anchorY: 0.5
	});
});
// Assets are automatically created based on usage in the code.
// Snake Head Class
var SnakeHead = Container.expand(function () {
	var self = Container.call(this);
	// Use the custom head image
	var headGraphics = self.attachAsset('snakeHeadNormal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Store reference for easy swapping
	self.headGraphics = headGraphics;
	self.currentAssetId = 'snakeHeadNormal';
	// Track direction for rotation
	self.direction = {
		x: 0,
		y: -1
	};
	// Method to update head orientation
	self.setDirection = function (dir) {
		self.direction = {
			x: dir.x,
			y: dir.y
		};
		// Set rotation based on direction
		if (dir.x === 0 && dir.y === -1) {
			// Up
			self.headGraphics.rotation = 0;
		} else if (dir.x === 1 && dir.y === 0) {
			// Right
			self.headGraphics.rotation = Math.PI / 2;
		} else if (dir.x === 0 && dir.y === 1) {
			// Down
			self.headGraphics.rotation = Math.PI;
		} else if (dir.x === -1 && dir.y === 0) {
			// Left
			self.headGraphics.rotation = -Math.PI / 2;
		}
	};
	// Method to trigger bite effect
	self.biteEffect = function () {
		// Swap to bite asset
		if (self.currentAssetId !== 'snakeHeadBite') {
			self.removeChild(self.headGraphics);
			self.headGraphics = self.attachAsset('snakeHeadBite', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			self.setDirection(self.direction);
			self.currentAssetId = 'snakeHeadBite';
		}
		// After 0.5s, revert to normal
		LK.setTimeout(function () {
			if (self.currentAssetId !== 'snakeHeadNormal') {
				self.removeChild(self.headGraphics);
				self.headGraphics = self.attachAsset('snakeHeadNormal', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.setDirection(self.direction);
				self.currentAssetId = 'snakeHeadNormal';
			}
		}, 500);
	};
	self.isValidMove = function (nextX, nextY) {
		for (var i = 0; i < snake.length; i++) {
			if (snake[i].x === nextX && snake[i].y === nextY) {
				return false;
			}
		}
		return true;
	};
	return self;
});
// Snake Segment Class
var SnakeSegment = Container.expand(function () {
	var self = Container.call(this);
	var segmentGraphics = self.attachAsset('snakeSegment', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Method to check if the next move is valid
	self.isValidMove = function (nextX, nextY) {
		// Check if the next move would result in the snake's head moving onto one of its body segments
		for (var i = 0; i < snake.length; i++) {
			if (snake[i].x === nextX && snake[i].y === nextY) {
				return false;
			}
		}
		return true;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xFFFFFF // Init game with white background
});
/**** 
* Game Code
****/ 
// Global variables
// Replace 'custom_head_image_id' with your actual image id
var snake = [];
var food;
var direction = {
	x: 0,
	y: -1
}; // Initial direction: up
var nextDirection = {
	x: 0,
	y: -1
};
var snakeSpeed = 5; // How many frames before the snake moves one block
var frameCounter = 0;
var gridSize = 180;
var score = 0;
// Initialize snake
function initSnake() {
	var initialLength = 5;
	for (var i = 0; i < initialLength; i++) {
		var segment;
		if (i === 0) {
			segment = game.addChild(new SnakeHead());
		} else {
			segment = game.addChild(new SnakeSegment());
		}
		segment.x = 1024; // Center of the screen width
		segment.y = 1366 + i * gridSize; // Center of the screen height, plus offset for initial length
		snake.push(segment);
	}
}
// Initialize food
function placeFood() {
	if (food) {
		food.destroy();
	} // Remove old food if it exists
	food = game.addChild(new Food());
	// Random position for food
	do {
		food.x = Math.floor(Math.random() * (2048 / gridSize)) * gridSize + gridSize / 2;
		food.y = Math.floor(Math.random() * (2732 / gridSize)) * gridSize + gridSize / 2;
	} while (food.x > 2048 - 3 * gridSize && food.y < 3 * gridSize); // Prevent food from overlapping with the scoreboard
}
// Check collision with food
function checkFoodCollision() {
	if (snake[0].intersects(food)) {
		LK.getSound('der1n').play();
		score += 10; // Increase score
		scoreText.setText('Score: ' + score); // Update score text
		growSnake(); // Grow snake
		placeFood(); // Place new food
	}
}
// Grow snake by adding a segment at the end
function growSnake() {
	var lastSegment = snake[snake.length - 1];
	var newSegment = game.addChild(new SnakeSegment());
	newSegment.x = lastSegment.x - direction.x * gridSize;
	newSegment.y = lastSegment.y - direction.y * gridSize;
	snake.push(newSegment);
}
// Check collision with walls or self
function checkCollision() {
	var head = snake[0];
	// Wall collision
	if (head.x < 0 || head.x > 2048 || head.y < 0 || head.y > 2732) {
		LK.showGameOver();
	}
	// Self collision
	for (var i = 4; i < snake.length; i++) {
		if (head.intersects(snake[i]) && i != snake.length - 1) {
			LK.showGameOver();
		}
	}
}
// Move snake
function moveSnake() {
	// Move each segment to the position of the previous segment
	for (var i = snake.length - 1; i > 0; i--) {
		snake[i].x = snake[i - 1].x;
		snake[i].y = snake[i - 1].y;
	}
	// Move head in the current direction
	snake[0].x += direction.x * gridSize;
	snake[0].y += direction.y * gridSize;
}
// Game tick
LK.on('tick', function () {
	frameCounter++;
	if (frameCounter >= snakeSpeed) {
		frameCounter = 0;
		direction = nextDirection; // Update direction
		// Update head orientation before moving
		if (snake.length > 0 && snake[0].setDirection) {
			snake[0].setDirection(direction);
		}
		moveSnake();
		// Check food collision and trigger bite effect if needed
		var ateFood = false;
		if (snake[0].intersects && food && snake[0].intersects(food)) {
			ateFood = true;
		}
		checkFoodCollision();
		if (ateFood && snake[0].biteEffect) {
			snake[0].biteEffect();
		}
		checkCollision();
	}
});
// Touch controls
game.on('down', function (x, y, obj) {
	var touchPos = game.toLocal(obj.global);
	// Calculate touch direction relative to snake head
	var diffX = touchPos.x - snake[0].x;
	var diffY = touchPos.y - snake[0].y;
	// If snake is moving horizontally, prioritize vertical movements
	if (direction.x !== 0) {
		if (diffY < 0 && direction.y !== 1) {
			nextDirection = {
				x: 0,
				y: -1
			}; // Move up if not moving down
		} else if (diffY > 0 && direction.y !== -1) {
			nextDirection = {
				x: 0,
				y: 1
			}; // Move down if not moving up
		}
	}
	// If snake is moving vertically, prioritize horizontal movements
	if (direction.y !== 0) {
		if (diffX > 0 && direction.x !== -1) {
			nextDirection = {
				x: 1,
				y: 0
			}; // Move right if not moving left
		} else if (diffX < 0 && direction.x !== 1) {
			nextDirection = {
				x: -1,
				y: 0
			}; // Move left if not moving right
		}
	}
	// If the snake is not already moving in the determined direction
	var nextX = snake[0].x + nextDirection.x * gridSize;
	var nextY = snake[0].y + nextDirection.y * gridSize;
	if (!snake[0].isValidMove(nextX, nextY)) {
		// If the next move is not valid, keep the current direction
		nextDirection = {
			x: direction.x,
			y: direction.y
		};
	}
});
// Initialize game elements
initSnake();
placeFood();
// Create a new Text2 object to display the score
var scoreText = new Text2('Score: 0', {
	size: 50,
	fill: 0x000000
});
// Move anchor to right edge, but not top, and offset left and down
scoreText.anchor.set(1, 0);
// Offset: 200px left, 60px down from top right
scoreText.x = -200;
scoreText.y = 60;
LK.gui.topRight.addChild(scoreText);
// --- Create a frame (visual border) around the play area using shape assets ---
var frameThickness = 60; // Increased thickness for thicker frame borders
// Top border
var topBorder = LK.getAsset('frameBorderTop', {
	width: 2048,
	height: frameThickness,
	color: 0x00000000,
	shape: 'box',
	x: 1024,
	y: frameThickness / 2,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(topBorder);
// Bottom border
var bottomBorder = LK.getAsset('frameBorderBottom', {
	width: 2048,
	height: frameThickness,
	color: 0x00000000,
	shape: 'box',
	x: 1024,
	y: 2732 - frameThickness / 2,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(bottomBorder);
// Left border
var leftBorder = LK.getAsset('frameBorderLeft', {
	width: frameThickness,
	height: 2732,
	color: 0x00000000,
	shape: 'box',
	x: frameThickness / 2,
	y: 1366,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(leftBorder);
// Right border
var rightBorder = LK.getAsset('frameBorderRight', {
	width: frameThickness,
	height: 2732,
	color: 0x00000000,
	shape: 'box',
	x: 2048 - frameThickness / 2,
	y: 1366,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(rightBorder);
; /**** 
* Classes
****/ 
// Replace 'custom_head_bite_image_id' with your actual image id for the bite effect
// Food Class
var Food = Container.expand(function () {
	var self = Container.call(this);
	var foodGraphics = self.attachAsset('food', {
		anchorX: 0.5,
		anchorY: 0.5
	});
});
// Assets are automatically created based on usage in the code.
// Snake Head Class
var SnakeHead = Container.expand(function () {
	var self = Container.call(this);
	// Use the custom head image
	var headGraphics = self.attachAsset('snakeHeadNormal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Store reference for easy swapping
	self.headGraphics = headGraphics;
	self.currentAssetId = 'snakeHeadNormal';
	// Track direction for rotation
	self.direction = {
		x: 0,
		y: -1
	};
	// Method to update head orientation
	self.setDirection = function (dir) {
		self.direction = {
			x: dir.x,
			y: dir.y
		};
		// Set rotation based on direction
		if (dir.x === 0 && dir.y === -1) {
			// Up
			self.headGraphics.rotation = 0;
		} else if (dir.x === 1 && dir.y === 0) {
			// Right
			self.headGraphics.rotation = Math.PI / 2;
		} else if (dir.x === 0 && dir.y === 1) {
			// Down
			self.headGraphics.rotation = Math.PI;
		} else if (dir.x === -1 && dir.y === 0) {
			// Left
			self.headGraphics.rotation = -Math.PI / 2;
		}
	};
	// Method to trigger bite effect
	self.biteEffect = function () {
		// Swap to bite asset
		if (self.currentAssetId !== 'snakeHeadBite') {
			self.removeChild(self.headGraphics);
			self.headGraphics = self.attachAsset('snakeHeadBite', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			self.setDirection(self.direction);
			self.currentAssetId = 'snakeHeadBite';
		}
		// After 0.5s, revert to normal
		LK.setTimeout(function () {
			if (self.currentAssetId !== 'snakeHeadNormal') {
				self.removeChild(self.headGraphics);
				self.headGraphics = self.attachAsset('snakeHeadNormal', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.setDirection(self.direction);
				self.currentAssetId = 'snakeHeadNormal';
			}
		}, 500);
	};
	self.isValidMove = function (nextX, nextY) {
		for (var i = 0; i < snake.length; i++) {
			if (snake[i].x === nextX && snake[i].y === nextY) {
				return false;
			}
		}
		return true;
	};
	return self;
});
// Snake Segment Class
var SnakeSegment = Container.expand(function () {
	var self = Container.call(this);
	var segmentGraphics = self.attachAsset('snakeSegment', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Method to check if the next move is valid
	self.isValidMove = function (nextX, nextY) {
		// Check if the next move would result in the snake's head moving onto one of its body segments
		for (var i = 0; i < snake.length; i++) {
			if (snake[i].x === nextX && snake[i].y === nextY) {
				return false;
			}
		}
		return true;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xFFFFFF // Init game with white background
});
/**** 
* Game Code
****/ 
// Global variables
// Replace 'custom_head_image_id' with your actual image id
var snake = [];
var food;
var direction = {
	x: 0,
	y: -1
}; // Initial direction: up
var nextDirection = {
	x: 0,
	y: -1
};
var snakeSpeed = 5; // How many frames before the snake moves one block
var frameCounter = 0;
var gridSize = 180;
var score = 0;
// Initialize snake
function initSnake() {
	var initialLength = 5;
	for (var i = 0; i < initialLength; i++) {
		var segment;
		if (i === 0) {
			segment = game.addChild(new SnakeHead());
		} else {
			segment = game.addChild(new SnakeSegment());
		}
		segment.x = 1024; // Center of the screen width
		segment.y = 1366 + i * gridSize; // Center of the screen height, plus offset for initial length
		snake.push(segment);
	}
}
// Initialize food
function placeFood() {
	if (food) {
		food.destroy();
	} // Remove old food if it exists
	food = game.addChild(new Food());
	// Random position for food
	do {
		food.x = Math.floor(Math.random() * (2048 / gridSize)) * gridSize + gridSize / 2;
		food.y = Math.floor(Math.random() * (2732 / gridSize)) * gridSize + gridSize / 2;
	} while (food.x > 2048 - 3 * gridSize && food.y < 3 * gridSize); // Prevent food from overlapping with the scoreboard
}
// Check collision with food
function checkFoodCollision() {
	if (snake[0].intersects(food)) {
		LK.getSound('der1n').play();
		score += 10; // Increase score
		scoreText.setText('Score: ' + score); // Update score text
		growSnake(); // Grow snake
		placeFood(); // Place new food
	}
}
// Grow snake by adding a segment at the end
function growSnake() {
	var lastSegment = snake[snake.length - 1];
	var newSegment = game.addChild(new SnakeSegment());
	newSegment.x = lastSegment.x - direction.x * gridSize;
	newSegment.y = lastSegment.y - direction.y * gridSize;
	snake.push(newSegment);
}
// Check collision with walls or self
function checkCollision() {
	var head = snake[0];
	// Wall collision
	if (head.x < 0 || head.x > 2048 || head.y < 0 || head.y > 2732) {
		LK.showGameOver();
	}
	// Self collision
	for (var i = 4; i < snake.length; i++) {
		if (head.intersects(snake[i]) && i != snake.length - 1) {
			LK.showGameOver();
		}
	}
}
// Move snake
function moveSnake() {
	// Move each segment to the position of the previous segment
	for (var i = snake.length - 1; i > 0; i--) {
		snake[i].x = snake[i - 1].x;
		snake[i].y = snake[i - 1].y;
	}
	// Move head in the current direction
	snake[0].x += direction.x * gridSize;
	snake[0].y += direction.y * gridSize;
}
// Game tick
LK.on('tick', function () {
	frameCounter++;
	if (frameCounter >= snakeSpeed) {
		frameCounter = 0;
		direction = nextDirection; // Update direction
		// Update head orientation before moving
		if (snake.length > 0 && snake[0].setDirection) {
			snake[0].setDirection(direction);
		}
		moveSnake();
		// Check food collision and trigger bite effect if needed
		var ateFood = false;
		if (snake[0].intersects && food && snake[0].intersects(food)) {
			ateFood = true;
		}
		checkFoodCollision();
		if (ateFood && snake[0].biteEffect) {
			snake[0].biteEffect();
		}
		checkCollision();
	}
});
// Touch controls
game.on('down', function (x, y, obj) {
	var touchPos = game.toLocal(obj.global);
	// Calculate touch direction relative to snake head
	var diffX = touchPos.x - snake[0].x;
	var diffY = touchPos.y - snake[0].y;
	// If snake is moving horizontally, prioritize vertical movements
	if (direction.x !== 0) {
		if (diffY < 0 && direction.y !== 1) {
			nextDirection = {
				x: 0,
				y: -1
			}; // Move up if not moving down
		} else if (diffY > 0 && direction.y !== -1) {
			nextDirection = {
				x: 0,
				y: 1
			}; // Move down if not moving up
		}
	}
	// If snake is moving vertically, prioritize horizontal movements
	if (direction.y !== 0) {
		if (diffX > 0 && direction.x !== -1) {
			nextDirection = {
				x: 1,
				y: 0
			}; // Move right if not moving left
		} else if (diffX < 0 && direction.x !== 1) {
			nextDirection = {
				x: -1,
				y: 0
			}; // Move left if not moving right
		}
	}
	// If the snake is not already moving in the determined direction
	var nextX = snake[0].x + nextDirection.x * gridSize;
	var nextY = snake[0].y + nextDirection.y * gridSize;
	if (!snake[0].isValidMove(nextX, nextY)) {
		// If the next move is not valid, keep the current direction
		nextDirection = {
			x: direction.x,
			y: direction.y
		};
	}
});
// Initialize game elements
initSnake();
placeFood();
// Create a new Text2 object to display the score
var scoreText = new Text2('Score: 0', {
	size: 50,
	fill: 0x000000
});
// Move anchor to right edge, but not top, and offset left and down
scoreText.anchor.set(1, 0);
// Offset: 200px left, 60px down from top right
scoreText.x = -200;
scoreText.y = 60;
LK.gui.topRight.addChild(scoreText);
// --- Create a frame (visual border) around the play area using shape assets ---
var frameThickness = 60; // Increased thickness for thicker frame borders
// Top border
var topBorder = LK.getAsset('frameBorderTop', {
	width: 2048,
	height: frameThickness,
	color: 0x00000000,
	shape: 'box',
	x: 1024,
	y: frameThickness / 2,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(topBorder);
// Bottom border
var bottomBorder = LK.getAsset('frameBorderBottom', {
	width: 2048,
	height: frameThickness,
	color: 0x00000000,
	shape: 'box',
	x: 1024,
	y: 2732 - frameThickness / 2,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(bottomBorder);
// Left border
var leftBorder = LK.getAsset('frameBorderLeft', {
	width: frameThickness,
	height: 2732,
	color: 0x00000000,
	shape: 'box',
	x: frameThickness / 2,
	y: 1366,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(leftBorder);
// Right border
var rightBorder = LK.getAsset('frameBorderRight', {
	width: frameThickness,
	height: 2732,
	color: 0x00000000,
	shape: 'box',
	x: 2048 - frameThickness / 2,
	y: 1366,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(rightBorder);
;