User prompt
Bueno es mejor eliminar el modo de la nave.
User prompt
Corrige el error en el código porfa
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'if (!s.passed && s.x + 50 < cube.x) {' Line Number: 502
User prompt
As que en el nivel 3 y 4 haiga un nuevo modo:nave
User prompt
As un editor de niveles, también que ahora has 3 niveles que duren 1 minuto y un buscador de niveles ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Cube Runner: Spike Escape
Initial prompt
Quiero que el juego sea un runner infinito 2d,que el personaje sea un cubo,un menu con un personalizador de personaje y un botón para jugar y que los obstáculos sean pinchos
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
cubeColor: "cube_blue"
});
/****
* Classes
****/
// Player Cube
var Cube = Container.expand(function () {
var self = Container.call(this);
// Attach cube asset (color set externally)
self.cubeAsset = null;
self.setCubeColor = function (colorId) {
if (self.cubeAsset) {
self.removeChild(self.cubeAsset);
}
self.cubeAsset = self.attachAsset(colorId, {
anchorX: 0.5,
anchorY: 1
});
};
// Physics
self.vy = 0;
self.isOnGround = true;
// Jump method
self.jump = function () {
if (self.isOnGround) {
self.vy = -38;
self.isOnGround = false;
LK.getSound('jump').play();
}
};
// Update method
self.update = function () {
// Gravity
self.vy += 2.2;
self.y += self.vy;
// Ground collision
if (self.y > groundY) {
self.y = groundY;
self.vy = 0;
self.isOnGround = true;
}
};
return self;
});
// Spike Obstacle
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeAsset = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1
});
self.passed = false; // For scoring
// Update method
self.update = function () {
self.x -= spikeSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xfafafa
});
/****
* Game Code
****/
// Music
// Hit sound
// Jump sound
// Ground
// Spike obstacle
// Cube (player) - customizable color, default blue
// --- Global Variables ---
var groundY = 2732 - 80; // y position of ground
var cube = null;
var spikes = [];
var spikeTimer = 0;
var spikeInterval = 90; // frames between spikes (decreases with difficulty)
var spikeSpeed = 18; // pixels per frame (increases with difficulty)
var score = 0;
var scoreTxt = null;
var running = false;
var menuContainer = null;
var playBtn = null;
var colorBtns = [];
var selectedColor = storage.cubeColor || 'cube_blue';
var ground = null;
var lastTick = 0;
// --- Main Menu ---
function showMenu() {
running = false;
// Remove game elements if present
if (cube) {
cube.destroy();
cube = null;
}
for (var i = 0; i < spikes.length; i++) {
spikes[i].destroy();
}
spikes = [];
if (ground) {
ground.destroy();
ground = null;
}
if (scoreTxt) {
scoreTxt.destroy();
scoreTxt = null;
}
// Menu container
menuContainer = new Container();
// Title
var title = new Text2('Cube Runner', {
size: 180,
fill: 0x222222
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 220;
menuContainer.addChild(title);
// Subtitle
var subtitle = new Text2('Spike Escape', {
size: 90,
fill: 0x888888
});
subtitle.anchor.set(0.5, 0);
subtitle.x = 2048 / 2;
subtitle.y = 420;
menuContainer.addChild(subtitle);
// Customizer label
var customLabel = new Text2('Customize Your Cube', {
size: 70,
fill: 0x444444
});
customLabel.anchor.set(0.5, 0);
customLabel.x = 2048 / 2;
customLabel.y = 700;
menuContainer.addChild(customLabel);
// Color buttons
var colors = ['cube_blue', 'cube_red', 'cube_green', 'cube_yellow', 'cube_purple'];
var colorNames = ['Blue', 'Red', 'Green', 'Yellow', 'Purple'];
colorBtns = [];
for (var i = 0; i < colors.length; i++) {
(function (idx) {
var btn = new Container();
var asset = btn.attachAsset(colors[idx], {
anchorX: 0.5,
anchorY: 0.5
});
btn.x = 2048 / 2 - 350 + idx * 175;
btn.y = 950;
btn.scale.set(1.1, 1.1);
// Highlight if selected
if (selectedColor === colors[idx]) {
asset.width += 18;
asset.height += 18;
}
// Label
var lbl = new Text2(colorNames[idx], {
size: 38,
fill: 0x222222
});
lbl.anchor.set(0.5, 0);
lbl.x = 0;
lbl.y = 90;
btn.addChild(lbl);
// Touch event
btn.down = function (x, y, obj) {
selectedColor = colors[idx];
storage.cubeColor = selectedColor;
showMenu();
};
colorBtns.push(btn);
menuContainer.addChild(btn);
})(i);
}
// Play button
playBtn = new Container();
var playBtnShape = playBtn.attachAsset('cube_green', {
anchorX: 0.5,
anchorY: 0.5
});
playBtnShape.width = 320;
playBtnShape.height = 120;
playBtn.x = 2048 / 2;
playBtn.y = 1300;
var playTxt = new Text2('PLAY', {
size: 80,
fill: 0xFFFFFF
});
playTxt.anchor.set(0.5, 0.5);
playBtn.addChild(playTxt);
playBtn.down = function (x, y, obj) {
startGame();
};
menuContainer.addChild(playBtn);
// Instructions
var inst = new Text2('Tap to jump. Dodge the spikes!\nCustomize your cube above.', {
size: 54,
fill: 0x666666
});
inst.anchor.set(0.5, 0);
inst.x = 2048 / 2;
inst.y = 1550;
menuContainer.addChild(inst);
game.addChild(menuContainer);
// Play music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
}
// --- Start Game ---
function startGame() {
running = true;
if (menuContainer) {
menuContainer.destroy();
menuContainer = null;
}
// Reset variables
score = 0;
spikeTimer = 0;
spikeInterval = 90;
spikeSpeed = 18;
spikes = [];
// Ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
});
ground.x = 0;
ground.y = groundY;
game.addChild(ground);
// Cube
cube = new Cube();
cube.setCubeColor(selectedColor);
cube.x = 420;
cube.y = groundY;
game.addChild(cube);
// Score text
scoreTxt = new Text2('0', {
size: 120,
fill: 0x222222
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Play music (if not already playing)
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
}
// --- Game Over ---
function gameOver() {
running = false;
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
// After game over, return to menu
LK.setTimeout(function () {
showMenu();
}, 1200);
}
// --- Game Tap (Jump) ---
game.down = function (x, y, obj) {
if (!running) return;
cube.jump();
};
// --- Main Update Loop ---
game.update = function () {
if (!running) return;
// Update cube
if (cube) cube.update();
// Update spikes
for (var i = spikes.length - 1; i >= 0; i--) {
var s = spikes[i];
s.update();
// Remove if off screen
if (s.x < -120) {
s.destroy();
spikes.splice(i, 1);
continue;
}
// Score if passed
if (!s.passed && s.x + 50 < cube.x) {
s.passed = true;
score += 1;
scoreTxt.setText(score);
// Increase difficulty
if (score % 10 === 0 && spikeInterval > 45) {
spikeInterval -= 7;
spikeSpeed += 2.5;
}
}
// Collision
if (cube.intersects(s)) {
gameOver();
return;
}
}
// Spawn spikes
spikeTimer++;
if (spikeTimer >= spikeInterval) {
spikeTimer = 0;
var spike = new Spike();
spike.x = 2048 + 80;
spike.y = groundY;
game.addChild(spike);
spikes.push(spike);
}
};
// --- Show Menu on Load ---
showMenu(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,327 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ cubeColor: "cube_blue"
+});
+
+/****
+* Classes
+****/
+// Player Cube
+var Cube = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach cube asset (color set externally)
+ self.cubeAsset = null;
+ self.setCubeColor = function (colorId) {
+ if (self.cubeAsset) {
+ self.removeChild(self.cubeAsset);
+ }
+ self.cubeAsset = self.attachAsset(colorId, {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ };
+ // Physics
+ self.vy = 0;
+ self.isOnGround = true;
+ // Jump method
+ self.jump = function () {
+ if (self.isOnGround) {
+ self.vy = -38;
+ self.isOnGround = false;
+ LK.getSound('jump').play();
+ }
+ };
+ // Update method
+ self.update = function () {
+ // Gravity
+ self.vy += 2.2;
+ self.y += self.vy;
+ // Ground collision
+ if (self.y > groundY) {
+ self.y = groundY;
+ self.vy = 0;
+ self.isOnGround = true;
+ }
+ };
+ return self;
+});
+// Spike Obstacle
+var Spike = Container.expand(function () {
+ var self = Container.call(this);
+ var spikeAsset = self.attachAsset('spike', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ self.passed = false; // For scoring
+ // Update method
+ self.update = function () {
+ self.x -= spikeSpeed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xfafafa
+});
+
+/****
+* Game Code
+****/
+// Music
+// Hit sound
+// Jump sound
+// Ground
+// Spike obstacle
+// Cube (player) - customizable color, default blue
+// --- Global Variables ---
+var groundY = 2732 - 80; // y position of ground
+var cube = null;
+var spikes = [];
+var spikeTimer = 0;
+var spikeInterval = 90; // frames between spikes (decreases with difficulty)
+var spikeSpeed = 18; // pixels per frame (increases with difficulty)
+var score = 0;
+var scoreTxt = null;
+var running = false;
+var menuContainer = null;
+var playBtn = null;
+var colorBtns = [];
+var selectedColor = storage.cubeColor || 'cube_blue';
+var ground = null;
+var lastTick = 0;
+// --- Main Menu ---
+function showMenu() {
+ running = false;
+ // Remove game elements if present
+ if (cube) {
+ cube.destroy();
+ cube = null;
+ }
+ for (var i = 0; i < spikes.length; i++) {
+ spikes[i].destroy();
+ }
+ spikes = [];
+ if (ground) {
+ ground.destroy();
+ ground = null;
+ }
+ if (scoreTxt) {
+ scoreTxt.destroy();
+ scoreTxt = null;
+ }
+ // Menu container
+ menuContainer = new Container();
+ // Title
+ var title = new Text2('Cube Runner', {
+ size: 180,
+ fill: 0x222222
+ });
+ title.anchor.set(0.5, 0);
+ title.x = 2048 / 2;
+ title.y = 220;
+ menuContainer.addChild(title);
+ // Subtitle
+ var subtitle = new Text2('Spike Escape', {
+ size: 90,
+ fill: 0x888888
+ });
+ subtitle.anchor.set(0.5, 0);
+ subtitle.x = 2048 / 2;
+ subtitle.y = 420;
+ menuContainer.addChild(subtitle);
+ // Customizer label
+ var customLabel = new Text2('Customize Your Cube', {
+ size: 70,
+ fill: 0x444444
+ });
+ customLabel.anchor.set(0.5, 0);
+ customLabel.x = 2048 / 2;
+ customLabel.y = 700;
+ menuContainer.addChild(customLabel);
+ // Color buttons
+ var colors = ['cube_blue', 'cube_red', 'cube_green', 'cube_yellow', 'cube_purple'];
+ var colorNames = ['Blue', 'Red', 'Green', 'Yellow', 'Purple'];
+ colorBtns = [];
+ for (var i = 0; i < colors.length; i++) {
+ (function (idx) {
+ var btn = new Container();
+ var asset = btn.attachAsset(colors[idx], {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ btn.x = 2048 / 2 - 350 + idx * 175;
+ btn.y = 950;
+ btn.scale.set(1.1, 1.1);
+ // Highlight if selected
+ if (selectedColor === colors[idx]) {
+ asset.width += 18;
+ asset.height += 18;
+ }
+ // Label
+ var lbl = new Text2(colorNames[idx], {
+ size: 38,
+ fill: 0x222222
+ });
+ lbl.anchor.set(0.5, 0);
+ lbl.x = 0;
+ lbl.y = 90;
+ btn.addChild(lbl);
+ // Touch event
+ btn.down = function (x, y, obj) {
+ selectedColor = colors[idx];
+ storage.cubeColor = selectedColor;
+ showMenu();
+ };
+ colorBtns.push(btn);
+ menuContainer.addChild(btn);
+ })(i);
+ }
+ // Play button
+ playBtn = new Container();
+ var playBtnShape = playBtn.attachAsset('cube_green', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ playBtnShape.width = 320;
+ playBtnShape.height = 120;
+ playBtn.x = 2048 / 2;
+ playBtn.y = 1300;
+ var playTxt = new Text2('PLAY', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ playTxt.anchor.set(0.5, 0.5);
+ playBtn.addChild(playTxt);
+ playBtn.down = function (x, y, obj) {
+ startGame();
+ };
+ menuContainer.addChild(playBtn);
+ // Instructions
+ var inst = new Text2('Tap to jump. Dodge the spikes!\nCustomize your cube above.', {
+ size: 54,
+ fill: 0x666666
+ });
+ inst.anchor.set(0.5, 0);
+ inst.x = 2048 / 2;
+ inst.y = 1550;
+ menuContainer.addChild(inst);
+ game.addChild(menuContainer);
+ // Play music
+ LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 1,
+ duration: 1000
+ }
+ });
+}
+// --- Start Game ---
+function startGame() {
+ running = true;
+ if (menuContainer) {
+ menuContainer.destroy();
+ menuContainer = null;
+ }
+ // Reset variables
+ score = 0;
+ spikeTimer = 0;
+ spikeInterval = 90;
+ spikeSpeed = 18;
+ spikes = [];
+ // Ground
+ ground = LK.getAsset('ground', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ ground.x = 0;
+ ground.y = groundY;
+ game.addChild(ground);
+ // Cube
+ cube = new Cube();
+ cube.setCubeColor(selectedColor);
+ cube.x = 420;
+ cube.y = groundY;
+ game.addChild(cube);
+ // Score text
+ scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0x222222
+ });
+ scoreTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(scoreTxt);
+ // Play music (if not already playing)
+ LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 1,
+ duration: 1000
+ }
+ });
+}
+// --- Game Over ---
+function gameOver() {
+ running = false;
+ LK.getSound('hit').play();
+ LK.effects.flashScreen(0xff0000, 800);
+ LK.showGameOver();
+ // After game over, return to menu
+ LK.setTimeout(function () {
+ showMenu();
+ }, 1200);
+}
+// --- Game Tap (Jump) ---
+game.down = function (x, y, obj) {
+ if (!running) return;
+ cube.jump();
+};
+// --- Main Update Loop ---
+game.update = function () {
+ if (!running) return;
+ // Update cube
+ if (cube) cube.update();
+ // Update spikes
+ for (var i = spikes.length - 1; i >= 0; i--) {
+ var s = spikes[i];
+ s.update();
+ // Remove if off screen
+ if (s.x < -120) {
+ s.destroy();
+ spikes.splice(i, 1);
+ continue;
+ }
+ // Score if passed
+ if (!s.passed && s.x + 50 < cube.x) {
+ s.passed = true;
+ score += 1;
+ scoreTxt.setText(score);
+ // Increase difficulty
+ if (score % 10 === 0 && spikeInterval > 45) {
+ spikeInterval -= 7;
+ spikeSpeed += 2.5;
+ }
+ }
+ // Collision
+ if (cube.intersects(s)) {
+ gameOver();
+ return;
+ }
+ }
+ // Spawn spikes
+ spikeTimer++;
+ if (spikeTimer >= spikeInterval) {
+ spikeTimer = 0;
+ var spike = new Spike();
+ spike.x = 2048 + 80;
+ spike.y = groundY;
+ game.addChild(spike);
+ spikes.push(spike);
+ }
+};
+// --- Show Menu on Load ---
+showMenu();
\ No newline at end of file