/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Crystal = Container.expand(function () { var self = Container.call(this); var crystalGraphics = self.attachAsset('crystal', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.update = function () { // Simple hover animation self.y += Math.sin(LK.ticks / 10) * 0.5; // Simple rotation crystalGraphics.rotation += 0.02; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.velocity = { x: 1, y: 0 }; self.patrolDistance = 100; self.startX = 0; self.direction = 1; self.update = function () { self.x += self.velocity.x * self.direction; if (self.x < 0) { self.x = 0; self.direction *= -1; } else if (self.x > GAME_WIDTH) { self.x = GAME_WIDTH; self.direction *= -1; } // Change direction when patrol limit reached if (Math.abs(self.x - self.startX) > self.patrolDistance) { self.direction *= -1; } }; self.initialize = function (x, y, patrolDistance) { self.x = x; self.y = y; self.startX = x; self.patrolDistance = patrolDistance || 100; }; 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; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player visual var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Player properties self.velocity = { x: 0, y: 0 }; self.gravity = 0.1; self.jumpStrength = -15; self.isGrounded = false; self.canDash = true; self.dashCooldown = 30; // frames self.dashCooldownTimer = 0; self.dashSpeed = 10; self.dashDuration = 10; // frames self.dashTimer = 0; self.isDashing = false; self.dashDirection = { x: 0, y: 0 }; self.dashDistanceMultiplier = 1; // Dash effect var dashEffect = self.attachAsset('dashEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.update = function () { // Apply gravity if not dashing if (!self.isDashing) { self.velocity.y += self.gravity; } // Handle dash cooldown if (!self.canDash) { self.dashCooldownTimer--; if (self.dashCooldownTimer <= 0) { self.canDash = true; } } // Handle dash execution if (self.isDashing) { self.dashTimer--; // Apply dash movement self.x += self.dashDirection.x * self.dashSpeed * self.dashDistanceMultiplier; self.y += self.dashDirection.y * self.dashSpeed * self.dashDistanceMultiplier; // End dash if (self.dashTimer <= 0) { self.isDashing = false; tween(dashEffect, { alpha: 0 }, { duration: 200 }); self.velocity.x = self.dashDirection.x * 5; // Maintain some momentum self.velocity.y = self.dashDirection.y * 5; } } else { // Normal movement self.x += self.velocity.x; if (self.x < 0) { self.x = 0; self.velocity.x = 0; } else if (self.x > GAME_WIDTH) { self.x = GAME_WIDTH; self.velocity.x = 0; } self.y += self.velocity.y; // Dampen horizontal velocity self.velocity.x *= 0.95; } // Reset grounded status each frame self.isGrounded = false; }; self.dash = function (dirX, dirY) { if (!self.canDash) { return; } // Normalize direction var magnitude = Math.sqrt(dirX * dirX + dirY * dirY); if (magnitude === 0) { return; } // Prevent division by zero self.dashDirection.x = dirX / magnitude; self.dashDirection.y = dirY / magnitude; // Start dash self.isDashing = true; self.dashTimer = self.dashDuration; self.velocity.x = 0; self.velocity.y = 0; // Start cooldown self.canDash = false; self.dashCooldownTimer = self.dashCooldown; // Visual effect dashEffect.x = 0; dashEffect.y = 0; tween(dashEffect, { alpha: 0.7 }, { duration: 100 }); // Play sound LK.getSound('dash').play(); }; self.jump = function () { if (self.isGrounded) { self.velocity.y = self.jumpStrength; self.isGrounded = false; } else if (!self.isDashing && self.canDash) { self.dash(0, -1); // Perform a vertical dash if in the air and dash is available } }; self.upgradeDash = function () { // Increase dash distance self.dashDistanceMultiplier += 0.2; if (self.dashDistanceMultiplier > 2) { self.dashDistanceMultiplier = 2; } // Decrease cooldown self.dashCooldown -= 5; if (self.dashCooldown < 15) { self.dashCooldown = 15; } }; return self; }); var Portal = Container.expand(function () { var self = Container.call(this); var portalGraphics = self.attachAsset('portal', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Portal pulsing effect var scale = 1 + Math.sin(LK.ticks / 15) * 0.1; portalGraphics.scale.set(scale, scale); // Portal rotation portalGraphics.rotation += 0.01; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLATFORM_COUNT = 5; var ENEMY_COUNT = 5; var CRYSTAL_COUNT = 3; // Game state var currentLevel = storage.currentLevel || 1; var crystalsCollected = 0; var totalCrystals = 0; // Game entities var player; var platforms = []; var enemies = []; var crystals = []; var portal; // UI elements var levelText = new Text2("Level " + currentLevel, { size: 80, fill: 0xFFFFFF }); var crystalCountText = new Text2("Crystals: 0/" + CRYSTAL_COUNT, { size: 60, fill: 0xFFFFFF }); // Setup game elements function setupGame() { // Add background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 }); game.addChild(background); // Create player platforms = []; enemies = []; crystals = []; crystalsCollected = 0; totalCrystals = CRYSTAL_COUNT; // Create player player = new Player(); player.x = GAME_WIDTH / 2; player.y = GAME_HEIGHT - 200; game.addChild(player); // Create initial platform under player var startPlatform = new Platform(); startPlatform.x = GAME_WIDTH / 2; startPlatform.y = GAME_HEIGHT - 150; game.addChild(startPlatform); platforms.push(startPlatform); // Generate level generateLevel(); // Add portal at the highest platform var highestPlatform = platforms.reduce(function (prev, current) { return prev.y < current.y ? prev : current; }); portal = new Portal(); portal.x = highestPlatform.x; portal.y = highestPlatform.y - 100; game.addChild(portal); // Update UI levelText.setText("Level " + currentLevel); crystalCountText.setText("Crystals: " + crystalsCollected + "/" + totalCrystals); // Add UI to game LK.gui.top.addChild(levelText); levelText.anchor.set(0.5, 0); levelText.y = 50; LK.gui.topRight.addChild(crystalCountText); crystalCountText.anchor.set(1, 0); crystalCountText.x = -50; crystalCountText.y = 50; // Play background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.5, duration: 1000 } }); } function generateLevel() { // Generate platforms with increasing difficulty based on level var minGapX = 100 + currentLevel * 5; // Adjusted minimum horizontal gap var maxGapX = 200 + currentLevel * 10; // Adjusted maximum horizontal gap var minGapY = 100; // Adjusted minimum vertical gap var maxGapY = 150 + currentLevel * 5; // Adjusted maximum vertical gap var lastX = GAME_WIDTH / 2; var lastY = GAME_HEIGHT - 150; for (var i = 0; i < PLATFORM_COUNT; i++) { var platform = new Platform(); // Calculate new position with gaps var gapX = Math.random() * (maxGapX - minGapX) + minGapX; var gapY = Math.random() * (maxGapY - minGapY) + minGapY; // Alternate direction var directionX = Math.random() > 0.5 ? 1 : -1; var newX = lastX + gapX * directionX; var newY = lastY - gapY; // Keep platforms within bounds newX = Math.max(platform.width / 2, Math.min(GAME_WIDTH - platform.width / 2, newX)); platform.x = newX; platform.y = newY; game.addChild(platform); platforms.push(platform); lastX = newX; lastY = newY; // Add a crystal to each platform var crystal = new Crystal(); crystal.x = platform.x; crystal.y = platform.y - 50; // Position crystal above the platform game.addChild(crystal); crystals.push(crystal); // Add enemy on some platforms if (i > 0 && Math.random() < 0.3 && enemies.length < ENEMY_COUNT) { var enemy = new Enemy(); enemy.initialize(newX, newY - 50, platform.width * 0.8); game.addChild(enemy); enemies.push(enemy); } } // Add crystals in challenging positions for (var j = 0; j < CRYSTAL_COUNT; j++) { var crystal = new Crystal(); // Place crystals in challenging positions between platforms var platformIndex = Math.floor(Math.random() * (platforms.length - 1)) + 1; var platform1 = platforms[platformIndex - 1]; var platform2 = platforms[platformIndex]; crystal.x = platform1.x + (platform2.x - platform1.x) * 0.5; crystal.y = platform1.y + (platform2.y - platform1.y) * 0.5; game.addChild(crystal); crystals.push(crystal); } } function checkCollisions() { // Player-Platform collision platforms.forEach(function (platform) { if (player.y + 30 >= platform.y - platform.height / 2 && player.y - 30 <= platform.y + platform.height / 2 && player.x + 30 >= platform.x - platform.width / 2 && player.x - 30 <= platform.x + platform.width / 2 && player.velocity.y > 0) { player.y = platform.y - platform.height / 2 - 30; player.velocity.y = 0; player.isGrounded = true; } }); // Player-Enemy collision enemies.forEach(function (enemy, index) { if (player.isDashing && player.intersects(enemy)) { // Destroy enemy if player is dashing LK.effects.flashObject(enemy, 0xff0000, 300); LK.getSound('enemyDefeat').play(); LK.setTimeout(function () { enemy.destroy(); enemies.splice(index, 1); }, 300); } else if (!player.isDashing && player.intersects(enemy)) { // Player dies if not dashing LK.effects.flashScreen(0xff0000, 1000); resetGame(); } }); // Player-Crystal collision crystals.forEach(function (crystal, index) { if (!crystal.collected && player.intersects(crystal)) { crystal.collected = true; crystalsCollected++; // Visual effect tween(crystal, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 500, onFinish: function onFinish() { crystal.destroy(); crystals.splice(index, 1); } }); // Update UI crystalCountText.setText("Crystals: " + crystalsCollected + "/" + totalCrystals); // Play sound LK.getSound('crystal').play(); // Upgrade player player.upgradeDash(); } }); // Player-Portal collision if (player.intersects(portal)) { // Complete level LK.getSound('portalReached').play(); // Transition effect tween(portal, { scaleX: 3, scaleY: 3, alpha: 0.2 }, { duration: 1000, onFinish: function onFinish() { // Save progress and go to next level currentLevel++; storage.currentLevel = currentLevel; // Check if all levels are completed if (currentLevel > 10) { LK.showYouWin(); } else { // Transition to the next level setupGame(); } } }); } // Check if player fell off the bottom of the screen if (player.y > GAME_HEIGHT + 100) { LK.effects.flashScreen(0xff0000, 1000); resetGame(); } } function resetGame() { // Destroy existing entities if (player) { player.destroy(); } platforms.forEach(function (p) { return p.destroy(); }); enemies.forEach(function (e) { return e.destroy(); }); crystals.forEach(function (c) { return c.destroy(); }); if (portal) { portal.destroy(); } // Remove UI LK.gui.top.removeChild(levelText); LK.gui.topRight.removeChild(crystalCountText); // Final score text is not displayed, so no need to remove it // Setup new game setupGame(); } // Mouse/touch controls var startDragX = 0; var startDragY = 0; var isDragging = false; game.down = function (x, y) { startDragX = x; startDragY = y; isDragging = true; }; game.move = function (x, y) { // Used for drag-to-dash functionality }; game.up = function (x, y) { if (!isDragging || !player) { return; } // Calculate direction vector var dirX = x - startDragX; var dirY = y - startDragY; // Calculate magnitude var magnitude = Math.sqrt(dirX * dirX + dirY * dirY); // If the drag was long enough, dash in that direction if (magnitude > 30) { player.dash(dirX / magnitude, dirY / magnitude); } else { player.jump(); } isDragging = false; }; // Main game loop game.update = function () { // Skip if game hasn't been set up yet if (!player) { return; } // Update all game entities player.update(); platforms.forEach(function (platform) { return platform.update && platform.update(); }); enemies.forEach(function (enemy) { return enemy.update(); }); crystals.forEach(function (crystal) { return crystal.update(); }); if (portal) { portal.update(); } // Check for collisions checkCollisions(); }; // Initialize game setupGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Crystal = Container.expand(function () {
var self = Container.call(this);
var crystalGraphics = self.attachAsset('crystal', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.update = function () {
// Simple hover animation
self.y += Math.sin(LK.ticks / 10) * 0.5;
// Simple rotation
crystalGraphics.rotation += 0.02;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 1,
y: 0
};
self.patrolDistance = 100;
self.startX = 0;
self.direction = 1;
self.update = function () {
self.x += self.velocity.x * self.direction;
if (self.x < 0) {
self.x = 0;
self.direction *= -1;
} else if (self.x > GAME_WIDTH) {
self.x = GAME_WIDTH;
self.direction *= -1;
}
// Change direction when patrol limit reached
if (Math.abs(self.x - self.startX) > self.patrolDistance) {
self.direction *= -1;
}
};
self.initialize = function (x, y, patrolDistance) {
self.x = x;
self.y = y;
self.startX = x;
self.patrolDistance = patrolDistance || 100;
};
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;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player visual
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Player properties
self.velocity = {
x: 0,
y: 0
};
self.gravity = 0.1;
self.jumpStrength = -15;
self.isGrounded = false;
self.canDash = true;
self.dashCooldown = 30; // frames
self.dashCooldownTimer = 0;
self.dashSpeed = 10;
self.dashDuration = 10; // frames
self.dashTimer = 0;
self.isDashing = false;
self.dashDirection = {
x: 0,
y: 0
};
self.dashDistanceMultiplier = 1;
// Dash effect
var dashEffect = self.attachAsset('dashEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.update = function () {
// Apply gravity if not dashing
if (!self.isDashing) {
self.velocity.y += self.gravity;
}
// Handle dash cooldown
if (!self.canDash) {
self.dashCooldownTimer--;
if (self.dashCooldownTimer <= 0) {
self.canDash = true;
}
}
// Handle dash execution
if (self.isDashing) {
self.dashTimer--;
// Apply dash movement
self.x += self.dashDirection.x * self.dashSpeed * self.dashDistanceMultiplier;
self.y += self.dashDirection.y * self.dashSpeed * self.dashDistanceMultiplier;
// End dash
if (self.dashTimer <= 0) {
self.isDashing = false;
tween(dashEffect, {
alpha: 0
}, {
duration: 200
});
self.velocity.x = self.dashDirection.x * 5; // Maintain some momentum
self.velocity.y = self.dashDirection.y * 5;
}
} else {
// Normal movement
self.x += self.velocity.x;
if (self.x < 0) {
self.x = 0;
self.velocity.x = 0;
} else if (self.x > GAME_WIDTH) {
self.x = GAME_WIDTH;
self.velocity.x = 0;
}
self.y += self.velocity.y;
// Dampen horizontal velocity
self.velocity.x *= 0.95;
}
// Reset grounded status each frame
self.isGrounded = false;
};
self.dash = function (dirX, dirY) {
if (!self.canDash) {
return;
}
// Normalize direction
var magnitude = Math.sqrt(dirX * dirX + dirY * dirY);
if (magnitude === 0) {
return;
} // Prevent division by zero
self.dashDirection.x = dirX / magnitude;
self.dashDirection.y = dirY / magnitude;
// Start dash
self.isDashing = true;
self.dashTimer = self.dashDuration;
self.velocity.x = 0;
self.velocity.y = 0;
// Start cooldown
self.canDash = false;
self.dashCooldownTimer = self.dashCooldown;
// Visual effect
dashEffect.x = 0;
dashEffect.y = 0;
tween(dashEffect, {
alpha: 0.7
}, {
duration: 100
});
// Play sound
LK.getSound('dash').play();
};
self.jump = function () {
if (self.isGrounded) {
self.velocity.y = self.jumpStrength;
self.isGrounded = false;
} else if (!self.isDashing && self.canDash) {
self.dash(0, -1); // Perform a vertical dash if in the air and dash is available
}
};
self.upgradeDash = function () {
// Increase dash distance
self.dashDistanceMultiplier += 0.2;
if (self.dashDistanceMultiplier > 2) {
self.dashDistanceMultiplier = 2;
}
// Decrease cooldown
self.dashCooldown -= 5;
if (self.dashCooldown < 15) {
self.dashCooldown = 15;
}
};
return self;
});
var Portal = Container.expand(function () {
var self = Container.call(this);
var portalGraphics = self.attachAsset('portal', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Portal pulsing effect
var scale = 1 + Math.sin(LK.ticks / 15) * 0.1;
portalGraphics.scale.set(scale, scale);
// Portal rotation
portalGraphics.rotation += 0.01;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLATFORM_COUNT = 5;
var ENEMY_COUNT = 5;
var CRYSTAL_COUNT = 3;
// Game state
var currentLevel = storage.currentLevel || 1;
var crystalsCollected = 0;
var totalCrystals = 0;
// Game entities
var player;
var platforms = [];
var enemies = [];
var crystals = [];
var portal;
// UI elements
var levelText = new Text2("Level " + currentLevel, {
size: 80,
fill: 0xFFFFFF
});
var crystalCountText = new Text2("Crystals: 0/" + CRYSTAL_COUNT, {
size: 60,
fill: 0xFFFFFF
});
// Setup game elements
function setupGame() {
// Add background
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT / 2
});
game.addChild(background);
// Create player
platforms = [];
enemies = [];
crystals = [];
crystalsCollected = 0;
totalCrystals = CRYSTAL_COUNT;
// Create player
player = new Player();
player.x = GAME_WIDTH / 2;
player.y = GAME_HEIGHT - 200;
game.addChild(player);
// Create initial platform under player
var startPlatform = new Platform();
startPlatform.x = GAME_WIDTH / 2;
startPlatform.y = GAME_HEIGHT - 150;
game.addChild(startPlatform);
platforms.push(startPlatform);
// Generate level
generateLevel();
// Add portal at the highest platform
var highestPlatform = platforms.reduce(function (prev, current) {
return prev.y < current.y ? prev : current;
});
portal = new Portal();
portal.x = highestPlatform.x;
portal.y = highestPlatform.y - 100;
game.addChild(portal);
// Update UI
levelText.setText("Level " + currentLevel);
crystalCountText.setText("Crystals: " + crystalsCollected + "/" + totalCrystals);
// Add UI to game
LK.gui.top.addChild(levelText);
levelText.anchor.set(0.5, 0);
levelText.y = 50;
LK.gui.topRight.addChild(crystalCountText);
crystalCountText.anchor.set(1, 0);
crystalCountText.x = -50;
crystalCountText.y = 50;
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
}
function generateLevel() {
// Generate platforms with increasing difficulty based on level
var minGapX = 100 + currentLevel * 5; // Adjusted minimum horizontal gap
var maxGapX = 200 + currentLevel * 10; // Adjusted maximum horizontal gap
var minGapY = 100; // Adjusted minimum vertical gap
var maxGapY = 150 + currentLevel * 5; // Adjusted maximum vertical gap
var lastX = GAME_WIDTH / 2;
var lastY = GAME_HEIGHT - 150;
for (var i = 0; i < PLATFORM_COUNT; i++) {
var platform = new Platform();
// Calculate new position with gaps
var gapX = Math.random() * (maxGapX - minGapX) + minGapX;
var gapY = Math.random() * (maxGapY - minGapY) + minGapY;
// Alternate direction
var directionX = Math.random() > 0.5 ? 1 : -1;
var newX = lastX + gapX * directionX;
var newY = lastY - gapY;
// Keep platforms within bounds
newX = Math.max(platform.width / 2, Math.min(GAME_WIDTH - platform.width / 2, newX));
platform.x = newX;
platform.y = newY;
game.addChild(platform);
platforms.push(platform);
lastX = newX;
lastY = newY;
// Add a crystal to each platform
var crystal = new Crystal();
crystal.x = platform.x;
crystal.y = platform.y - 50; // Position crystal above the platform
game.addChild(crystal);
crystals.push(crystal);
// Add enemy on some platforms
if (i > 0 && Math.random() < 0.3 && enemies.length < ENEMY_COUNT) {
var enemy = new Enemy();
enemy.initialize(newX, newY - 50, platform.width * 0.8);
game.addChild(enemy);
enemies.push(enemy);
}
}
// Add crystals in challenging positions
for (var j = 0; j < CRYSTAL_COUNT; j++) {
var crystal = new Crystal();
// Place crystals in challenging positions between platforms
var platformIndex = Math.floor(Math.random() * (platforms.length - 1)) + 1;
var platform1 = platforms[platformIndex - 1];
var platform2 = platforms[platformIndex];
crystal.x = platform1.x + (platform2.x - platform1.x) * 0.5;
crystal.y = platform1.y + (platform2.y - platform1.y) * 0.5;
game.addChild(crystal);
crystals.push(crystal);
}
}
function checkCollisions() {
// Player-Platform collision
platforms.forEach(function (platform) {
if (player.y + 30 >= platform.y - platform.height / 2 && player.y - 30 <= platform.y + platform.height / 2 && player.x + 30 >= platform.x - platform.width / 2 && player.x - 30 <= platform.x + platform.width / 2 && player.velocity.y > 0) {
player.y = platform.y - platform.height / 2 - 30;
player.velocity.y = 0;
player.isGrounded = true;
}
});
// Player-Enemy collision
enemies.forEach(function (enemy, index) {
if (player.isDashing && player.intersects(enemy)) {
// Destroy enemy if player is dashing
LK.effects.flashObject(enemy, 0xff0000, 300);
LK.getSound('enemyDefeat').play();
LK.setTimeout(function () {
enemy.destroy();
enemies.splice(index, 1);
}, 300);
} else if (!player.isDashing && player.intersects(enemy)) {
// Player dies if not dashing
LK.effects.flashScreen(0xff0000, 1000);
resetGame();
}
});
// Player-Crystal collision
crystals.forEach(function (crystal, index) {
if (!crystal.collected && player.intersects(crystal)) {
crystal.collected = true;
crystalsCollected++;
// Visual effect
tween(crystal, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 500,
onFinish: function onFinish() {
crystal.destroy();
crystals.splice(index, 1);
}
});
// Update UI
crystalCountText.setText("Crystals: " + crystalsCollected + "/" + totalCrystals);
// Play sound
LK.getSound('crystal').play();
// Upgrade player
player.upgradeDash();
}
});
// Player-Portal collision
if (player.intersects(portal)) {
// Complete level
LK.getSound('portalReached').play();
// Transition effect
tween(portal, {
scaleX: 3,
scaleY: 3,
alpha: 0.2
}, {
duration: 1000,
onFinish: function onFinish() {
// Save progress and go to next level
currentLevel++;
storage.currentLevel = currentLevel;
// Check if all levels are completed
if (currentLevel > 10) {
LK.showYouWin();
} else {
// Transition to the next level
setupGame();
}
}
});
}
// Check if player fell off the bottom of the screen
if (player.y > GAME_HEIGHT + 100) {
LK.effects.flashScreen(0xff0000, 1000);
resetGame();
}
}
function resetGame() {
// Destroy existing entities
if (player) {
player.destroy();
}
platforms.forEach(function (p) {
return p.destroy();
});
enemies.forEach(function (e) {
return e.destroy();
});
crystals.forEach(function (c) {
return c.destroy();
});
if (portal) {
portal.destroy();
}
// Remove UI
LK.gui.top.removeChild(levelText);
LK.gui.topRight.removeChild(crystalCountText);
// Final score text is not displayed, so no need to remove it
// Setup new game
setupGame();
}
// Mouse/touch controls
var startDragX = 0;
var startDragY = 0;
var isDragging = false;
game.down = function (x, y) {
startDragX = x;
startDragY = y;
isDragging = true;
};
game.move = function (x, y) {
// Used for drag-to-dash functionality
};
game.up = function (x, y) {
if (!isDragging || !player) {
return;
}
// Calculate direction vector
var dirX = x - startDragX;
var dirY = y - startDragY;
// Calculate magnitude
var magnitude = Math.sqrt(dirX * dirX + dirY * dirY);
// If the drag was long enough, dash in that direction
if (magnitude > 30) {
player.dash(dirX / magnitude, dirY / magnitude);
} else {
player.jump();
}
isDragging = false;
};
// Main game loop
game.update = function () {
// Skip if game hasn't been set up yet
if (!player) {
return;
}
// Update all game entities
player.update();
platforms.forEach(function (platform) {
return platform.update && platform.update();
});
enemies.forEach(function (enemy) {
return enemy.update();
});
crystals.forEach(function (crystal) {
return crystal.update();
});
if (portal) {
portal.update();
}
// Check for collisions
checkCollisions();
};
// Initialize game
setupGame();
chibi 8 bit image green hopper insect anime protagonist. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
8 bit image anime green leaf. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
8 bit image 2d brown classic old door with beehive pattern. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows