Code edit (1 edits merged)
Please save this source code
User prompt
its not loading
User prompt
fix opning time
Code edit (1 edits merged)
Please save this source code
User prompt
Face Dash Frenzy
User prompt
Please continue polishing my design document.
Initial prompt
from coding to generating images & sounds. To kick things off, could you tell me a bit about the game we are making?
/****
* Plugins
****/
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroAsset = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = heroAsset.width / 2;
self.hitRadius = self.radius * 0.85;
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var asset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = 'horizontal';
self.speed = 8;
self.amplitude = 300;
self.baseX = 0;
self.baseY = 0;
self.phase = 0;
self.width = asset.width;
self.height = asset.height;
self.spawnTime = 0;
self.update = function () {
var t = (LK.ticks * self.speed + self.phase) * 0.02;
if (self.direction === 'horizontal') {
self.x = self.baseX + Math.sin(t) * self.amplitude;
} else {
self.y = self.baseY + Math.sin(t) * self.amplitude;
}
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var asset = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = asset.width / 2;
return self;
});
/****
* Initialize Game
****/
/****
* Game Init
****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xffffff
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var hero = new Hero();
game.addChild(hero);
var target = null;
var obstacles = [];
var score = 0;
var difficulty = 1;
var lastObstacleTime = 0;
var gameStarted = false;
var gameOver = false;
/**** Helpers ****/
function clampHero(x, y) {
var r = hero.radius;
return {
x: Math.max(r + 40, Math.min(2048 - r - 40, x)),
y: Math.max(r + 140, Math.min(2732 - r - 40, y))
};
}
function randomTargetPosition() {
var margin = 200;
var tx, ty, dist;
do {
tx = margin + Math.random() * (2048 - margin * 2);
ty = margin + 200 + Math.random() * (2732 - margin * 2 - 200);
dist = Math.hypot(tx - hero.x, ty - hero.y);
} while (dist < 400);
return {
x: tx,
y: ty
};
}
function spawnTarget() {
if (target) target.destroy();
target = new Target();
var p = randomTargetPosition();
target.x = p.x;
target.y = p.y;
game.addChild(target);
}
function spawnObstacle() {
var obs = new Obstacle();
obs.direction = Math.random() < 0.5 ? 'horizontal' : 'vertical';
obs.amplitude = 200 + difficulty * 60;
obs.speed = 4 + difficulty * 1.5;
obs.phase = Math.random() * 1000;
obs.spawnTime = LK.ticks;
if (obs.direction === 'horizontal') {
obs.baseX = 1024;
obs.baseY = 300 + Math.random() * (2732 - 600);
} else {
obs.baseY = 1366;
obs.baseX = 300 + Math.random() * (2048 - 600);
}
obs.x = obs.baseX;
obs.y = obs.baseY;
obstacles.push(obs);
game.addChild(obs);
}
function circleHit(x1, y1, r1, x2, y2, r2) {
return Math.hypot(x1 - x2, y1 - y2) <= r1 + r2;
}
function circleBoxHit(cx, cy, cr, bx, by, bw, bh) {
var dx = Math.abs(cx - bx);
var dy = Math.abs(cy - by);
var hw = bw / 2,
hh = bh / 2;
if (dx > hw + cr) return false;
if (dy > hh + cr) return false;
if (dx <= hw) return true;
if (dy <= hh) return true;
return Math.pow(dx - hw, 2) + Math.pow(dy - hh, 2) <= cr * cr;
}
function updateDifficulty() {
difficulty = 1 + score * 0.2;
}
/**** Game Flow ****/
function startGame() {
score = 0;
scoreTxt.setText(score);
gameOver = false;
hero.x = 1024;
hero.y = 1366;
if (target) target.destroy();
target = null;
obstacles.forEach(function (o) {
return o.destroy();
});
obstacles = [];
spawnTarget();
for (var i = 0; i < 2; i++) spawnObstacle();
lastObstacleTime = LK.ticks;
updateDifficulty();
gameStarted = true;
}
function triggerGameOver() {
if (gameOver) return;
gameOver = true;
LK.effects.flashScreen(0xff0000, 500);
LK.getSound('hit').play();
LK.showGameOver();
}
/**** Main Loop ****/
game.update = function () {
var _facekit$mouthCenter, _facekit$mouthCenter2;
// Start only when face detected
if (!gameStarted) {
if (facekit.ready && facekit.faceDetected) {
startGame();
}
return;
}
if (gameOver) return;
// Hero follow face
var fx = ((_facekit$mouthCenter = facekit.mouthCenter) === null || _facekit$mouthCenter === void 0 ? void 0 : _facekit$mouthCenter.x) || 1024;
var fy = ((_facekit$mouthCenter2 = facekit.mouthCenter) === null || _facekit$mouthCenter2 === void 0 ? void 0 : _facekit$mouthCenter2.y) || 1366;
var pos = clampHero(fx, fy);
hero.x = pos.x;
hero.y = pos.y;
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var o = obstacles[i];
o.update();
// remove old obstacles
if (LK.ticks - o.spawnTime > 2000) {
o.destroy();
obstacles.splice(i, 1);
}
}
// Spawn new obstacles over time
if (LK.ticks - lastObstacleTime > 120 - difficulty * 5) {
spawnObstacle();
lastObstacleTime = LK.ticks;
}
// Target movement (small)
if (target) {
target.x += Math.sin(LK.ticks * 0.05) * 2;
}
// Collect
if (target && circleHit(hero.x, hero.y, hero.radius, target.x, target.y, target.radius)) {
LK.getSound('collect').play();
LK.effects.pulse(target, 200);
score++;
scoreTxt.setText(score);
spawnTarget();
updateDifficulty();
}
// Collision
for (var _i = 0, _obstacles = obstacles; _i < _obstacles.length; _i++) {
var o = _obstacles[_i];
if (circleBoxHit(hero.x, hero.y, hero.hitRadius, o.x, o.y, o.width, o.height)) {
triggerGameOver();
return;
}
}
};
LK.on('gameover', function () {
return gameStarted = false;
}); ===================================================================
--- original.js
+++ change.js
@@ -1,296 +1,229 @@
/****
* Plugins
****/
-var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
-// Hero class: follows face position
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroAsset = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
- // For collision detection, keep radius
self.radius = heroAsset.width / 2;
- // No update needed; position is set by facekit in main game loop
+ self.hitRadius = self.radius * 0.85;
return self;
});
-// Obstacle class: moves horizontally or vertically
var Obstacle = Container.expand(function () {
var self = Container.call(this);
- var obstacleAsset = self.attachAsset('obstacle', {
+ var asset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
- // Movement direction: 'horizontal' or 'vertical'
self.direction = 'horizontal';
self.speed = 8;
- self.amplitude = 400;
+ self.amplitude = 300;
self.baseX = 0;
self.baseY = 0;
self.phase = 0;
- self.width = obstacleAsset.width;
- self.height = obstacleAsset.height;
- // For collision, use bounding box
+ self.width = asset.width;
+ self.height = asset.height;
+ self.spawnTime = 0;
self.update = function () {
+ var t = (LK.ticks * self.speed + self.phase) * 0.02;
if (self.direction === 'horizontal') {
- self.x = self.baseX + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
+ self.x = self.baseX + Math.sin(t) * self.amplitude;
} else {
- self.y = self.baseY + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
+ self.y = self.baseY + Math.sin(t) * self.amplitude;
}
};
return self;
});
-// Target class: collectible, static
var Target = Container.expand(function () {
var self = Container.call(this);
- var targetAsset = self.attachAsset('target', {
+ var asset = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
- self.radius = targetAsset.width / 2;
- // No update needed; handled in main game loop
+ self.radius = asset.width / 2;
return self;
});
/****
* Initialize Game
****/
+/****
+* Game Init
+****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
-// Music (optional, will not be played in MVP)
-// Sound for hitting obstacle
-// Sound for collecting target
-// Obstacle: box, red, variable size
-// Target: ellipse, green, smaller
-// Hero: ellipse, bright color, medium size
-// Game area: 2048x2732
-// Keep all gameplay elements away from top-left 100x100
-// Score display
var scoreTxt = new Text2('0', {
size: 120,
- fill: 0xFFFFFF
+ fill: 0xffffff
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
-// Main game objects
var hero = new Hero();
game.addChild(hero);
-// Target
var target = null;
-// Obstacles array
var obstacles = [];
-// Game state
var score = 0;
var difficulty = 1;
-var lastTargetTime = 0;
var lastObstacleTime = 0;
var gameStarted = false;
var gameOver = false;
-// Helper: clamp hero inside screen
-function clampHeroPosition(x, y) {
+/**** Helpers ****/
+function clampHero(x, y) {
var r = hero.radius;
- var minX = r + 40;
- var maxX = 2048 - r - 40;
- var minY = r + 140; // leave space for GUI
- var maxY = 2732 - r - 40;
- if (x < minX) x = minX;
- if (x > maxX) x = maxX;
- if (y < minY) y = minY;
- if (y > maxY) y = maxY;
return {
- x: x,
- y: y
+ x: Math.max(r + 40, Math.min(2048 - r - 40, x)),
+ y: Math.max(r + 140, Math.min(2732 - r - 40, y))
};
}
-// Helper: random position for target, not too close to hero or edges
function randomTargetPosition() {
var margin = 200;
- var r = 0;
- var tx = 0,
- ty = 0;
+ var tx, ty, dist;
do {
- tx = margin + Math.random() * (2048 - 2 * margin);
- ty = margin + 200 + Math.random() * (2732 - 2 * margin - 200);
- r = Math.sqrt((tx - hero.x) * (tx - hero.x) + (ty - hero.y) * (ty - hero.y));
- } while (r < 400); // not too close to hero
+ tx = margin + Math.random() * (2048 - margin * 2);
+ ty = margin + 200 + Math.random() * (2732 - margin * 2 - 200);
+ dist = Math.hypot(tx - hero.x, ty - hero.y);
+ } while (dist < 400);
return {
x: tx,
y: ty
};
}
-// Helper: spawn target
function spawnTarget() {
- if (target) {
- target.destroy();
- }
+ if (target) target.destroy();
target = new Target();
- var pos = randomTargetPosition();
- target.x = pos.x;
- target.y = pos.y;
+ var p = randomTargetPosition();
+ target.x = p.x;
+ target.y = p.y;
game.addChild(target);
}
-// Helper: spawn obstacle
function spawnObstacle() {
var obs = new Obstacle();
- // Randomize direction
obs.direction = Math.random() < 0.5 ? 'horizontal' : 'vertical';
- obs.amplitude = 200 + Math.random() * 600;
- obs.phase = Math.floor(Math.random() * 1000);
- obs.speed = 6 + difficulty * 2 + Math.random() * 2;
- // Randomize base position, avoid top 200px and bottom 200px
+ obs.amplitude = 200 + difficulty * 60;
+ obs.speed = 4 + difficulty * 1.5;
+ obs.phase = Math.random() * 1000;
+ obs.spawnTime = LK.ticks;
if (obs.direction === 'horizontal') {
- obs.baseY = 300 + Math.random() * (2732 - 600);
obs.baseX = 1024;
- obs.x = obs.baseX;
- obs.y = obs.baseY;
+ obs.baseY = 300 + Math.random() * (2732 - 600);
} else {
- obs.baseX = 300 + Math.random() * (2048 - 600);
obs.baseY = 1366;
- obs.x = obs.baseX;
- obs.y = obs.baseY;
+ obs.baseX = 300 + Math.random() * (2048 - 600);
}
+ obs.x = obs.baseX;
+ obs.y = obs.baseY;
obstacles.push(obs);
game.addChild(obs);
}
-// Helper: check collision (circle vs circle)
-function circlesIntersect(x1, y1, r1, x2, y2, r2) {
- var dx = x1 - x2;
- var dy = y1 - y2;
- var dist = dx * dx + dy * dy;
- var rad = r1 + r2;
- return dist <= rad * rad;
+function circleHit(x1, y1, r1, x2, y2, r2) {
+ return Math.hypot(x1 - x2, y1 - y2) <= r1 + r2;
}
-// Helper: check collision (circle vs box)
-function circleBoxIntersect(cx, cy, cr, bx, by, bw, bh) {
- // bx,by: center of box
+function circleBoxHit(cx, cy, cr, bx, by, bw, bh) {
var dx = Math.abs(cx - bx);
var dy = Math.abs(cy - by);
- var hw = bw / 2;
- var hh = bh / 2;
+ var hw = bw / 2,
+ hh = bh / 2;
if (dx > hw + cr) return false;
if (dy > hh + cr) return false;
if (dx <= hw) return true;
if (dy <= hh) return true;
- var cornerDist = (dx - hw) * (dx - hw) + (dy - hh) * (dy - hh);
- return cornerDist <= cr * cr;
+ return Math.pow(dx - hw, 2) + Math.pow(dy - hh, 2) <= cr * cr;
}
-// Helper: increase difficulty
function updateDifficulty() {
- difficulty = 1 + Math.floor(score / 5);
+ difficulty = 1 + score * 0.2;
}
-// Game start: place hero in center, spawn target, clear obstacles
+/**** Game Flow ****/
function startGame() {
score = 0;
scoreTxt.setText(score);
gameOver = false;
- // Place hero in center
- hero.x = 2048 / 2;
- hero.y = 2732 / 2;
- // Remove old target
- if (target) {
- target.destroy();
- target = null;
- }
- // Remove obstacles
- for (var i = 0; i < obstacles.length; ++i) {
- obstacles[i].destroy();
- }
+ hero.x = 1024;
+ hero.y = 1366;
+ if (target) target.destroy();
+ target = null;
+ obstacles.forEach(function (o) {
+ return o.destroy();
+ });
obstacles = [];
- // Spawn first target
spawnTarget();
- // Spawn initial obstacles
- for (var i = 0; i < 2; ++i) {
- spawnObstacle();
- }
- lastTargetTime = LK.ticks;
+ for (var i = 0; i < 2; i++) spawnObstacle();
lastObstacleTime = LK.ticks;
updateDifficulty();
gameStarted = true;
}
-// Game over
function triggerGameOver() {
if (gameOver) return;
gameOver = true;
- LK.effects.flashScreen(0xff0000, 800);
+ LK.effects.flashScreen(0xff0000, 500);
LK.getSound('hit').play();
LK.showGameOver();
}
-// Main update loop
+/**** Main Loop ****/
game.update = function () {
- // If game is not started, wait for facekit to be ready and face detected before starting
+ var _facekit$mouthCenter, _facekit$mouthCenter2;
+ // Start only when face detected
if (!gameStarted) {
- // Wait for facekit to be initialized and a face to be detected
- if (facekit.ready && facekit.faceDetected && facekit.mouthCenter && typeof facekit.mouthCenter.x === "number" && typeof facekit.mouthCenter.y === "number") {
+ if (facekit.ready && facekit.faceDetected) {
startGame();
}
return;
}
if (gameOver) return;
- // 1. Update hero position from facekit
- var fx = facekit.mouthCenter.x;
- var fy = facekit.mouthCenter.y;
- // If facekit not ready, keep hero in center
- if (!fx || !fy) {
- fx = 2048 / 2;
- fy = 2732 / 2;
- }
- var pos = clampHeroPosition(fx, fy);
+ // Hero follow face
+ var fx = ((_facekit$mouthCenter = facekit.mouthCenter) === null || _facekit$mouthCenter === void 0 ? void 0 : _facekit$mouthCenter.x) || 1024;
+ var fy = ((_facekit$mouthCenter2 = facekit.mouthCenter) === null || _facekit$mouthCenter2 === void 0 ? void 0 : _facekit$mouthCenter2.y) || 1366;
+ var pos = clampHero(fx, fy);
hero.x = pos.x;
hero.y = pos.y;
- // 2. Update obstacles
- for (var i = obstacles.length - 1; i >= 0; --i) {
- var obs = obstacles[i];
- obs.update();
- // Remove obstacles that have drifted off screen (shouldn't happen, but safety)
- if (obs.x < -300 || obs.x > 2348 || obs.y < -300 || obs.y > 3032) {
- obs.destroy();
+ // Update obstacles
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var o = obstacles[i];
+ o.update();
+ // remove old obstacles
+ if (LK.ticks - o.spawnTime > 2000) {
+ o.destroy();
obstacles.splice(i, 1);
}
}
- // 3. Check collision: hero vs target
- if (target && circlesIntersect(hero.x, hero.y, hero.radius, target.x, target.y, target.radius)) {
- // Collect target
+ // Spawn new obstacles over time
+ if (LK.ticks - lastObstacleTime > 120 - difficulty * 5) {
+ spawnObstacle();
+ lastObstacleTime = LK.ticks;
+ }
+ // Target movement (small)
+ if (target) {
+ target.x += Math.sin(LK.ticks * 0.05) * 2;
+ }
+ // Collect
+ if (target && circleHit(hero.x, hero.y, hero.radius, target.x, target.y, target.radius)) {
LK.getSound('collect').play();
- score += 1;
+ LK.effects.pulse(target, 200);
+ score++;
scoreTxt.setText(score);
spawnTarget();
updateDifficulty();
- // Add new obstacle every 3 points, up to 8
- if (score % 3 === 0 && obstacles.length < 8) {
- spawnObstacle();
- }
}
- // 4. Check collision: hero vs obstacles
- for (var j = 0; j < obstacles.length; ++j) {
- var obs2 = obstacles[j];
- if (circleBoxIntersect(hero.x, hero.y, hero.radius * 0.85, obs2.x, obs2.y, obs2.width, obs2.height)) {
+ // Collision
+ for (var _i = 0, _obstacles = obstacles; _i < _obstacles.length; _i++) {
+ var o = _obstacles[_i];
+ if (circleBoxHit(hero.x, hero.y, hero.hitRadius, o.x, o.y, o.width, o.height)) {
triggerGameOver();
return;
}
}
- // 5. Increase obstacle speed with difficulty
- for (var k = 0; k < obstacles.length; ++k) {
- obstacles[k].amplitude = 200 + difficulty * 60 + Math.random() * 100;
- obstacles[k].speed = 6 + difficulty * 2 + Math.random() * 2;
- }
};
-// No touch controls needed; facekit only
-// On game over, restart on next update
LK.on('gameover', function () {
- // Wait for LK to reset, then restart
- gameStarted = false;
-});
-// On you win (not used in MVP, but for future)
-LK.on('youwin', function () {
- gameStarted = false;
+ return gameStarted = false;
});
\ No newline at end of file