/****
* 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
****/
// Camera background asset (used by facekit plugin)
// 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
@@ -57,8 +57,9 @@
/****
* Game Code
****/
+// Camera background asset (used by facekit plugin)
// Point: Green circle
// Obstacle: Red rectangles
// Character: A bright ellipse for the player
// Game constants