/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ // Bonus class: falls from top, destroys itself when off screen var Bonus = Container.expand(function () { var self = Container.call(this); var gfx = self.attachAsset('bonus', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; // Will be increased as game progresses self.update = function () { self.y += self.speed; }; return self; }); // Obstacle class: falls from top, destroys itself when off screen var Obstacle = Container.expand(function () { var self = Container.call(this); var gfx = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; // Will be increased as game progresses self.update = function () { self.y += self.speed; }; return self; }); // Player class: follows face position var Player = Container.expand(function () { var self = Container.call(this); var gfx = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // No update needed; position is set by facekit in main game loop return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Player: blue ellipse // Bonus: yellow ellipse // Obstacles: gray boxes // Game variables var player = new Player(); game.addChild(player); player.x = 2048 / 2; player.y = 2732 - 350; // Start near bottom var obstacles = []; var bonuses = []; var score = 0; var bonusScore = 0; var gameOver = false; var ticksSurvived = 0; // Score text var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Bonus text var bonusTxt = new Text2('', { size: 80, fill: 0xFFE066 }); bonusTxt.anchor.set(0.5, 0); LK.gui.top.addChild(bonusTxt); bonusTxt.y = 130; // Difficulty progression var obstacleInterval = 60; // ticks between obstacles (start: 1/sec) var bonusInterval = 180; // ticks between bonuses (start: 1/3sec) var minObstacleInterval = 18; // fastest: ~3/sec var minBonusInterval = 240; // slowest: ~1/4sec var lastObstacleTick = 0; var lastBonusTick = 0; var obstacleSpeed = 12; var bonusSpeed = 10; var speedIncreaseEvery = 600; // every 10 seconds // Main update loop game.update = function () { if (gameOver) return; // Update player position from facekit // Clamp to game area var fx = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : 2048 / 2; var fy = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : 2732 - 350; // Keep player inside bounds var px = Math.max(player.width / 2, Math.min(2048 - player.width / 2, fx)); var py = Math.max(player.height / 2 + 100, Math.min(2732 - player.height / 2, fy)); player.x = px; player.y = py; // Spawn obstacles if (LK.ticks - lastObstacleTick >= obstacleInterval) { var obs = new Obstacle(); obs.x = Math.random() * (2048 - 200) + 100; obs.y = -obs.height / 2; obs.speed = obstacleSpeed; obstacles.push(obs); game.addChild(obs); lastObstacleTick = LK.ticks; } // Spawn bonuses if (LK.ticks - lastBonusTick >= bonusInterval) { // 60% chance to spawn a bonus if (Math.random() < 0.6) { var bon = new Bonus(); bon.x = Math.random() * (2048 - 160) + 80; bon.y = -bon.height / 2; bon.speed = bonusSpeed; bonuses.push(bon); game.addChild(bon); } lastBonusTick = LK.ticks; } // Increase difficulty over time if (LK.ticks % speedIncreaseEvery === 0 && LK.ticks > 0) { if (obstacleInterval > minObstacleInterval) obstacleInterval -= 4; if (bonusInterval < minBonusInterval) bonusInterval += 8; obstacleSpeed += 1.5; bonusSpeed += 1; } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y - obs.height / 2 > 2732 + 50) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (obs.intersects(player)) { // Game over LK.effects.flashScreen(0xff0000, 800); gameOver = true; tween(player, { alpha: 0.2 }, { duration: 400, easing: tween.easeOut }); LK.setTimeout(function () { LK.showGameOver(); }, 900); return; } } // Update bonuses for (var j = bonuses.length - 1; j >= 0; j--) { var bon = bonuses[j]; bon.update(); // Remove if off screen if (bon.y - bon.height / 2 > 2732 + 50) { bon.destroy(); bonuses.splice(j, 1); continue; } // Collision with player if (bon.intersects(player)) { bonusScore += 1; score += 5; scoreTxt.setText(score); bonusTxt.setText('Bonuses: ' + bonusScore); // Flash bonus LK.effects.flashObject(bon, 0xffff00, 300); bon.destroy(); bonuses.splice(j, 1); continue; } } // Score: 1 point per 30 ticks survived ticksSurvived++; if (ticksSurvived % 30 === 0) { score += 1; scoreTxt.setText(score); } }; // Reset game state on restart game.on('reset', function () { // Remove all obstacles and bonuses for (var i = 0; i < obstacles.length; i++) { obstacles[i].destroy(); } for (var j = 0; j < bonuses.length; j++) { bonuses[j].destroy(); } obstacles = []; bonuses = []; score = 0; bonusScore = 0; ticksSurvived = 0; gameOver = false; player.x = 2048 / 2; player.y = 2732 - 350; scoreTxt.setText('0'); bonusTxt.setText(''); obstacleInterval = 60; bonusInterval = 180; obstacleSpeed = 12; bonusSpeed = 10; lastObstacleTick = 0; lastBonusTick = 0; }); // Show camera background game.setBackgroundColor(0x000000); // Camera will show behind game elements // No need to handle music, pause, or leaderboard
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,223 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+// Bonus class: falls from top, destroys itself when off screen
+var Bonus = Container.expand(function () {
+ var self = Container.call(this);
+ var gfx = self.attachAsset('bonus', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10; // Will be increased as game progresses
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Obstacle class: falls from top, destroys itself when off screen
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var gfx = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 12; // Will be increased as game progresses
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player class: follows face position
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var gfx = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // No update needed; position is set by facekit in main game loop
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Player: blue ellipse
+// Bonus: yellow ellipse
+// Obstacles: gray boxes
+// Game variables
+var player = new Player();
+game.addChild(player);
+player.x = 2048 / 2;
+player.y = 2732 - 350; // Start near bottom
+var obstacles = [];
+var bonuses = [];
+var score = 0;
+var bonusScore = 0;
+var gameOver = false;
+var ticksSurvived = 0;
+// Score text
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Bonus text
+var bonusTxt = new Text2('', {
+ size: 80,
+ fill: 0xFFE066
+});
+bonusTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(bonusTxt);
+bonusTxt.y = 130;
+// Difficulty progression
+var obstacleInterval = 60; // ticks between obstacles (start: 1/sec)
+var bonusInterval = 180; // ticks between bonuses (start: 1/3sec)
+var minObstacleInterval = 18; // fastest: ~3/sec
+var minBonusInterval = 240; // slowest: ~1/4sec
+var lastObstacleTick = 0;
+var lastBonusTick = 0;
+var obstacleSpeed = 12;
+var bonusSpeed = 10;
+var speedIncreaseEvery = 600; // every 10 seconds
+// Main update loop
+game.update = function () {
+ if (gameOver) return;
+ // Update player position from facekit
+ // Clamp to game area
+ var fx = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : 2048 / 2;
+ var fy = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : 2732 - 350;
+ // Keep player inside bounds
+ var px = Math.max(player.width / 2, Math.min(2048 - player.width / 2, fx));
+ var py = Math.max(player.height / 2 + 100, Math.min(2732 - player.height / 2, fy));
+ player.x = px;
+ player.y = py;
+ // Spawn obstacles
+ if (LK.ticks - lastObstacleTick >= obstacleInterval) {
+ var obs = new Obstacle();
+ obs.x = Math.random() * (2048 - 200) + 100;
+ obs.y = -obs.height / 2;
+ obs.speed = obstacleSpeed;
+ obstacles.push(obs);
+ game.addChild(obs);
+ lastObstacleTick = LK.ticks;
+ }
+ // Spawn bonuses
+ if (LK.ticks - lastBonusTick >= bonusInterval) {
+ // 60% chance to spawn a bonus
+ if (Math.random() < 0.6) {
+ var bon = new Bonus();
+ bon.x = Math.random() * (2048 - 160) + 80;
+ bon.y = -bon.height / 2;
+ bon.speed = bonusSpeed;
+ bonuses.push(bon);
+ game.addChild(bon);
+ }
+ lastBonusTick = LK.ticks;
+ }
+ // Increase difficulty over time
+ if (LK.ticks % speedIncreaseEvery === 0 && LK.ticks > 0) {
+ if (obstacleInterval > minObstacleInterval) obstacleInterval -= 4;
+ if (bonusInterval < minBonusInterval) bonusInterval += 8;
+ obstacleSpeed += 1.5;
+ bonusSpeed += 1;
+ }
+ // Update obstacles
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obs = obstacles[i];
+ obs.update();
+ // Remove if off screen
+ if (obs.y - obs.height / 2 > 2732 + 50) {
+ obs.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ // Collision with player
+ if (obs.intersects(player)) {
+ // Game over
+ LK.effects.flashScreen(0xff0000, 800);
+ gameOver = true;
+ tween(player, {
+ alpha: 0.2
+ }, {
+ duration: 400,
+ easing: tween.easeOut
+ });
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 900);
+ return;
+ }
+ }
+ // Update bonuses
+ for (var j = bonuses.length - 1; j >= 0; j--) {
+ var bon = bonuses[j];
+ bon.update();
+ // Remove if off screen
+ if (bon.y - bon.height / 2 > 2732 + 50) {
+ bon.destroy();
+ bonuses.splice(j, 1);
+ continue;
+ }
+ // Collision with player
+ if (bon.intersects(player)) {
+ bonusScore += 1;
+ score += 5;
+ scoreTxt.setText(score);
+ bonusTxt.setText('Bonuses: ' + bonusScore);
+ // Flash bonus
+ LK.effects.flashObject(bon, 0xffff00, 300);
+ bon.destroy();
+ bonuses.splice(j, 1);
+ continue;
+ }
+ }
+ // Score: 1 point per 30 ticks survived
+ ticksSurvived++;
+ if (ticksSurvived % 30 === 0) {
+ score += 1;
+ scoreTxt.setText(score);
+ }
+};
+// Reset game state on restart
+game.on('reset', function () {
+ // Remove all obstacles and bonuses
+ for (var i = 0; i < obstacles.length; i++) {
+ obstacles[i].destroy();
+ }
+ for (var j = 0; j < bonuses.length; j++) {
+ bonuses[j].destroy();
+ }
+ obstacles = [];
+ bonuses = [];
+ score = 0;
+ bonusScore = 0;
+ ticksSurvived = 0;
+ gameOver = false;
+ player.x = 2048 / 2;
+ player.y = 2732 - 350;
+ scoreTxt.setText('0');
+ bonusTxt.setText('');
+ obstacleInterval = 60;
+ bonusInterval = 180;
+ obstacleSpeed = 12;
+ bonusSpeed = 10;
+ lastObstacleTick = 0;
+ lastBonusTick = 0;
+});
+// Show camera background
+game.setBackgroundColor(0x000000); // Camera will show behind game elements
+// No need to handle music, pause, or leaderboard
\ No newline at end of file