User prompt
range of platform not to far
User prompt
player and enemies can move left and right
User prompt
player movement light movement
User prompt
reduce more player speed
User prompt
reduce speed player
User prompt
make platform and platform not to closed
User prompt
go another level after win
User prompt
range of platform dont to far
User prompt
erase text final score
User prompt
add crystal every platform
User prompt
just 5 platforms
User prompt
limited platform just 7 platforms
User prompt
restart level when game over
User prompt
restart level when game over
User prompt
add asset background
User prompt
7x jump
User prompt
erase unlimited jump
User prompt
unlimited jump
User prompt
5x jump
User prompt
reduce speed player
User prompt
jump attack
Code edit (1 edits merged)
Please save this source code
User prompt
Dash Assault: Aerial Onslaught
User prompt
Please continue polishing my design document.
Initial prompt
make static random platform. dash attack game.
/****
* 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;
// 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.5;
self.jumpStrength = -12;
self.isGrounded = false;
self.canDash = true;
self.dashCooldown = 30; // frames
self.dashCooldownTimer = 0;
self.dashSpeed = 20;
self.dashDuration = 15; // 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;
self.y += self.velocity.y;
// Dampen horizontal velocity
self.velocity.x *= 0.9;
}
// 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;
}
};
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 = 10;
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() {
// Reset state
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 * 20;
var maxGapX = 300 + currentLevel * 30;
var minGapY = 120;
var maxGapY = 200 + currentLevel * 10;
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 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);
LK.showGameOver();
}
});
// 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 {
resetGame();
}
}
});
}
// Check if player fell off the bottom of the screen
if (player.y > GAME_HEIGHT + 100) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
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);
// 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 if (player.isGrounded) {
// Short tap = jump if on ground
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(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,488 @@
-/****
+/****
+* 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;
+ // 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.5;
+ self.jumpStrength = -12;
+ self.isGrounded = false;
+ self.canDash = true;
+ self.dashCooldown = 30; // frames
+ self.dashCooldownTimer = 0;
+ self.dashSpeed = 20;
+ self.dashDuration = 15; // 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;
+ self.y += self.velocity.y;
+ // Dampen horizontal velocity
+ self.velocity.x *= 0.9;
+ }
+ // 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;
+ }
+ };
+ 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: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87CEEB
+});
+
+/****
+* Game Code
+****/
+// Constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var PLATFORM_COUNT = 10;
+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() {
+ // Reset state
+ 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 * 20;
+ var maxGapX = 300 + currentLevel * 30;
+ var minGapY = 120;
+ var maxGapY = 200 + currentLevel * 10;
+ 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 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);
+ LK.showGameOver();
+ }
+ });
+ // 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 {
+ resetGame();
+ }
+ }
+ });
+ }
+ // Check if player fell off the bottom of the screen
+ if (player.y > GAME_HEIGHT + 100) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ }
+}
+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);
+ // 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 if (player.isGrounded) {
+ // Short tap = jump if on ground
+ 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();
\ No newline at end of file
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