/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, level: 1 }); /**** * Classes ****/ var Dot = Container.expand(function () { var self = Container.call(this); var dotGraphics = self.attachAsset('dot', { anchorX: 0.5, anchorY: 0.5 }); self.value = 10; return self; }); var Fruit = Container.expand(function () { var self = Container.call(this); var fruitGraphics = self.attachAsset('fruit', { anchorX: 0.5, anchorY: 0.5 }); self.value = 100; // Create wobble animation var _wobble = function wobble() { tween(fruitGraphics, { rotation: Math.PI / 16 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(fruitGraphics, { rotation: -Math.PI / 16 }, { duration: 300, easing: tween.easeInOut, onFinish: _wobble }); } }); }; _wobble(); return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.direction = null; self.nextDirection = null; self.move = function (direction) { self.nextDirection = direction; }; self.update = function () { if (!self.direction && !self.nextDirection) { return; } var nextX = self.x; var nextY = self.y; // Try to move in the next direction if available if (self.nextDirection) { if (self.nextDirection === 'up') { nextY -= self.speed; } else if (self.nextDirection === 'down') { nextY += self.speed; } else if (self.nextDirection === 'left') { nextX -= self.speed; } else if (self.nextDirection === 'right') { nextX += self.speed; } // Check if valid move if (!self.willCollideWithWall(nextX, nextY)) { self.direction = self.nextDirection; self.nextDirection = null; } else { // Revert to current position nextX = self.x; nextY = self.y; } } // Continue in current direction if (self.direction) { if (self.direction === 'up') { nextY -= self.speed; } else if (self.direction === 'down') { nextY += self.speed; } else if (self.direction === 'left') { nextX -= self.speed; } else if (self.direction === 'right') { nextX += self.speed; } // Check if valid move if (!self.willCollideWithWall(nextX, nextY)) { self.x = nextX; self.y = nextY; } else { // Stop moving in this direction self.direction = null; } } }; self.willCollideWithWall = function (nextX, nextY) { var playerHalfWidth = playerGraphics.width / 2; var playerHalfHeight = playerGraphics.height / 2; for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var wallHalfWidth = wall.getChildAt(0).width / 2; var wallHalfHeight = wall.getChildAt(0).height / 2; if (Math.abs(nextX - wall.x) < playerHalfWidth + wallHalfWidth && Math.abs(nextY - wall.y) < playerHalfHeight + wallHalfHeight) { return true; } } return false; }; return self; }); var PowerPellet = Container.expand(function () { var self = Container.call(this); var pelletGraphics = self.attachAsset('powerPellet', { anchorX: 0.5, anchorY: 0.5 }); self.value = 50; // Create pulsing animation var _pulse = function pulse() { tween(pelletGraphics, { scaleX: 0.8, scaleY: 0.8 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(pelletGraphics, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeInOut, onFinish: _pulse }); } }); }; _pulse(); return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Define game variables var player; var dots = []; var powerPellets = []; var walls = []; var fruits = []; var currentLevel = storage.level || 1; var timeLeft = 60; var isGameActive = false; var fruitTimer = null; var gameWidth = 2048; var gameHeight = 2732; var tileSize = 60; // Define gameTimer variable var gameTimer = null; var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -scoreTxt.width - 20; scoreTxt.y = 20; var timeTxt = new Text2('Time: 60', { size: 60, fill: 0xFFFFFF }); timeTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timeTxt); timeTxt.y = 20; var levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 120; // Avoid the top-left 100x100 area levelTxt.y = 20; var messageBox = new Container(); var messageBg = LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, width: 1000, height: 300, tint: 0x000088 }); messageBg.alpha = 0.8; messageBox.addChild(messageBg); var messageTxt = new Text2('Level 1', { size: 80, fill: 0xFFFFFF }); messageTxt.anchor.set(0.5, 0.5); messageBox.addChild(messageTxt); messageBox.visible = false; messageBox.x = gameWidth / 2; messageBox.y = gameHeight / 2; game.addChild(messageBox); // Level layouts - using a simple approach with 1 = wall, 0 = dot, 2 = power pellet, X = empty // These are small levels for the MVP, could be expanded later var levelLayouts = [ // Level 1 - Simple maze ["111111111111111111111", "100000000100000000001", "101111110101111110101", "101000010101000010101", "101010110101011010101", "101010110101011010101", "102010000000000010201", "101011111X11111010101", "101000001X10000010101", "101111101X10111110101", "100000100000100000001", "101111111111111111101", "100000000000000000001", "111111111111111111111"], // Level 2 - More complex ["111111111111111111111", "100000100000100000001", "101110101110101111101", "101000100000100000101", "101011111111111010101", "101000000100000010101", "101011110101111010101", "102000010101000010201", "101111010101011111101", "101000000000000000101", "101011111X11111010101", "100010000X00001010001", "111110101X10101011111", "100000101X10101000001", "101111101X10101111101", "100000000000000000001", "111111111111111111111"], // Level 3 - Even more complex ["111111111111111111111", "100000000100000000001", "101111110101111110101", "101000010101000010101", "101010110101011010101", "101010110101011010101", "102010000000000010201", "101010111X11101010101", "101010001X10001010101", "101011101X10111010101", "100000100000100000001", "101111111101111111101", "101000000000000000101", "101011111111111110101", "102010000000000010201", "101110101110101011101", "101000100000100010001", "101010111111101010101", "100010000000000010001", "111111111111111111111"]]; // Initialize the game level function initLevel(level) { // Clear the game board clearLevel(); // Reset time and update UI timeLeft = 60; currentLevel = level; isGameActive = true; // Set level text levelTxt.setText('Level: ' + level); timeTxt.setText('Time: ' + timeLeft); // Get the current level layout var layout = levelLayouts[level - 1] || levelLayouts[0]; // Calculate starting position to center the maze var mazeWidth = layout[0].length * tileSize; var mazeHeight = layout.length * tileSize; var startX = (gameWidth - mazeWidth) / 2 + tileSize / 2; var startY = (gameHeight - mazeHeight) / 2 + tileSize / 2; // Create the maze based on the layout for (var y = 0; y < layout.length; y++) { for (var x = 0; x < layout[y].length; x++) { var posX = startX + x * tileSize; var posY = startY + y * tileSize; if (layout[y][x] === '1') { // Wall var wall = new Wall(); wall.x = posX; wall.y = posY; walls.push(wall); game.addChild(wall); } else if (layout[y][x] === '0') { // Dot var dot = new Dot(); dot.x = posX; dot.y = posY; dots.push(dot); game.addChild(dot); } else if (layout[y][x] === '2') { // Power Pellet var powerPellet = new PowerPellet(); powerPellet.x = posX; powerPellet.y = posY; powerPellets.push(powerPellet); game.addChild(powerPellet); } // If it's the first empty space we find, place the player there if (!player && (layout[y][x] === '0' || layout[y][x] === 'X')) { player = new Player(); player.x = posX; player.y = posY; game.addChild(player); } } } // Show level message showMessage('Level ' + level + '\nGet Ready!'); // Set up fruit spawn timer fruitTimer = LK.setInterval(spawnFruit, 15000); // Spawn fruit every 15 seconds // Start the game timer gameTimer = LK.setInterval(updateTimer, 1000); // Play background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.5, duration: 1000 } }); } // Clear the current level function clearLevel() { // Clear all game timers if (fruitTimer) { LK.clearInterval(fruitTimer); fruitTimer = null; } if (gameTimer) { LK.clearInterval(gameTimer); gameTimer = null; } // Remove all game objects if (player) { player.destroy(); player = null; } for (var i = 0; i < dots.length; i++) { dots[i].destroy(); } dots = []; for (var i = 0; i < powerPellets.length; i++) { powerPellets[i].destroy(); } powerPellets = []; for (var i = 0; i < walls.length; i++) { walls[i].destroy(); } walls = []; for (var i = 0; i < fruits.length; i++) { fruits[i].destroy(); } fruits = []; } // Update the game timer function updateTimer() { if (!isGameActive) { return; } timeLeft--; timeTxt.setText('Time: ' + timeLeft); if (timeLeft <= 0) { // Time's up! endGame(); } } // Spawn a fruit at a random empty location function spawnFruit() { if (!isGameActive || fruits.length >= 3) { return; } // Find all empty spots var emptySpots = []; var layout = levelLayouts[currentLevel - 1] || levelLayouts[0]; var mazeWidth = layout[0].length * tileSize; var mazeHeight = layout.length * tileSize; var startX = (gameWidth - mazeWidth) / 2 + tileSize / 2; var startY = (gameHeight - mazeHeight) / 2 + tileSize / 2; for (var y = 0; y < layout.length; y++) { for (var x = 0; x < layout[y].length; x++) { if (layout[y][x] === 'X') { emptySpots.push({ x: startX + x * tileSize, y: startY + y * tileSize }); } } } if (emptySpots.length > 0) { var spot = emptySpots[Math.floor(Math.random() * emptySpots.length)]; var fruit = new Fruit(); fruit.x = spot.x; fruit.y = spot.y; fruits.push(fruit); game.addChild(fruit); } } // Show a message on screen function showMessage(text) { messageTxt.setText(text); messageBox.visible = true; // Hide the message after 2 seconds LK.setTimeout(function () { messageBox.visible = false; }, 2000); } // End the current game function endGame() { isGameActive = false; // Update high score if needed if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); } // Show game over LK.showGameOver(); } // Complete the current level function completeLevel() { isGameActive = false; // Clear timers if (fruitTimer) { LK.clearInterval(fruitTimer); fruitTimer = null; } if (gameTimer) { LK.clearInterval(gameTimer); gameTimer = null; } // Calculate bonus points for remaining time var timeBonus = timeLeft * 10; LK.setScore(LK.getScore() + timeBonus); scoreTxt.setText('Score: ' + LK.getScore()); // Show level complete message showMessage('Level Complete!\nTime Bonus: ' + timeBonus); // Play level complete sound LK.getSound('levelComplete').play(); // Proceed to next level after a delay LK.setTimeout(function () { currentLevel++; storage.level = currentLevel; // Check if there are more levels if (currentLevel <= levelLayouts.length) { initLevel(currentLevel); } else { // Player beat all levels showMessage('Congratulations!\nYou beat all levels!'); LK.setTimeout(function () { LK.showYouWin(); }, 2000); } }, 3000); } // Handle touch input for movement game.down = function (x, y) { if (!player || !isGameActive) { return; } // Calculate direction based on touch position relative to player var dx = x - player.x; var dy = y - player.y; if (Math.abs(dx) > Math.abs(dy)) { // Horizontal movement if (dx > 0) { player.move('right'); } else { player.move('left'); } } else { // Vertical movement if (dy > 0) { player.move('down'); } else { player.move('up'); } } }; // Main game update loop game.update = function () { if (!isGameActive) { return; } // Update player if (player) { player.update(); // Check for dot collection for (var i = dots.length - 1; i >= 0; i--) { if (player.intersects(dots[i])) { // Collect dot LK.setScore(LK.getScore() + dots[i].value); scoreTxt.setText('Score: ' + LK.getScore()); // Play sound LK.getSound('eat').play(); // Remove dot dots[i].destroy(); dots.splice(i, 1); } } // Check for power pellet collection for (var i = powerPellets.length - 1; i >= 0; i--) { if (player.intersects(powerPellets[i])) { // Collect power pellet LK.setScore(LK.getScore() + powerPellets[i].value); scoreTxt.setText('Score: ' + LK.getScore()); // Play sound LK.getSound('powerUp').play(); // Add time bonus timeLeft += 10; timeTxt.setText('Time: ' + timeLeft); // Flash effect to indicate power-up LK.effects.flashScreen(0x00FFFF, 500); // Remove power pellet powerPellets[i].destroy(); powerPellets.splice(i, 1); } } // Check if level is complete if (dots.length === 0 && powerPellets.length === 0) { completeLevel(); return; } // Check for fruit collection for (var i = fruits.length - 1; i >= 0; i--) { if (player.intersects(fruits[i])) { // Collect fruit LK.setScore(LK.getScore() + fruits[i].value); scoreTxt.setText('Score: ' + LK.getScore()); // Play sound LK.getSound('fruitCollect').play(); // Remove fruit fruits[i].destroy(); fruits.splice(i, 1); break; // Exit loop after collecting a fruit } } } }; // Initialize the first level initLevel(currentLevel);
===================================================================
--- original.js
+++ change.js
@@ -107,11 +107,15 @@
}
}
};
self.willCollideWithWall = function (nextX, nextY) {
+ var playerHalfWidth = playerGraphics.width / 2;
+ var playerHalfHeight = playerGraphics.height / 2;
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
- if (Math.abs(nextX - wall.x) < playerGraphics.width / 2 + wall.getChildAt(0).width / 2 && Math.abs(nextY - wall.y) < playerGraphics.height / 2 + wall.getChildAt(0).height / 2) {
+ var wallHalfWidth = wall.getChildAt(0).width / 2;
+ var wallHalfHeight = wall.getChildAt(0).height / 2;
+ if (Math.abs(nextX - wall.x) < playerHalfWidth + wallHalfWidth && Math.abs(nextY - wall.y) < playerHalfHeight + wallHalfHeight) {
return true;
}
}
return false;
@@ -476,13 +480,8 @@
LK.getSound('eat').play();
// Remove dot
dots[i].destroy();
dots.splice(i, 1);
- // Check if level is complete
- if (dots.length === 0 && powerPellets.length === 0) {
- completeLevel();
- return;
- }
}
}
// Check for power pellet collection
for (var i = powerPellets.length - 1; i >= 0; i--) {
@@ -499,15 +498,15 @@
LK.effects.flashScreen(0x00FFFF, 500);
// Remove power pellet
powerPellets[i].destroy();
powerPellets.splice(i, 1);
- // Check if level is complete
- if (dots.length === 0 && powerPellets.length === 0) {
- completeLevel();
- return;
- }
}
}
+ // Check if level is complete
+ if (dots.length === 0 && powerPellets.length === 0) {
+ completeLevel();
+ return;
+ }
// Check for fruit collection
for (var i = fruits.length - 1; i >= 0; i--) {
if (player.intersects(fruits[i])) {
// Collect fruit
@@ -517,8 +516,9 @@
LK.getSound('fruitCollect').play();
// Remove fruit
fruits[i].destroy();
fruits.splice(i, 1);
+ break; // Exit loop after collecting a fruit
}
}
}
};