User prompt
Whenever someone plays the game they should be at level 1 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make level 2
User prompt
Now after level one there's level 2 and then after bunch up to 50
User prompt
The movement and jump system should only works if you use the buttons
User prompt
Make a movement and jump system that is ultra good ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove the problem that keeps making the player jump automatically
User prompt
Remove the movement system and jump system
User prompt
Just a block no body a block with eyes and a happy face
User prompt
Change the character to a block with eyes and a smiley face
User prompt
Fill in the rest of the ground
User prompt
I still see the character glitching through the ground
User prompt
The character is glitching again
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(part, {' Line Number: 460
User prompt
It won't stop glitching through the ground
User prompt
Reset the character and turn it into a pixilated kid
User prompt
When you start the game you should be at level 1
User prompt
Make the rest of the ground brown ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The character keeps glitching through the ground
User prompt
The character can't stop jumping low
User prompt
The game is lagging fix it
User prompt
Could you fix that
User prompt
Now make the character eyes
User prompt
Give the human hair
User prompt
The human legs are glitching through the ground
User prompt
Make the character a 128 bit human
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { currentLevel: 1, coins: 0, highScore: 0 }); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); // Coin sprite var sprite = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); // Animate coin self.update = function () { sprite.rotation += 0.05; }; self.collect = function () { LK.getSound('coin').play(); self.destroy(); }; return self; }); var ControlButton = Container.expand(function (type) { var self = Container.call(this); // Control button properties self.type = type; // 'jump', 'left', or 'right' self.isPressed = false; // Button sprite var sprite = self.attachAsset(type + 'Button', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); // Button icon (text inside the button) var icon; if (type === 'jump') { icon = new Text2('↑', { size: 100, fill: 0xFFFFFF }); } else if (type === 'left') { icon = new Text2('←', { size: 100, fill: 0xFFFFFF }); } else if (type === 'right') { icon = new Text2('→', { size: 100, fill: 0xFFFFFF }); } if (icon) { icon.anchor.set(0.5, 0.5); self.addChild(icon); } self.down = function (x, y, obj) { self.isPressed = true; sprite.alpha = 0.8; }; self.up = function (x, y, obj) { self.isPressed = false; sprite.alpha = 0.5; }; return self; }); var Enemy = Container.expand(function (patrolDistance) { var self = Container.call(this); // Default parameter patrolDistance = patrolDistance || 200; // Enemy properties self.speed = 3; self.direction = 1; self.patrolDistance = patrolDistance; self.startX = 0; // Enemy sprite var sprite = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x += self.speed * self.direction; // Check if we need to change direction if (Math.abs(self.x - self.startX) > self.patrolDistance) { self.direction *= -1; sprite.scaleX = -sprite.scaleX; // Flip the enemy when changing direction } }; self.setStartPosition = function (x, y) { self.x = x; self.y = y; self.startX = x; }; return self; }); var Goal = Container.expand(function () { var self = Container.call(this); // Goal sprite var sprite = self.attachAsset('goal', { anchorX: 0.5, anchorY: 0.5 }); self.reach = function () { LK.getSound('win').play(); LK.effects.flashObject(self, 0x00ff00, 1000); // Increment level and save progress var currentLevel = storage.currentLevel || 1; storage.currentLevel = currentLevel + 1; // Show win screen with delay LK.setTimeout(function () { LK.showYouWin(); }, 1000); }; return self; }); var Platform = Container.expand(function (width, height, isMoving) { var self = Container.call(this); // Default parameters width = width || 200; height = height || 30; isMoving = isMoving || false; // Platform properties self.isMoving = isMoving; self.moveSpeed = 2; self.direction = 1; self.moveDistance = 300; self.startX = 0; // Platform sprite var sprite = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5, width: width, height: height }); self.update = function () { if (self.isMoving) { self.x += self.moveSpeed * self.direction; // Check if we need to change direction if (Math.abs(self.x - self.startX) > self.moveDistance) { self.direction *= -1; } } }; self.setStartPosition = function (x, y) { self.x = x; self.y = y; self.startX = x; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player properties self.vx = 0; self.vy = 0; self.speed = 8; self.jumpForce = -20; self.gravity = 1; self.isJumping = false; self.isDead = false; self.facingRight = true; self.canJump = false; // Create 128-bit human character var head = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0.5, width: 50, height: 50, y: -50, tint: 0xFFC0CB // Pink head })); var body = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 80, y: 0, tint: 0x3498db // Blue body })); var leftArm = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0, width: 20, height: 60, x: -45, y: -30, tint: 0x3498db // Blue arm })); var rightArm = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0, width: 20, height: 60, x: 45, y: -30, tint: 0x3498db // Blue arm })); var leftLeg = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0, width: 20, height: 60, x: -20, y: 40, tint: 0x1a5276 // Dark blue leg })); var rightLeg = self.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0, width: 20, height: 60, x: 20, y: 40, tint: 0x1a5276 // Dark blue leg })); // Store reference to all parts for animation self.parts = { head: head, body: body, leftArm: leftArm, rightArm: rightArm, leftLeg: leftLeg, rightLeg: rightLeg }; // Create a hitbox for collision detection (invisible) var sprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, alpha: 0 // Make invisible, just for collision }); self.update = function () { if (self.isDead) { return; } // Apply gravity self.vy += self.gravity; // Update position based on velocity self.x += self.vx; self.y += self.vy; // Reset jump state if on ground if (self.canJump) { self.isJumping = false; } else { self.isJumping = true; } // Keep player oriented based on direction if (self.vx > 0 && !self.facingRight) { self.facingRight = true; sprite.scaleX = 1; // Flip all parts to face right Object.values(self.parts).forEach(function (part) { part.scaleX = Math.abs(part.scaleX); }); self.parts.leftArm.x = -45; self.parts.rightArm.x = 45; self.parts.leftLeg.x = -20; self.parts.rightLeg.x = 20; } else if (self.vx < 0 && self.facingRight) { self.facingRight = false; sprite.scaleX = -1; // Flip all parts to face left Object.values(self.parts).forEach(function (part) { part.scaleX = -Math.abs(part.scaleX); }); self.parts.leftArm.x = 45; self.parts.rightArm.x = -45; self.parts.leftLeg.x = 20; self.parts.rightLeg.x = -20; } // Animate legs and arms while moving if (self.vx !== 0) { var walkCycle = Math.sin(LK.ticks * 0.2) * 0.5; self.parts.leftLeg.rotation = walkCycle; self.parts.rightLeg.rotation = -walkCycle; self.parts.leftArm.rotation = -walkCycle; self.parts.rightArm.rotation = walkCycle; } else { // Reset animation when standing still self.parts.leftLeg.rotation = 0; self.parts.rightLeg.rotation = 0; self.parts.leftArm.rotation = 0; self.parts.rightArm.rotation = 0; } // Animate jumping if (self.isJumping) { self.parts.leftLeg.rotation = 0.3; self.parts.rightLeg.rotation = 0.3; self.parts.leftArm.rotation = -0.5; self.parts.rightArm.rotation = 0.5; } }; self.jump = function () { if (!self.isJumping && self.canJump) { self.vy = self.jumpForce; self.isJumping = true; self.canJump = false; LK.getSound('jump').play(); } }; self.moveLeft = function () { self.vx = -self.speed; }; self.moveRight = function () { self.vx = self.speed; }; self.stop = function () { self.vx = 0; }; self.die = function () { if (!self.isDead) { self.isDead = true; LK.getSound('hit').play(); LK.effects.flashObject(self, 0xff0000, 500); // Death animation Object.values(self.parts).forEach(function (part) { // Use tween to animate parts falling apart tween.to(part, { y: part.y + Math.random() * 200 - 100, x: part.x + Math.random() * 200 - 100, rotation: Math.random() * Math.PI * 2, alpha: 0 }, 800, 'easeInQuad'); }); LK.setTimeout(function () { LK.showGameOver(); }, 1000); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue }); /**** * Game Code ****/ // Game variables var player; var platforms = []; var coins = []; var enemies = []; var goal; var jumpButton; var leftButton; var rightButton; var cameraPosX = 0; var cameraPosY = 0; var worldContainer; var uiContainer; var levelWidth = 5000; // The total width of the level var groundY = 2732 - 100; // Y position of the ground var score = 0; var level = storage.currentLevel || 1; // Initialize UI var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -250; // Offset from topRight anchor var levelTxt = new Text2('Level: ' + level, { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.top.addChild(levelTxt); // Initialize world container to allow camera movement worldContainer = new Container(); game.addChild(worldContainer); // Create player player = new Player(); player.x = 200; player.y = groundY - 200; worldContainer.addChild(player); // Create control buttons jumpButton = new ControlButton('jump'); jumpButton.x = 2048 - 250; jumpButton.y = 2732 - 250; jumpButton.scale.set(1.5, 1.5); // Make jump button 50% larger game.addChild(jumpButton); leftButton = new ControlButton('left'); leftButton.x = 200; leftButton.y = 2732 - 250; leftButton.scale.set(1.5, 1.5); // Make left button 50% larger game.addChild(leftButton); rightButton = new ControlButton('right'); rightButton.x = 500; rightButton.y = 2732 - 250; rightButton.scale.set(1.5, 1.5); // Make right button 50% larger game.addChild(rightButton); // Create level function function createLevel(level) { // Clear previous level objects for (var i = platforms.length - 1; i >= 0; i--) { worldContainer.removeChild(platforms[i]); platforms.splice(i, 1); } for (var i = coins.length - 1; i >= 0; i--) { worldContainer.removeChild(coins[i]); coins.splice(i, 1); } for (var i = enemies.length - 1; i >= 0; i--) { worldContainer.removeChild(enemies[i]); enemies.splice(i, 1); } if (goal) { worldContainer.removeChild(goal); goal = null; } // Create ground for (var i = 0; i < levelWidth; i += 400) { var ground = new Platform(400, 50, false); ground.setStartPosition(i + 200, groundY); worldContainer.addChild(ground); platforms.push(ground); } // Level-specific configurations switch (level) { case 1: // Level 1: Basic platforms and coins createPlatform(600, groundY - 200, 200, 30, false); createPlatform(900, groundY - 350, 200, 30, false); createPlatform(1300, groundY - 500, 200, 30, false); createPlatform(1700, groundY - 350, 200, 30, false); createPlatform(2100, groundY - 200, 200, 30, false); createCoin(600, groundY - 300); createCoin(900, groundY - 450); createCoin(1300, groundY - 600); createCoin(1700, groundY - 450); createCoin(2100, groundY - 300); // Place goal at the end of level 1 createGoal(2400, groundY - 100); break; case 2: // Level 2: Moving platforms and enemies createPlatform(600, groundY - 200, 200, 30, true); createPlatform(1000, groundY - 350, 200, 30, false); createPlatform(1400, groundY - 500, 200, 30, true); createPlatform(1800, groundY - 350, 200, 30, false); createPlatform(2200, groundY - 200, 200, 30, true); createPlatform(2600, groundY - 350, 200, 30, false); createCoin(600, groundY - 300); createCoin(1000, groundY - 450); createCoin(1400, groundY - 600); createCoin(1800, groundY - 450); createCoin(2200, groundY - 300); createCoin(2600, groundY - 450); createEnemy(800, groundY - 50, 300); createEnemy(1600, groundY - 50, 400); // Place goal at the end of level 2 createGoal(3000, groundY - 100); break; case 3: // Level 3: Complex platforming with more enemies createPlatform(500, groundY - 200, 200, 30, false); createPlatform(800, groundY - 350, 200, 30, true); createPlatform(1200, groundY - 500, 200, 30, false); createPlatform(1600, groundY - 650, 200, 30, true); createPlatform(2000, groundY - 500, 200, 30, false); createPlatform(2400, groundY - 350, 200, 30, true); createPlatform(2800, groundY - 200, 200, 30, false); createPlatform(3200, groundY - 350, 200, 30, true); createCoin(500, groundY - 300); createCoin(800, groundY - 450); createCoin(1200, groundY - 600); createCoin(1600, groundY - 750); createCoin(2000, groundY - 600); createCoin(2400, groundY - 450); createCoin(2800, groundY - 300); createCoin(3200, groundY - 450); createEnemy(700, groundY - 50, 200); createEnemy(1400, groundY - 50, 300); createEnemy(2100, groundY - 50, 400); createEnemy(2800, groundY - 50, 500); // Place goal at the end of level 3 createGoal(3600, groundY - 100); break; default: // If level > 3, generate a procedural level with increasing difficulty var platformCount = level * 5; var enemyCount = level * 2; var coinCount = level * 5; // Create platforms with varying heights and spacing for (var i = 0; i < platformCount; i++) { var x = 500 + i * 500; var y = groundY - (Math.random() * 500 + 100); var isMoving = Math.random() > 0.5; createPlatform(x, y, 200, 30, isMoving); // Add a coin above each platform createCoin(x, y - 100); } // Add enemies for (var i = 0; i < enemyCount; i++) { var x = 800 + i * 800; var patrolDistance = 200 + Math.random() * 300; createEnemy(x, groundY - 50, patrolDistance); } // Place goal at the end createGoal(500 + platformCount * 500 + 200, groundY - 100); break; } // Reset player position player.x = 200; player.y = groundY - 200; player.vx = 0; player.vy = 0; player.isDead = false; // Reset camera cameraPosX = 0; worldContainer.x = 0; } // Helper functions for creating level elements function createPlatform(x, y, width, height, isMoving) { var platform = new Platform(width, height, isMoving); platform.setStartPosition(x, y); worldContainer.addChild(platform); platforms.push(platform); return platform; } function createCoin(x, y) { var coin = new Coin(); coin.x = x; coin.y = y; worldContainer.addChild(coin); coins.push(coin); return coin; } function createEnemy(x, y, patrolDistance) { var enemy = new Enemy(patrolDistance); enemy.setStartPosition(x, y); worldContainer.addChild(enemy); enemies.push(enemy); return enemy; } function createGoal(x, y) { goal = new Goal(); goal.x = x; goal.y = y; worldContainer.addChild(goal); return goal; } // Check collisions between player and platforms function checkPlatformCollisions() { player.canJump = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; // Get platform dimensions (adjust based on asset size) var platformWidth = platform.children[0].width; var platformHeight = platform.children[0].height; var platformLeft = platform.x - platformWidth / 2; var platformRight = platform.x + platformWidth / 2; var platformTop = platform.y - platformHeight / 2; var platformBottom = platform.y + platformHeight / 2; // Get player dimensions var playerWidth = player.children[0].width; var playerHeight = player.children[0].height; var playerLeft = player.x - playerWidth / 2; var playerRight = player.x + playerWidth / 2; var playerTop = player.y - playerHeight / 2; var playerBottom = player.y + playerHeight / 2; // Check for collision if (playerRight > platformLeft && playerLeft < platformRight && playerBottom > platformTop && playerTop < platformBottom) { // Calculate overlap on each side var overlapLeft = playerRight - platformLeft; var overlapRight = platformRight - playerLeft; var overlapTop = playerBottom - platformTop; var overlapBottom = platformBottom - playerTop; // Find the smallest overlap var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); // Resolve collision based on the smallest overlap if (minOverlap === overlapTop && player.vy >= 0) { // Landing on top of platform player.y = platformTop - playerHeight / 2; player.vy = 0; player.canJump = true; // If platform is moving, adjust player x position if (platform.isMoving) { player.x += platform.moveSpeed * platform.direction; } } else if (minOverlap === overlapBottom && player.vy <= 0) { // Hitting bottom of platform player.y = platformBottom + playerHeight / 2; player.vy = 0; } else if (minOverlap === overlapLeft && player.vx > 0) { // Hitting left side of platform player.x = platformLeft - playerWidth / 2; player.vx = 0; } else if (minOverlap === overlapRight && player.vx < 0) { // Hitting right side of platform player.x = platformRight + playerWidth / 2; player.vx = 0; } } } } // Check collisions with coins function checkCoinCollisions() { for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (player.intersects(coin)) { // Collect coin score += 10; scoreTxt.setText('Score: ' + score); storage.coins = (storage.coins || 0) + 1; coin.collect(); coins.splice(i, 1); } } } // Check collisions with enemies function checkEnemyCollisions() { for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (player.intersects(enemy) && !player.isDead) { // Check if player is landing on enemy (from above) var playerBottom = player.y + player.children[0].height / 2; var enemyTop = enemy.y - enemy.children[0].height / 2; if (player.vy > 0 && playerBottom - enemyTop < 20) { // Bounce off enemy player.vy = player.jumpForce * 0.7; // Remove enemy enemy.destroy(); enemies.splice(i, 1); // Add points score += 50; scoreTxt.setText('Score: ' + score); } else { // Player dies player.die(); } break; } } } // Check if player reached the goal function checkGoalCollision() { if (goal && player.intersects(goal)) { goal.reach(); } } // Update camera to follow player function updateCamera() { // Only follow horizontally var targetX = Math.max(0, Math.min(levelWidth - 2048, player.x - 2048 / 2)); cameraPosX += (targetX - cameraPosX) * 0.1; // Smooth camera movement worldContainer.x = -cameraPosX; } // Check if player fell off the level function checkFallOffLevel() { if (player.y > 2732 + 200 && !player.isDead) { player.die(); } } // Initialize the level createLevel(level); // Play background music LK.playMusic('gameMusic'); // Main game loop game.update = function () { // Handle controls if (leftButton.isPressed) { player.moveLeft(); } else if (rightButton.isPressed) { player.moveRight(); } else { player.stop(); } if (jumpButton.isPressed && !jumpButton.wasPressed) { player.jump(); jumpButton.wasPressed = true; } else if (!jumpButton.isPressed) { jumpButton.wasPressed = false; } // Update player player.update(); // Update platforms for (var i = 0; i < platforms.length; i++) { platforms[i].update(); } // Update coins for (var i = 0; i < coins.length; i++) { coins[i].update(); } // Update enemies for (var i = 0; i < enemies.length; i++) { enemies[i].update(); } // Check collisions checkPlatformCollisions(); checkCoinCollisions(); checkEnemyCollisions(); checkGoalCollision(); checkFallOffLevel(); // Update camera updateCamera(); }; // Game-wide touch events game.down = function (x, y, obj) { // Handle touch input for areas outside of control buttons var touchX = x; var touchY = y; // Check if we should handle this touch ourselves or if a control button will handle it var controlButtonPressed = false; if (!controlButtonPressed && touchY < 2732 - 300) { // If touch is in the game area (not on controls), treat it as jump player.jump(); } }; game.move = function (x, y, obj) { // No additional move handling needed at game level }; game.up = function (x, y, obj) { // No additional up handling needed at game level };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentLevel: 1,
coins: 0,
highScore: 0
});
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
// Coin sprite
var sprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Animate coin
self.update = function () {
sprite.rotation += 0.05;
};
self.collect = function () {
LK.getSound('coin').play();
self.destroy();
};
return self;
});
var ControlButton = Container.expand(function (type) {
var self = Container.call(this);
// Control button properties
self.type = type; // 'jump', 'left', or 'right'
self.isPressed = false;
// Button sprite
var sprite = self.attachAsset(type + 'Button', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
// Button icon (text inside the button)
var icon;
if (type === 'jump') {
icon = new Text2('↑', {
size: 100,
fill: 0xFFFFFF
});
} else if (type === 'left') {
icon = new Text2('←', {
size: 100,
fill: 0xFFFFFF
});
} else if (type === 'right') {
icon = new Text2('→', {
size: 100,
fill: 0xFFFFFF
});
}
if (icon) {
icon.anchor.set(0.5, 0.5);
self.addChild(icon);
}
self.down = function (x, y, obj) {
self.isPressed = true;
sprite.alpha = 0.8;
};
self.up = function (x, y, obj) {
self.isPressed = false;
sprite.alpha = 0.5;
};
return self;
});
var Enemy = Container.expand(function (patrolDistance) {
var self = Container.call(this);
// Default parameter
patrolDistance = patrolDistance || 200;
// Enemy properties
self.speed = 3;
self.direction = 1;
self.patrolDistance = patrolDistance;
self.startX = 0;
// Enemy sprite
var sprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x += self.speed * self.direction;
// Check if we need to change direction
if (Math.abs(self.x - self.startX) > self.patrolDistance) {
self.direction *= -1;
sprite.scaleX = -sprite.scaleX; // Flip the enemy when changing direction
}
};
self.setStartPosition = function (x, y) {
self.x = x;
self.y = y;
self.startX = x;
};
return self;
});
var Goal = Container.expand(function () {
var self = Container.call(this);
// Goal sprite
var sprite = self.attachAsset('goal', {
anchorX: 0.5,
anchorY: 0.5
});
self.reach = function () {
LK.getSound('win').play();
LK.effects.flashObject(self, 0x00ff00, 1000);
// Increment level and save progress
var currentLevel = storage.currentLevel || 1;
storage.currentLevel = currentLevel + 1;
// Show win screen with delay
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
};
return self;
});
var Platform = Container.expand(function (width, height, isMoving) {
var self = Container.call(this);
// Default parameters
width = width || 200;
height = height || 30;
isMoving = isMoving || false;
// Platform properties
self.isMoving = isMoving;
self.moveSpeed = 2;
self.direction = 1;
self.moveDistance = 300;
self.startX = 0;
// Platform sprite
var sprite = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
width: width,
height: height
});
self.update = function () {
if (self.isMoving) {
self.x += self.moveSpeed * self.direction;
// Check if we need to change direction
if (Math.abs(self.x - self.startX) > self.moveDistance) {
self.direction *= -1;
}
}
};
self.setStartPosition = function (x, y) {
self.x = x;
self.y = y;
self.startX = x;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player properties
self.vx = 0;
self.vy = 0;
self.speed = 8;
self.jumpForce = -20;
self.gravity = 1;
self.isJumping = false;
self.isDead = false;
self.facingRight = true;
self.canJump = false;
// Create 128-bit human character
var head = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
width: 50,
height: 50,
y: -50,
tint: 0xFFC0CB // Pink head
}));
var body = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
width: 60,
height: 80,
y: 0,
tint: 0x3498db // Blue body
}));
var leftArm = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0,
width: 20,
height: 60,
x: -45,
y: -30,
tint: 0x3498db // Blue arm
}));
var rightArm = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0,
width: 20,
height: 60,
x: 45,
y: -30,
tint: 0x3498db // Blue arm
}));
var leftLeg = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0,
width: 20,
height: 60,
x: -20,
y: 40,
tint: 0x1a5276 // Dark blue leg
}));
var rightLeg = self.addChild(LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0,
width: 20,
height: 60,
x: 20,
y: 40,
tint: 0x1a5276 // Dark blue leg
}));
// Store reference to all parts for animation
self.parts = {
head: head,
body: body,
leftArm: leftArm,
rightArm: rightArm,
leftLeg: leftLeg,
rightLeg: rightLeg
};
// Create a hitbox for collision detection (invisible)
var sprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0 // Make invisible, just for collision
});
self.update = function () {
if (self.isDead) {
return;
}
// Apply gravity
self.vy += self.gravity;
// Update position based on velocity
self.x += self.vx;
self.y += self.vy;
// Reset jump state if on ground
if (self.canJump) {
self.isJumping = false;
} else {
self.isJumping = true;
}
// Keep player oriented based on direction
if (self.vx > 0 && !self.facingRight) {
self.facingRight = true;
sprite.scaleX = 1;
// Flip all parts to face right
Object.values(self.parts).forEach(function (part) {
part.scaleX = Math.abs(part.scaleX);
});
self.parts.leftArm.x = -45;
self.parts.rightArm.x = 45;
self.parts.leftLeg.x = -20;
self.parts.rightLeg.x = 20;
} else if (self.vx < 0 && self.facingRight) {
self.facingRight = false;
sprite.scaleX = -1;
// Flip all parts to face left
Object.values(self.parts).forEach(function (part) {
part.scaleX = -Math.abs(part.scaleX);
});
self.parts.leftArm.x = 45;
self.parts.rightArm.x = -45;
self.parts.leftLeg.x = 20;
self.parts.rightLeg.x = -20;
}
// Animate legs and arms while moving
if (self.vx !== 0) {
var walkCycle = Math.sin(LK.ticks * 0.2) * 0.5;
self.parts.leftLeg.rotation = walkCycle;
self.parts.rightLeg.rotation = -walkCycle;
self.parts.leftArm.rotation = -walkCycle;
self.parts.rightArm.rotation = walkCycle;
} else {
// Reset animation when standing still
self.parts.leftLeg.rotation = 0;
self.parts.rightLeg.rotation = 0;
self.parts.leftArm.rotation = 0;
self.parts.rightArm.rotation = 0;
}
// Animate jumping
if (self.isJumping) {
self.parts.leftLeg.rotation = 0.3;
self.parts.rightLeg.rotation = 0.3;
self.parts.leftArm.rotation = -0.5;
self.parts.rightArm.rotation = 0.5;
}
};
self.jump = function () {
if (!self.isJumping && self.canJump) {
self.vy = self.jumpForce;
self.isJumping = true;
self.canJump = false;
LK.getSound('jump').play();
}
};
self.moveLeft = function () {
self.vx = -self.speed;
};
self.moveRight = function () {
self.vx = self.speed;
};
self.stop = function () {
self.vx = 0;
};
self.die = function () {
if (!self.isDead) {
self.isDead = true;
LK.getSound('hit').play();
LK.effects.flashObject(self, 0xff0000, 500);
// Death animation
Object.values(self.parts).forEach(function (part) {
// Use tween to animate parts falling apart
tween.to(part, {
y: part.y + Math.random() * 200 - 100,
x: part.x + Math.random() * 200 - 100,
rotation: Math.random() * Math.PI * 2,
alpha: 0
}, 800, 'easeInQuad');
});
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game variables
var player;
var platforms = [];
var coins = [];
var enemies = [];
var goal;
var jumpButton;
var leftButton;
var rightButton;
var cameraPosX = 0;
var cameraPosY = 0;
var worldContainer;
var uiContainer;
var levelWidth = 5000; // The total width of the level
var groundY = 2732 - 100; // Y position of the ground
var score = 0;
var level = storage.currentLevel || 1;
// Initialize UI
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -250; // Offset from topRight anchor
var levelTxt = new Text2('Level: ' + level, {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.top.addChild(levelTxt);
// Initialize world container to allow camera movement
worldContainer = new Container();
game.addChild(worldContainer);
// Create player
player = new Player();
player.x = 200;
player.y = groundY - 200;
worldContainer.addChild(player);
// Create control buttons
jumpButton = new ControlButton('jump');
jumpButton.x = 2048 - 250;
jumpButton.y = 2732 - 250;
jumpButton.scale.set(1.5, 1.5); // Make jump button 50% larger
game.addChild(jumpButton);
leftButton = new ControlButton('left');
leftButton.x = 200;
leftButton.y = 2732 - 250;
leftButton.scale.set(1.5, 1.5); // Make left button 50% larger
game.addChild(leftButton);
rightButton = new ControlButton('right');
rightButton.x = 500;
rightButton.y = 2732 - 250;
rightButton.scale.set(1.5, 1.5); // Make right button 50% larger
game.addChild(rightButton);
// Create level function
function createLevel(level) {
// Clear previous level objects
for (var i = platforms.length - 1; i >= 0; i--) {
worldContainer.removeChild(platforms[i]);
platforms.splice(i, 1);
}
for (var i = coins.length - 1; i >= 0; i--) {
worldContainer.removeChild(coins[i]);
coins.splice(i, 1);
}
for (var i = enemies.length - 1; i >= 0; i--) {
worldContainer.removeChild(enemies[i]);
enemies.splice(i, 1);
}
if (goal) {
worldContainer.removeChild(goal);
goal = null;
}
// Create ground
for (var i = 0; i < levelWidth; i += 400) {
var ground = new Platform(400, 50, false);
ground.setStartPosition(i + 200, groundY);
worldContainer.addChild(ground);
platforms.push(ground);
}
// Level-specific configurations
switch (level) {
case 1:
// Level 1: Basic platforms and coins
createPlatform(600, groundY - 200, 200, 30, false);
createPlatform(900, groundY - 350, 200, 30, false);
createPlatform(1300, groundY - 500, 200, 30, false);
createPlatform(1700, groundY - 350, 200, 30, false);
createPlatform(2100, groundY - 200, 200, 30, false);
createCoin(600, groundY - 300);
createCoin(900, groundY - 450);
createCoin(1300, groundY - 600);
createCoin(1700, groundY - 450);
createCoin(2100, groundY - 300);
// Place goal at the end of level 1
createGoal(2400, groundY - 100);
break;
case 2:
// Level 2: Moving platforms and enemies
createPlatform(600, groundY - 200, 200, 30, true);
createPlatform(1000, groundY - 350, 200, 30, false);
createPlatform(1400, groundY - 500, 200, 30, true);
createPlatform(1800, groundY - 350, 200, 30, false);
createPlatform(2200, groundY - 200, 200, 30, true);
createPlatform(2600, groundY - 350, 200, 30, false);
createCoin(600, groundY - 300);
createCoin(1000, groundY - 450);
createCoin(1400, groundY - 600);
createCoin(1800, groundY - 450);
createCoin(2200, groundY - 300);
createCoin(2600, groundY - 450);
createEnemy(800, groundY - 50, 300);
createEnemy(1600, groundY - 50, 400);
// Place goal at the end of level 2
createGoal(3000, groundY - 100);
break;
case 3:
// Level 3: Complex platforming with more enemies
createPlatform(500, groundY - 200, 200, 30, false);
createPlatform(800, groundY - 350, 200, 30, true);
createPlatform(1200, groundY - 500, 200, 30, false);
createPlatform(1600, groundY - 650, 200, 30, true);
createPlatform(2000, groundY - 500, 200, 30, false);
createPlatform(2400, groundY - 350, 200, 30, true);
createPlatform(2800, groundY - 200, 200, 30, false);
createPlatform(3200, groundY - 350, 200, 30, true);
createCoin(500, groundY - 300);
createCoin(800, groundY - 450);
createCoin(1200, groundY - 600);
createCoin(1600, groundY - 750);
createCoin(2000, groundY - 600);
createCoin(2400, groundY - 450);
createCoin(2800, groundY - 300);
createCoin(3200, groundY - 450);
createEnemy(700, groundY - 50, 200);
createEnemy(1400, groundY - 50, 300);
createEnemy(2100, groundY - 50, 400);
createEnemy(2800, groundY - 50, 500);
// Place goal at the end of level 3
createGoal(3600, groundY - 100);
break;
default:
// If level > 3, generate a procedural level with increasing difficulty
var platformCount = level * 5;
var enemyCount = level * 2;
var coinCount = level * 5;
// Create platforms with varying heights and spacing
for (var i = 0; i < platformCount; i++) {
var x = 500 + i * 500;
var y = groundY - (Math.random() * 500 + 100);
var isMoving = Math.random() > 0.5;
createPlatform(x, y, 200, 30, isMoving);
// Add a coin above each platform
createCoin(x, y - 100);
}
// Add enemies
for (var i = 0; i < enemyCount; i++) {
var x = 800 + i * 800;
var patrolDistance = 200 + Math.random() * 300;
createEnemy(x, groundY - 50, patrolDistance);
}
// Place goal at the end
createGoal(500 + platformCount * 500 + 200, groundY - 100);
break;
}
// Reset player position
player.x = 200;
player.y = groundY - 200;
player.vx = 0;
player.vy = 0;
player.isDead = false;
// Reset camera
cameraPosX = 0;
worldContainer.x = 0;
}
// Helper functions for creating level elements
function createPlatform(x, y, width, height, isMoving) {
var platform = new Platform(width, height, isMoving);
platform.setStartPosition(x, y);
worldContainer.addChild(platform);
platforms.push(platform);
return platform;
}
function createCoin(x, y) {
var coin = new Coin();
coin.x = x;
coin.y = y;
worldContainer.addChild(coin);
coins.push(coin);
return coin;
}
function createEnemy(x, y, patrolDistance) {
var enemy = new Enemy(patrolDistance);
enemy.setStartPosition(x, y);
worldContainer.addChild(enemy);
enemies.push(enemy);
return enemy;
}
function createGoal(x, y) {
goal = new Goal();
goal.x = x;
goal.y = y;
worldContainer.addChild(goal);
return goal;
}
// Check collisions between player and platforms
function checkPlatformCollisions() {
player.canJump = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Get platform dimensions (adjust based on asset size)
var platformWidth = platform.children[0].width;
var platformHeight = platform.children[0].height;
var platformLeft = platform.x - platformWidth / 2;
var platformRight = platform.x + platformWidth / 2;
var platformTop = platform.y - platformHeight / 2;
var platformBottom = platform.y + platformHeight / 2;
// Get player dimensions
var playerWidth = player.children[0].width;
var playerHeight = player.children[0].height;
var playerLeft = player.x - playerWidth / 2;
var playerRight = player.x + playerWidth / 2;
var playerTop = player.y - playerHeight / 2;
var playerBottom = player.y + playerHeight / 2;
// Check for collision
if (playerRight > platformLeft && playerLeft < platformRight && playerBottom > platformTop && playerTop < platformBottom) {
// Calculate overlap on each side
var overlapLeft = playerRight - platformLeft;
var overlapRight = platformRight - playerLeft;
var overlapTop = playerBottom - platformTop;
var overlapBottom = platformBottom - playerTop;
// Find the smallest overlap
var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
// Resolve collision based on the smallest overlap
if (minOverlap === overlapTop && player.vy >= 0) {
// Landing on top of platform
player.y = platformTop - playerHeight / 2;
player.vy = 0;
player.canJump = true;
// If platform is moving, adjust player x position
if (platform.isMoving) {
player.x += platform.moveSpeed * platform.direction;
}
} else if (minOverlap === overlapBottom && player.vy <= 0) {
// Hitting bottom of platform
player.y = platformBottom + playerHeight / 2;
player.vy = 0;
} else if (minOverlap === overlapLeft && player.vx > 0) {
// Hitting left side of platform
player.x = platformLeft - playerWidth / 2;
player.vx = 0;
} else if (minOverlap === overlapRight && player.vx < 0) {
// Hitting right side of platform
player.x = platformRight + playerWidth / 2;
player.vx = 0;
}
}
}
}
// Check collisions with coins
function checkCoinCollisions() {
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (player.intersects(coin)) {
// Collect coin
score += 10;
scoreTxt.setText('Score: ' + score);
storage.coins = (storage.coins || 0) + 1;
coin.collect();
coins.splice(i, 1);
}
}
}
// Check collisions with enemies
function checkEnemyCollisions() {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (player.intersects(enemy) && !player.isDead) {
// Check if player is landing on enemy (from above)
var playerBottom = player.y + player.children[0].height / 2;
var enemyTop = enemy.y - enemy.children[0].height / 2;
if (player.vy > 0 && playerBottom - enemyTop < 20) {
// Bounce off enemy
player.vy = player.jumpForce * 0.7;
// Remove enemy
enemy.destroy();
enemies.splice(i, 1);
// Add points
score += 50;
scoreTxt.setText('Score: ' + score);
} else {
// Player dies
player.die();
}
break;
}
}
}
// Check if player reached the goal
function checkGoalCollision() {
if (goal && player.intersects(goal)) {
goal.reach();
}
}
// Update camera to follow player
function updateCamera() {
// Only follow horizontally
var targetX = Math.max(0, Math.min(levelWidth - 2048, player.x - 2048 / 2));
cameraPosX += (targetX - cameraPosX) * 0.1; // Smooth camera movement
worldContainer.x = -cameraPosX;
}
// Check if player fell off the level
function checkFallOffLevel() {
if (player.y > 2732 + 200 && !player.isDead) {
player.die();
}
}
// Initialize the level
createLevel(level);
// Play background music
LK.playMusic('gameMusic');
// Main game loop
game.update = function () {
// Handle controls
if (leftButton.isPressed) {
player.moveLeft();
} else if (rightButton.isPressed) {
player.moveRight();
} else {
player.stop();
}
if (jumpButton.isPressed && !jumpButton.wasPressed) {
player.jump();
jumpButton.wasPressed = true;
} else if (!jumpButton.isPressed) {
jumpButton.wasPressed = false;
}
// Update player
player.update();
// Update platforms
for (var i = 0; i < platforms.length; i++) {
platforms[i].update();
}
// Update coins
for (var i = 0; i < coins.length; i++) {
coins[i].update();
}
// Update enemies
for (var i = 0; i < enemies.length; i++) {
enemies[i].update();
}
// Check collisions
checkPlatformCollisions();
checkCoinCollisions();
checkEnemyCollisions();
checkGoalCollision();
checkFallOffLevel();
// Update camera
updateCamera();
};
// Game-wide touch events
game.down = function (x, y, obj) {
// Handle touch input for areas outside of control buttons
var touchX = x;
var touchY = y;
// Check if we should handle this touch ourselves or if a control button will handle it
var controlButtonPressed = false;
if (!controlButtonPressed && touchY < 2732 - 300) {
// If touch is in the game area (not on controls), treat it as jump
player.jump();
}
};
game.move = function (x, y, obj) {
// No additional move handling needed at game level
};
game.up = function (x, y, obj) {
// No additional up handling needed at game level
};