User prompt
Just delete the idea
User prompt
Make a start screen, but just with a start button
User prompt
Just delete the whole start screen
User prompt
so basically what should happen is I press the start button and it starts the game but it’s not working
User prompt
Make a start screen
User prompt
Make the game a little hard
User prompt
Make the slider a separate asset
User prompt
Replace the camera with a blue background
User prompt
Yes, but when the fireball is going, make it have less projectiles
User prompt
Make the fireball power up an asset
User prompt
I have an idea make a fireball power up and basically what it does is it shoots tiny fireball projectiles for about between five and 10 seconds and can kill obstacles
User prompt
OK, I have an idea. I want to make a power up called the fireball basically what it does is once you get it for about like five or 10 seconds you shoot, tiny fireball projectiles that instantly kill enemies or obstacles
User prompt
Do you know why just disable the the whole shop it’s not working out
User prompt
Can you just like disable that feature cause I don’t like it
User prompt
so thing isn’t working, so I have a new idea basically what I’m thinking is it keeps your score on top in the shop and see how much points you have earned in all and then when you go to select your skin, your player automatically goes to that ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
so basically it’s not working. Can you please fix it?
User prompt
OK so one thing I’ve noticed is when you’re in the menu and you’re trying to get skins and you have got this certain amount of skins to afford it. It does not let you I pressed on it and it doesn’t automatically give me it either.
User prompt
Create like new Skins in that menu and make them selectable to players that reach Eastern amount of points ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.getItem is not a function. (In 'storage.getItem('ownedSkins')', 'storage.getItem' is undefined)' in or related to this line: 'if (storage.getItem('ownedSkins')) {' Line Number: 339 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function. (In 'storage.get('ownedSkins')', 'storage.get' is undefined)' in or related to this line: 'if (storage.get('ownedSkins')) {' Line Number: 339
User prompt
I like customize, so here’s my idea, idea what if there’s like a little circle in the top right of the screen so when you press on it and show you skins that you can buy for certain in the amount of points
User prompt
The collectible is still not reachable. If you make the bar longer I’ll be able to reach even the hardest Jesus.
User prompt
Hi, I want to change the game a little bit. I wanna give a control option a try where there’s just like a slider that you slide the player back-and-forth
Code edit (1 edits merged)
Please save this source code
User prompt
Face Dash: Smile Runner
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Collectible class: moves downward, destroys itself off screen
var Collectible = Container.expand(function () {
var self = Container.call(this);
var colAsset = self.attachAsset('collectible', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = colAsset.width / 2;
self.speed = 12; // Will be set by game
self.update = function () {
self.y += self.speed;
};
return self;
});
// Obstacle class: moves downward, destroys itself off screen
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obsAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = obsAsset.width;
self.height = obsAsset.height;
self.speed = 12; // Will be set by game
self.update = function () {
self.y += self.speed;
};
return self;
});
// Player class: follows face position, grows when mouth is open
var Player = Container.expand(function () {
var self = Container.call(this);
var playerAsset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = playerAsset.width / 2;
// For collision, always use self.x, self.y, and self.radius
// Animate mouth open/close (scale up/down)
self.setMouthOpen = function (open) {
var targetScale = open ? 1.25 : 1.0;
tween.stop(self, {
scaleX: true,
scaleY: true
});
tween(self, {
scaleX: targetScale,
scaleY: targetScale
}, {
duration: 180,
easing: tween.easeOut
});
};
// For update, nothing needed (position is set by game)
self.update = function () {};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
// Game area
// Character: The player avatar, a bright ellipse
// Obstacle: Red rectangles
// Collectible: Green circle
var GAME_W = 2048;
var GAME_H = 2732;
// Player setup
var player = new Player();
player.x = GAME_W / 2;
player.y = GAME_H * 0.8;
player.scaleX = 1.0;
player.scaleY = 1.0;
game.addChild(player);
// Apply selected skin if not default
if (typeof selectedSkin !== 'undefined' && selectedSkin !== 'player') {
player.removeChildren();
var newAsset = player.attachAsset(selectedSkin, {
anchorX: 0.5,
anchorY: 0.5
});
player.radius = newAsset.width / 2;
}
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Arrays for obstacles and collectibles
var obstacles = [];
var collectibles = [];
// Game state
var score = 0;
var ticks = 0;
var gameSpeed = 12; // Initial speed
var spawnInterval = 60; // Frames between spawns (1 sec at 60fps)
var collectibleInterval = 180; // Frames between collectibles
// For collision detection
function circleRectIntersect(cx, cy, cr, rx, ry, rw, rh) {
// Find closest point to circle within rectangle
var closestX = Math.max(rx - rw / 2, Math.min(cx, rx + rw / 2));
var closestY = Math.max(ry - rh / 2, Math.min(cy, ry + rh / 2));
var dx = cx - closestX;
var dy = cy - closestY;
return dx * dx + dy * dy < cr * cr;
}
function circleCircleIntersect(x1, y1, r1, x2, y2, r2) {
var dx = x1 - x2;
var dy = y1 - y2;
var distSq = dx * dx + dy * dy;
var rSum = r1 + r2;
return distSq < rSum * rSum;
}
// Slider control variables
var sliderBar = null;
var sliderKnob = null;
var sliderDragging = false;
var sliderBarWidth = GAME_W; // Make the slider bar as wide as the game area
var sliderBarHeight = 32;
var sliderKnobRadius = 70;
var sliderBarY = GAME_H - 220; // Place slider above bottom, visible on all screens
// Create slider bar and knob
sliderBar = LK.getAsset('obstacle', {
width: sliderBarWidth,
height: sliderBarHeight,
color: 0x333a4d,
anchorX: 0.5,
anchorY: 0.5,
x: GAME_W / 2,
y: sliderBarY
});
sliderKnob = LK.getAsset('player', {
width: sliderKnobRadius * 2,
height: sliderKnobRadius * 2,
anchorX: 0.5,
anchorY: 0.5,
x: GAME_W / 2,
y: sliderBarY
});
game.addChild(sliderBar);
game.addChild(sliderKnob);
// Helper to clamp knob position
function clampSliderKnobX(x) {
// Allow knob to reach the very left and right edges of the bar
var minX = sliderBar.x - sliderBarWidth / 2 + sliderKnobRadius;
var maxX = sliderBar.x + sliderBarWidth / 2 - sliderKnobRadius;
// If the knob is wider than the bar, clamp to center
if (minX > maxX) {
return sliderBar.x;
}
return Math.max(minX, Math.min(maxX, x));
}
// Set initial knob position
sliderKnob.x = GAME_W / 2;
// Update player position from slider
function updatePlayerFromSlider() {
// Map knob X to player X, allowing player to reach the very left and right edges
var minX = player.radius;
var maxX = GAME_W - player.radius;
var knobMinX = sliderBar.x - sliderBarWidth / 2 + sliderKnobRadius;
var knobMaxX = sliderBar.x + sliderBarWidth / 2 - sliderKnobRadius;
// If the knob is wider than the bar, set t to 0.5 (center)
var t = knobMaxX === knobMinX ? 0.5 : (sliderKnob.x - knobMinX) / (knobMaxX - knobMinX);
player.x = minX + t * (maxX - minX);
// Player Y is fixed
player.y = GAME_H * 0.8;
}
// Touch/mouse events for slider
game.down = function (x, y, obj) {
// Only start drag if touch is near knob
var dx = x - sliderKnob.x;
var dy = y - sliderKnob.y;
if (dx * dx + dy * dy <= sliderKnobRadius * sliderKnobRadius * 1.2) {
sliderDragging = true;
// Move knob immediately
sliderKnob.x = clampSliderKnobX(x);
updatePlayerFromSlider();
}
};
game.move = function (x, y, obj) {
if (sliderDragging) {
sliderKnob.x = clampSliderKnobX(x);
updatePlayerFromSlider();
}
};
game.up = function (x, y, obj) {
sliderDragging = false;
};
// Remove facekit control entirely
// Spawning
function spawnObstacle() {
var obs = new Obstacle();
// Random X, avoid edges
var margin = 200;
obs.x = margin + Math.random() * (GAME_W - 2 * margin);
obs.y = -obs.height / 2;
obs.speed = gameSpeed;
obstacles.push(obs);
game.addChild(obs);
}
function spawnCollectible() {
var col = new Collectible();
var margin = 200;
col.x = margin + Math.random() * (GAME_W - 2 * margin);
col.y = -col.radius;
col.speed = gameSpeed;
collectibles.push(col);
game.addChild(col);
}
// Difficulty scaling
function updateDifficulty() {
// Every 10 points, increase speed and spawn rate
var level = Math.floor(score / 10);
gameSpeed = 12 + level * 2;
spawnInterval = Math.max(30, 60 - level * 4); // Min 0.5s
}
// Main update loop
game.update = function () {
ticks++;
// Slider control
updatePlayerFromSlider();
// Spawn obstacles
if (ticks % spawnInterval === 0) {
spawnObstacle();
}
// Spawn collectibles
if (ticks % collectibleInterval === 0) {
spawnCollectible();
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.speed = gameSpeed;
obs.update();
// Collision with player
if (circleRectIntersect(player.x, player.y, player.radius * player.scaleX, obs.x, obs.y, obs.width, obs.height)) {
// Flash screen, game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
// Off screen
if (obs.y - obs.height / 2 > GAME_H + 100) {
obs.destroy();
obstacles.splice(i, 1);
}
}
// Update collectibles
for (var j = collectibles.length - 1; j >= 0; j--) {
var col = collectibles[j];
col.speed = gameSpeed;
col.update();
// Collect
if (circleCircleIntersect(player.x, player.y, player.radius * player.scaleX, col.x, col.y, col.radius)) {
score += 1;
LK.setScore(score);
scoreTxt.setText(score);
updateDifficulty();
// Flash green
LK.effects.flashObject(player, 0x7ed957, 300);
col.destroy();
collectibles.splice(j, 1);
// Win condition
if (score >= 50) {
LK.showYouWin();
return;
}
}
// Off screen
if (col.y - col.radius > GAME_H + 100) {
col.destroy();
collectibles.splice(j, 1);
}
}
};
// Initial score
LK.setScore(0);
scoreTxt.setText(0);
// Place score text at top center, avoid top left 100x100
scoreTxt.y = 0;
scoreTxt.x = 0;
// --- Skin Shop Button ---
var skinShopBtn = LK.getAsset('collectible', {
width: 120,
height: 120,
anchorX: 1,
anchorY: 0,
x: GAME_W - 40,
y: 40
});
skinShopBtn.interactive = true;
skinShopBtn.buttonMode = true;
game.addChild(skinShopBtn);
// --- Skin Shop Overlay ---
var skinShopOverlay = null;
var skinShopVisible = false;
var availableSkins = [{
id: 'player',
name: 'Classic',
cost: 0
}, {
id: 'collectible',
name: 'Greeny',
cost: 10
}, {
id: 'obstacle',
name: 'Blocky',
cost: 20
},
// New Skins!
{
id: 'skin_blue',
name: 'Blueberry',
cost: 30
}, {
id: 'skin_gold',
name: 'Goldy',
cost: 50
}, {
id: 'skin_pink',
name: 'Pink Pop',
cost: 40
}];
// Register new skin assets (simple colored ellipses/boxes for demo)
var ownedSkins = ['player'];
var selectedSkin = 'player';
// Persistent storage for owned/selected skins
if (storage.ownedSkins) ownedSkins = storage.ownedSkins;
if (storage.selectedSkin) selectedSkin = storage.selectedSkin;
// Helper to show/hide skin shop
function showSkinShop() {
if (skinShopOverlay) return;
skinShopOverlay = new Container();
// Dim background
var bg = LK.getAsset('obstacle', {
width: GAME_W,
height: GAME_H,
color: 0x000000,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
bg.alpha = 0.7;
skinShopOverlay.addChild(bg);
// Title
var title = new Text2('Skin Shop', {
size: 90,
fill: 0xffffff
});
title.anchor.set(0.5, 0);
title.x = GAME_W / 2;
title.y = 120;
skinShopOverlay.addChild(title);
// List skins
var startY = 300;
var gapY = 260;
for (var i = 0; i < availableSkins.length; i++) {
(function (i) {
var skin = availableSkins[i];
var y = startY + i * gapY;
var icon = LK.getAsset(skin.id, {
width: 160,
height: 160,
anchorX: 0.5,
anchorY: 0.5,
x: GAME_W / 2 - 200,
y: y
});
skinShopOverlay.addChild(icon);
var label = new Text2(skin.name + (skin.cost ? ' (' + skin.cost + ')' : ''), {
size: 60,
fill: 0xffffff
});
label.anchor.set(0, 0.5);
label.x = GAME_W / 2 - 80;
label.y = y;
skinShopOverlay.addChild(label);
// Always use up-to-date score for buy/select logic
var currentScore = LK.getScore();
var isOwned = ownedSkins.includes(skin.id);
var canBuy = !isOwned && currentScore >= skin.cost && skin.cost > 0;
var btnText = 'Select';
if (!isOwned && skin.cost > 0) btnText = 'Buy';
if (selectedSkin === skin.id) btnText = 'Selected';
if (canBuy) btnText = 'Buy';
var btn = new Text2(btnText, {
size: 54,
fill: canBuy ? 0x22bb22 : 0x2222ff
});
btn.anchor.set(0, 0.5);
btn.x = GAME_W / 2 + 220;
btn.y = y;
btn.interactive = true;
btn.buttonMode = true;
btn.skinId = skin.id;
btn.on('down', function () {
var sid = this.skinId;
// If already selected, do nothing
if (selectedSkin === sid) return;
// If not owned, try to buy if enough points
if (!ownedSkins.includes(sid)) {
// Find skin object for cost
var skinObj = null;
for (var si = 0; si < availableSkins.length; si++) {
if (availableSkins[si].id === sid) {
skinObj = availableSkins[si];
break;
}
}
if (!skinObj) return;
var currentScore = LK.getScore();
if (currentScore >= skinObj.cost) {
currentScore -= skinObj.cost;
LK.setScore(currentScore);
scoreTxt.setText(currentScore);
ownedSkins.push(sid);
storage.ownedSkins = ownedSkins;
} else {
// Not enough points
LK.effects.flashScreen(0xff0000, 400);
return;
}
}
selectedSkin = sid;
storage.selectedSkin = selectedSkin;
// Update player skin
player.removeChildren();
var newAsset = player.attachAsset(selectedSkin, {
anchorX: 0.5,
anchorY: 0.5
});
player.radius = newAsset.width / 2;
// Refresh overlay
hideSkinShop();
showSkinShop();
});
skinShopOverlay.addChild(btn);
})(i);
}
// Close button
var closeBtn = new Text2('Close', {
size: 70,
fill: 0xff4444
});
closeBtn.anchor.set(1, 0);
closeBtn.x = GAME_W - 40;
closeBtn.y = 40;
closeBtn.interactive = true;
closeBtn.buttonMode = true;
closeBtn.on('down', function () {
hideSkinShop();
});
skinShopOverlay.addChild(closeBtn);
game.addChild(skinShopOverlay);
skinShopVisible = true;
}
function hideSkinShop() {
if (skinShopOverlay) {
skinShopOverlay.destroy();
skinShopOverlay = null;
skinShopVisible = false;
}
}
// Open skin shop on button press
skinShopBtn.on('down', function () {
if (!skinShopVisible) showSkinShop();
});
// If game over, hide skin shop overlay
var oldShowGameOver = LK.showGameOver;
LK.showGameOver = function () {
hideSkinShop();
oldShowGameOver();
};
// No drag/move events needed; all control is via facekit
// End of MVP ===================================================================
--- original.js
+++ change.js
@@ -394,11 +394,12 @@
label.anchor.set(0, 0.5);
label.x = GAME_W / 2 - 80;
label.y = y;
skinShopOverlay.addChild(label);
- // Determine if skin is owned or can be bought
+ // Always use up-to-date score for buy/select logic
+ var currentScore = LK.getScore();
var isOwned = ownedSkins.includes(skin.id);
- var canBuy = !isOwned && score >= skin.cost && skin.cost > 0;
+ var canBuy = !isOwned && currentScore >= skin.cost && skin.cost > 0;
var btnText = 'Select';
if (!isOwned && skin.cost > 0) btnText = 'Buy';
if (selectedSkin === skin.id) btnText = 'Selected';
if (canBuy) btnText = 'Buy';
@@ -426,12 +427,13 @@
break;
}
}
if (!skinObj) return;
- if (score >= skinObj.cost) {
- score -= skinObj.cost;
- LK.setScore(score);
- scoreTxt.setText(score);
+ var currentScore = LK.getScore();
+ if (currentScore >= skinObj.cost) {
+ currentScore -= skinObj.cost;
+ LK.setScore(currentScore);
+ scoreTxt.setText(currentScore);
ownedSkins.push(sid);
storage.ownedSkins = ownedSkins;
} else {
// Not enough points