/**** * 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();
/****
* 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();