/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Collectible = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'button';
var collectibleGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.update = function () {
// Simple animation
collectibleGraphics.rotation += 0.02;
// Floating effect
collectibleGraphics.y = Math.sin(LK.ticks * 0.05) * 5;
};
self.collect = function () {
if (self.collected) {
return;
}
self.collected = true;
LK.getSound('collect').play();
// Collect animation
tween(collectibleGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self.type;
};
return self;
});
var Hazard = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'scissors';
var hazardGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
self.moving = false;
self.moveSpeed = 0;
self.moveDirection = 1;
self.moveDistance = 0;
self.startX = 0;
self.setMoving = function (speed, distance) {
self.moving = true;
self.moveSpeed = speed;
self.moveDistance = distance;
self.startX = self.x;
};
self.update = function () {
if (self.moving) {
self.x += self.moveSpeed * self.moveDirection;
if (Math.abs(self.x - self.startX) > self.moveDistance) {
self.moveDirection *= -1;
}
}
// Animation
if (self.type === 'scissors') {
hazardGraphics.rotation = Math.sin(LK.ticks * 0.05) * 0.2;
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platformGraphics.width;
self.height = platformGraphics.height;
self.moving = false;
self.moveSpeed = 0;
self.moveDirection = 1;
self.moveDistance = 0;
self.startX = 0;
self.setMoving = function (speed, distance) {
self.moving = true;
self.moveSpeed = speed;
self.moveDistance = distance;
self.startX = self.x;
};
self.update = function () {
if (self.moving) {
self.x += self.moveSpeed * self.moveDirection;
if (Math.abs(self.x - self.startX) > self.moveDistance) {
self.moveDirection *= -1;
}
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'random';
self.collected = false;
// Choose a random power-up type
var types = ['fly', 'big', 'invincible'];
self.powerType = types[Math.floor(Math.random() * types.length)];
// Set color based on type
if (self.powerType === 'fly') {
powerupGraphics.tint = 0x88CCFF;
} else if (self.powerType === 'big') {
powerupGraphics.tint = 0xFF8866;
} else if (self.powerType === 'invincible') {
powerupGraphics.tint = 0xFFDD44;
}
self.update = function () {
// Floating and rotation animation
powerupGraphics.rotation += 0.03;
powerupGraphics.y = Math.sin(LK.ticks * 0.1) * 8;
};
self.collect = function () {
if (self.collected) {
return null;
}
self.collected = true;
// Collect animation
tween(powerupGraphics, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self.powerType;
};
return self;
});
var Sackboy = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('sackboy', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xDDAA66
});
// Physics properties
self.velocity = {
x: 0,
y: 0
};
self.gravity = 0.5;
self.bounce = 0.8;
self.grounded = false;
self.alive = true;
self.powered = false;
self.powerType = null;
self.powerTime = 0;
// Apply physics
self.update = function () {
if (!self.alive) {
return;
}
// Apply gravity
self.velocity.y += self.gravity;
// Apply velocity
self.x += self.velocity.x;
self.y += self.velocity.y;
// Handle power-ups
if (self.powered) {
self.powerTime--;
// Power-up effects
if (self.powerType === 'fly') {
self.velocity.y = Math.min(self.velocity.y, 1);
} else if (self.powerType === 'big') {
// Already scaled in activatePower
} else if (self.powerType === 'invincible') {
// Visual pulsing effect
body.alpha = 0.5 + Math.sin(LK.ticks * 0.2) * 0.5;
}
// End power-up
if (self.powerTime <= 0) {
self.deactivatePower();
}
}
// Screen boundaries
if (self.x < 50) {
self.x = 50;
self.velocity.x *= -0.5;
} else if (self.x > 2048 - 50) {
self.x = 2048 - 50;
self.velocity.x *= -0.5;
}
// Bottom boundary - game over
if (self.y > 2732 + 100) {
self.die();
}
// Simple animation
body.rotation += self.velocity.x * 0.01;
};
self.bounce = function (power) {
self.velocity.y = -power;
self.grounded = false;
LK.getSound('bounce').play();
};
self.activatePower = function (type) {
self.powered = true;
self.powerType = type;
self.powerTime = 300; // 5 seconds at 60fps
if (type === 'big') {
tween(body, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeOut
});
} else if (type === 'invincible') {
body.tint = 0xFFDD44;
} else if (type === 'fly') {
body.tint = 0x88CCFF;
}
LK.getSound('powerup').play();
};
self.deactivatePower = function () {
self.powered = false;
// Reset visual effects
if (self.powerType === 'big') {
tween(body, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
} else if (self.powerType === 'invincible' || self.powerType === 'fly') {
body.tint = 0xDDAA66;
body.alpha = 1;
}
self.powerType = null;
};
self.die = function () {
if (!self.alive) {
return;
}
self.alive = false;
LK.getSound('hurt').play();
// Visual effect for death
tween(body, {
alpha: 0,
rotation: Math.PI * 4,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.showGameOver();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x88BBCC
});
/****
* Game Code
****/
// Game variables
var sackboy;
var platforms = [];
var collectibles = [];
var hazards = [];
var powerups = [];
var score = 0;
var level = 1;
var maxLevel = 3;
var touchStart = {
x: 0,
y: 0
};
var touchDragging = false;
// UI elements
var scoreTxt;
var levelTxt;
var instructionsTxt;
function initGame() {
// Reset game state
platforms = [];
collectibles = [];
hazards = [];
powerups = [];
score = 0;
// Get saved level or start at level 1
level = storage.level || 1;
if (level > maxLevel) {
level = 1;
}
// Set up UI
setupUI();
// Create Sackboy
sackboy = new Sackboy();
sackboy.x = 1024;
sackboy.y = 2000;
game.addChild(sackboy);
// Create level based on current level
createLevel(level);
// Play background music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 0.6,
duration: 1000
}
});
}
function setupUI() {
// Score text
scoreTxt = new Text2('Buttons: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
// Level text
levelTxt = new Text2('Level ' + level, {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(levelTxt);
// Instructions
instructionsTxt = new Text2('Tilt to move Sackboy\nCollect buttons & bounce higher!', {
size: 60,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(instructionsTxt);
// Hide instructions after 3 seconds
LK.setTimeout(function () {
tween(instructionsTxt, {
alpha: 0
}, {
duration: 1000
});
}, 3000);
}
function createLevel(levelNum) {
// Position platforms and collectibles based on level
if (levelNum === 1) {
// Level 1: Simple introduction level
createPlatform(1024, 2200);
createPlatform(600, 1900);
createPlatform(1450, 1900);
createPlatform(1024, 1600);
createPlatform(600, 1300);
createPlatform(1450, 1300);
createPlatform(1024, 1000);
createPlatform(600, 700);
createPlatform(1450, 700);
// Add collectibles
createCollectible('button', 600, 1800);
createCollectible('button', 1450, 1800);
createCollectible('button', 1024, 1500);
createCollectible('yarn', 600, 1200);
createCollectible('button', 1450, 1200);
createCollectible('yarn', 1024, 900);
// Add power-up
createPowerUp(1024, 600);
} else if (levelNum === 2) {
// Level 2: Add some moving platforms and hazards
createPlatform(1024, 2200);
var movingPlatform1 = createPlatform(600, 1900);
movingPlatform1.setMoving(2, 300);
createPlatform(1450, 1900);
createPlatform(1024, 1600);
// Add hazards
createHazard('scissors', 1024, 1500);
var movingPlatform2 = createPlatform(600, 1300);
movingPlatform2.setMoving(3, 400);
createPlatform(1450, 1300);
createPlatform(1024, 1000);
createHazard('thread', 600, 900);
createPlatform(1450, 700);
// Add collectibles
createCollectible('button', 600, 1800);
createCollectible('button', 1450, 1800);
createCollectible('yarn', 800, 1500);
createCollectible('button', 1250, 1500);
createCollectible('button', 600, 1200);
createCollectible('yarn', 1450, 1200);
createCollectible('yarn', 1024, 900);
createCollectible('button', 1450, 600);
// Add power-ups
createPowerUp(800, 600);
} else if (levelNum === 3) {
// Level 3: Most challenging level
createPlatform(1024, 2200);
var movingPlatform1 = createPlatform(600, 1900);
movingPlatform1.setMoving(3, 400);
var movingPlatform2 = createPlatform(1450, 1800);
movingPlatform2.setMoving(4, 300);
createPlatform(1024, 1600);
// Add hazards
createHazard('scissors', 800, 1500);
createHazard('scissors', 1250, 1500);
var movingHazard = createHazard('thread', 1024, 1400);
movingHazard.setMoving(5, 500);
var movingPlatform3 = createPlatform(600, 1300);
movingPlatform3.setMoving(3, 350);
var movingPlatform4 = createPlatform(1450, 1200);
movingPlatform4.setMoving(4, 400);
createPlatform(1024, 1000);
createHazard('thread', 600, 900);
createHazard('scissors', 1450, 900);
createPlatform(800, 700);
createPlatform(1250, 600);
// Add collectibles
createCollectible('button', 600, 1800);
createCollectible('yarn', 1450, 1700);
createCollectible('button', 800, 1500);
createCollectible('button', 1250, 1500);
createCollectible('yarn', 600, 1200);
createCollectible('button', 1450, 1100);
createCollectible('yarn', 1024, 900);
createCollectible('button', 800, 600);
createCollectible('yarn', 1250, 500);
// Add power-ups
createPowerUp(600, 800);
createPowerUp(1450, 800);
}
}
function createPlatform(x, y) {
var platform = new Platform();
platform.x = x;
platform.y = y;
game.addChild(platform);
platforms.push(platform);
return platform;
}
function createCollectible(type, x, y) {
var collectible = new Collectible(type);
collectible.x = x;
collectible.y = y;
game.addChild(collectible);
collectibles.push(collectible);
return collectible;
}
function createHazard(type, x, y) {
var hazard = new Hazard(type);
hazard.x = x;
hazard.y = y;
game.addChild(hazard);
hazards.push(hazard);
return hazard;
}
function createPowerUp(x, y) {
var powerup = new PowerUp();
powerup.x = x;
powerup.y = y;
game.addChild(powerup);
powerups.push(powerup);
return powerup;
}
function updateScore(points) {
score += points;
scoreTxt.setText('Buttons: ' + score);
// Check win condition
if (score >= 10) {
completeLevel();
}
}
function completeLevel() {
// Save progress
level++;
storage.level = level;
if (level > maxLevel) {
// Player completed all levels
LK.showYouWin();
} else {
// Show level complete message
var levelCompleteTxt = new Text2('Level Complete!', {
size: 120,
fill: 0xFFFFFF
});
levelCompleteTxt.anchor.set(0.5, 0.5);
levelCompleteTxt.x = 1024;
levelCompleteTxt.y = 1366;
game.addChild(levelCompleteTxt);
// Fade out and load next level
LK.setTimeout(function () {
tween(levelCompleteTxt, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
levelCompleteTxt.destroy();
initGame();
}
});
}, 2000);
}
}
function checkCollisions() {
if (!sackboy.alive) {
return;
}
// Check platform collisions
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Only bounce when falling
if (sackboy.velocity.y > 0 && sackboy.intersects(platform)) {
// Check if Sackboy is above the platform
if (sackboy.y < platform.y - platform.height / 2) {
sackboy.y = platform.y - platform.height / 2 - sackboy.height / 2;
sackboy.bounce(15);
}
}
}
// Check collectible collisions
for (var j = collectibles.length - 1; j >= 0; j--) {
var collectible = collectibles[j];
if (sackboy.intersects(collectible) && !collectible.collected) {
var type = collectible.collect();
if (type === 'button') {
updateScore(1);
} else if (type === 'yarn') {
// Yarn gives extra bounce
sackboy.bounce(25);
}
collectibles.splice(j, 1);
}
}
// Check hazard collisions
for (var k = 0; k < hazards.length; k++) {
var hazard = hazards[k];
if (sackboy.intersects(hazard)) {
// Check if invincible
if (sackboy.powered && sackboy.powerType === 'invincible') {
// Invincible - ignore hazard
continue;
}
sackboy.die();
break;
}
}
// Check power-up collisions
for (var l = powerups.length - 1; l >= 0; l--) {
var powerup = powerups[l];
if (sackboy.intersects(powerup) && !powerup.collected) {
var powerType = powerup.collect();
if (powerType) {
sackboy.activatePower(powerType);
}
powerups.splice(l, 1);
}
}
}
// Game control touch handlers
game.down = function (x, y, obj) {
touchStart.x = x;
touchStart.y = y;
touchDragging = true;
};
game.move = function (x, y, obj) {
if (touchDragging && sackboy && sackboy.alive) {
// Calculate drag amount
var dragX = x - touchStart.x;
// Apply horizontal velocity based on drag
sackboy.velocity.x = dragX * 0.1;
// Update touch position
touchStart.x = x;
touchStart.y = y;
}
};
game.up = function (x, y, obj) {
touchDragging = false;
// Gradually slow down horizontal velocity
if (sackboy && sackboy.alive) {
sackboy.velocity.x *= 0.5;
}
};
// Main game update loop
game.update = function () {
// Check collisions
checkCollisions();
// Update all game objects
for (var i = 0; i < platforms.length; i++) {
platforms[i].update();
}
for (var j = 0; j < collectibles.length; j++) {
collectibles[j].update();
}
for (var k = 0; k < hazards.length; k++) {
hazards[k].update();
}
for (var l = 0; l < powerups.length; l++) {
powerups[l].update();
}
// Automatically slow down horizontal velocity
if (sackboy && sackboy.alive) {
sackboy.velocity.x *= 0.98;
}
};
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,624 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Collectible = Container.expand(function (type) {
+ var self = Container.call(this);
+ self.type = type || 'button';
+ var collectibleGraphics = self.attachAsset(self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.collected = false;
+ self.update = function () {
+ // Simple animation
+ collectibleGraphics.rotation += 0.02;
+ // Floating effect
+ collectibleGraphics.y = Math.sin(LK.ticks * 0.05) * 5;
+ };
+ self.collect = function () {
+ if (self.collected) {
+ return;
+ }
+ self.collected = true;
+ LK.getSound('collect').play();
+ // Collect animation
+ tween(collectibleGraphics, {
+ alpha: 0,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ return self.type;
+ };
+ return self;
+});
+var Hazard = Container.expand(function (type) {
+ var self = Container.call(this);
+ self.type = type || 'scissors';
+ var hazardGraphics = self.attachAsset(self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.moving = false;
+ self.moveSpeed = 0;
+ self.moveDirection = 1;
+ self.moveDistance = 0;
+ self.startX = 0;
+ self.setMoving = function (speed, distance) {
+ self.moving = true;
+ self.moveSpeed = speed;
+ self.moveDistance = distance;
+ self.startX = self.x;
+ };
+ self.update = function () {
+ if (self.moving) {
+ self.x += self.moveSpeed * self.moveDirection;
+ if (Math.abs(self.x - self.startX) > self.moveDistance) {
+ self.moveDirection *= -1;
+ }
+ }
+ // Animation
+ if (self.type === 'scissors') {
+ hazardGraphics.rotation = Math.sin(LK.ticks * 0.05) * 0.2;
+ }
+ };
+ return self;
+});
+var Platform = Container.expand(function () {
+ var self = Container.call(this);
+ var platformGraphics = self.attachAsset('platform', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = platformGraphics.width;
+ self.height = platformGraphics.height;
+ self.moving = false;
+ self.moveSpeed = 0;
+ self.moveDirection = 1;
+ self.moveDistance = 0;
+ self.startX = 0;
+ self.setMoving = function (speed, distance) {
+ self.moving = true;
+ self.moveSpeed = speed;
+ self.moveDistance = distance;
+ self.startX = self.x;
+ };
+ self.update = function () {
+ if (self.moving) {
+ self.x += self.moveSpeed * self.moveDirection;
+ if (Math.abs(self.x - self.startX) > self.moveDistance) {
+ self.moveDirection *= -1;
+ }
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerupGraphics = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = 'random';
+ self.collected = false;
+ // Choose a random power-up type
+ var types = ['fly', 'big', 'invincible'];
+ self.powerType = types[Math.floor(Math.random() * types.length)];
+ // Set color based on type
+ if (self.powerType === 'fly') {
+ powerupGraphics.tint = 0x88CCFF;
+ } else if (self.powerType === 'big') {
+ powerupGraphics.tint = 0xFF8866;
+ } else if (self.powerType === 'invincible') {
+ powerupGraphics.tint = 0xFFDD44;
+ }
+ self.update = function () {
+ // Floating and rotation animation
+ powerupGraphics.rotation += 0.03;
+ powerupGraphics.y = Math.sin(LK.ticks * 0.1) * 8;
+ };
+ self.collect = function () {
+ if (self.collected) {
+ return null;
+ }
+ self.collected = true;
+ // Collect animation
+ tween(powerupGraphics, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ return self.powerType;
+ };
+ return self;
+});
+var Sackboy = Container.expand(function () {
+ var self = Container.call(this);
+ var body = self.attachAsset('sackboy', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0xDDAA66
+ });
+ // Physics properties
+ self.velocity = {
+ x: 0,
+ y: 0
+ };
+ self.gravity = 0.5;
+ self.bounce = 0.8;
+ self.grounded = false;
+ self.alive = true;
+ self.powered = false;
+ self.powerType = null;
+ self.powerTime = 0;
+ // Apply physics
+ self.update = function () {
+ if (!self.alive) {
+ return;
+ }
+ // Apply gravity
+ self.velocity.y += self.gravity;
+ // Apply velocity
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ // Handle power-ups
+ if (self.powered) {
+ self.powerTime--;
+ // Power-up effects
+ if (self.powerType === 'fly') {
+ self.velocity.y = Math.min(self.velocity.y, 1);
+ } else if (self.powerType === 'big') {
+ // Already scaled in activatePower
+ } else if (self.powerType === 'invincible') {
+ // Visual pulsing effect
+ body.alpha = 0.5 + Math.sin(LK.ticks * 0.2) * 0.5;
+ }
+ // End power-up
+ if (self.powerTime <= 0) {
+ self.deactivatePower();
+ }
+ }
+ // Screen boundaries
+ if (self.x < 50) {
+ self.x = 50;
+ self.velocity.x *= -0.5;
+ } else if (self.x > 2048 - 50) {
+ self.x = 2048 - 50;
+ self.velocity.x *= -0.5;
+ }
+ // Bottom boundary - game over
+ if (self.y > 2732 + 100) {
+ self.die();
+ }
+ // Simple animation
+ body.rotation += self.velocity.x * 0.01;
+ };
+ self.bounce = function (power) {
+ self.velocity.y = -power;
+ self.grounded = false;
+ LK.getSound('bounce').play();
+ };
+ self.activatePower = function (type) {
+ self.powered = true;
+ self.powerType = type;
+ self.powerTime = 300; // 5 seconds at 60fps
+ if (type === 'big') {
+ tween(body, {
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ } else if (type === 'invincible') {
+ body.tint = 0xFFDD44;
+ } else if (type === 'fly') {
+ body.tint = 0x88CCFF;
+ }
+ LK.getSound('powerup').play();
+ };
+ self.deactivatePower = function () {
+ self.powered = false;
+ // Reset visual effects
+ if (self.powerType === 'big') {
+ tween(body, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ } else if (self.powerType === 'invincible' || self.powerType === 'fly') {
+ body.tint = 0xDDAA66;
+ body.alpha = 1;
+ }
+ self.powerType = null;
+ };
+ self.die = function () {
+ if (!self.alive) {
+ return;
+ }
+ self.alive = false;
+ LK.getSound('hurt').play();
+ // Visual effect for death
+ tween(body, {
+ alpha: 0,
+ rotation: Math.PI * 4,
+ scaleX: 0.1,
+ scaleY: 0.1
+ }, {
+ duration: 1000,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ LK.showGameOver();
+ }
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x88BBCC
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var sackboy;
+var platforms = [];
+var collectibles = [];
+var hazards = [];
+var powerups = [];
+var score = 0;
+var level = 1;
+var maxLevel = 3;
+var touchStart = {
+ x: 0,
+ y: 0
+};
+var touchDragging = false;
+// UI elements
+var scoreTxt;
+var levelTxt;
+var instructionsTxt;
+function initGame() {
+ // Reset game state
+ platforms = [];
+ collectibles = [];
+ hazards = [];
+ powerups = [];
+ score = 0;
+ // Get saved level or start at level 1
+ level = storage.level || 1;
+ if (level > maxLevel) {
+ level = 1;
+ }
+ // Set up UI
+ setupUI();
+ // Create Sackboy
+ sackboy = new Sackboy();
+ sackboy.x = 1024;
+ sackboy.y = 2000;
+ game.addChild(sackboy);
+ // Create level based on current level
+ createLevel(level);
+ // Play background music
+ LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 0.6,
+ duration: 1000
+ }
+ });
+}
+function setupUI() {
+ // Score text
+ scoreTxt = new Text2('Buttons: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ // Level text
+ levelTxt = new Text2('Level ' + level, {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(1, 0);
+ LK.gui.topRight.addChild(levelTxt);
+ // Instructions
+ instructionsTxt = new Text2('Tilt to move Sackboy\nCollect buttons & bounce higher!', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ instructionsTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(instructionsTxt);
+ // Hide instructions after 3 seconds
+ LK.setTimeout(function () {
+ tween(instructionsTxt, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 3000);
+}
+function createLevel(levelNum) {
+ // Position platforms and collectibles based on level
+ if (levelNum === 1) {
+ // Level 1: Simple introduction level
+ createPlatform(1024, 2200);
+ createPlatform(600, 1900);
+ createPlatform(1450, 1900);
+ createPlatform(1024, 1600);
+ createPlatform(600, 1300);
+ createPlatform(1450, 1300);
+ createPlatform(1024, 1000);
+ createPlatform(600, 700);
+ createPlatform(1450, 700);
+ // Add collectibles
+ createCollectible('button', 600, 1800);
+ createCollectible('button', 1450, 1800);
+ createCollectible('button', 1024, 1500);
+ createCollectible('yarn', 600, 1200);
+ createCollectible('button', 1450, 1200);
+ createCollectible('yarn', 1024, 900);
+ // Add power-up
+ createPowerUp(1024, 600);
+ } else if (levelNum === 2) {
+ // Level 2: Add some moving platforms and hazards
+ createPlatform(1024, 2200);
+ var movingPlatform1 = createPlatform(600, 1900);
+ movingPlatform1.setMoving(2, 300);
+ createPlatform(1450, 1900);
+ createPlatform(1024, 1600);
+ // Add hazards
+ createHazard('scissors', 1024, 1500);
+ var movingPlatform2 = createPlatform(600, 1300);
+ movingPlatform2.setMoving(3, 400);
+ createPlatform(1450, 1300);
+ createPlatform(1024, 1000);
+ createHazard('thread', 600, 900);
+ createPlatform(1450, 700);
+ // Add collectibles
+ createCollectible('button', 600, 1800);
+ createCollectible('button', 1450, 1800);
+ createCollectible('yarn', 800, 1500);
+ createCollectible('button', 1250, 1500);
+ createCollectible('button', 600, 1200);
+ createCollectible('yarn', 1450, 1200);
+ createCollectible('yarn', 1024, 900);
+ createCollectible('button', 1450, 600);
+ // Add power-ups
+ createPowerUp(800, 600);
+ } else if (levelNum === 3) {
+ // Level 3: Most challenging level
+ createPlatform(1024, 2200);
+ var movingPlatform1 = createPlatform(600, 1900);
+ movingPlatform1.setMoving(3, 400);
+ var movingPlatform2 = createPlatform(1450, 1800);
+ movingPlatform2.setMoving(4, 300);
+ createPlatform(1024, 1600);
+ // Add hazards
+ createHazard('scissors', 800, 1500);
+ createHazard('scissors', 1250, 1500);
+ var movingHazard = createHazard('thread', 1024, 1400);
+ movingHazard.setMoving(5, 500);
+ var movingPlatform3 = createPlatform(600, 1300);
+ movingPlatform3.setMoving(3, 350);
+ var movingPlatform4 = createPlatform(1450, 1200);
+ movingPlatform4.setMoving(4, 400);
+ createPlatform(1024, 1000);
+ createHazard('thread', 600, 900);
+ createHazard('scissors', 1450, 900);
+ createPlatform(800, 700);
+ createPlatform(1250, 600);
+ // Add collectibles
+ createCollectible('button', 600, 1800);
+ createCollectible('yarn', 1450, 1700);
+ createCollectible('button', 800, 1500);
+ createCollectible('button', 1250, 1500);
+ createCollectible('yarn', 600, 1200);
+ createCollectible('button', 1450, 1100);
+ createCollectible('yarn', 1024, 900);
+ createCollectible('button', 800, 600);
+ createCollectible('yarn', 1250, 500);
+ // Add power-ups
+ createPowerUp(600, 800);
+ createPowerUp(1450, 800);
+ }
+}
+function createPlatform(x, y) {
+ var platform = new Platform();
+ platform.x = x;
+ platform.y = y;
+ game.addChild(platform);
+ platforms.push(platform);
+ return platform;
+}
+function createCollectible(type, x, y) {
+ var collectible = new Collectible(type);
+ collectible.x = x;
+ collectible.y = y;
+ game.addChild(collectible);
+ collectibles.push(collectible);
+ return collectible;
+}
+function createHazard(type, x, y) {
+ var hazard = new Hazard(type);
+ hazard.x = x;
+ hazard.y = y;
+ game.addChild(hazard);
+ hazards.push(hazard);
+ return hazard;
+}
+function createPowerUp(x, y) {
+ var powerup = new PowerUp();
+ powerup.x = x;
+ powerup.y = y;
+ game.addChild(powerup);
+ powerups.push(powerup);
+ return powerup;
+}
+function updateScore(points) {
+ score += points;
+ scoreTxt.setText('Buttons: ' + score);
+ // Check win condition
+ if (score >= 10) {
+ completeLevel();
+ }
+}
+function completeLevel() {
+ // Save progress
+ level++;
+ storage.level = level;
+ if (level > maxLevel) {
+ // Player completed all levels
+ LK.showYouWin();
+ } else {
+ // Show level complete message
+ var levelCompleteTxt = new Text2('Level Complete!', {
+ size: 120,
+ fill: 0xFFFFFF
+ });
+ levelCompleteTxt.anchor.set(0.5, 0.5);
+ levelCompleteTxt.x = 1024;
+ levelCompleteTxt.y = 1366;
+ game.addChild(levelCompleteTxt);
+ // Fade out and load next level
+ LK.setTimeout(function () {
+ tween(levelCompleteTxt, {
+ alpha: 0
+ }, {
+ duration: 1000,
+ onFinish: function onFinish() {
+ levelCompleteTxt.destroy();
+ initGame();
+ }
+ });
+ }, 2000);
+ }
+}
+function checkCollisions() {
+ if (!sackboy.alive) {
+ return;
+ }
+ // Check platform collisions
+ for (var i = 0; i < platforms.length; i++) {
+ var platform = platforms[i];
+ // Only bounce when falling
+ if (sackboy.velocity.y > 0 && sackboy.intersects(platform)) {
+ // Check if Sackboy is above the platform
+ if (sackboy.y < platform.y - platform.height / 2) {
+ sackboy.y = platform.y - platform.height / 2 - sackboy.height / 2;
+ sackboy.bounce(15);
+ }
+ }
+ }
+ // Check collectible collisions
+ for (var j = collectibles.length - 1; j >= 0; j--) {
+ var collectible = collectibles[j];
+ if (sackboy.intersects(collectible) && !collectible.collected) {
+ var type = collectible.collect();
+ if (type === 'button') {
+ updateScore(1);
+ } else if (type === 'yarn') {
+ // Yarn gives extra bounce
+ sackboy.bounce(25);
+ }
+ collectibles.splice(j, 1);
+ }
+ }
+ // Check hazard collisions
+ for (var k = 0; k < hazards.length; k++) {
+ var hazard = hazards[k];
+ if (sackboy.intersects(hazard)) {
+ // Check if invincible
+ if (sackboy.powered && sackboy.powerType === 'invincible') {
+ // Invincible - ignore hazard
+ continue;
+ }
+ sackboy.die();
+ break;
+ }
+ }
+ // Check power-up collisions
+ for (var l = powerups.length - 1; l >= 0; l--) {
+ var powerup = powerups[l];
+ if (sackboy.intersects(powerup) && !powerup.collected) {
+ var powerType = powerup.collect();
+ if (powerType) {
+ sackboy.activatePower(powerType);
+ }
+ powerups.splice(l, 1);
+ }
+ }
+}
+// Game control touch handlers
+game.down = function (x, y, obj) {
+ touchStart.x = x;
+ touchStart.y = y;
+ touchDragging = true;
+};
+game.move = function (x, y, obj) {
+ if (touchDragging && sackboy && sackboy.alive) {
+ // Calculate drag amount
+ var dragX = x - touchStart.x;
+ // Apply horizontal velocity based on drag
+ sackboy.velocity.x = dragX * 0.1;
+ // Update touch position
+ touchStart.x = x;
+ touchStart.y = y;
+ }
+};
+game.up = function (x, y, obj) {
+ touchDragging = false;
+ // Gradually slow down horizontal velocity
+ if (sackboy && sackboy.alive) {
+ sackboy.velocity.x *= 0.5;
+ }
+};
+// Main game update loop
+game.update = function () {
+ // Check collisions
+ checkCollisions();
+ // Update all game objects
+ for (var i = 0; i < platforms.length; i++) {
+ platforms[i].update();
+ }
+ for (var j = 0; j < collectibles.length; j++) {
+ collectibles[j].update();
+ }
+ for (var k = 0; k < hazards.length; k++) {
+ hazards[k].update();
+ }
+ for (var l = 0; l < powerups.length; l++) {
+ powerups[l].update();
+ }
+ // Automatically slow down horizontal velocity
+ if (sackboy && sackboy.alive) {
+ sackboy.velocity.x *= 0.98;
+ }
+};
+// Initialize the game
+initGame();
\ No newline at end of file