/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentLevel: 1,
highestLevel: 1
});
/****
* Classes
****/
var Bridge = Container.expand(function (direction) {
var self = Container.call(this);
var bridgeGraphic = self.attachAsset('bridge', {
anchorX: 0.5,
anchorY: 0.5
});
if (direction === 'vertical') {
bridgeGraphic.rotation = Math.PI / 2;
}
// Bridge disappears after some time
self.lifespan = 5000; // 5 seconds
self.creationTime = Date.now();
self.update = function () {
var elapsedTime = Date.now() - self.creationTime;
var timeLeft = self.lifespan - elapsedTime;
if (timeLeft <= 0) {
self.destroy();
var index = bridges.indexOf(self);
if (index > -1) {
bridges.splice(index, 1);
}
} else if (timeLeft < 1000) {
// Fade out when almost gone
bridgeGraphic.alpha = timeLeft / 1000;
}
};
return self;
});
var LevelButton = Container.expand(function (levelNum, unlocked) {
var self = Container.call(this);
// Create button background
var bgColor = unlocked ? 0x3498db : 0x7f8c8d;
var bg = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 150
});
bg.tint = bgColor;
// Create level text
var levelText = new Text2(levelNum.toString(), {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
self.addChild(levelText);
self.levelNum = levelNum;
self.unlocked = unlocked;
// Interaction handlers
self.down = function (x, y, obj) {
if (self.unlocked) {
tween(bg, {
tint: 0x2980b9
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
if (self.unlocked) {
tween(bg, {
tint: bgColor
}, {
duration: 100
});
currentLevel = self.levelNum;
showGame();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphic = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.isInvincible = false;
self.hasBridge = false;
self.makeInvincible = function (duration) {
self.isInvincible = true;
// Visual feedback for invincibility
tween(playerGraphic, {
tint: 0xFFD700
}, {
duration: 300
});
LK.setTimeout(function () {
self.isInvincible = false;
tween(playerGraphic, {
tint: 0xFFFFFF
}, {
duration: 300
});
}, duration);
};
self.giveBridge = function () {
self.hasBridge = true;
// Visual feedback for bridge ability
tween(playerGraphic, {
tint: 0x9b59b6
}, {
duration: 300
});
};
self.useBridge = function () {
if (self.hasBridge) {
self.hasBridge = false;
tween(playerGraphic, {
tint: 0xFFFFFF
}, {
duration: 300
});
return true;
}
return false;
};
return self;
});
var PowerOrb = Container.expand(function (type) {
var self = Container.call(this);
var orbGraphic = self.attachAsset('powerOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type || 'invincibility'; // Default type is invincibility
// Visual differentiation based on type
if (self.type === 'bridge') {
orbGraphic.tint = 0x9b59b6; // Purple for bridge
} else {
orbGraphic.tint = 0xf1c40f; // Yellow for invincibility
}
// Floating animation
self.update = function () {
self.rotation += 0.01;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xecf0f1
});
/****
* Game Code
****/
// Game state variables
var currentLevel = storage.currentLevel || 1;
var highestLevel = storage.highestLevel || 1;
var gameActive = false;
var levelComplete = false;
var player = null;
var goal = null;
var walls = [];
var negativeZones = [];
var powerOrbs = [];
var bridges = [];
var dragNode = null;
var levelMenu = null;
var currentLevelText = null;
var totalLevels = 5;
var dragStartPos = {
x: 0,
y: 0
};
// Create level selection menu
function createLevelMenu() {
if (levelMenu) {
game.removeChild(levelMenu);
}
levelMenu = new Container();
game.addChild(levelMenu);
// Title
var titleText = new Text2("Positive Path", {
size: 120,
fill: 0x2C3E50
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 200;
levelMenu.addChild(titleText);
// Subtitle
var subtitleText = new Text2("Select a Level", {
size: 80,
fill: 0x7F8C8D
});
subtitleText.anchor.set(0.5, 0);
subtitleText.x = 2048 / 2;
subtitleText.y = 350;
levelMenu.addChild(subtitleText);
// Level buttons
var buttonsPerRow = 3;
var buttonSize = 200;
var spacing = 50;
var startX = (2048 - (buttonsPerRow * buttonSize + (buttonsPerRow - 1) * spacing)) / 2 + buttonSize / 2;
var startY = 500;
for (var i = 1; i <= totalLevels; i++) {
var row = Math.floor((i - 1) / buttonsPerRow);
var col = (i - 1) % buttonsPerRow;
var x = startX + col * (buttonSize + spacing);
var y = startY + row * (buttonSize + spacing);
var button = new LevelButton(i, i <= highestLevel);
button.x = x;
button.y = y;
levelMenu.addChild(button);
}
}
// Create level
function createLevel(levelNumber) {
clearLevel();
// Create player
player = new Player();
game.addChild(player);
// Create goal
goal = game.addChild(LK.getAsset('goal', {
anchorX: 0.5,
anchorY: 0.5
}));
// Setup level-specific layout
switch (levelNumber) {
case 1:
createLevel1();
break;
case 2:
createLevel2();
break;
case 3:
createLevel3();
break;
case 4:
createLevel4();
break;
case 5:
createLevel5();
break;
default:
createLevel1();
}
// Create level text
if (currentLevelText) {
LK.gui.topRight.removeChild(currentLevelText);
}
currentLevelText = new Text2("Level " + levelNumber, {
size: 60,
fill: 0x34495E
});
currentLevelText.anchor.set(1, 0);
currentLevelText.x = -50;
currentLevelText.y = 50;
LK.gui.topRight.addChild(currentLevelText);
gameActive = true;
}
function clearLevel() {
if (player) {
player.destroy();
player = null;
}
if (goal) {
goal.destroy();
goal = null;
}
// Clear walls
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
// Clear negative zones
for (var i = 0; i < negativeZones.length; i++) {
negativeZones[i].destroy();
}
negativeZones = [];
// Clear power orbs
for (var i = 0; i < powerOrbs.length; i++) {
powerOrbs[i].destroy();
}
powerOrbs = [];
// Clear bridges
for (var i = 0; i < bridges.length; i++) {
bridges[i].destroy();
}
bridges = [];
gameActive = false;
levelComplete = false;
}
function createWall(x, y, width, height) {
var wall = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: width / 100,
scaleY: height / 100
});
wall.x = x;
wall.y = y;
game.addChild(wall);
walls.push(wall);
return wall;
}
function createNegativeZone(x, y, width, height) {
var zone = LK.getAsset('negative', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: width / 100,
scaleY: height / 100
});
zone.x = x;
zone.y = y;
game.addChild(zone);
negativeZones.push(zone);
return zone;
}
function createPowerOrb(x, y, type) {
var orb = new PowerOrb(type);
orb.x = x;
orb.y = y;
game.addChild(orb);
powerOrbs.push(orb);
return orb;
}
function createBridge(x, y, direction) {
var bridge = new Bridge(direction);
bridge.x = x;
bridge.y = y;
game.addChild(bridge);
bridges.push(bridge);
return bridge;
}
// Level layouts
function createLevel1() {
// Tutorial level - simple path with one negative zone
player.x = 400;
player.y = 1366;
goal.x = 1648;
goal.y = 1366;
// Walls to create a path
createWall(1024, 1066, 1600, 100); // Top wall
createWall(1024, 1666, 1600, 100); // Bottom wall
// One negative zone to avoid
createNegativeZone(1024, 1366, 300, 300);
// Instructions
var instructionText = new Text2("Drag the blue ball to the green goal.\nAvoid the red areas!", {
size: 60,
fill: 0x34495E
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 1024;
instructionText.y = 800;
game.addChild(instructionText);
walls.push(instructionText); // Add to walls array to be cleared properly
}
function createLevel2() {
// More complex path with multiple negative zones
player.x = 300;
player.y = 500;
goal.x = 1748;
goal.y = 2200;
// Create maze walls
createWall(1024, 300, 1600, 100); // Top wall
createWall(1024, 2400, 1600, 100); // Bottom wall
createWall(300, 1350, 100, 2000); // Left wall
createWall(1748, 1350, 100, 2000); // Right wall
// Create inner walls
createWall(800, 800, 800, 100);
createWall(1300, 1200, 800, 100);
createWall(800, 1600, 800, 100);
createWall(1300, 2000, 800, 100);
// Create negative zones
createNegativeZone(800, 1200, 300, 300);
createNegativeZone(1300, 1600, 300, 300);
createNegativeZone(800, 2000, 300, 300);
// Add a power orb
createPowerOrb(1024, 600, 'invincibility');
}
function createLevel3() {
// Introduce bridge power-up
player.x = 300;
player.y = 400;
goal.x = 1748;
goal.y = 2300;
// Create outer walls
createWall(1024, 250, 1600, 100); // Top wall
createWall(1024, 2500, 1600, 100); // Bottom wall
createWall(250, 1375, 100, 2250); // Left wall
createWall(1798, 1375, 100, 2250); // Right wall
// Create gaps with negative zones
createNegativeZone(700, 800, 900, 200);
createNegativeZone(1350, 1400, 900, 200);
createNegativeZone(700, 2000, 900, 200);
// Add bridge power-up
createPowerOrb(1024, 600, 'bridge');
// Instructions
var instructionText = new Text2("Yellow orbs give you special powers.\nPurple orbs let you create bridges!", {
size: 50,
fill: 0x34495E
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 1024;
instructionText.y = 300;
game.addChild(instructionText);
walls.push(instructionText);
}
function createLevel4() {
// Complex level with both power-ups
player.x = 300;
player.y = 400;
goal.x = 1748;
goal.y = 2300;
// Create outer walls
createWall(1024, 250, 1600, 100); // Top wall
createWall(1024, 2500, 1600, 100); // Bottom wall
createWall(250, 1375, 100, 2250); // Left wall
createWall(1798, 1375, 100, 2250); // Right wall
// Create maze structure
createWall(700, 800, 100, 700);
createWall(1350, 800, 100, 700);
createWall(700, 1800, 100, 700);
createWall(1350, 1800, 100, 700);
// Create negative zones - forming a checkerboard pattern
createNegativeZone(500, 600, 200, 200);
createNegativeZone(900, 600, 200, 200);
createNegativeZone(1300, 600, 200, 200);
createNegativeZone(1700, 600, 200, 200);
createNegativeZone(700, 1000, 200, 200);
createNegativeZone(1100, 1000, 200, 200);
createNegativeZone(1500, 1000, 200, 200);
createNegativeZone(500, 1400, 200, 200);
createNegativeZone(900, 1400, 200, 200);
createNegativeZone(1300, 1400, 200, 200);
createNegativeZone(1700, 1400, 200, 200);
createNegativeZone(700, 1800, 200, 200);
createNegativeZone(1100, 1800, 200, 200);
createNegativeZone(1500, 1800, 200, 200);
createNegativeZone(500, 2200, 200, 200);
createNegativeZone(900, 2200, 200, 200);
createNegativeZone(1300, 2200, 200, 200);
createNegativeZone(1700, 2200, 200, 200);
// Add power-ups
createPowerOrb(500, 1000, 'invincibility');
createPowerOrb(1500, 1000, 'bridge');
createPowerOrb(1100, 1400, 'invincibility');
createPowerOrb(500, 1800, 'bridge');
}
function createLevel5() {
// Final challenge level
player.x = 1024;
player.y = 400;
goal.x = 1024;
goal.y = 2300;
// Create outer walls
createWall(1024, 250, 1600, 100); // Top wall
createWall(1024, 2500, 1600, 100); // Bottom wall
createWall(250, 1375, 100, 2250); // Left wall
createWall(1798, 1375, 100, 2250); // Right wall
// Create a spiral of negative zones
var center = {
x: 1024,
y: 1375
};
var spiralRadius = 800;
var spiralWidth = 150;
var angleStep = Math.PI / 8;
for (var angle = 0; angle < 4 * Math.PI; angle += angleStep) {
var radius = spiralRadius * (1 - angle / (4 * Math.PI));
var x = center.x + radius * Math.cos(angle);
var y = center.y + radius * Math.sin(angle);
createNegativeZone(x, y, spiralWidth, spiralWidth);
}
// Add power-ups strategically
createPowerOrb(1024, 600, 'invincibility');
createPowerOrb(600, 1000, 'bridge');
createPowerOrb(1450, 1800, 'invincibility');
createPowerOrb(800, 2100, 'bridge');
}
// Game mechanics
function checkCollisions() {
if (!gameActive || levelComplete) {
return;
}
// Check if player reached goal
if (player.intersects(goal)) {
levelComplete = true;
LK.getSound('win').play();
// Update highest level if needed
if (currentLevel >= highestLevel) {
highestLevel = currentLevel + 1;
if (highestLevel > totalLevels) {
highestLevel = totalLevels;
}
storage.highestLevel = highestLevel;
}
// Show completion message and proceed to next level
var completionText = new Text2("Level Complete!", {
size: 100,
fill: 0x2ECC71
});
completionText.anchor.set(0.5, 0.5);
completionText.x = 1024;
completionText.y = 1366;
game.addChild(completionText);
LK.setTimeout(function () {
completionText.destroy();
if (currentLevel < totalLevels) {
currentLevel++;
storage.currentLevel = currentLevel;
createLevel(currentLevel);
} else {
// Game completed
LK.showYouWin();
}
}, 2000);
return;
}
// Check collision with negative zones
for (var i = 0; i < negativeZones.length; i++) {
if (player.intersects(negativeZones[i]) && !player.isInvincible) {
gameActive = false;
LK.getSound('lose').play();
// Visual feedback
LK.effects.flashScreen(0xe74c3c, 1000);
// Restart level after a delay
LK.setTimeout(function () {
createLevel(currentLevel);
}, 1500);
return;
}
}
// Check collision with power orbs
for (var i = powerOrbs.length - 1; i >= 0; i--) {
if (player.intersects(powerOrbs[i])) {
// Apply power-up effect
if (powerOrbs[i].type === 'invincibility') {
player.makeInvincible(5000); // 5 seconds of invincibility
} else if (powerOrbs[i].type === 'bridge') {
player.giveBridge();
}
// Remove the orb
LK.getSound('collect').play();
powerOrbs[i].destroy();
powerOrbs.splice(i, 1);
}
}
// Check if player is trying to cross a wall
if (dragNode) {
for (var i = 0; i < walls.length; i++) {
if (player.intersects(walls[i])) {
// Move player back to valid position
player.x = dragStartPos.x;
player.y = dragStartPos.y;
return;
}
}
}
}
// Bridge placement
function placeBridge(x, y) {
if (!player.hasBridge) {
return false;
}
// Determine bridge direction based on player position
var direction = 'horizontal';
var minDistanceToWall = 9999;
var nearestWall = null;
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
var dx = Math.abs(wall.x - player.x);
var dy = Math.abs(wall.y - player.y);
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistanceToWall) {
minDistanceToWall = distance;
nearestWall = wall;
}
}
if (nearestWall) {
// Determine orientation based on nearest wall position
var dx = Math.abs(nearestWall.x - player.x);
var dy = Math.abs(nearestWall.y - player.y);
direction = dx > dy ? 'horizontal' : 'vertical';
}
// Place bridge slightly ahead of player in the direction of drag
var placeX = x;
var placeY = y;
createBridge(placeX, placeY, direction);
return player.useBridge();
}
// Game state management
function showMenu() {
clearLevel();
createLevelMenu();
gameActive = false;
}
function showGame() {
if (levelMenu) {
game.removeChild(levelMenu);
levelMenu = null;
}
createLevel(currentLevel);
// Play background music when starting the game
LK.playMusic('bgmusic', {
loop: true,
fade: {
start: 0,
end: 0.4,
duration: 1000
}
});
}
// Event handlers
game.down = function (x, y, obj) {
if (!gameActive) {
return;
}
if (player) {
// Check if we're clicking on player
var playerBounds = {
left: player.x - player.width / 2,
right: player.x + player.width / 2,
top: player.y - player.height / 2,
bottom: player.y + player.height / 2
};
if (x >= playerBounds.left && x <= playerBounds.right && y >= playerBounds.top && y <= playerBounds.bottom) {
dragNode = player;
dragStartPos = {
x: player.x,
y: player.y
};
} else if (player.hasBridge) {
// Try to place a bridge
placeBridge(x, y);
}
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.move = function (x, y, obj) {
if (dragNode && gameActive && !levelComplete) {
// Store the current position in case we need to revert
var oldX = dragNode.x;
var oldY = dragNode.y;
// Update position
dragNode.x = x;
dragNode.y = y;
// Check for wall collisions
for (var i = 0; i < walls.length; i++) {
if (dragNode.intersects(walls[i])) {
// Revert position
dragNode.x = oldX;
dragNode.y = oldY;
return;
}
}
// Check if we can cross with a bridge
for (var i = 0; i < bridges.length; i++) {
if (dragNode.intersects(bridges[i])) {
return; // We're on a bridge, allow movement
}
}
}
};
game.update = function () {
if (!gameActive) {
return;
}
// Update all objects with update methods
for (var i = 0; i < powerOrbs.length; i++) {
powerOrbs[i].update();
}
for (var i = 0; i < bridges.length; i++) {
bridges[i].update();
}
// Check for collisions
checkCollisions();
};
// Initialize the game
showMenu(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,689 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ currentLevel: 1,
+ highestLevel: 1
+});
+
+/****
+* Classes
+****/
+var Bridge = Container.expand(function (direction) {
+ var self = Container.call(this);
+ var bridgeGraphic = self.attachAsset('bridge', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ if (direction === 'vertical') {
+ bridgeGraphic.rotation = Math.PI / 2;
+ }
+ // Bridge disappears after some time
+ self.lifespan = 5000; // 5 seconds
+ self.creationTime = Date.now();
+ self.update = function () {
+ var elapsedTime = Date.now() - self.creationTime;
+ var timeLeft = self.lifespan - elapsedTime;
+ if (timeLeft <= 0) {
+ self.destroy();
+ var index = bridges.indexOf(self);
+ if (index > -1) {
+ bridges.splice(index, 1);
+ }
+ } else if (timeLeft < 1000) {
+ // Fade out when almost gone
+ bridgeGraphic.alpha = timeLeft / 1000;
+ }
+ };
+ return self;
+});
+var LevelButton = Container.expand(function (levelNum, unlocked) {
+ var self = Container.call(this);
+ // Create button background
+ var bgColor = unlocked ? 0x3498db : 0x7f8c8d;
+ var bg = self.attachAsset('wall', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 150,
+ height: 150
+ });
+ bg.tint = bgColor;
+ // Create level text
+ var levelText = new Text2(levelNum.toString(), {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ levelText.anchor.set(0.5, 0.5);
+ self.addChild(levelText);
+ self.levelNum = levelNum;
+ self.unlocked = unlocked;
+ // Interaction handlers
+ self.down = function (x, y, obj) {
+ if (self.unlocked) {
+ tween(bg, {
+ tint: 0x2980b9
+ }, {
+ duration: 100
+ });
+ }
+ };
+ self.up = function (x, y, obj) {
+ if (self.unlocked) {
+ tween(bg, {
+ tint: bgColor
+ }, {
+ duration: 100
+ });
+ currentLevel = self.levelNum;
+ showGame();
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerGraphic = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.isInvincible = false;
+ self.hasBridge = false;
+ self.makeInvincible = function (duration) {
+ self.isInvincible = true;
+ // Visual feedback for invincibility
+ tween(playerGraphic, {
+ tint: 0xFFD700
+ }, {
+ duration: 300
+ });
+ LK.setTimeout(function () {
+ self.isInvincible = false;
+ tween(playerGraphic, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 300
+ });
+ }, duration);
+ };
+ self.giveBridge = function () {
+ self.hasBridge = true;
+ // Visual feedback for bridge ability
+ tween(playerGraphic, {
+ tint: 0x9b59b6
+ }, {
+ duration: 300
+ });
+ };
+ self.useBridge = function () {
+ if (self.hasBridge) {
+ self.hasBridge = false;
+ tween(playerGraphic, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 300
+ });
+ return true;
+ }
+ return false;
+ };
+ return self;
+});
+var PowerOrb = Container.expand(function (type) {
+ var self = Container.call(this);
+ var orbGraphic = self.attachAsset('powerOrb', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = type || 'invincibility'; // Default type is invincibility
+ // Visual differentiation based on type
+ if (self.type === 'bridge') {
+ orbGraphic.tint = 0x9b59b6; // Purple for bridge
+ } else {
+ orbGraphic.tint = 0xf1c40f; // Yellow for invincibility
+ }
+ // Floating animation
+ self.update = function () {
+ self.rotation += 0.01;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xecf0f1
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var currentLevel = storage.currentLevel || 1;
+var highestLevel = storage.highestLevel || 1;
+var gameActive = false;
+var levelComplete = false;
+var player = null;
+var goal = null;
+var walls = [];
+var negativeZones = [];
+var powerOrbs = [];
+var bridges = [];
+var dragNode = null;
+var levelMenu = null;
+var currentLevelText = null;
+var totalLevels = 5;
+var dragStartPos = {
+ x: 0,
+ y: 0
+};
+// Create level selection menu
+function createLevelMenu() {
+ if (levelMenu) {
+ game.removeChild(levelMenu);
+ }
+ levelMenu = new Container();
+ game.addChild(levelMenu);
+ // Title
+ var titleText = new Text2("Positive Path", {
+ size: 120,
+ fill: 0x2C3E50
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.x = 2048 / 2;
+ titleText.y = 200;
+ levelMenu.addChild(titleText);
+ // Subtitle
+ var subtitleText = new Text2("Select a Level", {
+ size: 80,
+ fill: 0x7F8C8D
+ });
+ subtitleText.anchor.set(0.5, 0);
+ subtitleText.x = 2048 / 2;
+ subtitleText.y = 350;
+ levelMenu.addChild(subtitleText);
+ // Level buttons
+ var buttonsPerRow = 3;
+ var buttonSize = 200;
+ var spacing = 50;
+ var startX = (2048 - (buttonsPerRow * buttonSize + (buttonsPerRow - 1) * spacing)) / 2 + buttonSize / 2;
+ var startY = 500;
+ for (var i = 1; i <= totalLevels; i++) {
+ var row = Math.floor((i - 1) / buttonsPerRow);
+ var col = (i - 1) % buttonsPerRow;
+ var x = startX + col * (buttonSize + spacing);
+ var y = startY + row * (buttonSize + spacing);
+ var button = new LevelButton(i, i <= highestLevel);
+ button.x = x;
+ button.y = y;
+ levelMenu.addChild(button);
+ }
+}
+// Create level
+function createLevel(levelNumber) {
+ clearLevel();
+ // Create player
+ player = new Player();
+ game.addChild(player);
+ // Create goal
+ goal = game.addChild(LK.getAsset('goal', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ // Setup level-specific layout
+ switch (levelNumber) {
+ case 1:
+ createLevel1();
+ break;
+ case 2:
+ createLevel2();
+ break;
+ case 3:
+ createLevel3();
+ break;
+ case 4:
+ createLevel4();
+ break;
+ case 5:
+ createLevel5();
+ break;
+ default:
+ createLevel1();
+ }
+ // Create level text
+ if (currentLevelText) {
+ LK.gui.topRight.removeChild(currentLevelText);
+ }
+ currentLevelText = new Text2("Level " + levelNumber, {
+ size: 60,
+ fill: 0x34495E
+ });
+ currentLevelText.anchor.set(1, 0);
+ currentLevelText.x = -50;
+ currentLevelText.y = 50;
+ LK.gui.topRight.addChild(currentLevelText);
+ gameActive = true;
+}
+function clearLevel() {
+ if (player) {
+ player.destroy();
+ player = null;
+ }
+ if (goal) {
+ goal.destroy();
+ goal = null;
+ }
+ // Clear walls
+ for (var i = 0; i < walls.length; i++) {
+ walls[i].destroy();
+ }
+ walls = [];
+ // Clear negative zones
+ for (var i = 0; i < negativeZones.length; i++) {
+ negativeZones[i].destroy();
+ }
+ negativeZones = [];
+ // Clear power orbs
+ for (var i = 0; i < powerOrbs.length; i++) {
+ powerOrbs[i].destroy();
+ }
+ powerOrbs = [];
+ // Clear bridges
+ for (var i = 0; i < bridges.length; i++) {
+ bridges[i].destroy();
+ }
+ bridges = [];
+ gameActive = false;
+ levelComplete = false;
+}
+function createWall(x, y, width, height) {
+ var wall = LK.getAsset('wall', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: width / 100,
+ scaleY: height / 100
+ });
+ wall.x = x;
+ wall.y = y;
+ game.addChild(wall);
+ walls.push(wall);
+ return wall;
+}
+function createNegativeZone(x, y, width, height) {
+ var zone = LK.getAsset('negative', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: width / 100,
+ scaleY: height / 100
+ });
+ zone.x = x;
+ zone.y = y;
+ game.addChild(zone);
+ negativeZones.push(zone);
+ return zone;
+}
+function createPowerOrb(x, y, type) {
+ var orb = new PowerOrb(type);
+ orb.x = x;
+ orb.y = y;
+ game.addChild(orb);
+ powerOrbs.push(orb);
+ return orb;
+}
+function createBridge(x, y, direction) {
+ var bridge = new Bridge(direction);
+ bridge.x = x;
+ bridge.y = y;
+ game.addChild(bridge);
+ bridges.push(bridge);
+ return bridge;
+}
+// Level layouts
+function createLevel1() {
+ // Tutorial level - simple path with one negative zone
+ player.x = 400;
+ player.y = 1366;
+ goal.x = 1648;
+ goal.y = 1366;
+ // Walls to create a path
+ createWall(1024, 1066, 1600, 100); // Top wall
+ createWall(1024, 1666, 1600, 100); // Bottom wall
+ // One negative zone to avoid
+ createNegativeZone(1024, 1366, 300, 300);
+ // Instructions
+ var instructionText = new Text2("Drag the blue ball to the green goal.\nAvoid the red areas!", {
+ size: 60,
+ fill: 0x34495E
+ });
+ instructionText.anchor.set(0.5, 0);
+ instructionText.x = 1024;
+ instructionText.y = 800;
+ game.addChild(instructionText);
+ walls.push(instructionText); // Add to walls array to be cleared properly
+}
+function createLevel2() {
+ // More complex path with multiple negative zones
+ player.x = 300;
+ player.y = 500;
+ goal.x = 1748;
+ goal.y = 2200;
+ // Create maze walls
+ createWall(1024, 300, 1600, 100); // Top wall
+ createWall(1024, 2400, 1600, 100); // Bottom wall
+ createWall(300, 1350, 100, 2000); // Left wall
+ createWall(1748, 1350, 100, 2000); // Right wall
+ // Create inner walls
+ createWall(800, 800, 800, 100);
+ createWall(1300, 1200, 800, 100);
+ createWall(800, 1600, 800, 100);
+ createWall(1300, 2000, 800, 100);
+ // Create negative zones
+ createNegativeZone(800, 1200, 300, 300);
+ createNegativeZone(1300, 1600, 300, 300);
+ createNegativeZone(800, 2000, 300, 300);
+ // Add a power orb
+ createPowerOrb(1024, 600, 'invincibility');
+}
+function createLevel3() {
+ // Introduce bridge power-up
+ player.x = 300;
+ player.y = 400;
+ goal.x = 1748;
+ goal.y = 2300;
+ // Create outer walls
+ createWall(1024, 250, 1600, 100); // Top wall
+ createWall(1024, 2500, 1600, 100); // Bottom wall
+ createWall(250, 1375, 100, 2250); // Left wall
+ createWall(1798, 1375, 100, 2250); // Right wall
+ // Create gaps with negative zones
+ createNegativeZone(700, 800, 900, 200);
+ createNegativeZone(1350, 1400, 900, 200);
+ createNegativeZone(700, 2000, 900, 200);
+ // Add bridge power-up
+ createPowerOrb(1024, 600, 'bridge');
+ // Instructions
+ var instructionText = new Text2("Yellow orbs give you special powers.\nPurple orbs let you create bridges!", {
+ size: 50,
+ fill: 0x34495E
+ });
+ instructionText.anchor.set(0.5, 0);
+ instructionText.x = 1024;
+ instructionText.y = 300;
+ game.addChild(instructionText);
+ walls.push(instructionText);
+}
+function createLevel4() {
+ // Complex level with both power-ups
+ player.x = 300;
+ player.y = 400;
+ goal.x = 1748;
+ goal.y = 2300;
+ // Create outer walls
+ createWall(1024, 250, 1600, 100); // Top wall
+ createWall(1024, 2500, 1600, 100); // Bottom wall
+ createWall(250, 1375, 100, 2250); // Left wall
+ createWall(1798, 1375, 100, 2250); // Right wall
+ // Create maze structure
+ createWall(700, 800, 100, 700);
+ createWall(1350, 800, 100, 700);
+ createWall(700, 1800, 100, 700);
+ createWall(1350, 1800, 100, 700);
+ // Create negative zones - forming a checkerboard pattern
+ createNegativeZone(500, 600, 200, 200);
+ createNegativeZone(900, 600, 200, 200);
+ createNegativeZone(1300, 600, 200, 200);
+ createNegativeZone(1700, 600, 200, 200);
+ createNegativeZone(700, 1000, 200, 200);
+ createNegativeZone(1100, 1000, 200, 200);
+ createNegativeZone(1500, 1000, 200, 200);
+ createNegativeZone(500, 1400, 200, 200);
+ createNegativeZone(900, 1400, 200, 200);
+ createNegativeZone(1300, 1400, 200, 200);
+ createNegativeZone(1700, 1400, 200, 200);
+ createNegativeZone(700, 1800, 200, 200);
+ createNegativeZone(1100, 1800, 200, 200);
+ createNegativeZone(1500, 1800, 200, 200);
+ createNegativeZone(500, 2200, 200, 200);
+ createNegativeZone(900, 2200, 200, 200);
+ createNegativeZone(1300, 2200, 200, 200);
+ createNegativeZone(1700, 2200, 200, 200);
+ // Add power-ups
+ createPowerOrb(500, 1000, 'invincibility');
+ createPowerOrb(1500, 1000, 'bridge');
+ createPowerOrb(1100, 1400, 'invincibility');
+ createPowerOrb(500, 1800, 'bridge');
+}
+function createLevel5() {
+ // Final challenge level
+ player.x = 1024;
+ player.y = 400;
+ goal.x = 1024;
+ goal.y = 2300;
+ // Create outer walls
+ createWall(1024, 250, 1600, 100); // Top wall
+ createWall(1024, 2500, 1600, 100); // Bottom wall
+ createWall(250, 1375, 100, 2250); // Left wall
+ createWall(1798, 1375, 100, 2250); // Right wall
+ // Create a spiral of negative zones
+ var center = {
+ x: 1024,
+ y: 1375
+ };
+ var spiralRadius = 800;
+ var spiralWidth = 150;
+ var angleStep = Math.PI / 8;
+ for (var angle = 0; angle < 4 * Math.PI; angle += angleStep) {
+ var radius = spiralRadius * (1 - angle / (4 * Math.PI));
+ var x = center.x + radius * Math.cos(angle);
+ var y = center.y + radius * Math.sin(angle);
+ createNegativeZone(x, y, spiralWidth, spiralWidth);
+ }
+ // Add power-ups strategically
+ createPowerOrb(1024, 600, 'invincibility');
+ createPowerOrb(600, 1000, 'bridge');
+ createPowerOrb(1450, 1800, 'invincibility');
+ createPowerOrb(800, 2100, 'bridge');
+}
+// Game mechanics
+function checkCollisions() {
+ if (!gameActive || levelComplete) {
+ return;
+ }
+ // Check if player reached goal
+ if (player.intersects(goal)) {
+ levelComplete = true;
+ LK.getSound('win').play();
+ // Update highest level if needed
+ if (currentLevel >= highestLevel) {
+ highestLevel = currentLevel + 1;
+ if (highestLevel > totalLevels) {
+ highestLevel = totalLevels;
+ }
+ storage.highestLevel = highestLevel;
+ }
+ // Show completion message and proceed to next level
+ var completionText = new Text2("Level Complete!", {
+ size: 100,
+ fill: 0x2ECC71
+ });
+ completionText.anchor.set(0.5, 0.5);
+ completionText.x = 1024;
+ completionText.y = 1366;
+ game.addChild(completionText);
+ LK.setTimeout(function () {
+ completionText.destroy();
+ if (currentLevel < totalLevels) {
+ currentLevel++;
+ storage.currentLevel = currentLevel;
+ createLevel(currentLevel);
+ } else {
+ // Game completed
+ LK.showYouWin();
+ }
+ }, 2000);
+ return;
+ }
+ // Check collision with negative zones
+ for (var i = 0; i < negativeZones.length; i++) {
+ if (player.intersects(negativeZones[i]) && !player.isInvincible) {
+ gameActive = false;
+ LK.getSound('lose').play();
+ // Visual feedback
+ LK.effects.flashScreen(0xe74c3c, 1000);
+ // Restart level after a delay
+ LK.setTimeout(function () {
+ createLevel(currentLevel);
+ }, 1500);
+ return;
+ }
+ }
+ // Check collision with power orbs
+ for (var i = powerOrbs.length - 1; i >= 0; i--) {
+ if (player.intersects(powerOrbs[i])) {
+ // Apply power-up effect
+ if (powerOrbs[i].type === 'invincibility') {
+ player.makeInvincible(5000); // 5 seconds of invincibility
+ } else if (powerOrbs[i].type === 'bridge') {
+ player.giveBridge();
+ }
+ // Remove the orb
+ LK.getSound('collect').play();
+ powerOrbs[i].destroy();
+ powerOrbs.splice(i, 1);
+ }
+ }
+ // Check if player is trying to cross a wall
+ if (dragNode) {
+ for (var i = 0; i < walls.length; i++) {
+ if (player.intersects(walls[i])) {
+ // Move player back to valid position
+ player.x = dragStartPos.x;
+ player.y = dragStartPos.y;
+ return;
+ }
+ }
+ }
+}
+// Bridge placement
+function placeBridge(x, y) {
+ if (!player.hasBridge) {
+ return false;
+ }
+ // Determine bridge direction based on player position
+ var direction = 'horizontal';
+ var minDistanceToWall = 9999;
+ var nearestWall = null;
+ for (var i = 0; i < walls.length; i++) {
+ var wall = walls[i];
+ var dx = Math.abs(wall.x - player.x);
+ var dy = Math.abs(wall.y - player.y);
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < minDistanceToWall) {
+ minDistanceToWall = distance;
+ nearestWall = wall;
+ }
+ }
+ if (nearestWall) {
+ // Determine orientation based on nearest wall position
+ var dx = Math.abs(nearestWall.x - player.x);
+ var dy = Math.abs(nearestWall.y - player.y);
+ direction = dx > dy ? 'horizontal' : 'vertical';
+ }
+ // Place bridge slightly ahead of player in the direction of drag
+ var placeX = x;
+ var placeY = y;
+ createBridge(placeX, placeY, direction);
+ return player.useBridge();
+}
+// Game state management
+function showMenu() {
+ clearLevel();
+ createLevelMenu();
+ gameActive = false;
+}
+function showGame() {
+ if (levelMenu) {
+ game.removeChild(levelMenu);
+ levelMenu = null;
+ }
+ createLevel(currentLevel);
+ // Play background music when starting the game
+ LK.playMusic('bgmusic', {
+ loop: true,
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
+ });
+}
+// Event handlers
+game.down = function (x, y, obj) {
+ if (!gameActive) {
+ return;
+ }
+ if (player) {
+ // Check if we're clicking on player
+ var playerBounds = {
+ left: player.x - player.width / 2,
+ right: player.x + player.width / 2,
+ top: player.y - player.height / 2,
+ bottom: player.y + player.height / 2
+ };
+ if (x >= playerBounds.left && x <= playerBounds.right && y >= playerBounds.top && y <= playerBounds.bottom) {
+ dragNode = player;
+ dragStartPos = {
+ x: player.x,
+ y: player.y
+ };
+ } else if (player.hasBridge) {
+ // Try to place a bridge
+ placeBridge(x, y);
+ }
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+game.move = function (x, y, obj) {
+ if (dragNode && gameActive && !levelComplete) {
+ // Store the current position in case we need to revert
+ var oldX = dragNode.x;
+ var oldY = dragNode.y;
+ // Update position
+ dragNode.x = x;
+ dragNode.y = y;
+ // Check for wall collisions
+ for (var i = 0; i < walls.length; i++) {
+ if (dragNode.intersects(walls[i])) {
+ // Revert position
+ dragNode.x = oldX;
+ dragNode.y = oldY;
+ return;
+ }
+ }
+ // Check if we can cross with a bridge
+ for (var i = 0; i < bridges.length; i++) {
+ if (dragNode.intersects(bridges[i])) {
+ return; // We're on a bridge, allow movement
+ }
+ }
+ }
+};
+game.update = function () {
+ if (!gameActive) {
+ return;
+ }
+ // Update all objects with update methods
+ for (var i = 0; i < powerOrbs.length; i++) {
+ powerOrbs[i].update();
+ }
+ for (var i = 0; i < bridges.length; i++) {
+ bridges[i].update();
+ }
+ // Check for collisions
+ checkCollisions();
+};
+// Initialize the game
+showMenu();
\ No newline at end of file