User prompt
Please fix the bug: 'Uncaught TypeError: setTimeout is not a function' in or related to this line: 'setTimeout(syncKnobToNull, 100);' Line Number: 291
User prompt
make a slide bar to conroll null
User prompt
move null player down more
User prompt
make it so the player can only move left and right
User prompt
revert it to the original game
User prompt
do endless mode but make it a option at the begining
Code edit (1 edits merged)
Please save this source code
User prompt
Null Is The Way
Initial prompt
null is the way
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Fragment: Collectible fragments var Fragment = Container.expand(function () { var self = Container.call(this); var frag = self.attachAsset('fragment', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); // Animate scale for a subtle pulse function pulseUp() { tween(frag, { scaleX: 1.2, scaleY: 1.2 }, { duration: 600, easing: tween.sineInOut, onFinish: pulseDown }); } function pulseDown() { tween(frag, { scaleX: 1.0, scaleY: 1.0 }, { duration: 600, easing: tween.sineInOut, onFinish: pulseUp }); } frag.scaleX = frag.scaleY = 1.0; pulseUp(); // Movement speed (downward) self.speedY = 6; // For collision self.radius = frag.width * 0.5; self.update = function () { self.y += self.speedY; }; return self; }); // NullEntity: The player-controlled "null" entity. var NullEntity = Container.expand(function () { var self = Container.call(this); var entity = self.attachAsset('nullEntity', { anchorX: 0.5, anchorY: 0.5, alpha: 0.18 }); // Add a subtle glow effect by animating alpha tween(entity, { alpha: 0.32 }, { duration: 1200, easing: tween.sineInOut, onFinish: function onFinish() { tween(entity, { alpha: 0.18 }, { duration: 1200, easing: tween.sineInOut, onFinish: function onFinish() { // Loop tween(entity, { alpha: 0.32 }, { duration: 1200, easing: tween.sineInOut, onFinish: arguments.callee }); } }); } }); // For collision, use self's position and size self.radius = entity.width * 0.5; // No update needed; movement is handled by drag/tap return self; }); // Obstacle: Abstract void obstacles to avoid var Obstacle = Container.expand(function () { var self = Container.call(this); var obs = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.32 }); // Randomize rotation for abstractness obs.rotation = (Math.random() - 0.5) * 0.7; // Movement speed (downward) self.speedY = 7 + Math.random() * 3; // For collision self.width = obs.width; self.height = obs.height; self.update = function () { self.y += self.speedY; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111111 // Deep void }); /**** * Game Code ****/ /* We use minimalist shapes for the "null" entity, obstacles, and collectible fragments. - nullEntity: a faint ellipse, representing the player. - obstacle: a semi-transparent box, representing void obstacles. - fragment: a small glowing ellipse, representing fragments to collect. - messageBg: a translucent box for cryptic message popups. */ // --- Game State --- var nullEntity = new NullEntity(); game.addChild(nullEntity); // Start position: center horizontally, 80% down vertically nullEntity.x = 2048 / 2; nullEntity.y = 2732 * 0.8; // Arrays for obstacles and fragments var obstacles = []; var fragments = []; // Level and progress var level = 1; var fragmentsCollected = 0; var fragmentsToNext = 5; var showingMessage = false; // Cryptic messages for fragments var messages = ["Nothing is the beginning of everything.", "In emptiness, potential awaits.", "Absence shapes the void.", "Meaning emerges from nothing.", "The null is not empty, but full of possibility."]; // --- GUI: Progress Display --- var progressTxt = new Text2('Fragments: 0/5', { size: 90, fill: 0xCCCCCC }); progressTxt.anchor.set(0.5, 0); LK.gui.top.addChild(progressTxt); // --- Message Popup --- var messageContainer = new Container(); var messageBg = LK.getAsset('messageBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.82 }); messageContainer.addChild(messageBg); var messageTxt = new Text2('', { size: 70, fill: 0xE0E0E0, align: "center", wordWrap: true, wordWrapWidth: 800 }); messageTxt.anchor.set(0.5, 0.5); messageTxt.x = 0; messageTxt.y = 0; messageContainer.addChild(messageTxt); messageContainer.visible = false; messageContainer.x = 2048 / 2; messageContainer.y = 2732 / 2; game.addChild(messageContainer); // --- Drag/Touch Controls --- var dragActive = false; var dragOffsetX = 0; var dragOffsetY = 0; // Helper: Clamp nullEntity inside game bounds (with margin) function clampNullEntity() { var margin = 80; var r = nullEntity.radius; if (nullEntity.x < margin + r) nullEntity.x = margin + r; if (nullEntity.x > 2048 - margin - r) nullEntity.x = 2048 - margin - r; if (nullEntity.y < margin + r) nullEntity.y = margin + r; if (nullEntity.y > 2732 - margin - r) nullEntity.y = 2732 - margin - r; } // --- Event Handlers --- function handleMove(x, y, obj) { if (showingMessage) return; // Pause movement when message is shown if (dragActive) { nullEntity.x = x - dragOffsetX; nullEntity.y = y - dragOffsetY; clampNullEntity(); } } game.move = handleMove; game.down = function (x, y, obj) { if (showingMessage) { // Hide message on tap messageContainer.visible = false; showingMessage = false; return; } // Start drag if touch is near nullEntity var dx = x - nullEntity.x; var dy = y - nullEntity.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < nullEntity.radius * 1.2) { dragActive = true; dragOffsetX = x - nullEntity.x; dragOffsetY = y - nullEntity.y; } }; game.up = function (x, y, obj) { dragActive = false; }; // --- Collision Helpers --- 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; } // --- Spawning Obstacles and Fragments --- var obstacleTimer = 0; var fragmentTimer = 0; function spawnObstacle() { var obs = new Obstacle(); obs.x = 200 + Math.random() * (2048 - 400); obs.y = -80; obstacles.push(obs); game.addChild(obs); } function spawnFragment() { var frag = new Fragment(); frag.x = 200 + Math.random() * (2048 - 400); frag.y = -60; fragments.push(frag); game.addChild(frag); } // --- Level Progression --- function nextLevel() { if (endlessMode) { // In endless mode, do not level up, just keep going return; } level += 1; fragmentsCollected = 0; fragmentsToNext = 5 + level * 2; progressTxt.setText('Fragments: 0/' + fragmentsToNext); // Show cryptic message var msg = messages[(level - 2) % messages.length] || "The void deepens."; messageTxt.setText(msg); messageContainer.visible = true; showingMessage = true; // Increase difficulty: spawn rates obstacleTimer = 0; fragmentTimer = 0; } // --- Game Update Loop --- game.update = function () { if (showingMessage) return; // Spawn obstacles obstacleTimer++; var obsInterval = Math.max(38 - level * 2, 16); if (obstacleTimer >= obsInterval) { spawnObstacle(); obstacleTimer = 0; } // Spawn fragments fragmentTimer++; var fragInterval = Math.max(120 - level * 8, 40); if (fragmentTimer >= fragInterval) { spawnFragment(); fragmentTimer = 0; } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y - obs.height / 2 > 2732 + 100) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with nullEntity if (circleRectIntersect(nullEntity.x, nullEntity.y, nullEntity.radius * 0.8, obs.x, obs.y, obs.width, obs.height)) { // Flash and game over LK.effects.flashScreen(0xffffff, 900); LK.showGameOver(); return; } } // Update fragments for (var j = fragments.length - 1; j >= 0; j--) { var frag = fragments[j]; frag.update(); // Remove if off screen if (frag.y - frag.radius > 2732 + 80) { frag.destroy(); fragments.splice(j, 1); continue; } // Collision with nullEntity if (circleCircleIntersect(nullEntity.x, nullEntity.y, nullEntity.radius * 0.8, frag.x, frag.y, frag.radius)) { // Collect fragment fragmentsCollected += 1; if (endlessMode) { progressTxt.setText('Fragments: ' + fragmentsCollected); } else { progressTxt.setText('Fragments: ' + fragmentsCollected + '/' + fragmentsToNext); } // Subtle flash LK.effects.flashObject(nullEntity, 0x8ecae6, 400); frag.destroy(); fragments.splice(j, 1); // Level up if (!endlessMode && fragmentsCollected >= fragmentsToNext) { nextLevel(); } continue; } } }; // --- Initial Progress Text --- progressTxt.setText('Fragments: 0/' + fragmentsToNext); // --- Mode Selection Popup --- var modeSelectContainer = new Container(); var modeBg = LK.getAsset('messageBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.92 }); modeSelectContainer.addChild(modeBg); modeSelectContainer.x = 2048 / 2; modeSelectContainer.y = 2732 / 2; var modeTitle = new Text2('Choose Mode', { size: 90, fill: 0xE0E0E0, align: "center" }); modeTitle.anchor.set(0.5, 0.5); modeTitle.y = -110; modeSelectContainer.addChild(modeTitle); var btnNormal = new Text2('Progressive', { size: 80, fill: 0x8ecae6, align: "center" }); btnNormal.anchor.set(0.5, 0.5); btnNormal.y = 0; modeSelectContainer.addChild(btnNormal); var btnEndless = new Text2('Endless', { size: 80, fill: 0x219ebc, align: "center" }); btnEndless.anchor.set(0.5, 0.5); btnEndless.y = 110; modeSelectContainer.addChild(btnEndless); modeSelectContainer.visible = true; game.addChild(modeSelectContainer); var endlessMode = false; // Helper: Hide mode select and start game function startGameWithMode(isEndless) { endlessMode = isEndless; modeSelectContainer.visible = false; messageContainer.visible = true; showingMessage = true; if (endlessMode) { // Endless mode: show different intro messageTxt.setText("Endless: Survive and collect as many fragments as you can!"); // Set up endless mode parameters level = 1; fragmentsCollected = 0; fragmentsToNext = 99999; // never triggers nextLevel progressTxt.setText('Fragments: 0'); } else { // Normal mode messageTxt.setText("Guide the null. Collect fragments. Avoid the void."); level = 1; fragmentsCollected = 0; fragmentsToNext = 5; progressTxt.setText('Fragments: 0/' + fragmentsToNext); } // Remove all obstacles/fragments if any for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } for (var j = fragments.length - 1; j >= 0; j--) { fragments[j].destroy(); fragments.splice(j, 1); } // Reset timers obstacleTimer = 0; fragmentTimer = 0; // Reset nullEntity position nullEntity.x = 2048 / 2; nullEntity.y = 2732 * 0.8; } // Touch handler for mode selection modeSelectContainer.down = function (x, y, obj) { var local = modeSelectContainer.toLocal({ x: x, y: y }); // Check if tap is on btnNormal if (local.y > btnNormal.y - 60 && local.y < btnNormal.y + 60) { startGameWithMode(false); } // Check if tap is on btnEndless if (local.y > btnEndless.y - 60 && local.y < btnEndless.y + 60) { startGameWithMode(true); } }; modeSelectContainer.interactive = true; // --- Initial Message (Level 1) --- // (Now handled by startGameWithMode) messageContainer.visible = false; showingMessage = false;
===================================================================
--- original.js
+++ change.js
@@ -245,8 +245,12 @@
game.addChild(frag);
}
// --- Level Progression ---
function nextLevel() {
+ if (endlessMode) {
+ // In endless mode, do not level up, just keep going
+ return;
+ }
level += 1;
fragmentsCollected = 0;
fragmentsToNext = 5 + level * 2;
progressTxt.setText('Fragments: 0/' + fragmentsToNext);
@@ -307,23 +311,118 @@
// Collision with nullEntity
if (circleCircleIntersect(nullEntity.x, nullEntity.y, nullEntity.radius * 0.8, frag.x, frag.y, frag.radius)) {
// Collect fragment
fragmentsCollected += 1;
- progressTxt.setText('Fragments: ' + fragmentsCollected + '/' + fragmentsToNext);
+ if (endlessMode) {
+ progressTxt.setText('Fragments: ' + fragmentsCollected);
+ } else {
+ progressTxt.setText('Fragments: ' + fragmentsCollected + '/' + fragmentsToNext);
+ }
// Subtle flash
LK.effects.flashObject(nullEntity, 0x8ecae6, 400);
frag.destroy();
fragments.splice(j, 1);
// Level up
- if (fragmentsCollected >= fragmentsToNext) {
+ if (!endlessMode && fragmentsCollected >= fragmentsToNext) {
nextLevel();
}
continue;
}
}
};
// --- Initial Progress Text ---
progressTxt.setText('Fragments: 0/' + fragmentsToNext);
+// --- Mode Selection Popup ---
+var modeSelectContainer = new Container();
+var modeBg = LK.getAsset('messageBg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.92
+});
+modeSelectContainer.addChild(modeBg);
+modeSelectContainer.x = 2048 / 2;
+modeSelectContainer.y = 2732 / 2;
+var modeTitle = new Text2('Choose Mode', {
+ size: 90,
+ fill: 0xE0E0E0,
+ align: "center"
+});
+modeTitle.anchor.set(0.5, 0.5);
+modeTitle.y = -110;
+modeSelectContainer.addChild(modeTitle);
+var btnNormal = new Text2('Progressive', {
+ size: 80,
+ fill: 0x8ecae6,
+ align: "center"
+});
+btnNormal.anchor.set(0.5, 0.5);
+btnNormal.y = 0;
+modeSelectContainer.addChild(btnNormal);
+var btnEndless = new Text2('Endless', {
+ size: 80,
+ fill: 0x219ebc,
+ align: "center"
+});
+btnEndless.anchor.set(0.5, 0.5);
+btnEndless.y = 110;
+modeSelectContainer.addChild(btnEndless);
+modeSelectContainer.visible = true;
+game.addChild(modeSelectContainer);
+var endlessMode = false;
+// Helper: Hide mode select and start game
+function startGameWithMode(isEndless) {
+ endlessMode = isEndless;
+ modeSelectContainer.visible = false;
+ messageContainer.visible = true;
+ showingMessage = true;
+ if (endlessMode) {
+ // Endless mode: show different intro
+ messageTxt.setText("Endless: Survive and collect as many fragments as you can!");
+ // Set up endless mode parameters
+ level = 1;
+ fragmentsCollected = 0;
+ fragmentsToNext = 99999; // never triggers nextLevel
+ progressTxt.setText('Fragments: 0');
+ } else {
+ // Normal mode
+ messageTxt.setText("Guide the null. Collect fragments. Avoid the void.");
+ level = 1;
+ fragmentsCollected = 0;
+ fragmentsToNext = 5;
+ progressTxt.setText('Fragments: 0/' + fragmentsToNext);
+ }
+ // Remove all obstacles/fragments if any
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ obstacles[i].destroy();
+ obstacles.splice(i, 1);
+ }
+ for (var j = fragments.length - 1; j >= 0; j--) {
+ fragments[j].destroy();
+ fragments.splice(j, 1);
+ }
+ // Reset timers
+ obstacleTimer = 0;
+ fragmentTimer = 0;
+ // Reset nullEntity position
+ nullEntity.x = 2048 / 2;
+ nullEntity.y = 2732 * 0.8;
+}
+// Touch handler for mode selection
+modeSelectContainer.down = function (x, y, obj) {
+ var local = modeSelectContainer.toLocal({
+ x: x,
+ y: y
+ });
+ // Check if tap is on btnNormal
+ if (local.y > btnNormal.y - 60 && local.y < btnNormal.y + 60) {
+ startGameWithMode(false);
+ }
+ // Check if tap is on btnEndless
+ if (local.y > btnEndless.y - 60 && local.y < btnEndless.y + 60) {
+ startGameWithMode(true);
+ }
+};
+modeSelectContainer.interactive = true;
// --- Initial Message (Level 1) ---
-messageTxt.setText("Guide the null. Collect fragments. Avoid the void.");
-messageContainer.visible = true;
-showingMessage = true;
\ No newline at end of file
+// (Now handled by startGameWithMode)
+messageContainer.visible = false;
+showingMessage = false;
\ No newline at end of file