User prompt
make the obstacles little slower
User prompt
start this game a little slower, make it speed up a little every time you get a powerup, and sometimes add the ability to pass through rare obstacles ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Face Dash: Smile Runner
User prompt
Please continue polishing my design document.
User prompt
Please continue polishing my design document.
User prompt
Please continue polishing my design document.
Initial prompt
make me roblox
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ // Obstacle class: moves downward, destroys itself off-screen var Obstacle = Container.expand(function () { var self = Container.call(this); var obsGfx = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12 + Math.random() * 6; // pixels per frame, slower base speed self.update = function () { self.y += self.speed; }; return self; }); // Player class: follows face position var Player = Container.expand(function () { var self = Container.call(this); var playerGfx = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // For possible future effects self.flash = function () { tween(self, { alpha: 0.3 }, { duration: 80, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 120 }); } }); }; return self; }); // Powerup class: moves downward, destroys itself off-screen var Powerup = Container.expand(function () { var self = Container.call(this); var powGfx = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 14 + Math.random() * 6; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // Powerup: Green ellipse // Obstacle: Red box // Character: Player avatar (ellipse, bright color) // Game area margins (to avoid top-left menu) var marginTop = 100; var marginLeft = 100; var marginRight = 100; var marginBottom = 100; // Player setup var player = new Player(); game.addChild(player); // Start in center player.x = 2048 / 2; player.y = 2732 - 400; // Score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Powerup timer display (hidden by default) var powerupTxt = new Text2('', { size: 80, fill: 0xFFE066 }); powerupTxt.anchor.set(0.5, 0); LK.gui.top.addChild(powerupTxt); powerupTxt.visible = false; // Game state var obstacles = []; var powerups = []; var powerupActive = false; var powerupTimer = 0; var powerupDuration = 180; // frames (3 seconds) var score = 0; var ticks = 0; var gameOver = false; // --- Speed scaling and rare obstacle pass-through --- var speedScale = 1.0; // Start slow, increases with powerups var rarePassThroughActive = false; var rarePassThroughTimer = 0; var rarePassThroughDuration = 120; // frames (2 seconds) // Helper: clamp value function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Main update loop game.update = function () { if (gameOver) return; ticks++; // --- Face tracking: update player position --- // Use mouth center if available, else fallback to noseTip var faceX = facekit.mouthCenter && facekit.mouthCenter.x ? facekit.mouthCenter.x : facekit.noseTip && facekit.noseTip.x ? facekit.noseTip.x : 2048 / 2; var faceY = facekit.mouthCenter && facekit.mouthCenter.y ? facekit.mouthCenter.y : facekit.noseTip && facekit.noseTip.y ? facekit.noseTip.y : 2732 - 400; // Clamp to game area (avoid top-left menu and screen edges) var px = clamp(faceX, marginLeft + player.width / 2, 2048 - marginRight - player.width / 2); var py = clamp(faceY, marginTop + player.height / 2, 2732 - marginBottom - player.height / 2); // Smooth movement (lerp) player.x += (px - player.x) * 0.35; player.y += (py - player.y) * 0.35; // --- Spawn obstacles --- // Increase spawn rate over time var spawnInterval = Math.max(32, 80 - Math.floor(ticks / 600)); if (ticks % spawnInterval === 0) { var obs = new Obstacle(); // Random X, avoid edges obs.x = clamp(180 + Math.random() * (2048 - 360), marginLeft + 90, 2048 - marginRight - 90); obs.y = -80; // Speed up as score increases and with powerups obs.speed = (12 + Math.random() * 6 + Math.floor(score / 10) * 1.2) * speedScale; // 10% chance: rare pass-through obstacle (if not already active) if (!rarePassThroughActive && Math.random() < 0.10) { obs.isPassThrough = true; obs.alpha = 0.45; // visually faded obs.tint = 0x8e44ad; // purple tint for rare } else { obs.isPassThrough = false; } obstacles.push(obs); game.addChild(obs); } // --- Spawn powerups --- if (!powerupActive && ticks > 120 && ticks % 420 === 0) { var pow = new Powerup(); pow.x = clamp(180 + Math.random() * (2048 - 360), marginLeft + 90, 2048 - marginRight - 90); pow.y = -60; pow.speed = (14 + Math.random() * 6) * speedScale; powerups.push(pow); game.addChild(pow); } // --- Update obstacles --- for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Off-screen if (obs.y - obs.height / 2 > 2732 + 40) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (!powerupActive && player.intersects(obs)) { // If rare obstacle and pass-through is active, skip collision if (obs.isPassThrough && rarePassThroughActive) { // No effect, pass through } else { player.flash(); LK.effects.flashScreen(0xff0000, 600); gameOver = true; LK.setTimeout(function () { LK.showGameOver(); }, 600); return; } } } // --- Update powerups --- for (var j = powerups.length - 1; j >= 0; j--) { var pow = powerups[j]; pow.update(); // Off-screen if (pow.y - pow.height / 2 > 2732 + 40) { pow.destroy(); powerups.splice(j, 1); continue; } // Collect if (player.intersects(pow)) { pow.destroy(); powerups.splice(j, 1); powerupActive = true; powerupTimer = powerupDuration; powerupTxt.visible = true; // --- Speed up game a little every powerup --- speedScale = Math.min(speedScale + 0.08, 2.5); // Cap max speed // --- 25% chance: activate rare pass-through mode for a short time --- if (!rarePassThroughActive && Math.random() < 0.25) { rarePassThroughActive = true; rarePassThroughTimer = rarePassThroughDuration; powerupTxt.setText("Pass Through!"); powerupTxt.visible = true; // Visual feedback: player turns purple tween(player, { tint: 0x8e44ad }, { duration: 120 }); } // Visual feedback tween(player, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, onFinish: function onFinish() { tween(player, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } } // --- Powerup effect --- if (powerupActive) { powerupTimer--; if (rarePassThroughActive) { powerupTxt.setText("Pass Through: " + Math.ceil(rarePassThroughTimer / 60) + "s"); } else { powerupTxt.setText("Invincible: " + Math.ceil(powerupTimer / 60) + "s"); } if (powerupTimer <= 0) { powerupActive = false; if (!rarePassThroughActive) powerupTxt.visible = false; } } // --- Rare pass-through effect --- if (rarePassThroughActive) { rarePassThroughTimer--; if (rarePassThroughTimer <= 0) { rarePassThroughActive = false; powerupTxt.visible = false; // Restore player color tween(player, { tint: 0x3fa9f5 }, { duration: 120 }); } } // --- Score --- if (ticks % 6 === 0 && !gameOver) { score++; LK.setScore(score); scoreTxt.setText(score); } }; // Reset state on game restart game.on('reset', function () { // Remove all obstacles and powerups for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy(); for (var j = 0; j < powerups.length; j++) powerups[j].destroy(); obstacles = []; powerups = []; score = 0; LK.setScore(0); scoreTxt.setText('0'); powerupActive = false; powerupTimer = 0; powerupTxt.visible = false; player.x = 2048 / 2; player.y = 2732 - 400; gameOver = false; ticks = 0; speedScale = 1.0; rarePassThroughActive = false; rarePassThroughTimer = 0; }); // No touch controls: face only, but allow drag fallback for debug var dragNode = null; game.down = function (x, y, obj) { // For debug: allow dragging player if facekit not available if (!facekit.mouthCenter) dragNode = player; }; game.move = function (x, y, obj) { if (dragNode) { player.x = clamp(x, marginLeft + player.width / 2, 2048 - marginRight - player.width / 2); player.y = clamp(y, marginTop + player.height / 2, 2732 - marginBottom - player.height / 2); } }; game.up = function (x, y, obj) { dragNode = null; };
===================================================================
--- original.js
+++ change.js
@@ -13,9 +13,9 @@
var obsGfx = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
- self.speed = 18 + Math.random() * 10; // pixels per frame, increases with time
+ self.speed = 12 + Math.random() * 6; // pixels per frame, slower base speed
self.update = function () {
self.y += self.speed;
};
return self;
@@ -137,9 +137,9 @@
// Random X, avoid edges
obs.x = clamp(180 + Math.random() * (2048 - 360), marginLeft + 90, 2048 - marginRight - 90);
obs.y = -80;
// Speed up as score increases and with powerups
- obs.speed = (18 + Math.random() * 10 + Math.floor(score / 10) * 2) * speedScale;
+ obs.speed = (12 + Math.random() * 6 + Math.floor(score / 10) * 1.2) * speedScale;
// 10% chance: rare pass-through obstacle (if not already active)
if (!rarePassThroughActive && Math.random() < 0.10) {
obs.isPassThrough = true;
obs.alpha = 0.45; // visually faded