/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Cloud obstacle var Cloud = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5 }); self.radius = sprite.width / 2; self.vx = -10; self.update = function () { self.x += self.vx; }; return self; }); // Ember collectible var Ember = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('ember', { anchorX: 0.5, anchorY: 0.5 }); self.radius = sprite.width / 2; self.vx = -12; self.update = function () { self.x += self.vx; }; return self; }); // Falcon (Richard) class var Falcon = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('falcon', { anchorX: 0.5, anchorY: 0.5 }); self.radius = sprite.width / 2; self.vx = 18; self.update = function () { self.x += self.vx; }; return self; }); // Phoenix (Vixen) class var Phoenix = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('phoenix', { anchorX: 0.5, anchorY: 0.5 }); self.radius = sprite.width / 2; self.energy = 0; // 0-1 self.isTransformed = false; self.update = function () { // No auto-movement; movement is handled by drag/touch }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1e2a44 }); /**** * Game Code ****/ // Energy bar fill // Energy bar background // Dark cloud (obstacle) // Ember collectible // Falcon (Richard) // Phoenix (Vixen) // Game state var phoenix, falcon; var embers = []; var clouds = []; var dragNode = null; var energyBarBg, energyBarFill; var score = 0; var scoreTxt; var energy = 0; // 0-1 var inBonusStage = false; var bonusTimer = 0; var lastPhoenixPos = { x: 0, y: 0 }; // Place Phoenix at start phoenix = new Phoenix(); phoenix.x = 400; phoenix.y = 1366; game.addChild(phoenix); // Energy bar UI energyBarBg = LK.getAsset('energyBarBg', { anchorX: 0, anchorY: 0.5, x: 724, y: 120 }); energyBarFill = LK.getAsset('energyBarFill', { anchorX: 0, anchorY: 0.5, x: 724, y: 120 }); energyBarFill.width = 0; LK.gui.top.addChild(energyBarBg); LK.gui.top.addChild(energyBarFill); // Score UI scoreTxt = new Text2('0', { size: 100, fill: '#fff' }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.x = 2048 / 2; scoreTxt.y = 30; // Helper: spawn ember function spawnEmber() { var ember = new Ember(); ember.x = 2048 + 80; ember.y = 300 + Math.floor(Math.random() * (2732 - 600)); embers.push(ember); game.addChild(ember); } // Helper: spawn cloud function spawnCloud() { var cloud = new Cloud(); cloud.x = 2048 + 120; cloud.y = 200 + Math.floor(Math.random() * (2732 - 400)); clouds.push(cloud); game.addChild(cloud); } // Dragging Phoenix function handleMove(x, y, obj) { if (dragNode && !inBonusStage) { // Clamp to screen, avoid top left 100x100 var nx = Math.max(phoenix.radius + 100, Math.min(2048 - phoenix.radius, x)); var ny = Math.max(phoenix.radius, Math.min(2732 - phoenix.radius, y)); dragNode.x = nx; dragNode.y = ny; } } game.move = handleMove; game.down = function (x, y, obj) { // Only allow drag if not in bonus if (!inBonusStage) { dragNode = phoenix; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Main update loop game.update = function () { // Phoenix stage if (!inBonusStage) { // Spawn embers if (LK.ticks % 45 === 0) { spawnEmber(); } // Spawn clouds if (LK.ticks % 90 === 0) { spawnCloud(); } // Update embers for (var i = embers.length - 1; i >= 0; i--) { var ember = embers[i]; ember.update(); // Off screen if (ember.x < -80) { ember.destroy(); embers.splice(i, 1); continue; } // Collect if (phoenix.intersects(ember)) { ember.destroy(); embers.splice(i, 1); score += 1; if (energy < 1) { energy += 0.08; if (energy > 1) energy = 1; } scoreTxt.setText(score); // Animate energy bar tween(energyBarFill, { width: 600 * energy }, { duration: 200, easing: tween.cubicOut }); } } // Update clouds for (var j = clouds.length - 1; j >= 0; j--) { var cloud = clouds[j]; cloud.update(); if (cloud.x < -120) { cloud.destroy(); clouds.splice(j, 1); continue; } // Hit if (phoenix.intersects(cloud)) { // Flash, game over LK.effects.flashScreen(0x222244, 900); LK.showGameOver(); return; } } // Energy full: transform! if (energy >= 1 && !phoenix.isTransformed) { phoenix.isTransformed = true; // Animate: fade out phoenix, fade in falcon tween(phoenix, { alpha: 0 }, { duration: 600, easing: tween.linear, onFinish: function onFinish() { phoenix.visible = false; startBonusStage(); } }); } } // Bonus stage: Falcon if (inBonusStage && falcon) { falcon.update(); // End bonus after 4 seconds or off screen bonusTimer++; if (falcon.x > 2048 + 200 || bonusTimer > 240) { LK.showYouWin(); return; } } }; // Start bonus stage: Falcon function startBonusStage() { inBonusStage = true; // Remove embers/clouds for (var i = 0; i < embers.length; i++) embers[i].destroy(); for (var j = 0; j < clouds.length; j++) clouds[j].destroy(); embers = []; clouds = []; // Place Falcon at Phoenix's last position falcon = new Falcon(); falcon.x = phoenix.x; falcon.y = phoenix.y; game.addChild(falcon); bonusTimer = 0; // Animate falcon in falcon.alpha = 0; tween(falcon, { alpha: 1 }, { duration: 400, easing: tween.linear }); // Animate energy bar out tween(energyBarBg, { alpha: 0 }, { duration: 400 }); tween(energyBarFill, { alpha: 0 }, { duration: 400 }); } // Set initial energy bar width energyBarFill.width = 0; // Place UI elements energyBarBg.y = 120; energyBarFill.y = 120; energyBarBg.x = 724; energyBarFill.x = 724; // Make sure phoenix is above clouds/embers phoenix.zIndex = 10; // Initial score scoreTxt.setText(score); // Ensure all elements are visible and not in top left 100x100 phoenix.x = Math.max(phoenix.radius + 100, phoenix.x); phoenix.y = Math.max(phoenix.radius, phoenix.y);
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,297 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Cloud obstacle
+var Cloud = Container.expand(function () {
+ var self = Container.call(this);
+ var sprite = self.attachAsset('cloud', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = sprite.width / 2;
+ self.vx = -10;
+ self.update = function () {
+ self.x += self.vx;
+ };
+ return self;
+});
+// Ember collectible
+var Ember = Container.expand(function () {
+ var self = Container.call(this);
+ var sprite = self.attachAsset('ember', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = sprite.width / 2;
+ self.vx = -12;
+ self.update = function () {
+ self.x += self.vx;
+ };
+ return self;
+});
+// Falcon (Richard) class
+var Falcon = Container.expand(function () {
+ var self = Container.call(this);
+ var sprite = self.attachAsset('falcon', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = sprite.width / 2;
+ self.vx = 18;
+ self.update = function () {
+ self.x += self.vx;
+ };
+ return self;
+});
+// Phoenix (Vixen) class
+var Phoenix = Container.expand(function () {
+ var self = Container.call(this);
+ var sprite = self.attachAsset('phoenix', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = sprite.width / 2;
+ self.energy = 0; // 0-1
+ self.isTransformed = false;
+ self.update = function () {
+ // No auto-movement; movement is handled by drag/touch
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x1e2a44
+});
+
+/****
+* Game Code
+****/
+// Energy bar fill
+// Energy bar background
+// Dark cloud (obstacle)
+// Ember collectible
+// Falcon (Richard)
+// Phoenix (Vixen)
+// Game state
+var phoenix, falcon;
+var embers = [];
+var clouds = [];
+var dragNode = null;
+var energyBarBg, energyBarFill;
+var score = 0;
+var scoreTxt;
+var energy = 0; // 0-1
+var inBonusStage = false;
+var bonusTimer = 0;
+var lastPhoenixPos = {
+ x: 0,
+ y: 0
+};
+// Place Phoenix at start
+phoenix = new Phoenix();
+phoenix.x = 400;
+phoenix.y = 1366;
+game.addChild(phoenix);
+// Energy bar UI
+energyBarBg = LK.getAsset('energyBarBg', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 724,
+ y: 120
+});
+energyBarFill = LK.getAsset('energyBarFill', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 724,
+ y: 120
+});
+energyBarFill.width = 0;
+LK.gui.top.addChild(energyBarBg);
+LK.gui.top.addChild(energyBarFill);
+// Score UI
+scoreTxt = new Text2('0', {
+ size: 100,
+ fill: '#fff'
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+scoreTxt.x = 2048 / 2;
+scoreTxt.y = 30;
+// Helper: spawn ember
+function spawnEmber() {
+ var ember = new Ember();
+ ember.x = 2048 + 80;
+ ember.y = 300 + Math.floor(Math.random() * (2732 - 600));
+ embers.push(ember);
+ game.addChild(ember);
+}
+// Helper: spawn cloud
+function spawnCloud() {
+ var cloud = new Cloud();
+ cloud.x = 2048 + 120;
+ cloud.y = 200 + Math.floor(Math.random() * (2732 - 400));
+ clouds.push(cloud);
+ game.addChild(cloud);
+}
+// Dragging Phoenix
+function handleMove(x, y, obj) {
+ if (dragNode && !inBonusStage) {
+ // Clamp to screen, avoid top left 100x100
+ var nx = Math.max(phoenix.radius + 100, Math.min(2048 - phoenix.radius, x));
+ var ny = Math.max(phoenix.radius, Math.min(2732 - phoenix.radius, y));
+ dragNode.x = nx;
+ dragNode.y = ny;
+ }
+}
+game.move = handleMove;
+game.down = function (x, y, obj) {
+ // Only allow drag if not in bonus
+ if (!inBonusStage) {
+ dragNode = phoenix;
+ handleMove(x, y, obj);
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Main update loop
+game.update = function () {
+ // Phoenix stage
+ if (!inBonusStage) {
+ // Spawn embers
+ if (LK.ticks % 45 === 0) {
+ spawnEmber();
+ }
+ // Spawn clouds
+ if (LK.ticks % 90 === 0) {
+ spawnCloud();
+ }
+ // Update embers
+ for (var i = embers.length - 1; i >= 0; i--) {
+ var ember = embers[i];
+ ember.update();
+ // Off screen
+ if (ember.x < -80) {
+ ember.destroy();
+ embers.splice(i, 1);
+ continue;
+ }
+ // Collect
+ if (phoenix.intersects(ember)) {
+ ember.destroy();
+ embers.splice(i, 1);
+ score += 1;
+ if (energy < 1) {
+ energy += 0.08;
+ if (energy > 1) energy = 1;
+ }
+ scoreTxt.setText(score);
+ // Animate energy bar
+ tween(energyBarFill, {
+ width: 600 * energy
+ }, {
+ duration: 200,
+ easing: tween.cubicOut
+ });
+ }
+ }
+ // Update clouds
+ for (var j = clouds.length - 1; j >= 0; j--) {
+ var cloud = clouds[j];
+ cloud.update();
+ if (cloud.x < -120) {
+ cloud.destroy();
+ clouds.splice(j, 1);
+ continue;
+ }
+ // Hit
+ if (phoenix.intersects(cloud)) {
+ // Flash, game over
+ LK.effects.flashScreen(0x222244, 900);
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Energy full: transform!
+ if (energy >= 1 && !phoenix.isTransformed) {
+ phoenix.isTransformed = true;
+ // Animate: fade out phoenix, fade in falcon
+ tween(phoenix, {
+ alpha: 0
+ }, {
+ duration: 600,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ phoenix.visible = false;
+ startBonusStage();
+ }
+ });
+ }
+ }
+ // Bonus stage: Falcon
+ if (inBonusStage && falcon) {
+ falcon.update();
+ // End bonus after 4 seconds or off screen
+ bonusTimer++;
+ if (falcon.x > 2048 + 200 || bonusTimer > 240) {
+ LK.showYouWin();
+ return;
+ }
+ }
+};
+// Start bonus stage: Falcon
+function startBonusStage() {
+ inBonusStage = true;
+ // Remove embers/clouds
+ for (var i = 0; i < embers.length; i++) embers[i].destroy();
+ for (var j = 0; j < clouds.length; j++) clouds[j].destroy();
+ embers = [];
+ clouds = [];
+ // Place Falcon at Phoenix's last position
+ falcon = new Falcon();
+ falcon.x = phoenix.x;
+ falcon.y = phoenix.y;
+ game.addChild(falcon);
+ bonusTimer = 0;
+ // Animate falcon in
+ falcon.alpha = 0;
+ tween(falcon, {
+ alpha: 1
+ }, {
+ duration: 400,
+ easing: tween.linear
+ });
+ // Animate energy bar out
+ tween(energyBarBg, {
+ alpha: 0
+ }, {
+ duration: 400
+ });
+ tween(energyBarFill, {
+ alpha: 0
+ }, {
+ duration: 400
+ });
+}
+// Set initial energy bar width
+energyBarFill.width = 0;
+// Place UI elements
+energyBarBg.y = 120;
+energyBarFill.y = 120;
+energyBarBg.x = 724;
+energyBarFill.x = 724;
+// Make sure phoenix is above clouds/embers
+phoenix.zIndex = 10;
+// Initial score
+scoreTxt.setText(score);
+// Ensure all elements are visible and not in top left 100x100
+phoenix.x = Math.max(phoenix.radius + 100, phoenix.x);
+phoenix.y = Math.max(phoenix.radius, phoenix.y);
\ No newline at end of file