/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obs = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Speed will be set on creation
self.speed = 0;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// For possible future effects
self.flash = function () {
LK.effects.flashObject(self, 0xffff00, 300);
};
return self;
});
// Point (collectible) class
var PointItem = Container.expand(function () {
var self = Container.call(this);
var pt = self.attachAsset('point', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Point: Green circle
// Obstacle: Red rectangles
// Character: A bright ellipse for the player
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_Y = GAME_HEIGHT - 400; // Player stays near bottom
var OBSTACLE_MIN_SPEED = 10;
var OBSTACLE_MAX_SPEED = 28;
var OBSTACLE_SPAWN_INTERVAL = 60; // in ticks (~1s)
var POINT_SPAWN_INTERVAL = 90; // in ticks (~1.5s)
var DIFFICULTY_INCREASE_INTERVAL = 600; // every 10s
var OBSTACLE_WIDTH = 180;
var OBSTACLE_HEIGHT = 80;
var POINT_SIZE = 80;
// Game state
var player;
var obstacles = [];
var points = [];
var score = 0;
var scoreTxt;
var ticksSinceLastObstacle = 0;
var ticksSinceLastPoint = 0;
var gameSpeed = 1;
var lastMouthX = GAME_WIDTH / 2;
var lastMouthY = PLAYER_Y;
var lastIntersectingObstacle = false;
var lastIntersectingPoint = false;
// Set up background to be camera feed
game.setBackgroundColor(0x000000); // Black, but facekit will show camera
// Score display
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create player
player = new Player();
player.x = GAME_WIDTH / 2;
player.y = PLAYER_Y;
game.addChild(player);
// Helper: Clamp value
function clamp(val, min, max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
// Helper: Random X for obstacles/points
function randomX(margin) {
return margin + Math.random() * (GAME_WIDTH - 2 * margin);
}
// Main update loop
game.update = function () {
// --- Face tracking: Move player ---
// Use mouth center if available, else nose tip
var faceX = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : facekit.noseTip && facekit.noseTip.x ? facekit.noseTip.x : lastMouthX;
var faceY = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : facekit.noseTip && facekit.noseTip.y ? facekit.noseTip.y : lastMouthY;
// Clamp to game area, keep player near bottom
var targetX = clamp(faceX, 60, GAME_WIDTH - 60);
var targetY = PLAYER_Y;
// Smooth movement (optional, can be direct for more responsive)
player.x += (targetX - player.x) * 0.35;
player.y = targetY;
lastMouthX = faceX;
lastMouthY = faceY;
// --- Spawn obstacles ---
ticksSinceLastObstacle++;
if (ticksSinceLastObstacle >= Math.max(OBSTACLE_SPAWN_INTERVAL - Math.floor(gameSpeed * 5), 30)) {
var obs = new Obstacle();
obs.x = randomX(OBSTACLE_WIDTH / 2 + 40);
obs.y = -OBSTACLE_HEIGHT / 2;
obs.speed = OBSTACLE_MIN_SPEED + Math.random() * (OBSTACLE_MAX_SPEED - OBSTACLE_MIN_SPEED) * (0.7 + 0.3 * gameSpeed);
obstacles.push(obs);
game.addChild(obs);
ticksSinceLastObstacle = 0;
}
// --- Spawn points ---
ticksSinceLastPoint++;
if (ticksSinceLastPoint >= Math.max(POINT_SPAWN_INTERVAL - Math.floor(gameSpeed * 5), 40)) {
var pt = new PointItem();
pt.x = randomX(POINT_SIZE / 2 + 40);
pt.y = -POINT_SIZE / 2;
pt.speed = OBSTACLE_MIN_SPEED + Math.random() * 8 * (0.7 + 0.3 * gameSpeed);
points.push(pt);
game.addChild(pt);
ticksSinceLastPoint = 0;
}
// --- Move obstacles, check collision ---
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.y - OBSTACLE_HEIGHT / 2 > GAME_HEIGHT + 100) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with player
var intersecting = player.intersects(obs);
if (intersecting) {
// Flash screen, show game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// --- Move points, check collection ---
for (var j = points.length - 1; j >= 0; j--) {
var pt = points[j];
pt.update();
// Remove if off screen
if (pt.y - POINT_SIZE / 2 > GAME_HEIGHT + 100) {
pt.destroy();
points.splice(j, 1);
continue;
}
// Collection
var intersecting = player.intersects(pt);
if (intersecting) {
// Flash player
player.flash();
score += 1;
scoreTxt.setText(score);
pt.destroy();
points.splice(j, 1);
continue;
}
}
// --- Increase difficulty over time ---
if (LK.ticks % DIFFICULTY_INCREASE_INTERVAL === 0) {
gameSpeed += 0.15;
}
};
// No touch/drag controls needed; all movement is via facekit
// Reset state on game over (handled by LK automatically)
LK.setScore(0); // For leaderboard integration
// End of file ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,198 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+// Obstacle class
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var obs = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Speed will be set on creation
+ self.speed = 0;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player class
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerSprite = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // For possible future effects
+ self.flash = function () {
+ LK.effects.flashObject(self, 0xffff00, 300);
+ };
+ return self;
+});
+// Point (collectible) class
+var PointItem = Container.expand(function () {
+ var self = Container.call(this);
+ var pt = self.attachAsset('point', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 0;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Point: Green circle
+// Obstacle: Red rectangles
+// Character: A bright ellipse for the player
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var PLAYER_Y = GAME_HEIGHT - 400; // Player stays near bottom
+var OBSTACLE_MIN_SPEED = 10;
+var OBSTACLE_MAX_SPEED = 28;
+var OBSTACLE_SPAWN_INTERVAL = 60; // in ticks (~1s)
+var POINT_SPAWN_INTERVAL = 90; // in ticks (~1.5s)
+var DIFFICULTY_INCREASE_INTERVAL = 600; // every 10s
+var OBSTACLE_WIDTH = 180;
+var OBSTACLE_HEIGHT = 80;
+var POINT_SIZE = 80;
+// Game state
+var player;
+var obstacles = [];
+var points = [];
+var score = 0;
+var scoreTxt;
+var ticksSinceLastObstacle = 0;
+var ticksSinceLastPoint = 0;
+var gameSpeed = 1;
+var lastMouthX = GAME_WIDTH / 2;
+var lastMouthY = PLAYER_Y;
+var lastIntersectingObstacle = false;
+var lastIntersectingPoint = false;
+// Set up background to be camera feed
+game.setBackgroundColor(0x000000); // Black, but facekit will show camera
+// Score display
+scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Create player
+player = new Player();
+player.x = GAME_WIDTH / 2;
+player.y = PLAYER_Y;
+game.addChild(player);
+// Helper: Clamp value
+function clamp(val, min, max) {
+ if (val < min) return min;
+ if (val > max) return max;
+ return val;
+}
+// Helper: Random X for obstacles/points
+function randomX(margin) {
+ return margin + Math.random() * (GAME_WIDTH - 2 * margin);
+}
+// Main update loop
+game.update = function () {
+ // --- Face tracking: Move player ---
+ // Use mouth center if available, else nose tip
+ var faceX = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : facekit.noseTip && facekit.noseTip.x ? facekit.noseTip.x : lastMouthX;
+ var faceY = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : facekit.noseTip && facekit.noseTip.y ? facekit.noseTip.y : lastMouthY;
+ // Clamp to game area, keep player near bottom
+ var targetX = clamp(faceX, 60, GAME_WIDTH - 60);
+ var targetY = PLAYER_Y;
+ // Smooth movement (optional, can be direct for more responsive)
+ player.x += (targetX - player.x) * 0.35;
+ player.y = targetY;
+ lastMouthX = faceX;
+ lastMouthY = faceY;
+ // --- Spawn obstacles ---
+ ticksSinceLastObstacle++;
+ if (ticksSinceLastObstacle >= Math.max(OBSTACLE_SPAWN_INTERVAL - Math.floor(gameSpeed * 5), 30)) {
+ var obs = new Obstacle();
+ obs.x = randomX(OBSTACLE_WIDTH / 2 + 40);
+ obs.y = -OBSTACLE_HEIGHT / 2;
+ obs.speed = OBSTACLE_MIN_SPEED + Math.random() * (OBSTACLE_MAX_SPEED - OBSTACLE_MIN_SPEED) * (0.7 + 0.3 * gameSpeed);
+ obstacles.push(obs);
+ game.addChild(obs);
+ ticksSinceLastObstacle = 0;
+ }
+ // --- Spawn points ---
+ ticksSinceLastPoint++;
+ if (ticksSinceLastPoint >= Math.max(POINT_SPAWN_INTERVAL - Math.floor(gameSpeed * 5), 40)) {
+ var pt = new PointItem();
+ pt.x = randomX(POINT_SIZE / 2 + 40);
+ pt.y = -POINT_SIZE / 2;
+ pt.speed = OBSTACLE_MIN_SPEED + Math.random() * 8 * (0.7 + 0.3 * gameSpeed);
+ points.push(pt);
+ game.addChild(pt);
+ ticksSinceLastPoint = 0;
+ }
+ // --- Move obstacles, check collision ---
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obs = obstacles[i];
+ obs.update();
+ // Remove if off screen
+ if (obs.y - OBSTACLE_HEIGHT / 2 > GAME_HEIGHT + 100) {
+ obs.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ // Collision with player
+ var intersecting = player.intersects(obs);
+ if (intersecting) {
+ // Flash screen, show game over
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ return;
+ }
+ }
+ // --- Move points, check collection ---
+ for (var j = points.length - 1; j >= 0; j--) {
+ var pt = points[j];
+ pt.update();
+ // Remove if off screen
+ if (pt.y - POINT_SIZE / 2 > GAME_HEIGHT + 100) {
+ pt.destroy();
+ points.splice(j, 1);
+ continue;
+ }
+ // Collection
+ var intersecting = player.intersects(pt);
+ if (intersecting) {
+ // Flash player
+ player.flash();
+ score += 1;
+ scoreTxt.setText(score);
+ pt.destroy();
+ points.splice(j, 1);
+ continue;
+ }
+ }
+ // --- Increase difficulty over time ---
+ if (LK.ticks % DIFFICULTY_INCREASE_INTERVAL === 0) {
+ gameSpeed += 0.15;
+ }
+};
+// No touch/drag controls needed; all movement is via facekit
+// Reset state on game over (handled by LK automatically)
+LK.setScore(0); // For leaderboard integration
+// End of file
\ No newline at end of file