/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1, collectedKeys: 0, lives: 3 }); /**** * Classes ****/ var Boom = Container.expand(function () { var self = Container.call(this); var boomGraphics = self.attachAsset('boom', { anchorX: 0.5, anchorY: 0.5 }); self.explode = function () { tween(boomGraphics, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var Diamond = Container.expand(function () { var self = Container.call(this); var diamondGraphics = self.attachAsset('diamond', { anchorX: 0.5, anchorY: 0.5 }); self.isCollected = false; self.collect = function () { if (!self.isCollected) { self.isCollected = true; tween(diamondGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { self.destroy(); spawnAdditionalItems('diamond'); } }); LK.setScore(LK.getScore() + 40); // Diamonds give 40 points LK.getSound('collect').play(); LK.getSound('boom').play(); } }; self.update = function () { if (!self.isCollected) { // Shine animation var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2; diamondGraphics.alpha = 0.7 + glowIntensity * 0.3; } }; return self; }); var Explorer = Container.expand(function () { var self = Container.call(this); self.moveFreely = function (direction) { if (direction === 'fly') { self.y -= tileSize; // Move up by one tile size return; } if (!self.isMoving) { var currentGridPos = getGridPosition(self.x, self.y); var targetGridPos = { x: currentGridPos.x, y: currentGridPos.y }; switch (direction) { case 'up': targetGridPos.y -= 1; break; case 'down': targetGridPos.y += 1; break; case 'left': targetGridPos.x -= 1; break; case 'right': targetGridPos.x += 1; break; } if (isWalkable(targetGridPos.x, targetGridPos.y)) { var cellCenterX = targetGridPos.x * tileSize + tileSize / 2; var cellCenterY = targetGridPos.y * tileSize + tileSize / 2; self.moveToward(cellCenterX, cellCenterY); } } }; var explorerGraphics = self.attachAsset('explorer', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.isMoving = false; self.direction = null; self.targetX = 0; self.targetY = 0; self.hasKey = false; self.moveToward = function (x, y) { self.isMoving = true; self.targetX = x; self.targetY = y; // Calculate direction var dx = self.targetX - self.x; var dy = self.targetY - self.y; // Determine primary direction based on larger delta if (Math.abs(dx) > Math.abs(dy)) { self.direction = dx > 0 ? 'right' : 'left'; } else { self.direction = dy > 0 ? 'down' : 'up'; } }; self.stopMoving = function () { self.isMoving = false; self.direction = null; }; self.update = function () { if (self.isMoving) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.speed) { self.x = self.targetX; self.y = self.targetY; self.stopMoving(); } else { var ratio = self.speed / distance; var newX = self.x + dx * ratio; var newY = self.y + dy * ratio; var gridPos = getGridPosition(newX, newY); if (isWalkable(gridPos.x, gridPos.y)) { self.x = newX; self.y = newY; } else { self.stopMoving(); } } } }; self.collectKey = function () { self.hasKey = true; tween(explorerGraphics, { tint: 0xFFD700 }, { duration: 300, onFinish: function onFinish() { tween(explorerGraphics, { tint: 0xFFFFFF }, { duration: 300 }); } }); }; self.useKey = function () { self.hasKey = false; storage.collectedKeys++; }; self.takeDamage = function () { LK.effects.flashObject(self, 0xFF0000, 500); storage.lives--; LK.getSound('damage').play(); if (storage.lives <= 0) { LK.showGameOver(); } }; return self; }); var Key = Container.expand(function () { var self = Container.call(this); var keyGraphics = self.attachAsset('key', { anchorX: 0.5, anchorY: 0.5 }); self.isCollected = false; self.collect = function () { if (!self.isCollected) { self.isCollected = true; tween(keyGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { self.destroy(); spawnAdditionalItems('key'); } }); LK.setScore(LK.getScore() + 20); // Keys give 20 points LK.getSound('collect').play(); LK.getSound('boom').play(); } }; self.update = function () { if (!self.isCollected) { var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2; keyGraphics.alpha = 0.7 + glowIntensity * 0.3; } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Treasure = Container.expand(function () { var self = Container.call(this); var treasureGraphics = self.attachAsset('treasure', { anchorX: 0.5, anchorY: 0.5 }); self.isCollected = false; self.collect = function () { if (!self.isCollected) { self.isCollected = true; tween(treasureGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { self.destroy(); spawnAdditionalItems('treasure'); } }); LK.setScore(LK.getScore() + 75); LK.getSound('collectTreasure').play(); LK.getSound('boom').play(); // Check if all treasures are collected var allCollected = true; for (var i = 0; i < treasures.length; i++) { if (!treasures[i].isCollected) { allCollected = false; break; } } // Removed game end condition when all treasures are collected } }; self.update = function () { if (!self.isCollected) { // Shine animation var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2; treasureGraphics.alpha = 0.7 + glowIntensity * 0.3; } }; 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: 0x808080 // Gray/Concrete color for the floor }); /**** * Game Code ****/ function spawnAdditionalItems(type) { // Define possible positions for new items var possiblePositions = []; for (var i = 0; i < 10; i++) { possiblePositions.push({ x: Math.floor(Math.random() * gridWidth), y: Math.floor(Math.random() * gridHeight) }); } // Randomly select a position for the new item var pos = possiblePositions[Math.floor(Math.random() * possiblePositions.length)]; if (type === 'key') { // Spawn a key var key = new Key(); key.x = pos.x * tileSize + tileSize / 2; key.y = pos.y * tileSize + tileSize / 2; game.addChild(key); keys.push(key); } else if (type === 'treasure') { // Spawn a treasure var treasure = new Treasure(); treasure.x = pos.x * tileSize + tileSize / 2; treasure.y = pos.y * tileSize + tileSize / 2; game.addChild(treasure); treasures.push(treasure); } else if (type === 'diamond') { // Spawn a diamond var diamond = new Diamond(); diamond.x = pos.x * tileSize + tileSize / 2; diamond.y = pos.y * tileSize + tileSize / 2; game.addChild(diamond); diamonds.push(diamond); } } function spawnAdditionalKeysAndTreasures() { // Define possible positions for new keys and treasures var possiblePositions = [{ x: 3, y: 3 }, { x: 7, y: 7 }, { x: 12, y: 12 }, { x: 15, y: 15 } // Add more positions as needed ]; // Randomly select positions for new keys and treasures possiblePositions.forEach(function (pos) { if (Math.random() > 0.5) { // Spawn a key var key = new Key(); key.x = pos.x * tileSize + tileSize / 2; key.y = pos.y * tileSize + tileSize / 2; key.y = explorer.y; // Ensure key is on the same floor level as the explorer game.addChild(key); keys.push(key); } else { // Spawn a treasure var treasure = new Treasure(); treasure.x = pos.x * tileSize + tileSize / 2; treasure.y = pos.y * tileSize + tileSize / 2; treasure.y = explorer.y; // Ensure treasure is on the same floor level as the explorer game.addChild(treasure); treasures.push(treasure); } }); } function shouldRemoveWall(x, y) { // Define conditions to remove walls, e.g., based on position // Example: Remove walls at specific coordinates var removablePositions = [{ x: 5, y: 5 }, { x: 10, y: 10 } // Add more positions as needed ]; return removablePositions.some(function (pos) { return pos.x === x && pos.y === y; }); } // New diamond asset // Game variables var keys = []; var lastCelebratedScore = 0; var tileSize = 100; var gridWidth = 20; var gridHeight = 27; var explorer; var walls = []; var diamonds = []; var obstacles = []; var doors = []; var treasures = []; var spikes = []; var diamonds = []; var fallingRocks = []; var levelGrid = []; var gameStarted = false; // UI Elements var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); var levelTxt = new Text2('Level: ' + storage.level, { size: 60, fill: 0xFFFFFF }); var keysTxt = new Text2('Keys: ' + storage.collectedKeys, { size: 60, fill: 0xFFD700 }); var livesTxt = new Text2('Lives: ' + storage.lives, { size: 60, fill: 0xFF5252 }); // Initialize game function initializeGame() { // Clear previous game elements resetGameElements(); // Generate level based on current level generateLevel(storage.level); // Initialize explorer createExplorer(); // Setup UI setupUI(); // Randomly place treasures, keys, diamonds, and obstacles on the game floor for (var i = 0; i < 15; i++) { var treasure = new Treasure(); treasure.x = Math.random() * gridWidth * tileSize; treasure.y = Math.random() * gridHeight * tileSize; // Random Y position game.addChild(treasure); treasures.push(treasure); var key = new Key(); key.x = Math.random() * gridWidth * tileSize; key.y = Math.random() * gridHeight * tileSize; // Random Y position game.addChild(key); keys.push(key); var diamond = new Diamond(); diamond.x = Math.random() * gridWidth * tileSize; diamond.y = Math.random() * gridHeight * tileSize; // Random Y position game.addChild(diamond); diamonds.push(diamond); var obstacle = new Obstacle(); obstacle.x = Math.random() * gridWidth * tileSize; obstacle.y = Math.random() * gridHeight * tileSize; // Random Y position game.addChild(obstacle); obstacles.push(obstacle); } // Start game gameStarted = true; // Play background music with fade-in effect LK.playMusic('caveMusic', { fade: { start: 0, end: 0.5, duration: 1000 } }); } function resetGameElements() { // Remove all existing game elements for (var i = 0; i < walls.length; i++) { walls[i].destroy(); } walls = []; for (var i = 0; i < diamonds.length; i++) { diamonds[i].destroy(); } diamonds = []; for (var i = 0; i < treasures.length; i++) { treasures[i].destroy(); } treasures = []; for (var i = 0; i < fallingRocks.length; i++) { fallingRocks[i].destroy(); } fallingRocks = []; levelGrid = []; if (explorer) { explorer.destroy(); explorer = null; } } function createExplorer() { explorer = new Explorer(); game.addChild(explorer); explorer.inactivityTime = 0; // Initialize inactivity time // Position explorer at start position for (var y = 0; y < gridHeight; y++) { for (var x = 0; x < gridWidth; x++) { if (levelGrid[y][x] === 'S') { explorer.x = x * tileSize + tileSize / 2; explorer.y = y * tileSize + tileSize / 2; break; } } } } function setupUI() { // Setup collection title var scoreTitleTxt = new Text2('Score:', { size: 60, fill: 0xFFD700, // Gold color fontWeight: 'bold' // Add bold font }); scoreTitleTxt.anchor.set(1, 0); LK.gui.topRight.addChild(scoreTitleTxt); scoreTxt.setText(LK.getScore()); scoreTxt.anchor.set(1, 0); scoreTxt.y = 60; // Adjust position to be below the title LK.gui.topRight.addChild(scoreTxt); // Setup keys text keysTxt.setText('Keys: ' + storage.collectedKeys); keysTxt.anchor.set(0, 0); keysTxt.y = 80; LK.gui.topRight.addChild(keysTxt); // Setup lives text livesTxt.setText('Lives: ' + storage.lives); livesTxt.anchor.set(0, 0); LK.gui.topRight.addChild(livesTxt); } function generateLevel(level) { // Define different level layouts var layouts = []; // Level 1: Simple tutorial level layouts[1] = ["WWWWWWWWWWWWWWWWWWWW", "W W W", "W WWWWWW W WWWWWWW W", "W W K W W", "W W WWWWWWWWWWWW W W", "W W W W W", "W W W WWWWWWWWWW W W", "W W W W W W W", "W W W W WWWWWW W W W", "W W W W W W W W W", "W W W W W WW W W W W", "W W W W W W W W", "W WWWWW WWWWWWWW W W", "W W W", "W WWWWWWWWWWWWWWWW W", "W W", "W WWWWWWWW WWWWWWW W", "W W W W W", "W W WWWW WWWWWWW W W", "W W W W W W", "W W W WWWWWWWWW W W W", "W W W W W W W", "W W WWWWWWWWW W W W W", " DW W W W W", "TST ", "W W W", "WWWWWWWWWWWWWWWWWWWWW"]; var currentLayout = layouts[1]; // Parse level layout for (var y = 0; y < currentLayout.length; y++) { levelGrid[y] = []; for (var x = 0; x < currentLayout[y].length; x++) { var cellType = currentLayout[y][x]; levelGrid[y][x] = cellType; var xPos = x * tileSize + tileSize / 2; var Pos = xPos; // Define Pos variable var yPos = y * tileSize + tileSize / 2; switch (cellType) { case 'W': // Wall if (!shouldRemoveWall(x, y)) { var wall = new Wall(); wall.x = Pos; wall.y = yPos; game.addChild(wall); walls.push(wall); } else { // Log or handle the removal of the wall for debugging or game design purposes console.log("Wall at (".concat(x, ", ").concat(y, ") removed to clear the path.")); } break; case 'K': // Diamond var diamond = new Diamond(); diamond.x = xPos; diamond.y = yPos; game.addChild(diamond); diamonds.push(diamond); break; case 'T': // Treasure var treasure = new Treasure(); treasure.x = xPos; treasure.y = yPos; game.addChild(treasure); treasures.push(treasure); break; case 'K': // Key var key = new Key(); key.x = xPos; key.y = yPos; game.addChild(key); keys.push(key); break; case 'D': // Diamond var diamond = new Diamond(); diamond.x = xPos; diamond.y = yPos; game.addChild(diamond); diamonds.push(diamond); break; case 'O': // Obstacle var obstacle = new Obstacle(); obstacle.x = xPos; obstacle.y = yPos; game.addChild(obstacle); obstacles.push(obstacle); break; } } } } function getGridPosition(x, y) { var gridX = Math.floor(x / tileSize); var gridY = Math.floor(y / tileSize); if (gridX >= 0 && gridX < gridWidth && gridY >= 0 && gridY < gridHeight) { return { x: gridX, y: gridY }; } return null; } function isWalkable(gridX, gridY) { if (gridX < 0 || gridX >= gridWidth || gridY < 0 || gridY >= gridHeight) { return false; } var cellType = levelGrid[gridY][gridX]; // Check if cell is walkable if (cellType === 'W') { return false; } return true; } function getDoorAt(gridX, gridY) { for (var i = 0; i < doors.length; i++) { var doorPos = getGridPosition(doors[i].x, doors[i].y); if (doorPos && doorPos.x === gridX && doorPos.y === gridY) { return doors[i]; } } return null; } function getRiverAt(gridX, gridY) { for (var i = 0; i < rivers.length; i++) { var riverPos = getGridPosition(rivers[i].x, rivers[i].y); if (riverPos && riverPos.x === gridX && riverPos.y === gridY) { return rivers[i]; } } return null; } // Update UI function updateUI() { scoreTxt.setText(LK.getScore()); levelTxt.setText('Level: ' + storage.level); keysTxt.setText('Keys: ' + storage.collectedKeys); livesTxt.setText('Lives: ' + storage.lives); } // Check for collisions function checkCollisions() { if (!explorer) { return; } var explorerPos = getGridPosition(explorer.x, explorer.y); if (!explorerPos) { return; } var cellType = levelGrid[explorerPos.y][explorerPos.x]; // Check diamond collision for (var i = 0; i < diamonds.length; i++) { var diamondPos = getGridPosition(diamonds[i].x, diamonds[i].y); if (diamondPos && diamondPos.x === explorerPos.x && (diamondPos.y === explorerPos.y || diamondPos.y === explorerPos.y - 1) && !diamonds[i].isCollected) { diamonds[i].collect(); spawnAdditionalItems(); break; } } // Check treasure collision if (cellType === 'T') { for (var i = 0; i < treasures.length; i++) { var treasurePos = getGridPosition(treasures[i].x, treasures[i].y); if (treasurePos && treasurePos.x === explorerPos.x && (treasurePos.y === explorerPos.y || treasurePos.y === explorerPos.y - 1) && !treasures[i].isCollected) { treasures[i].collect(); spawnAdditionalItems(); break; } } } // Check key collision for (var i = 0; i < keys.length; i++) { var keyPos = getGridPosition(keys[i].x, keys[i].y); if (keyPos && keyPos.x === explorerPos.x && (keyPos.y === explorerPos.y || keyPos.y === explorerPos.y - 1) && !keys[i].isCollected) { keys[i].collect(); spawnAdditionalItems(); break; } } // Check obstacle collision for (var i = 0; i < obstacles.length; i++) { var obstaclePos = getGridPosition(obstacles[i].x, obstacles[i].y); if (obstaclePos && obstaclePos.x === explorerPos.x && obstaclePos.y === explorerPos.y) { // Play boom sound LK.getSound('boom').play(); // Create a big blast effect var blast = new Boom(); blast.x = explorer.x; blast.y = explorer.y; game.addChild(blast); blast.explode(); // Show game over with score LK.showGameOver("Game Over! Your score: " + LK.getScore()); break; } } } function moveExplorer(targetX, targetY) { if (!explorer || explorer.isjumping) { return; } var currentGridPos = getGridPosition(explorer.x, explorer.y); var targetGridPos = getGridPosition(targetX, targetY); if (!currentGridPos || !targetGridPos) { return; } // Use pathfinding to find a path to the target var path = findPath(currentGridPos, targetGridPos); if (path && path.length > 0) { var nextStep = path[0]; var cellCenterX = nextStep.x * tileSize + tileSize / 2; var cellCenterY = nextStep.y * tileSize + tileSize / 2; explorer.moveToward(cellCenterX, cellCenterY); } // Check if the explorer is at the diamond's position if (levelGrid[currentGridPos.y][currentGridPos.x] === 'K') { explorer.collectKey(); for (var i = 0; i < diamonds.length; i++) { var diamondPos = getGridPosition(diamonds[i].x, diamonds[i].y); if (diamondPos && diamondPos.x === currentGridPos.x && diamondPos.y === currentGridPos.y) { diamonds[i].destroy(); diamonds.splice(i, 1); levelGrid[currentGridPos.y][currentGridPos.x] = ' '; LK.getSound('collect').play(); break; } } } } function findPath(start, end) { // Implement a simple pathfinding algorithm, e.g., A* or BFS // This is a placeholder for the pathfinding logic // Return an array of grid positions from start to end return []; } // Handle touch/mouse events function handleGameInput(x, y, obj) { if (!gameStarted) { return; } var direction = null; var currentGridPos = getGridPosition(explorer.x, explorer.y); var targetGridPos = getGridPosition(x, y); if (targetGridPos) { if (targetGridPos.x < currentGridPos.x) { direction = 'left'; } else if (targetGridPos.x > currentGridPos.x) { direction = 'right'; } else if (targetGridPos.y < currentGridPos.y) { direction = 'up'; } else if (targetGridPos.y > currentGridPos.y) { direction = 'down'; } if (direction) { if (direction === 'up' && targetGridPos.y < currentGridPos.y - 1) { direction = 'fly'; } // Set explorer's target position to the clicked position explorer.moveToward(targetGridPos.x * tileSize + tileSize / 2, targetGridPos.y * tileSize + tileSize / 2); } // Check for left mouse button click to make the explorer jump if (obj.event && obj.event.button === 0) { // Left mouse button if (!explorer.isMoving) { var currentGridPos = getGridPosition(explorer.x, explorer.y); var targetGridPos = { x: currentGridPos.x, y: currentGridPos.y - 2 // Jump up two tiles }; if (isWalkable(targetGridPos.x, targetGridPos.y)) { var cellCenterX = targetGridPos.x * tileSize + tileSize / 2; var cellCenterY = targetGridPos.y * tileSize + tileSize / 2; explorer.moveToward(cellCenterX, cellCenterY); } } } } // Check for left mouse button click to make the explorer jump if (obj.event && obj.event.button === 0) { // Left mouse button if (!explorer.isMoving) { var currentGridPos = getGridPosition(explorer.x, explorer.y); var targetGridPos = { x: currentGridPos.x, y: currentGridPos.y - 2 // Jump up two tiles }; if (isWalkable(targetGridPos.x, targetGridPos.y)) { var cellCenterX = targetGridPos.x * tileSize + tileSize / 2; var cellCenterY = targetGridPos.y * tileSize + tileSize / 2; explorer.moveToward(cellCenterX, cellCenterY); } } } } // Start game when page loads initializeGame(); // Handle touch/mouse events game.down = handleGameInput; // Game update loop game.update = function () { if (!gameStarted) { return; } // Check for explorer inactivity if (explorer) { if (explorer.lastX === undefined) { explorer.lastX = explorer.x; } if (explorer.lastY === undefined) { explorer.lastY = explorer.y; } if (explorer.x === explorer.lastX && explorer.y === explorer.lastY) { explorer.inactivityTime += 1 / 60; // Increment inactivity time in seconds } else { explorer.inactivityTime = 0; // Reset inactivity time if explorer moves } explorer.lastX = explorer.x; explorer.lastY = explorer.y; if (explorer.inactivityTime >= 60) { // If inactivity time reaches 60 seconds LK.showGameOver("Game Over! You were inactive for too long."); return; // Ensure game loop stops after game over } } // Update UI updateUI(); // Check collisions checkCollisions(); // Check for score milestones and trigger celebration var currentScore = LK.getScore(); if (Math.floor(currentScore / 250) > Math.floor(lastCelebratedScore / 250)) { lastCelebratedScore = currentScore; // Play boom sound LK.getSound('boom').play(); // Display congratulations message var message = new Text2("Congratulations! You reached ".concat(currentScore, "!"), { size: 100, fill: 0xFFD700, fontWeight: 'bold' }); message.anchor.set(0.5, 0.5); message.x = 2048 / 2; message.y = 2732 / 2; game.addChild(message); // Remove message after 4 seconds LK.setTimeout(function () { message.destroy(); }, 4000); // Trigger color paper blast effect in big size var color = 0xFFD700; // Gold color var paper = new Container(); var paperGraphics = paper.attachAsset('boom', { anchorX: 0.5, anchorY: 0.5 }); paperGraphics.tint = color; paper.x = 2048 / 2; paper.y = 2732 / 2; game.addChild(paper); tween(paperGraphics, { scaleX: 20, scaleY: 20, alpha: 0 }, { duration: 4000, onFinish: function onFinish() { paper.destroy(); } }); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1,
collectedKeys: 0,
lives: 3
});
/****
* Classes
****/
var Boom = Container.expand(function () {
var self = Container.call(this);
var boomGraphics = self.attachAsset('boom', {
anchorX: 0.5,
anchorY: 0.5
});
self.explode = function () {
tween(boomGraphics, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Diamond = Container.expand(function () {
var self = Container.call(this);
var diamondGraphics = self.attachAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCollected = false;
self.collect = function () {
if (!self.isCollected) {
self.isCollected = true;
tween(diamondGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
spawnAdditionalItems('diamond');
}
});
LK.setScore(LK.getScore() + 40); // Diamonds give 40 points
LK.getSound('collect').play();
LK.getSound('boom').play();
}
};
self.update = function () {
if (!self.isCollected) {
// Shine animation
var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2;
diamondGraphics.alpha = 0.7 + glowIntensity * 0.3;
}
};
return self;
});
var Explorer = Container.expand(function () {
var self = Container.call(this);
self.moveFreely = function (direction) {
if (direction === 'fly') {
self.y -= tileSize; // Move up by one tile size
return;
}
if (!self.isMoving) {
var currentGridPos = getGridPosition(self.x, self.y);
var targetGridPos = {
x: currentGridPos.x,
y: currentGridPos.y
};
switch (direction) {
case 'up':
targetGridPos.y -= 1;
break;
case 'down':
targetGridPos.y += 1;
break;
case 'left':
targetGridPos.x -= 1;
break;
case 'right':
targetGridPos.x += 1;
break;
}
if (isWalkable(targetGridPos.x, targetGridPos.y)) {
var cellCenterX = targetGridPos.x * tileSize + tileSize / 2;
var cellCenterY = targetGridPos.y * tileSize + tileSize / 2;
self.moveToward(cellCenterX, cellCenterY);
}
}
};
var explorerGraphics = self.attachAsset('explorer', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.isMoving = false;
self.direction = null;
self.targetX = 0;
self.targetY = 0;
self.hasKey = false;
self.moveToward = function (x, y) {
self.isMoving = true;
self.targetX = x;
self.targetY = y;
// Calculate direction
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
// Determine primary direction based on larger delta
if (Math.abs(dx) > Math.abs(dy)) {
self.direction = dx > 0 ? 'right' : 'left';
} else {
self.direction = dy > 0 ? 'down' : 'up';
}
};
self.stopMoving = function () {
self.isMoving = false;
self.direction = null;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.stopMoving();
} else {
var ratio = self.speed / distance;
var newX = self.x + dx * ratio;
var newY = self.y + dy * ratio;
var gridPos = getGridPosition(newX, newY);
if (isWalkable(gridPos.x, gridPos.y)) {
self.x = newX;
self.y = newY;
} else {
self.stopMoving();
}
}
}
};
self.collectKey = function () {
self.hasKey = true;
tween(explorerGraphics, {
tint: 0xFFD700
}, {
duration: 300,
onFinish: function onFinish() {
tween(explorerGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
});
};
self.useKey = function () {
self.hasKey = false;
storage.collectedKeys++;
};
self.takeDamage = function () {
LK.effects.flashObject(self, 0xFF0000, 500);
storage.lives--;
LK.getSound('damage').play();
if (storage.lives <= 0) {
LK.showGameOver();
}
};
return self;
});
var Key = Container.expand(function () {
var self = Container.call(this);
var keyGraphics = self.attachAsset('key', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCollected = false;
self.collect = function () {
if (!self.isCollected) {
self.isCollected = true;
tween(keyGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
spawnAdditionalItems('key');
}
});
LK.setScore(LK.getScore() + 20); // Keys give 20 points
LK.getSound('collect').play();
LK.getSound('boom').play();
}
};
self.update = function () {
if (!self.isCollected) {
var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2;
keyGraphics.alpha = 0.7 + glowIntensity * 0.3;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Treasure = Container.expand(function () {
var self = Container.call(this);
var treasureGraphics = self.attachAsset('treasure', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCollected = false;
self.collect = function () {
if (!self.isCollected) {
self.isCollected = true;
tween(treasureGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
spawnAdditionalItems('treasure');
}
});
LK.setScore(LK.getScore() + 75);
LK.getSound('collectTreasure').play();
LK.getSound('boom').play();
// Check if all treasures are collected
var allCollected = true;
for (var i = 0; i < treasures.length; i++) {
if (!treasures[i].isCollected) {
allCollected = false;
break;
}
}
// Removed game end condition when all treasures are collected
}
};
self.update = function () {
if (!self.isCollected) {
// Shine animation
var glowIntensity = (Math.sin(LK.ticks / 30) + 1) / 2;
treasureGraphics.alpha = 0.7 + glowIntensity * 0.3;
}
};
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: 0x808080 // Gray/Concrete color for the floor
});
/****
* Game Code
****/
function spawnAdditionalItems(type) {
// Define possible positions for new items
var possiblePositions = [];
for (var i = 0; i < 10; i++) {
possiblePositions.push({
x: Math.floor(Math.random() * gridWidth),
y: Math.floor(Math.random() * gridHeight)
});
}
// Randomly select a position for the new item
var pos = possiblePositions[Math.floor(Math.random() * possiblePositions.length)];
if (type === 'key') {
// Spawn a key
var key = new Key();
key.x = pos.x * tileSize + tileSize / 2;
key.y = pos.y * tileSize + tileSize / 2;
game.addChild(key);
keys.push(key);
} else if (type === 'treasure') {
// Spawn a treasure
var treasure = new Treasure();
treasure.x = pos.x * tileSize + tileSize / 2;
treasure.y = pos.y * tileSize + tileSize / 2;
game.addChild(treasure);
treasures.push(treasure);
} else if (type === 'diamond') {
// Spawn a diamond
var diamond = new Diamond();
diamond.x = pos.x * tileSize + tileSize / 2;
diamond.y = pos.y * tileSize + tileSize / 2;
game.addChild(diamond);
diamonds.push(diamond);
}
}
function spawnAdditionalKeysAndTreasures() {
// Define possible positions for new keys and treasures
var possiblePositions = [{
x: 3,
y: 3
}, {
x: 7,
y: 7
}, {
x: 12,
y: 12
}, {
x: 15,
y: 15
}
// Add more positions as needed
];
// Randomly select positions for new keys and treasures
possiblePositions.forEach(function (pos) {
if (Math.random() > 0.5) {
// Spawn a key
var key = new Key();
key.x = pos.x * tileSize + tileSize / 2;
key.y = pos.y * tileSize + tileSize / 2;
key.y = explorer.y; // Ensure key is on the same floor level as the explorer
game.addChild(key);
keys.push(key);
} else {
// Spawn a treasure
var treasure = new Treasure();
treasure.x = pos.x * tileSize + tileSize / 2;
treasure.y = pos.y * tileSize + tileSize / 2;
treasure.y = explorer.y; // Ensure treasure is on the same floor level as the explorer
game.addChild(treasure);
treasures.push(treasure);
}
});
}
function shouldRemoveWall(x, y) {
// Define conditions to remove walls, e.g., based on position
// Example: Remove walls at specific coordinates
var removablePositions = [{
x: 5,
y: 5
}, {
x: 10,
y: 10
}
// Add more positions as needed
];
return removablePositions.some(function (pos) {
return pos.x === x && pos.y === y;
});
}
// New diamond asset
// Game variables
var keys = [];
var lastCelebratedScore = 0;
var tileSize = 100;
var gridWidth = 20;
var gridHeight = 27;
var explorer;
var walls = [];
var diamonds = [];
var obstacles = [];
var doors = [];
var treasures = [];
var spikes = [];
var diamonds = [];
var fallingRocks = [];
var levelGrid = [];
var gameStarted = false;
// UI Elements
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
var levelTxt = new Text2('Level: ' + storage.level, {
size: 60,
fill: 0xFFFFFF
});
var keysTxt = new Text2('Keys: ' + storage.collectedKeys, {
size: 60,
fill: 0xFFD700
});
var livesTxt = new Text2('Lives: ' + storage.lives, {
size: 60,
fill: 0xFF5252
});
// Initialize game
function initializeGame() {
// Clear previous game elements
resetGameElements();
// Generate level based on current level
generateLevel(storage.level);
// Initialize explorer
createExplorer();
// Setup UI
setupUI();
// Randomly place treasures, keys, diamonds, and obstacles on the game floor
for (var i = 0; i < 15; i++) {
var treasure = new Treasure();
treasure.x = Math.random() * gridWidth * tileSize;
treasure.y = Math.random() * gridHeight * tileSize; // Random Y position
game.addChild(treasure);
treasures.push(treasure);
var key = new Key();
key.x = Math.random() * gridWidth * tileSize;
key.y = Math.random() * gridHeight * tileSize; // Random Y position
game.addChild(key);
keys.push(key);
var diamond = new Diamond();
diamond.x = Math.random() * gridWidth * tileSize;
diamond.y = Math.random() * gridHeight * tileSize; // Random Y position
game.addChild(diamond);
diamonds.push(diamond);
var obstacle = new Obstacle();
obstacle.x = Math.random() * gridWidth * tileSize;
obstacle.y = Math.random() * gridHeight * tileSize; // Random Y position
game.addChild(obstacle);
obstacles.push(obstacle);
}
// Start game
gameStarted = true;
// Play background music with fade-in effect
LK.playMusic('caveMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
}
function resetGameElements() {
// Remove all existing game elements
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
for (var i = 0; i < diamonds.length; i++) {
diamonds[i].destroy();
}
diamonds = [];
for (var i = 0; i < treasures.length; i++) {
treasures[i].destroy();
}
treasures = [];
for (var i = 0; i < fallingRocks.length; i++) {
fallingRocks[i].destroy();
}
fallingRocks = [];
levelGrid = [];
if (explorer) {
explorer.destroy();
explorer = null;
}
}
function createExplorer() {
explorer = new Explorer();
game.addChild(explorer);
explorer.inactivityTime = 0; // Initialize inactivity time
// Position explorer at start position
for (var y = 0; y < gridHeight; y++) {
for (var x = 0; x < gridWidth; x++) {
if (levelGrid[y][x] === 'S') {
explorer.x = x * tileSize + tileSize / 2;
explorer.y = y * tileSize + tileSize / 2;
break;
}
}
}
}
function setupUI() {
// Setup collection title
var scoreTitleTxt = new Text2('Score:', {
size: 60,
fill: 0xFFD700,
// Gold color
fontWeight: 'bold' // Add bold font
});
scoreTitleTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTitleTxt);
scoreTxt.setText(LK.getScore());
scoreTxt.anchor.set(1, 0);
scoreTxt.y = 60; // Adjust position to be below the title
LK.gui.topRight.addChild(scoreTxt);
// Setup keys text
keysTxt.setText('Keys: ' + storage.collectedKeys);
keysTxt.anchor.set(0, 0);
keysTxt.y = 80;
LK.gui.topRight.addChild(keysTxt);
// Setup lives text
livesTxt.setText('Lives: ' + storage.lives);
livesTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(livesTxt);
}
function generateLevel(level) {
// Define different level layouts
var layouts = [];
// Level 1: Simple tutorial level
layouts[1] = ["WWWWWWWWWWWWWWWWWWWW", "W W W", "W WWWWWW W WWWWWWW W", "W W K W W", "W W WWWWWWWWWWWW W W", "W W W W W", "W W W WWWWWWWWWW W W", "W W W W W W W", "W W W W WWWWWW W W W", "W W W W W W W W W", "W W W W W WW W W W W", "W W W W W W W W", "W WWWWW WWWWWWWW W W", "W W W", "W WWWWWWWWWWWWWWWW W", "W W", "W WWWWWWWW WWWWWWW W", "W W W W W", "W W WWWW WWWWWWW W W", "W W W W W W", "W W W WWWWWWWWW W W W", "W W W W W W W", "W W WWWWWWWWW W W W W", " DW W W W W", "TST ", "W W W", "WWWWWWWWWWWWWWWWWWWWW"];
var currentLayout = layouts[1];
// Parse level layout
for (var y = 0; y < currentLayout.length; y++) {
levelGrid[y] = [];
for (var x = 0; x < currentLayout[y].length; x++) {
var cellType = currentLayout[y][x];
levelGrid[y][x] = cellType;
var xPos = x * tileSize + tileSize / 2;
var Pos = xPos; // Define Pos variable
var yPos = y * tileSize + tileSize / 2;
switch (cellType) {
case 'W':
// Wall
if (!shouldRemoveWall(x, y)) {
var wall = new Wall();
wall.x = Pos;
wall.y = yPos;
game.addChild(wall);
walls.push(wall);
} else {
// Log or handle the removal of the wall for debugging or game design purposes
console.log("Wall at (".concat(x, ", ").concat(y, ") removed to clear the path."));
}
break;
case 'K':
// Diamond
var diamond = new Diamond();
diamond.x = xPos;
diamond.y = yPos;
game.addChild(diamond);
diamonds.push(diamond);
break;
case 'T':
// Treasure
var treasure = new Treasure();
treasure.x = xPos;
treasure.y = yPos;
game.addChild(treasure);
treasures.push(treasure);
break;
case 'K':
// Key
var key = new Key();
key.x = xPos;
key.y = yPos;
game.addChild(key);
keys.push(key);
break;
case 'D':
// Diamond
var diamond = new Diamond();
diamond.x = xPos;
diamond.y = yPos;
game.addChild(diamond);
diamonds.push(diamond);
break;
case 'O':
// Obstacle
var obstacle = new Obstacle();
obstacle.x = xPos;
obstacle.y = yPos;
game.addChild(obstacle);
obstacles.push(obstacle);
break;
}
}
}
}
function getGridPosition(x, y) {
var gridX = Math.floor(x / tileSize);
var gridY = Math.floor(y / tileSize);
if (gridX >= 0 && gridX < gridWidth && gridY >= 0 && gridY < gridHeight) {
return {
x: gridX,
y: gridY
};
}
return null;
}
function isWalkable(gridX, gridY) {
if (gridX < 0 || gridX >= gridWidth || gridY < 0 || gridY >= gridHeight) {
return false;
}
var cellType = levelGrid[gridY][gridX];
// Check if cell is walkable
if (cellType === 'W') {
return false;
}
return true;
}
function getDoorAt(gridX, gridY) {
for (var i = 0; i < doors.length; i++) {
var doorPos = getGridPosition(doors[i].x, doors[i].y);
if (doorPos && doorPos.x === gridX && doorPos.y === gridY) {
return doors[i];
}
}
return null;
}
function getRiverAt(gridX, gridY) {
for (var i = 0; i < rivers.length; i++) {
var riverPos = getGridPosition(rivers[i].x, rivers[i].y);
if (riverPos && riverPos.x === gridX && riverPos.y === gridY) {
return rivers[i];
}
}
return null;
}
// Update UI
function updateUI() {
scoreTxt.setText(LK.getScore());
levelTxt.setText('Level: ' + storage.level);
keysTxt.setText('Keys: ' + storage.collectedKeys);
livesTxt.setText('Lives: ' + storage.lives);
}
// Check for collisions
function checkCollisions() {
if (!explorer) {
return;
}
var explorerPos = getGridPosition(explorer.x, explorer.y);
if (!explorerPos) {
return;
}
var cellType = levelGrid[explorerPos.y][explorerPos.x];
// Check diamond collision
for (var i = 0; i < diamonds.length; i++) {
var diamondPos = getGridPosition(diamonds[i].x, diamonds[i].y);
if (diamondPos && diamondPos.x === explorerPos.x && (diamondPos.y === explorerPos.y || diamondPos.y === explorerPos.y - 1) && !diamonds[i].isCollected) {
diamonds[i].collect();
spawnAdditionalItems();
break;
}
}
// Check treasure collision
if (cellType === 'T') {
for (var i = 0; i < treasures.length; i++) {
var treasurePos = getGridPosition(treasures[i].x, treasures[i].y);
if (treasurePos && treasurePos.x === explorerPos.x && (treasurePos.y === explorerPos.y || treasurePos.y === explorerPos.y - 1) && !treasures[i].isCollected) {
treasures[i].collect();
spawnAdditionalItems();
break;
}
}
}
// Check key collision
for (var i = 0; i < keys.length; i++) {
var keyPos = getGridPosition(keys[i].x, keys[i].y);
if (keyPos && keyPos.x === explorerPos.x && (keyPos.y === explorerPos.y || keyPos.y === explorerPos.y - 1) && !keys[i].isCollected) {
keys[i].collect();
spawnAdditionalItems();
break;
}
}
// Check obstacle collision
for (var i = 0; i < obstacles.length; i++) {
var obstaclePos = getGridPosition(obstacles[i].x, obstacles[i].y);
if (obstaclePos && obstaclePos.x === explorerPos.x && obstaclePos.y === explorerPos.y) {
// Play boom sound
LK.getSound('boom').play();
// Create a big blast effect
var blast = new Boom();
blast.x = explorer.x;
blast.y = explorer.y;
game.addChild(blast);
blast.explode();
// Show game over with score
LK.showGameOver("Game Over! Your score: " + LK.getScore());
break;
}
}
}
function moveExplorer(targetX, targetY) {
if (!explorer || explorer.isjumping) {
return;
}
var currentGridPos = getGridPosition(explorer.x, explorer.y);
var targetGridPos = getGridPosition(targetX, targetY);
if (!currentGridPos || !targetGridPos) {
return;
}
// Use pathfinding to find a path to the target
var path = findPath(currentGridPos, targetGridPos);
if (path && path.length > 0) {
var nextStep = path[0];
var cellCenterX = nextStep.x * tileSize + tileSize / 2;
var cellCenterY = nextStep.y * tileSize + tileSize / 2;
explorer.moveToward(cellCenterX, cellCenterY);
}
// Check if the explorer is at the diamond's position
if (levelGrid[currentGridPos.y][currentGridPos.x] === 'K') {
explorer.collectKey();
for (var i = 0; i < diamonds.length; i++) {
var diamondPos = getGridPosition(diamonds[i].x, diamonds[i].y);
if (diamondPos && diamondPos.x === currentGridPos.x && diamondPos.y === currentGridPos.y) {
diamonds[i].destroy();
diamonds.splice(i, 1);
levelGrid[currentGridPos.y][currentGridPos.x] = ' ';
LK.getSound('collect').play();
break;
}
}
}
}
function findPath(start, end) {
// Implement a simple pathfinding algorithm, e.g., A* or BFS
// This is a placeholder for the pathfinding logic
// Return an array of grid positions from start to end
return [];
}
// Handle touch/mouse events
function handleGameInput(x, y, obj) {
if (!gameStarted) {
return;
}
var direction = null;
var currentGridPos = getGridPosition(explorer.x, explorer.y);
var targetGridPos = getGridPosition(x, y);
if (targetGridPos) {
if (targetGridPos.x < currentGridPos.x) {
direction = 'left';
} else if (targetGridPos.x > currentGridPos.x) {
direction = 'right';
} else if (targetGridPos.y < currentGridPos.y) {
direction = 'up';
} else if (targetGridPos.y > currentGridPos.y) {
direction = 'down';
}
if (direction) {
if (direction === 'up' && targetGridPos.y < currentGridPos.y - 1) {
direction = 'fly';
}
// Set explorer's target position to the clicked position
explorer.moveToward(targetGridPos.x * tileSize + tileSize / 2, targetGridPos.y * tileSize + tileSize / 2);
}
// Check for left mouse button click to make the explorer jump
if (obj.event && obj.event.button === 0) {
// Left mouse button
if (!explorer.isMoving) {
var currentGridPos = getGridPosition(explorer.x, explorer.y);
var targetGridPos = {
x: currentGridPos.x,
y: currentGridPos.y - 2 // Jump up two tiles
};
if (isWalkable(targetGridPos.x, targetGridPos.y)) {
var cellCenterX = targetGridPos.x * tileSize + tileSize / 2;
var cellCenterY = targetGridPos.y * tileSize + tileSize / 2;
explorer.moveToward(cellCenterX, cellCenterY);
}
}
}
}
// Check for left mouse button click to make the explorer jump
if (obj.event && obj.event.button === 0) {
// Left mouse button
if (!explorer.isMoving) {
var currentGridPos = getGridPosition(explorer.x, explorer.y);
var targetGridPos = {
x: currentGridPos.x,
y: currentGridPos.y - 2 // Jump up two tiles
};
if (isWalkable(targetGridPos.x, targetGridPos.y)) {
var cellCenterX = targetGridPos.x * tileSize + tileSize / 2;
var cellCenterY = targetGridPos.y * tileSize + tileSize / 2;
explorer.moveToward(cellCenterX, cellCenterY);
}
}
}
}
// Start game when page loads
initializeGame();
// Handle touch/mouse events
game.down = handleGameInput;
// Game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Check for explorer inactivity
if (explorer) {
if (explorer.lastX === undefined) {
explorer.lastX = explorer.x;
}
if (explorer.lastY === undefined) {
explorer.lastY = explorer.y;
}
if (explorer.x === explorer.lastX && explorer.y === explorer.lastY) {
explorer.inactivityTime += 1 / 60; // Increment inactivity time in seconds
} else {
explorer.inactivityTime = 0; // Reset inactivity time if explorer moves
}
explorer.lastX = explorer.x;
explorer.lastY = explorer.y;
if (explorer.inactivityTime >= 60) {
// If inactivity time reaches 60 seconds
LK.showGameOver("Game Over! You were inactive for too long.");
return; // Ensure game loop stops after game over
}
}
// Update UI
updateUI();
// Check collisions
checkCollisions();
// Check for score milestones and trigger celebration
var currentScore = LK.getScore();
if (Math.floor(currentScore / 250) > Math.floor(lastCelebratedScore / 250)) {
lastCelebratedScore = currentScore;
// Play boom sound
LK.getSound('boom').play();
// Display congratulations message
var message = new Text2("Congratulations! You reached ".concat(currentScore, "!"), {
size: 100,
fill: 0xFFD700,
fontWeight: 'bold'
});
message.anchor.set(0.5, 0.5);
message.x = 2048 / 2;
message.y = 2732 / 2;
game.addChild(message);
// Remove message after 4 seconds
LK.setTimeout(function () {
message.destroy();
}, 4000);
// Trigger color paper blast effect in big size
var color = 0xFFD700; // Gold color
var paper = new Container();
var paperGraphics = paper.attachAsset('boom', {
anchorX: 0.5,
anchorY: 0.5
});
paperGraphics.tint = color;
paper.x = 2048 / 2;
paper.y = 2732 / 2;
game.addChild(paper);
tween(paperGraphics, {
scaleX: 20,
scaleY: 20,
alpha: 0
}, {
duration: 4000,
onFinish: function onFinish() {
paper.destroy();
}
});
}
};
small rock. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a magic crackers boom effect. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
create a glod color key. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows