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 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
return self;
});
// Obstacle class: moves horizontally or vertically
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement direction: 'horizontal' or 'vertical'
self.direction = 'horizontal';
self.speed = 8;
self.amplitude = 400;
self.baseX = 0;
self.baseY = 0;
self.phase = 0;
self.width = obstacleAsset.width;
self.height = obstacleAsset.height;
// For collision, use bounding box
self.update = function () {
if (self.direction === 'horizontal') {
self.x = self.baseX + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
} else {
self.y = self.baseY + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
}
};
return self;
});
// Target class: collectible, static
var Target = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = targetAsset.width / 2;
// No update needed; handled in main game loop
return self;
});
/****
* Initialize Game
****/
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
});
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) {
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
};
}
// 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;
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
return {
x: tx,
y: ty
};
}
// Helper: spawn target
function spawnTarget() {
if (target) {
target.destroy();
}
target = new Target();
var pos = randomTargetPosition();
target.x = pos.x;
target.y = pos.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
if (obs.direction === 'horizontal') {
obs.baseY = 300 + Math.random() * (2732 - 600);
obs.baseX = 1024;
obs.x = obs.baseX;
obs.y = obs.baseY;
} else {
obs.baseX = 300 + Math.random() * (2048 - 600);
obs.baseY = 1366;
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;
}
// Helper: check collision (circle vs box)
function circleBoxIntersect(cx, cy, cr, bx, by, bw, bh) {
// bx,by: center of box
var dx = Math.abs(cx - bx);
var dy = Math.abs(cy - by);
var hw = bw / 2;
var 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;
}
// Helper: increase difficulty
function updateDifficulty() {
difficulty = 1 + Math.floor(score / 5);
}
// Game start: place hero in center, spawn target, clear obstacles
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();
}
obstacles = [];
// Spawn first target
spawnTarget();
// Spawn initial obstacles
for (var i = 0; i < 2; ++i) {
spawnObstacle();
}
lastTargetTime = LK.ticks;
lastObstacleTime = LK.ticks;
updateDifficulty();
gameStarted = true;
}
// Game over
function triggerGameOver() {
if (gameOver) return;
gameOver = true;
LK.effects.flashScreen(0xff0000, 800);
LK.getSound('hit').play();
LK.showGameOver();
}
// Main update loop
game.update = function () {
// If game is not started, start it
if (!gameStarted) {
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.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();
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
LK.getSound('collect').play();
score += 1;
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)) {
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;
}); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,293 @@
-/****
+/****
+* 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
+ return self;
+});
+// Obstacle class: moves horizontally or vertically
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var obstacleAsset = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Movement direction: 'horizontal' or 'vertical'
+ self.direction = 'horizontal';
+ self.speed = 8;
+ self.amplitude = 400;
+ self.baseX = 0;
+ self.baseY = 0;
+ self.phase = 0;
+ self.width = obstacleAsset.width;
+ self.height = obstacleAsset.height;
+ // For collision, use bounding box
+ self.update = function () {
+ if (self.direction === 'horizontal') {
+ self.x = self.baseX + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
+ } else {
+ self.y = self.baseY + Math.sin((LK.ticks + self.phase) * 0.02) * self.amplitude;
+ }
+ };
+ return self;
+});
+// Target class: collectible, static
+var Target = Container.expand(function () {
+ var self = Container.call(this);
+ var targetAsset = self.attachAsset('target', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = targetAsset.width / 2;
+ // No update needed; handled in main game loop
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ 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
+});
+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) {
+ 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
+ };
+}
+// 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;
+ 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
+ return {
+ x: tx,
+ y: ty
+ };
+}
+// Helper: spawn target
+function spawnTarget() {
+ if (target) {
+ target.destroy();
+ }
+ target = new Target();
+ var pos = randomTargetPosition();
+ target.x = pos.x;
+ target.y = pos.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
+ if (obs.direction === 'horizontal') {
+ obs.baseY = 300 + Math.random() * (2732 - 600);
+ obs.baseX = 1024;
+ obs.x = obs.baseX;
+ obs.y = obs.baseY;
+ } else {
+ obs.baseX = 300 + Math.random() * (2048 - 600);
+ obs.baseY = 1366;
+ 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;
+}
+// Helper: check collision (circle vs box)
+function circleBoxIntersect(cx, cy, cr, bx, by, bw, bh) {
+ // bx,by: center of box
+ var dx = Math.abs(cx - bx);
+ var dy = Math.abs(cy - by);
+ var hw = bw / 2;
+ var 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;
+}
+// Helper: increase difficulty
+function updateDifficulty() {
+ difficulty = 1 + Math.floor(score / 5);
+}
+// Game start: place hero in center, spawn target, clear obstacles
+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();
+ }
+ obstacles = [];
+ // Spawn first target
+ spawnTarget();
+ // Spawn initial obstacles
+ for (var i = 0; i < 2; ++i) {
+ spawnObstacle();
+ }
+ lastTargetTime = LK.ticks;
+ lastObstacleTime = LK.ticks;
+ updateDifficulty();
+ gameStarted = true;
+}
+// Game over
+function triggerGameOver() {
+ if (gameOver) return;
+ gameOver = true;
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.getSound('hit').play();
+ LK.showGameOver();
+}
+// Main update loop
+game.update = function () {
+ // If game is not started, start it
+ if (!gameStarted) {
+ 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.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();
+ 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
+ LK.getSound('collect').play();
+ score += 1;
+ 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)) {
+ 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;
});
\ No newline at end of file