User prompt
Make the game easy
User prompt
Add more lives
User prompt
Make the chicken jump higher
User prompt
Please add touch control
Code edit (1 edits merged)
Please save this source code
User prompt
Chicken Face Jump
Initial prompt
Please help me make a face game where you use your face to make a chicken jump over obstacles
/****
* Plugins
****/
var facekit = LK.import("@upit/facekit.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Chicken class
var Chicken = Container.expand(function () {
var self = Container.call(this);
// Chicken body
var chickenBody = self.attachAsset('chicken', {
anchorX: 0.5,
anchorY: 1
});
// Chicken shadow
var shadow = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
y: 20
});
// Physics
self.groundY = 0; // Set after adding to game
self.velY = 0;
self.isJumping = false;
self.jumpPower = -48; // Negative = up
self.gravity = 5.2;
self.jumpCooldown = 0; // Prevents double jumps
// Jump method
self.jump = function () {
if (!self.isJumping && self.jumpCooldown <= 0) {
self.velY = self.jumpPower;
self.isJumping = true;
self.jumpCooldown = 12; // ~0.2s lockout
LK.getSound('jump').play();
// Animate chicken up
tween(self, {
scaleX: 1.08,
scaleY: 0.92
}, {
duration: 120,
easing: tween.easeOut
});
tween(shadow, {
scaleX: 0.7,
scaleY: 0.7
}, {
duration: 120,
easing: tween.easeOut
});
}
};
// Update method
self.update = function () {
// Cooldown
if (self.jumpCooldown > 0) self.jumpCooldown--;
// Gravity
if (self.isJumping) {
self.y += self.velY;
self.velY += self.gravity;
// Land
if (self.y >= self.groundY) {
self.y = self.groundY;
self.velY = 0;
self.isJumping = false;
// Animate squash
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeOut
});
tween(shadow, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeOut
});
}
}
};
return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obs = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
self.speed = 0; // Set by game
self.passed = false; // For scoring
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xb3e0ff // Light blue sky
});
/****
* Game Code
****/
// Tween plugin
// Facekit plugin
// Hit sound
// Jump sound
// Shadow
// Ground
// Obstacle (box)
// Chicken (player)
// Game constants
var GROUND_Y = 2300;
var CHICKEN_X = 500;
var OBSTACLE_MIN_GAP = 700;
var OBSTACLE_MAX_GAP = 1100;
var OBSTACLE_MIN_HEIGHT = 180;
var OBSTACLE_MAX_HEIGHT = 320;
var OBSTACLE_WIDTH = 120;
var OBSTACLE_SPEED_START = 22;
var OBSTACLE_SPEED_INC = 0.012; // Per tick
var OBSTACLE_MAX_SPEED = 38;
// Game state
var chicken;
var ground;
var obstacles = [];
var score = 0;
var distance = 0;
var gameSpeed = OBSTACLE_SPEED_START;
var lastObstacleX = 0;
var isGameOver = false;
var jumpTriggered = false;
var scoreTxt;
var distTxt;
var dragNode = null;
// Add ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: GROUND_Y + 60
});
game.addChild(ground);
// Add chicken
chicken = new Chicken();
chicken.x = CHICKEN_X;
chicken.groundY = GROUND_Y;
chicken.y = GROUND_Y;
game.addChild(chicken);
// Score text
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Distance text (bottom center)
distTxt = new Text2('0m', {
size: 70,
fill: 0xFFFFFF
});
distTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(distTxt);
// Helper: spawn obstacle
function spawnObstacle() {
var obs = new Obstacle();
obs.speed = gameSpeed;
obs.x = 2048 + OBSTACLE_WIDTH;
obs.y = GROUND_Y;
// Randomize height
var h = OBSTACLE_MIN_HEIGHT + Math.floor(Math.random() * (OBSTACLE_MAX_HEIGHT - OBSTACLE_MIN_HEIGHT));
obs.children[0].height = h;
obs.children[0].y = 0; // AnchorY=1, so bottom at y=0
obstacles.push(obs);
game.addChild(obs);
lastObstacleX = obs.x;
}
// Helper: reset game state
function resetGame() {
// Remove obstacles
for (var i = 0; i < obstacles.length; ++i) {
obstacles[i].destroy();
}
obstacles = [];
score = 0;
distance = 0;
gameSpeed = OBSTACLE_SPEED_START;
lastObstacleX = 0;
isGameOver = false;
chicken.x = CHICKEN_X;
chicken.y = GROUND_Y;
chicken.velY = 0;
chicken.isJumping = false;
chicken.jumpCooldown = 0;
scoreTxt.setText('0');
distTxt.setText('0m');
}
// Face control: triggers jump if mouth opens or head moves up
function shouldJump() {
// If mouth open
if (facekit.mouthOpen) return true;
// If head moves up (nose tip y decreases quickly)
// We'll use a simple delta check
if (typeof shouldJump.lastNoseY === 'undefined') {
shouldJump.lastNoseY = facekit.noseTip ? facekit.noseTip.y : 0;
return false;
}
var currY = facekit.noseTip ? facekit.noseTip.y : 0;
var delta = shouldJump.lastNoseY - currY;
shouldJump.lastNoseY = currY;
if (delta > 22) return true; // Quick upward nod
return false;
}
// Main update loop
game.update = function () {
if (isGameOver) return;
// Chicken update
chicken.update();
// Facekit: check for jump
if (shouldJump() && !jumpTriggered) {
chicken.jump();
jumpTriggered = true;
}
if (!facekit.mouthOpen && !shouldJump()) {
jumpTriggered = false;
}
// Obstacles update
for (var i = obstacles.length - 1; i >= 0; --i) {
var obs = obstacles[i];
obs.speed = gameSpeed;
obs.update();
// Remove if off screen
if (obs.x < -OBSTACLE_WIDTH) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision
if (!isGameOver && chicken.y + 10 > obs.y - obs.children[0].height + 30) {
// Chicken feet near ground
// Simple AABB
var cLeft = chicken.x - chicken.children[0].width / 2 + 30;
var cRight = chicken.x + chicken.children[0].width / 2 - 30;
var oLeft = obs.x - OBSTACLE_WIDTH / 2;
var oRight = obs.x + OBSTACLE_WIDTH / 2;
if (cRight > oLeft && cLeft < oRight) {
// Hit!
isGameOver = true;
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 800);
tween(chicken, {
rotation: 0.7
}, {
duration: 300,
easing: tween.easeOut
});
LK.setTimeout(function () {
LK.showGameOver();
}, 900);
return;
}
}
// Score: passed obstacle
if (!obs.passed && obs.x + OBSTACLE_WIDTH / 2 < chicken.x - chicken.children[0].width / 2) {
obs.passed = true;
score++;
scoreTxt.setText(score);
}
}
// Distance
distance += gameSpeed / 8;
distTxt.setText(Math.floor(distance) + "m");
// Spawn new obstacle
if (obstacles.length === 0 || 2048 - lastObstacleX > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
spawnObstacle();
}
// Increase speed
if (gameSpeed < OBSTACLE_MAX_SPEED) {
gameSpeed += OBSTACLE_SPEED_INC;
}
};
// Touch control: tap anywhere to jump (always enabled)
game.down = function (x, y, obj) {
if (!isGameOver && !chicken.isJumping && chicken.jumpCooldown <= 0) {
chicken.jump();
}
// Drag chicken for debug/touch (optional, for mobile fallback)
if (!facekit.mouthOpen && !facekit.noseTip) {
if (x > chicken.x - 120 && x < chicken.x + 120 && y > chicken.y - 180 && y < chicken.y) {
dragNode = chicken;
}
}
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.y = Math.max(Math.min(y, GROUND_Y), GROUND_Y - 400);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Reset game on showGameOver
LK.on('gameover', function () {
resetGame();
});
// Reset game on showYouWin (not used, but for completeness)
LK.on('youwin', function () {
resetGame();
}); ===================================================================
--- original.js
+++ change.js
@@ -287,11 +287,14 @@
if (gameSpeed < OBSTACLE_MAX_SPEED) {
gameSpeed += OBSTACLE_SPEED_INC;
}
};
-// Drag chicken for debug/touch (optional, for mobile fallback)
+// Touch control: tap anywhere to jump (always enabled)
game.down = function (x, y, obj) {
- // Only allow drag if not using facekit
+ if (!isGameOver && !chicken.isJumping && chicken.jumpCooldown <= 0) {
+ chicken.jump();
+ }
+ // Drag chicken for debug/touch (optional, for mobile fallback)
if (!facekit.mouthOpen && !facekit.noseTip) {
if (x > chicken.x - 120 && x < chicken.x + 120 && y > chicken.y - 180 && y < chicken.y) {
dragNode = chicken;
}