User prompt
use hit sound when game ends
User prompt
Please fix the bug: 'TypeError: LK.effects.explosion is not a function' in or related to this line: 'LK.effects.explosion({' Line Number: 227
User prompt
add explosion effect when an obstacle is hit
User prompt
Please fix the bug: 'TypeError: LK.effects.explosion is not a function' in or related to this line: 'LK.effects.explosion(player.x, player.y, {' Line Number: 227
User prompt
add explosion when hit
User prompt
Play blast sound when player hits obstacle
User prompt
can not hear blast sound
User prompt
rename "HI" as "Best Score"
User prompt
rename HI as Best Score
User prompt
keep high score ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
dont keep high score
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var highScore = storage.get('highScore') || 0;' Line Number: 124 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
can we keep highest score
Code edit (1 edits merged)
Please save this source code
User prompt
Face Dash: Smile Runner
User prompt
Please continue polishing my design document.
Initial prompt
make a game like icy tower
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); var obsAsset = 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 var Player = Container.expand(function () { var self = Container.call(this); var playerAsset = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // For hit feedback self.flash = function () { tween(self, { alpha: 0.5 }, { duration: 80, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 120 }); } }); }; return self; }); // Point collectible class var PointItem = Container.expand(function () { var self = Container.call(this); var pointAsset = self.attachAsset('point', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // Music (background, optional) // Sound for hitting an obstacle // Sound for collecting a point // Point collectible: a yellow ellipse // Obstacle: a red box // Player character: a bright ellipse // Game area: 2048x2732 game.setBackgroundColor(0x181c2c); // Score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFF700 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // High score display var highScoreTxt = new Text2('Best: ' + highScore, { size: 60, fill: 0xFFFFFF }); highScoreTxt.anchor.set(0.5, 0); highScoreTxt.y = scoreTxt.height + 10; LK.gui.top.addChild(highScoreTxt); // Start music LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1200 } }); // Player setup var player = new Player(); game.addChild(player); // Start in lower center player.x = 2048 / 2; player.y = 2732 - 350; // Arrays for obstacles and points var obstacles = []; var points = []; // Game state var score = 0; var highScore = storage.get('highScore') || 0; var ticks = 0; var gameSpeed = 12; // Initial speed var spawnInterval = 60; // Ticks between spawns (1s at 60fps) var lastObstacleSpawn = 0; var lastPointSpawn = 0; var isGameOver = false; // Helper: clamp function clamp(val, min, max) { return val < min ? min : val > max ? max : val; } // Face control logic function updatePlayerPosition() { // Use facekit.mouthCenter if available, else fallback to noseTip or center var fx = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : facekit.noseTip && facekit.noseTip.x ? facekit.noseTip.x : 1024; var fy = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : facekit.noseTip && facekit.noseTip.y ? facekit.noseTip.y : 2048; // Clamp to game area, keep player fully visible var px = clamp(fx, player.width / 2, 2048 - player.width / 2); var py = clamp(fy, 2732 - 600, 2732 - player.height / 2); // Only allow movement in lower 600px // Smooth movement tween.stop(player, { x: true, y: true }); tween(player, { x: px, y: py }, { duration: 80, easing: tween.easeOut }); } // Spawn obstacle at random x function spawnObstacle() { var obs = new Obstacle(); obs.speed = gameSpeed; obs.x = clamp(200 + Math.floor(Math.random() * (2048 - 400)), obs.width / 2, 2048 - obs.width / 2); obs.y = -obs.height / 2; obstacles.push(obs); game.addChild(obs); } // Spawn point at random x function spawnPoint() { var pt = new PointItem(); pt.speed = gameSpeed; pt.x = clamp(200 + Math.floor(Math.random() * (2048 - 400)), pt.width / 2, 2048 - pt.width / 2); pt.y = -pt.height / 2; points.push(pt); game.addChild(pt); } // Game update loop game.update = function () { if (isGameOver) return; ticks++; // Increase speed every 10 seconds if (ticks % 600 === 0 && gameSpeed < 32) { gameSpeed += 2; if (spawnInterval > 30) spawnInterval -= 4; } // Face control: update player position updatePlayerPosition(); // Microphone: if volume > 0.5, give a small speed boost (visual feedback) if (facekit.volume > 0.5) { player.scale.x = 1.18; player.scale.y = 1.18; } else { player.scale.x = 1; player.scale.y = 1; } // Spawn obstacles if (ticks - lastObstacleSpawn > spawnInterval) { spawnObstacle(); lastObstacleSpawn = ticks; } // Spawn points less frequently if (ticks - lastPointSpawn > spawnInterval * 1.5) { spawnPoint(); lastPointSpawn = ticks; } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.speed = gameSpeed; obs.update(); // Remove if off screen if (obs.y - obs.height / 2 > 2732 + 100) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (player.intersects(obs)) { // Hit! isGameOver = true; LK.getSound('hit').play(); player.flash(); LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } // Update points for (var j = points.length - 1; j >= 0; j--) { var pt = points[j]; pt.speed = gameSpeed; pt.update(); // Remove if off screen if (pt.y - pt.height / 2 > 2732 + 100) { pt.destroy(); points.splice(j, 1); continue; } // Collect if (player.intersects(pt)) { score += 1; LK.setScore(score); scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.set('highScore', highScore); highScoreTxt.setText('Best: ' + highScore); } LK.getSound('collect').play(); // Visual feedback tween(pt, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 180, onFinish: function onFinish() { pt.destroy(); } }); points.splice(j, 1); continue; } } }; // Reset on game restart game.on('reset', function () { // Remove all obstacles and points for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy(); for (var j = 0; j < points.length; j++) points[j].destroy(); obstacles = []; points = []; score = 0; LK.setScore(0); scoreTxt.setText('0'); highScore = storage.get('highScore') || 0; highScoreTxt.setText('Best: ' + highScore); player.x = 2048 / 2; player.y = 2732 - 350; gameSpeed = 12; spawnInterval = 60; lastObstacleSpawn = 0; lastPointSpawn = 0; ticks = 0; isGameOver = false; }); // No touch/mouse controls: face only, so no game.down/game.move/game.up // Show instructions overlay for first 2 seconds var instructTxt = new Text2('Move your face to dodge! Open mouth for boost.', { size: 80, fill: 0xFFFFFF }); instructTxt.anchor.set(0.5, 0.5); instructTxt.x = 2048 / 2; instructTxt.y = 2732 / 2 - 200; game.addChild(instructTxt); tween(instructTxt, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { instructTxt.destroy(); } });
===================================================================
--- original.js
+++ change.js
@@ -2,8 +2,9 @@
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
+var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
@@ -82,8 +83,16 @@
fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
+// High score display
+var highScoreTxt = new Text2('Best: ' + highScore, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+highScoreTxt.anchor.set(0.5, 0);
+highScoreTxt.y = scoreTxt.height + 10;
+LK.gui.top.addChild(highScoreTxt);
// Start music
LK.playMusic('bgmusic', {
fade: {
start: 0,
@@ -101,8 +110,9 @@
var obstacles = [];
var points = [];
// Game state
var score = 0;
+var highScore = storage.get('highScore') || 0;
var ticks = 0;
var gameSpeed = 12; // Initial speed
var spawnInterval = 60; // Ticks between spawns (1s at 60fps)
var lastObstacleSpawn = 0;
@@ -217,8 +227,13 @@
if (player.intersects(pt)) {
score += 1;
LK.setScore(score);
scoreTxt.setText(score);
+ if (score > highScore) {
+ highScore = score;
+ storage.set('highScore', highScore);
+ highScoreTxt.setText('Best: ' + highScore);
+ }
LK.getSound('collect').play();
// Visual feedback
tween(pt, {
scaleX: 1.5,
@@ -244,8 +259,10 @@
points = [];
score = 0;
LK.setScore(0);
scoreTxt.setText('0');
+ highScore = storage.get('highScore') || 0;
+ highScoreTxt.setText('Best: ' + highScore);
player.x = 2048 / 2;
player.y = 2732 - 350;
gameSpeed = 12;
spawnInterval = 60;