/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // NumberPadOverride class (Number Pad Override puzzle) var NumberPadOverride = Container.expand(function () { var self = Container.call(this); // Puzzle state self.active = false; self.code = []; self.input = []; self.timeLimit = 6000; // ms, can be randomized 5000-7000 self.timer = null; self.codeText = null; self.padButtons = []; self.onResult = null; // function(success) self.shufflePad = false; // do not shuffle after each click self.fadeCode = false; // code does not fade after 2s self.flicker = true; // screen flicker effect self._codeFadeTimeout = null; self._flickerTimeout = null; // Background overlay var overlay = self.attachAsset('GrabPannel', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, alpha: 0.92, x: 0, y: 0 }); // Center the whole overlay container in the game area self.x = 2048 / 2; self.y = 2732 / 2; // Puzzle panel var panel = new Container(); panel.x = 0; panel.y = 0; self.addChild(panel); // Panel background var panelBg = panel.attachAsset('panel_bg', { anchorX: 0.5, anchorY: 0.5, width: 900, height: 1100, x: 0, y: 0 }); // Code display self.codeText = new Text2('', { size: 120, fill: '#fc1100' }); self.codeText.anchor.set(0.5, 0.5); self.codeText.x = 0; self.codeText.y = -400; panel.addChild(self.codeText); // Timer number self.timerText = new Text2('', { size: 90, fill: '#fc1100' }); self.timerText.anchor.set(0.5, 0.5); self.timerText.x = 0; self.timerText.y = -250; panel.addChild(self.timerText); // Pad buttons (0-9) self._createPad = function (numbers) { // Remove old buttons for (var i = 0; i < self.padButtons.length; i++) { self.padButtons[i].destroy(); } self.padButtons = []; // Layout: 3x4 grid (0 at bottom center) var padOrder = numbers || [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; var positions = [[-180, -60], [0, -60], [180, -60], [-180, 120], [0, 120], [180, 120], [-180, 300], [0, 300], [180, 300], [0, 480]]; for (var i = 0; i < 10; i++) { var n = padOrder[i]; var btn = new Container(); var btnBg = btn.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 160, height: 160, x: 0, y: 0 }); var btnText = new Text2('' + n, { size: 90, fill: '#222' }); btnText.anchor.set(0.5, 0.5); btnText.x = 0; btnText.y = 0; btn.addChild(btnText); btn.x = positions[i][0]; btn.y = positions[i][1]; // Touch/click event (function (num) { btn.down = function (x, y, obj) { self._handleInput(num); }; })(n); panel.addChild(btn); self.padButtons.push(btn); } }; // Shuffle pad numbers self._shufflePadNumbers = function () { var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; } return arr; }; // Start the puzzle self.start = function (code, timeLimit, onResult) { self.active = true; self.code = code.slice(); self.input = []; self.timeLimit = timeLimit || 5000 + Math.floor(Math.random() * 2000); self.onResult = onResult; self.visible = true; // Show code self.codeText.setText(code.join('')); self.codeText.visible = true; // Timer self._startTime = Date.now(); self._endTime = self._startTime + self.timeLimit; self._updateTimer(); if (self.timer) { LK.clearInterval(self.timer); } self.timer = LK.setInterval(self._updateTimer, 60); // Pad var padNums = self.shufflePad ? self._shufflePadNumbers() : [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; self._createPad(padNums); // Fade code after 2s if (self.fadeCode) { if (self._codeFadeTimeout) { LK.clearTimeout(self._codeFadeTimeout); } self._codeFadeTimeout = LK.setTimeout(function () { self.codeText.visible = false; }, 2000); } // Flicker effect if (self.flicker) { if (self._flickerTimeout) { LK.clearTimeout(self._flickerTimeout); } self._flickerTimeout = LK.setTimeout(function () { LK.effects.flashScreen(0xffffff, 120); }, 800 + Math.floor(Math.random() * 800)); } }; // Handle input self._handleInput = function (num) { if (!self.active) { return; } self.input.push(num); // Animate button press for (var i = 0; i < self.padButtons.length; i++) { var btn = self.padButtons[i]; var btnText = btn.children[1]; if (btnText && btnText.text == num) { tween(btn, { scaleX: 0.85, scaleY: 0.85 }, { duration: 60, yoyo: true, repeat: 1 }); } } // Shuffle pad after each click if (self.shufflePad) { var padNums = self._shufflePadNumbers(); self._createPad(padNums); } // Check input for (var i = 0; i < self.input.length; i++) { if (self.input[i] !== self.code[i]) { // Wrong input: fail instantly self._fail(); return; } } if (self.input.length === self.code.length) { // Success! self._success(); } }; // Timer update self._updateTimer = function () { if (!self.active) { return; } var now = Date.now(); var msLeft = Math.max(0, self._endTime - now); var secLeft = Math.ceil(msLeft / 1000); self.timerText.setText(secLeft); self.timerText.setStyle({ fill: '#fc1100' }); if (msLeft <= 0) { self._fail(); } }; // Success self._success = function () { self.active = false; if (self.timer) { LK.clearInterval(self.timer); } if (self._codeFadeTimeout) { LK.clearTimeout(self._codeFadeTimeout); } if (self._flickerTimeout) { LK.clearTimeout(self._flickerTimeout); } self.visible = false; // Add 3 seconds to timer after puzzle completion if (typeof timeLeft !== "undefined") { timeLeft += 3000; if (typeof updateTimerBar === "function") updateTimerBar(); } if (typeof self.onResult === 'function') { self.onResult(true); } }; // Fail self._fail = function () { self.active = false; if (self.timer) { LK.clearInterval(self.timer); } if (self._codeFadeTimeout) { LK.clearTimeout(self._codeFadeTimeout); } if (self._flickerTimeout) { LK.clearTimeout(self._flickerTimeout); } self.visible = false; // Play fail sound and flash LK.getSound('fail').play(); LK.effects.flashScreen(0xff0000, 600); if (typeof self.onResult === 'function') { self.onResult(false); } }; // Clean up self.destroy = function () { if (self.timer) { LK.clearInterval(self.timer); } if (self._codeFadeTimeout) { LK.clearTimeout(self._codeFadeTimeout); } if (self._flickerTimeout) { LK.clearTimeout(self._flickerTimeout); } for (var i = 0; i < self.padButtons.length; i++) { self.padButtons[i].destroy(); } self.padButtons = []; self.visible = false; }; self.visible = false; return self; }); // Screw class (for malfunction minigame) var Screw = Container.expand(function () { var self = Container.call(this); self.fixed = false; self.screwAsset = self.attachAsset('screw', { anchorX: 0.5, anchorY: 0.5 }); // Touch/click event self.down = function (x, y, obj) { if (self.fixed) { return; } self.fixed = true; // Animate: fade out and shrink tween(self, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 200, easing: tween.cubicIn, onFinish: function onFinish() { self.visible = false; } }); if (typeof self.onFix === 'function') { self.onFix(self); } }; return self; }); // Wire class var Wire = Container.expand(function () { var self = Container.call(this); // Properties self.color = 'red'; // default, will be set on init self.cut = false; // Attach asset self.wireAsset = null; self.init = function (color) { self.color = color; self.cut = false; var assetId = 'wire_' + color; self.wireAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; // Cut animation self.cutWire = function () { if (self.cut) { return; } self.cut = true; // Animate: fade out and shrink tween(self, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 300, easing: tween.cubicIn, onFinish: function onFinish() { self.visible = false; } }); }; // Touch/click event self.down = function (x, y, obj) { // Prevent cutting if NumberPadOverride is active if (typeof game !== "undefined" && game._numberPadOverride && game._numberPadOverride.active) { return; } // Prevent cutting if malfunction/screw minigame is active if (typeof malfunctionActive !== "undefined" && malfunctionActive) { return; } if (self.cut) { return; } if (typeof self.onCut === 'function') { self.onCut(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Sounds // Malfunction overlay // Screw (for malfunction minigame) // Communication screen // Panel // Wires: red, blue, green, yellow, black, white // --- Game constants --- var WIRE_COLORS = ['red', 'blue', 'green', 'yellow', 'black', 'white']; var WIRES_PER_PANEL = 4; var PANEL_X = 2048 / 2; var PANEL_Y = 2732 / 2; var PANEL_W = 700; var PANEL_H = 500; var SCREEN_H = 180; var ROUND_TIME = 8000; // ms per round var MALFUNCTION_CHANCE = 0.18; // 18% chance per round // --- Game state --- var wires = []; var panel = null; var screen = null; var screenText = null; var malOverlay = null; var screws = []; var screwBox = null; // Box for screws during malfunction minigame var malfunctionActive = false; var roundTimer = null; var timeLeft = 0; var timerBar = null; var correctWireColor = ''; var canCut = true; var scoreText = null; var roundNum = 0; var tickingSoundTimer = null; // --- GUI --- scoreText = new Text2('0', { size: 120, fill: "#fff" }); scoreText.anchor.set(0.5, 1); LK.gui.bottom.addChild(scoreText); // Timer bar timerBar = LK.getAsset('panel_bg', { width: 600, height: 24, color: 0x44ff44, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 180 }); game.addChild(timerBar); // --- Panel setup --- panel = new Container(); var panelBorder = panel.attachAsset('panel_border', { anchorX: 0.5, anchorY: 0.5 }); var panelBg = panel.attachAsset('panel_bg', { anchorX: 0.5, anchorY: 0.5 }); // Add a box inside the panel_bg (steel panel) var innerBox = panel.attachAsset('panel_border', { anchorX: 0.5, anchorY: 0.5, width: 900, // slightly smaller than panel_bg (1500x2000), visually inside height: 1200, x: 0, y: 50 // move it down a bit to be inside the panel visually }); panel.x = PANEL_X; panel.y = PANEL_Y; game.addChild(panel); // --- Communication screen --- screen = new Container(); var screenBg = screen.attachAsset('screen', { anchorX: 0.5, anchorY: 0.5 }); screen.x = 0; // Place the screen at the top of the panel, matching the panel_bg aspect ratio (panel_bg is 1500x2000, so screen should be near the top edge) screen.y = -1000 + SCREEN_H / 2 + 60 + 40; // -1000 is half of 2000 (panel_bg height), add some margin panel.addChild(screen); screenText = new Text2('', { size: 60, fill: "#fff" }); screenText.anchor.set(0.5, 0.5); screen.addChild(screenText); // Malfunction overlay (hidden by default) malOverlay = LK.getAsset('mal_overlay', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, alpha: 0.8 }); // Center malOverlay in the middle of the screen container malOverlay.x = 0; malOverlay.y = 0; malOverlay.visible = false; screen.addChild(malOverlay); // --- Functions --- function shuffle(arr) { // Fisher-Yates shuffle for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; } return arr; } function startRound() { roundNum += 1; canCut = true; malfunctionActive = false; // Remove old wires for (var i = 0; i < wires.length; i++) { wires[i].destroy(); } wires = []; // Remove screws if any for (var i = 0; i < screws.length; i++) { screws[i].destroy(); } screws = []; // Randomize wires var colorPool = shuffle(WIRE_COLORS.slice()); var roundWires = colorPool.slice(0, WIRES_PER_PANEL); // Pick correct wire correctWireColor = roundWires[Math.floor(Math.random() * roundWires.length)]; // Place wires vertically in panel var spacing = PANEL_H / (WIRES_PER_PANEL + 1); for (var i = 0; i < roundWires.length; i++) { var w = new Wire(); w.init(roundWires[i]); w.x = 0; w.y = -PANEL_H / 2 + spacing * (i + 1) + 40; w.onCut = handleWireCut; panel.addChild(w); wires.push(w); } // Set screen text screenText.setText(correctWireColor.toUpperCase() + ' WIRE!'); screenText.visible = true; screenText.setStyle({ fill: '#309191' }); // Always set text color to black for correctWireColor malOverlay.visible = false; // Malfunction? var malfunctionChance = MALFUNCTION_CHANCE; if (LK.getScore() > 30) { // Gradually increase malfunction chance after score 30, up to 35% malfunctionChance = Math.min(0.35, MALFUNCTION_CHANCE + 0.01 * (LK.getScore() - 30)); } // Immediately trigger malfunction after wires are reset if (Math.random() < malfunctionChance) { // 50% chance to trigger NumberPadOverride, 50% fallback to normal malfunction if (Math.random() < 0.5) { // Trigger NumberPadOverride ONLY here, after wires are reset if (typeof game._numberPadOverride === "undefined" || !game._numberPadOverride) { game._numberPadOverride = new NumberPadOverride(); game.addChild(game._numberPadOverride); } // Keep timer visible during NumberPadOverride var code = []; for (var i = 0; i < 4; i++) { code.push(Math.floor(Math.random() * 10)); } var timeLimit = 5000 + Math.floor(Math.random() * 2000); // 5-7s // Pause main timer during NumberPadOverride canCut = false; game._numberPadOverride.start(code, timeLimit, function (success) { malfunctionActive = false; malOverlay.visible = false; screenText.visible = true; canCut = true; if (!success) { LK.setTimeout(function () { LK.showGameOver(); }, 600); } }); LK.getSound('beep').play(); // Do not trigger other malfunctions this round return; } else { LK.setTimeout(triggerMalfunction, 600 + Math.floor(Math.random() * 800)); } } // Start timer timeLeft = ROUND_TIME; updateTimerBar(); if (roundTimer) { LK.clearInterval(roundTimer); } roundTimer = LK.setInterval(tickTimer, 30); // Ticking sound if (tickingSoundTimer) { LK.clearInterval(tickingSoundTimer); } tickingSoundTimer = LK.setInterval(function () { LK.getSound('tick').play(); }, 1000); } function handleWireCut(wire) { if (!canCut || malfunctionActive && !screws.length) { return; } canCut = false; wire.cutWire(); if (wire.color === correctWireColor) { // Success! LK.getSound('cut').play(); LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); // Animate panel flash green LK.effects.flashObject(panel, 0x44ff44, 300); // Next round after short delay LK.setTimeout(function () { startRound(); }, 700); } else { // Wrong wire! LK.getSound('fail').play(); LK.effects.flashScreen(0xff0000, 600); LK.setScore(Math.max(0, LK.getScore() - 1)); scoreText.setText(LK.getScore()); // Game over LK.setTimeout(function () { LK.showGameOver(); }, 600); } } function tickTimer() { if (!canCut) { return; } // Gradually speed up timer after score > 20 var timerDecrement = 30; var score = LK.getScore(); if (score > 20) { // Increase speed: for every 10 points above 20, timerDecrement increases by 2ms, up to a max of 20ms per tick var extra = Math.min(20, Math.floor((score - 20) / 10) * 2); timerDecrement += extra; } timeLeft -= timerDecrement; // --- Add: Score increases with time (every 1000ms, +1 score) --- if (typeof tickTimer._accum === "undefined") { tickTimer._accum = 0; tickTimer._lastScoreTime = 0; } tickTimer._accum += timerDecrement; if (tickTimer._accum - tickTimer._lastScoreTime >= 1000) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); tickTimer._lastScoreTime += 1000; } updateTimerBar(); if (timeLeft <= 0) { canCut = false; LK.getSound('fail').play(); LK.effects.flashScreen(0xff0000, 600); LK.setTimeout(function () { LK.showGameOver(); }, 600); } } function updateTimerBar() { // Remove bar visual, show countdown number instead timerBar.visible = false; // Add or update a countdown number Text2 object if (typeof updateTimerBar.timerNumber === "undefined") { updateTimerBar.timerNumber = new Text2('', { size: 100, fill: '#fc1100' }); updateTimerBar.timerNumber.anchor.set(0.5, 0.5); updateTimerBar.timerNumber.x = 2048 / 2; updateTimerBar.timerNumber.y = 180; game.addChild(updateTimerBar.timerNumber); } var secondsLeft = Math.ceil(Math.max(0, timeLeft) / 1000); updateTimerBar.timerNumber.setText(secondsLeft); // Always set timer number text color to red updateTimerBar.timerNumber.setStyle({ fill: '#fc1100' }); } function triggerMalfunction() { if (!canCut) { return; } malfunctionActive = true; screenText.visible = false; malOverlay.visible = true; // Hide screws for now, only show after click for (var i = 0; i < screws.length; i++) { screws[i].destroy(); } screws = []; // Always use screw minigame here; NumberPadOverride is only triggered after wires are reset // --- Screw minigame fallback --- // Add a click handler to the screen to show the screw minigame or penalize misclicks screen.down = function (x, y, obj) { // If the screw minigame is not yet started, start it if (!screwBox) { // Remove this handler after first click (but will be re-added below for misclicks) screen.down = undefined; // Create a new box (screwBox) that will contain the screws, centered on the bomb/panel if (typeof screwBox !== "undefined" && screwBox && screwBox.parent) { screwBox.parent.removeChild(screwBox); } screwBox = new Container(); // Add a background for the screwBox (use panel_border for visual consistency) var screwBoxBg = screwBox.attachAsset('CommBack', { anchorX: 0.5, anchorY: 0.5, width: 1500, // Match panel_bg width height: 1000, // Half of panel_bg height (2000px) x: 0, y: 0 }); // Center the screwBox on the panel screwBox.x = 0; screwBox.y = 0; panel.addChild(screwBox); // Show screws at random positions inside the screwBox var screwCount = 3 + Math.floor(Math.random() * 2); // 3 or 4 screws = []; for (var i = 0; i < screwCount; i++) { var s = new Screw(); // Place randomly within the screwBox area s.x = -220 + Math.random() * 440; s.y = -120 + Math.random() * 240; s.onFix = function (screw) { handleScrewFix(screw); // If all screws are fixed, remove the screwBox and return to bomb screen var allFixed = true; for (var j = 0; j < screws.length; j++) { if (!screws[j].fixed) { allFixed = false; break; } } if (allFixed) { if (screwBox && screwBox.parent) { screwBox.parent.removeChild(screwBox); } screwBox = null; // Remove misclick handler when done screen.down = undefined; } }; screwBox.addChild(s); screws.push(s); } LK.getSound('beep').play(); // Add a misclick handler to penalize clicks outside screws screen.down = function (x, y, obj) { // Only penalize if screws are still present and not all fixed var allFixed = true; for (var i = 0; i < screws.length; i++) { if (!screws[i].fixed) { allFixed = false; break; } } if (allFixed) { // Remove handler if all fixed screen.down = undefined; return; } // Check if click is on any visible, unfixed screw var local = screwBox.toLocal({ x: x, y: y }); var hitScrew = false; for (var i = 0; i < screws.length; i++) { var s = screws[i]; if (!s.fixed && s.visible) { // Check bounding box hit (screw asset is centered, 59x59) var dx = local.x - s.x; var dy = local.y - s.y; if (Math.abs(dx) <= 40 && Math.abs(dy) <= 40) { hitScrew = true; break; } } } if (!hitScrew) { // Flash red and reduce timer LK.effects.flashScreen(0xff0000, 300); // Reduce timer by 1 second (1000ms), but not below 0 timeLeft = Math.max(0, timeLeft - 1000); updateTimerBar(); } }; } }; } function handleScrewFix(screw) { // Don't allow fixing screws if the minigame hasn't started (blank screen) if (!screws.length) { return; } LK.getSound('fix').play(); // Check if all screws fixed var allFixed = true; for (var i = 0; i < screws.length; i++) { if (!screws[i].fixed) { allFixed = false; break; } } if (allFixed) { // Add 3 seconds to timer after screw minigame completion if (typeof timeLeft !== "undefined") { timeLeft += 3000; if (typeof updateTimerBar === "function") updateTimerBar(); } malfunctionActive = false; malOverlay.visible = false; screenText.visible = true; // Remove screws from screen for (var i = 0; i < screws.length; i++) { screws[i].destroy(); } screws = []; // Remove any leftover click handler screen.down = undefined; } } // --- Game event handlers --- // Drag prevention: no drag in this game game.move = function (x, y, obj) {}; // --- Game update loop --- game.update = function () { // Win condition: e.g. 20 points if (LK.getScore() >= 99999999999) { LK.showYouWin(); } }; // --- Start game --- // Add Starter asset as a closing plate visually covering the panel (add as top child of panel) var starterAsset = LK.getAsset('Starter', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); panel.addChild(starterAsset); // Add as top child so it covers the panel visually // Add "Ready to Defuse the bomb" text on top of the Starter asset var starterText = new Text2('Ready to Defuse the bomb', { size: 60, fill: "#fff" }); starterText.anchor.set(0.5, 0.5); starterText.x = 0; starterText.y = 0; panel.addChild(starterText); // Add "Cut the correct wire to defuse the bomb" at the top of the screen (GUI) var instructionText = new Text2('Cut the correct wire to defuse the bomb', { size: 48, fill: "#fff" }); instructionText.anchor.set(0.5, 0); instructionText.y = 120; // Move it 120px down from the top for more space LK.gui.top.addChild(instructionText); // Hide timer and panel content until game starts, but do NOT hide any other assets // Instead of hiding the panel, hide its children except the starterAsset and starterText for (var i = 0; i < panel.children.length; i++) { if (panel.children[i] !== starterAsset && panel.children[i] !== starterText) { panel.children[i].visible = false; } } if (typeof updateTimerBar.timerNumber !== "undefined") { updateTimerBar.timerNumber.visible = false; } timerBar.visible = false; // Do not hide or remove any other assets when Starter is present // Pause all game logic until Starter is clicked var gameStarted = false; var startGame = function startGame() { if (gameStarted) return; gameStarted = true; // Remove starter asset (the closing plate) if (starterAsset && starterAsset.parent) { starterAsset.parent.removeChild(starterAsset); } // Remove starter text if (starterText && starterText.parent) { starterText.parent.removeChild(starterText); } // Remove instruction text from GUI if (instructionText && instructionText.parent) { instructionText.parent.removeChild(instructionText); } // Show panel content and timer for (var i = 0; i < panel.children.length; i++) { if (panel.children[i] !== starterAsset && panel.children[i] !== starterText) { panel.children[i].visible = true; } } if (typeof updateTimerBar.timerNumber !== "undefined") { updateTimerBar.timerNumber.visible = true; } timerBar.visible = false; // timerBar is always hidden, only timerNumber is shown // Actually start the game LK.playMusic('Run'); LK.setScore(0); scoreText.setText('0'); startRound(); }; // Only start game on click/tap of Starter asset starterAsset.down = function (x, y, obj) { startGame(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// NumberPadOverride class (Number Pad Override puzzle)
var NumberPadOverride = Container.expand(function () {
var self = Container.call(this);
// Puzzle state
self.active = false;
self.code = [];
self.input = [];
self.timeLimit = 6000; // ms, can be randomized 5000-7000
self.timer = null;
self.codeText = null;
self.padButtons = [];
self.onResult = null; // function(success)
self.shufflePad = false; // do not shuffle after each click
self.fadeCode = false; // code does not fade after 2s
self.flicker = true; // screen flicker effect
self._codeFadeTimeout = null;
self._flickerTimeout = null;
// Background overlay
var overlay = self.attachAsset('GrabPannel', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 0.92,
x: 0,
y: 0
});
// Center the whole overlay container in the game area
self.x = 2048 / 2;
self.y = 2732 / 2;
// Puzzle panel
var panel = new Container();
panel.x = 0;
panel.y = 0;
self.addChild(panel);
// Panel background
var panelBg = panel.attachAsset('panel_bg', {
anchorX: 0.5,
anchorY: 0.5,
width: 900,
height: 1100,
x: 0,
y: 0
});
// Code display
self.codeText = new Text2('', {
size: 120,
fill: '#fc1100'
});
self.codeText.anchor.set(0.5, 0.5);
self.codeText.x = 0;
self.codeText.y = -400;
panel.addChild(self.codeText);
// Timer number
self.timerText = new Text2('', {
size: 90,
fill: '#fc1100'
});
self.timerText.anchor.set(0.5, 0.5);
self.timerText.x = 0;
self.timerText.y = -250;
panel.addChild(self.timerText);
// Pad buttons (0-9)
self._createPad = function (numbers) {
// Remove old buttons
for (var i = 0; i < self.padButtons.length; i++) {
self.padButtons[i].destroy();
}
self.padButtons = [];
// Layout: 3x4 grid (0 at bottom center)
var padOrder = numbers || [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
var positions = [[-180, -60], [0, -60], [180, -60], [-180, 120], [0, 120], [180, 120], [-180, 300], [0, 300], [180, 300], [0, 480]];
for (var i = 0; i < 10; i++) {
var n = padOrder[i];
var btn = new Container();
var btnBg = btn.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 160,
x: 0,
y: 0
});
var btnText = new Text2('' + n, {
size: 90,
fill: '#222'
});
btnText.anchor.set(0.5, 0.5);
btnText.x = 0;
btnText.y = 0;
btn.addChild(btnText);
btn.x = positions[i][0];
btn.y = positions[i][1];
// Touch/click event
(function (num) {
btn.down = function (x, y, obj) {
self._handleInput(num);
};
})(n);
panel.addChild(btn);
self.padButtons.push(btn);
}
};
// Shuffle pad numbers
self._shufflePadNumbers = function () {
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
return arr;
};
// Start the puzzle
self.start = function (code, timeLimit, onResult) {
self.active = true;
self.code = code.slice();
self.input = [];
self.timeLimit = timeLimit || 5000 + Math.floor(Math.random() * 2000);
self.onResult = onResult;
self.visible = true;
// Show code
self.codeText.setText(code.join(''));
self.codeText.visible = true;
// Timer
self._startTime = Date.now();
self._endTime = self._startTime + self.timeLimit;
self._updateTimer();
if (self.timer) {
LK.clearInterval(self.timer);
}
self.timer = LK.setInterval(self._updateTimer, 60);
// Pad
var padNums = self.shufflePad ? self._shufflePadNumbers() : [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
self._createPad(padNums);
// Fade code after 2s
if (self.fadeCode) {
if (self._codeFadeTimeout) {
LK.clearTimeout(self._codeFadeTimeout);
}
self._codeFadeTimeout = LK.setTimeout(function () {
self.codeText.visible = false;
}, 2000);
}
// Flicker effect
if (self.flicker) {
if (self._flickerTimeout) {
LK.clearTimeout(self._flickerTimeout);
}
self._flickerTimeout = LK.setTimeout(function () {
LK.effects.flashScreen(0xffffff, 120);
}, 800 + Math.floor(Math.random() * 800));
}
};
// Handle input
self._handleInput = function (num) {
if (!self.active) {
return;
}
self.input.push(num);
// Animate button press
for (var i = 0; i < self.padButtons.length; i++) {
var btn = self.padButtons[i];
var btnText = btn.children[1];
if (btnText && btnText.text == num) {
tween(btn, {
scaleX: 0.85,
scaleY: 0.85
}, {
duration: 60,
yoyo: true,
repeat: 1
});
}
}
// Shuffle pad after each click
if (self.shufflePad) {
var padNums = self._shufflePadNumbers();
self._createPad(padNums);
}
// Check input
for (var i = 0; i < self.input.length; i++) {
if (self.input[i] !== self.code[i]) {
// Wrong input: fail instantly
self._fail();
return;
}
}
if (self.input.length === self.code.length) {
// Success!
self._success();
}
};
// Timer update
self._updateTimer = function () {
if (!self.active) {
return;
}
var now = Date.now();
var msLeft = Math.max(0, self._endTime - now);
var secLeft = Math.ceil(msLeft / 1000);
self.timerText.setText(secLeft);
self.timerText.setStyle({
fill: '#fc1100'
});
if (msLeft <= 0) {
self._fail();
}
};
// Success
self._success = function () {
self.active = false;
if (self.timer) {
LK.clearInterval(self.timer);
}
if (self._codeFadeTimeout) {
LK.clearTimeout(self._codeFadeTimeout);
}
if (self._flickerTimeout) {
LK.clearTimeout(self._flickerTimeout);
}
self.visible = false;
// Add 3 seconds to timer after puzzle completion
if (typeof timeLeft !== "undefined") {
timeLeft += 3000;
if (typeof updateTimerBar === "function") updateTimerBar();
}
if (typeof self.onResult === 'function') {
self.onResult(true);
}
};
// Fail
self._fail = function () {
self.active = false;
if (self.timer) {
LK.clearInterval(self.timer);
}
if (self._codeFadeTimeout) {
LK.clearTimeout(self._codeFadeTimeout);
}
if (self._flickerTimeout) {
LK.clearTimeout(self._flickerTimeout);
}
self.visible = false;
// Play fail sound and flash
LK.getSound('fail').play();
LK.effects.flashScreen(0xff0000, 600);
if (typeof self.onResult === 'function') {
self.onResult(false);
}
};
// Clean up
self.destroy = function () {
if (self.timer) {
LK.clearInterval(self.timer);
}
if (self._codeFadeTimeout) {
LK.clearTimeout(self._codeFadeTimeout);
}
if (self._flickerTimeout) {
LK.clearTimeout(self._flickerTimeout);
}
for (var i = 0; i < self.padButtons.length; i++) {
self.padButtons[i].destroy();
}
self.padButtons = [];
self.visible = false;
};
self.visible = false;
return self;
});
// Screw class (for malfunction minigame)
var Screw = Container.expand(function () {
var self = Container.call(this);
self.fixed = false;
self.screwAsset = self.attachAsset('screw', {
anchorX: 0.5,
anchorY: 0.5
});
// Touch/click event
self.down = function (x, y, obj) {
if (self.fixed) {
return;
}
self.fixed = true;
// Animate: fade out and shrink
tween(self, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 200,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.visible = false;
}
});
if (typeof self.onFix === 'function') {
self.onFix(self);
}
};
return self;
});
// Wire class
var Wire = Container.expand(function () {
var self = Container.call(this);
// Properties
self.color = 'red'; // default, will be set on init
self.cut = false;
// Attach asset
self.wireAsset = null;
self.init = function (color) {
self.color = color;
self.cut = false;
var assetId = 'wire_' + color;
self.wireAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
// Cut animation
self.cutWire = function () {
if (self.cut) {
return;
}
self.cut = true;
// Animate: fade out and shrink
tween(self, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 300,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.visible = false;
}
});
};
// Touch/click event
self.down = function (x, y, obj) {
// Prevent cutting if NumberPadOverride is active
if (typeof game !== "undefined" && game._numberPadOverride && game._numberPadOverride.active) {
return;
}
// Prevent cutting if malfunction/screw minigame is active
if (typeof malfunctionActive !== "undefined" && malfunctionActive) {
return;
}
if (self.cut) {
return;
}
if (typeof self.onCut === 'function') {
self.onCut(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Sounds
// Malfunction overlay
// Screw (for malfunction minigame)
// Communication screen
// Panel
// Wires: red, blue, green, yellow, black, white
// --- Game constants ---
var WIRE_COLORS = ['red', 'blue', 'green', 'yellow', 'black', 'white'];
var WIRES_PER_PANEL = 4;
var PANEL_X = 2048 / 2;
var PANEL_Y = 2732 / 2;
var PANEL_W = 700;
var PANEL_H = 500;
var SCREEN_H = 180;
var ROUND_TIME = 8000; // ms per round
var MALFUNCTION_CHANCE = 0.18; // 18% chance per round
// --- Game state ---
var wires = [];
var panel = null;
var screen = null;
var screenText = null;
var malOverlay = null;
var screws = [];
var screwBox = null; // Box for screws during malfunction minigame
var malfunctionActive = false;
var roundTimer = null;
var timeLeft = 0;
var timerBar = null;
var correctWireColor = '';
var canCut = true;
var scoreText = null;
var roundNum = 0;
var tickingSoundTimer = null;
// --- GUI ---
scoreText = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(scoreText);
// Timer bar
timerBar = LK.getAsset('panel_bg', {
width: 600,
height: 24,
color: 0x44ff44,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 180
});
game.addChild(timerBar);
// --- Panel setup ---
panel = new Container();
var panelBorder = panel.attachAsset('panel_border', {
anchorX: 0.5,
anchorY: 0.5
});
var panelBg = panel.attachAsset('panel_bg', {
anchorX: 0.5,
anchorY: 0.5
});
// Add a box inside the panel_bg (steel panel)
var innerBox = panel.attachAsset('panel_border', {
anchorX: 0.5,
anchorY: 0.5,
width: 900,
// slightly smaller than panel_bg (1500x2000), visually inside
height: 1200,
x: 0,
y: 50 // move it down a bit to be inside the panel visually
});
panel.x = PANEL_X;
panel.y = PANEL_Y;
game.addChild(panel);
// --- Communication screen ---
screen = new Container();
var screenBg = screen.attachAsset('screen', {
anchorX: 0.5,
anchorY: 0.5
});
screen.x = 0;
// Place the screen at the top of the panel, matching the panel_bg aspect ratio (panel_bg is 1500x2000, so screen should be near the top edge)
screen.y = -1000 + SCREEN_H / 2 + 60 + 40; // -1000 is half of 2000 (panel_bg height), add some margin
panel.addChild(screen);
screenText = new Text2('', {
size: 60,
fill: "#fff"
});
screenText.anchor.set(0.5, 0.5);
screen.addChild(screenText);
// Malfunction overlay (hidden by default)
malOverlay = LK.getAsset('mal_overlay', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
alpha: 0.8
});
// Center malOverlay in the middle of the screen container
malOverlay.x = 0;
malOverlay.y = 0;
malOverlay.visible = false;
screen.addChild(malOverlay);
// --- Functions ---
function shuffle(arr) {
// Fisher-Yates shuffle
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
return arr;
}
function startRound() {
roundNum += 1;
canCut = true;
malfunctionActive = false;
// Remove old wires
for (var i = 0; i < wires.length; i++) {
wires[i].destroy();
}
wires = [];
// Remove screws if any
for (var i = 0; i < screws.length; i++) {
screws[i].destroy();
}
screws = [];
// Randomize wires
var colorPool = shuffle(WIRE_COLORS.slice());
var roundWires = colorPool.slice(0, WIRES_PER_PANEL);
// Pick correct wire
correctWireColor = roundWires[Math.floor(Math.random() * roundWires.length)];
// Place wires vertically in panel
var spacing = PANEL_H / (WIRES_PER_PANEL + 1);
for (var i = 0; i < roundWires.length; i++) {
var w = new Wire();
w.init(roundWires[i]);
w.x = 0;
w.y = -PANEL_H / 2 + spacing * (i + 1) + 40;
w.onCut = handleWireCut;
panel.addChild(w);
wires.push(w);
}
// Set screen text
screenText.setText(correctWireColor.toUpperCase() + ' WIRE!');
screenText.visible = true;
screenText.setStyle({
fill: '#309191'
}); // Always set text color to black for correctWireColor
malOverlay.visible = false;
// Malfunction?
var malfunctionChance = MALFUNCTION_CHANCE;
if (LK.getScore() > 30) {
// Gradually increase malfunction chance after score 30, up to 35%
malfunctionChance = Math.min(0.35, MALFUNCTION_CHANCE + 0.01 * (LK.getScore() - 30));
}
// Immediately trigger malfunction after wires are reset
if (Math.random() < malfunctionChance) {
// 50% chance to trigger NumberPadOverride, 50% fallback to normal malfunction
if (Math.random() < 0.5) {
// Trigger NumberPadOverride ONLY here, after wires are reset
if (typeof game._numberPadOverride === "undefined" || !game._numberPadOverride) {
game._numberPadOverride = new NumberPadOverride();
game.addChild(game._numberPadOverride);
}
// Keep timer visible during NumberPadOverride
var code = [];
for (var i = 0; i < 4; i++) {
code.push(Math.floor(Math.random() * 10));
}
var timeLimit = 5000 + Math.floor(Math.random() * 2000); // 5-7s
// Pause main timer during NumberPadOverride
canCut = false;
game._numberPadOverride.start(code, timeLimit, function (success) {
malfunctionActive = false;
malOverlay.visible = false;
screenText.visible = true;
canCut = true;
if (!success) {
LK.setTimeout(function () {
LK.showGameOver();
}, 600);
}
});
LK.getSound('beep').play();
// Do not trigger other malfunctions this round
return;
} else {
LK.setTimeout(triggerMalfunction, 600 + Math.floor(Math.random() * 800));
}
}
// Start timer
timeLeft = ROUND_TIME;
updateTimerBar();
if (roundTimer) {
LK.clearInterval(roundTimer);
}
roundTimer = LK.setInterval(tickTimer, 30);
// Ticking sound
if (tickingSoundTimer) {
LK.clearInterval(tickingSoundTimer);
}
tickingSoundTimer = LK.setInterval(function () {
LK.getSound('tick').play();
}, 1000);
}
function handleWireCut(wire) {
if (!canCut || malfunctionActive && !screws.length) {
return;
}
canCut = false;
wire.cutWire();
if (wire.color === correctWireColor) {
// Success!
LK.getSound('cut').play();
LK.setScore(LK.getScore() + 1);
scoreText.setText(LK.getScore());
// Animate panel flash green
LK.effects.flashObject(panel, 0x44ff44, 300);
// Next round after short delay
LK.setTimeout(function () {
startRound();
}, 700);
} else {
// Wrong wire!
LK.getSound('fail').play();
LK.effects.flashScreen(0xff0000, 600);
LK.setScore(Math.max(0, LK.getScore() - 1));
scoreText.setText(LK.getScore());
// Game over
LK.setTimeout(function () {
LK.showGameOver();
}, 600);
}
}
function tickTimer() {
if (!canCut) {
return;
}
// Gradually speed up timer after score > 20
var timerDecrement = 30;
var score = LK.getScore();
if (score > 20) {
// Increase speed: for every 10 points above 20, timerDecrement increases by 2ms, up to a max of 20ms per tick
var extra = Math.min(20, Math.floor((score - 20) / 10) * 2);
timerDecrement += extra;
}
timeLeft -= timerDecrement;
// --- Add: Score increases with time (every 1000ms, +1 score) ---
if (typeof tickTimer._accum === "undefined") {
tickTimer._accum = 0;
tickTimer._lastScoreTime = 0;
}
tickTimer._accum += timerDecrement;
if (tickTimer._accum - tickTimer._lastScoreTime >= 1000) {
LK.setScore(LK.getScore() + 1);
scoreText.setText(LK.getScore());
tickTimer._lastScoreTime += 1000;
}
updateTimerBar();
if (timeLeft <= 0) {
canCut = false;
LK.getSound('fail').play();
LK.effects.flashScreen(0xff0000, 600);
LK.setTimeout(function () {
LK.showGameOver();
}, 600);
}
}
function updateTimerBar() {
// Remove bar visual, show countdown number instead
timerBar.visible = false;
// Add or update a countdown number Text2 object
if (typeof updateTimerBar.timerNumber === "undefined") {
updateTimerBar.timerNumber = new Text2('', {
size: 100,
fill: '#fc1100'
});
updateTimerBar.timerNumber.anchor.set(0.5, 0.5);
updateTimerBar.timerNumber.x = 2048 / 2;
updateTimerBar.timerNumber.y = 180;
game.addChild(updateTimerBar.timerNumber);
}
var secondsLeft = Math.ceil(Math.max(0, timeLeft) / 1000);
updateTimerBar.timerNumber.setText(secondsLeft);
// Always set timer number text color to red
updateTimerBar.timerNumber.setStyle({
fill: '#fc1100'
});
}
function triggerMalfunction() {
if (!canCut) {
return;
}
malfunctionActive = true;
screenText.visible = false;
malOverlay.visible = true;
// Hide screws for now, only show after click
for (var i = 0; i < screws.length; i++) {
screws[i].destroy();
}
screws = [];
// Always use screw minigame here; NumberPadOverride is only triggered after wires are reset
// --- Screw minigame fallback ---
// Add a click handler to the screen to show the screw minigame or penalize misclicks
screen.down = function (x, y, obj) {
// If the screw minigame is not yet started, start it
if (!screwBox) {
// Remove this handler after first click (but will be re-added below for misclicks)
screen.down = undefined;
// Create a new box (screwBox) that will contain the screws, centered on the bomb/panel
if (typeof screwBox !== "undefined" && screwBox && screwBox.parent) {
screwBox.parent.removeChild(screwBox);
}
screwBox = new Container();
// Add a background for the screwBox (use panel_border for visual consistency)
var screwBoxBg = screwBox.attachAsset('CommBack', {
anchorX: 0.5,
anchorY: 0.5,
width: 1500,
// Match panel_bg width
height: 1000,
// Half of panel_bg height (2000px)
x: 0,
y: 0
});
// Center the screwBox on the panel
screwBox.x = 0;
screwBox.y = 0;
panel.addChild(screwBox);
// Show screws at random positions inside the screwBox
var screwCount = 3 + Math.floor(Math.random() * 2); // 3 or 4
screws = [];
for (var i = 0; i < screwCount; i++) {
var s = new Screw();
// Place randomly within the screwBox area
s.x = -220 + Math.random() * 440;
s.y = -120 + Math.random() * 240;
s.onFix = function (screw) {
handleScrewFix(screw);
// If all screws are fixed, remove the screwBox and return to bomb screen
var allFixed = true;
for (var j = 0; j < screws.length; j++) {
if (!screws[j].fixed) {
allFixed = false;
break;
}
}
if (allFixed) {
if (screwBox && screwBox.parent) {
screwBox.parent.removeChild(screwBox);
}
screwBox = null;
// Remove misclick handler when done
screen.down = undefined;
}
};
screwBox.addChild(s);
screws.push(s);
}
LK.getSound('beep').play();
// Add a misclick handler to penalize clicks outside screws
screen.down = function (x, y, obj) {
// Only penalize if screws are still present and not all fixed
var allFixed = true;
for (var i = 0; i < screws.length; i++) {
if (!screws[i].fixed) {
allFixed = false;
break;
}
}
if (allFixed) {
// Remove handler if all fixed
screen.down = undefined;
return;
}
// Check if click is on any visible, unfixed screw
var local = screwBox.toLocal({
x: x,
y: y
});
var hitScrew = false;
for (var i = 0; i < screws.length; i++) {
var s = screws[i];
if (!s.fixed && s.visible) {
// Check bounding box hit (screw asset is centered, 59x59)
var dx = local.x - s.x;
var dy = local.y - s.y;
if (Math.abs(dx) <= 40 && Math.abs(dy) <= 40) {
hitScrew = true;
break;
}
}
}
if (!hitScrew) {
// Flash red and reduce timer
LK.effects.flashScreen(0xff0000, 300);
// Reduce timer by 1 second (1000ms), but not below 0
timeLeft = Math.max(0, timeLeft - 1000);
updateTimerBar();
}
};
}
};
}
function handleScrewFix(screw) {
// Don't allow fixing screws if the minigame hasn't started (blank screen)
if (!screws.length) {
return;
}
LK.getSound('fix').play();
// Check if all screws fixed
var allFixed = true;
for (var i = 0; i < screws.length; i++) {
if (!screws[i].fixed) {
allFixed = false;
break;
}
}
if (allFixed) {
// Add 3 seconds to timer after screw minigame completion
if (typeof timeLeft !== "undefined") {
timeLeft += 3000;
if (typeof updateTimerBar === "function") updateTimerBar();
}
malfunctionActive = false;
malOverlay.visible = false;
screenText.visible = true;
// Remove screws from screen
for (var i = 0; i < screws.length; i++) {
screws[i].destroy();
}
screws = [];
// Remove any leftover click handler
screen.down = undefined;
}
}
// --- Game event handlers ---
// Drag prevention: no drag in this game
game.move = function (x, y, obj) {};
// --- Game update loop ---
game.update = function () {
// Win condition: e.g. 20 points
if (LK.getScore() >= 99999999999) {
LK.showYouWin();
}
};
// --- Start game ---
// Add Starter asset as a closing plate visually covering the panel (add as top child of panel)
var starterAsset = LK.getAsset('Starter', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
panel.addChild(starterAsset); // Add as top child so it covers the panel visually
// Add "Ready to Defuse the bomb" text on top of the Starter asset
var starterText = new Text2('Ready to Defuse the bomb', {
size: 60,
fill: "#fff"
});
starterText.anchor.set(0.5, 0.5);
starterText.x = 0;
starterText.y = 0;
panel.addChild(starterText);
// Add "Cut the correct wire to defuse the bomb" at the top of the screen (GUI)
var instructionText = new Text2('Cut the correct wire to defuse the bomb', {
size: 48,
fill: "#fff"
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 120; // Move it 120px down from the top for more space
LK.gui.top.addChild(instructionText);
// Hide timer and panel content until game starts, but do NOT hide any other assets
// Instead of hiding the panel, hide its children except the starterAsset and starterText
for (var i = 0; i < panel.children.length; i++) {
if (panel.children[i] !== starterAsset && panel.children[i] !== starterText) {
panel.children[i].visible = false;
}
}
if (typeof updateTimerBar.timerNumber !== "undefined") {
updateTimerBar.timerNumber.visible = false;
}
timerBar.visible = false;
// Do not hide or remove any other assets when Starter is present
// Pause all game logic until Starter is clicked
var gameStarted = false;
var startGame = function startGame() {
if (gameStarted) return;
gameStarted = true;
// Remove starter asset (the closing plate)
if (starterAsset && starterAsset.parent) {
starterAsset.parent.removeChild(starterAsset);
}
// Remove starter text
if (starterText && starterText.parent) {
starterText.parent.removeChild(starterText);
}
// Remove instruction text from GUI
if (instructionText && instructionText.parent) {
instructionText.parent.removeChild(instructionText);
}
// Show panel content and timer
for (var i = 0; i < panel.children.length; i++) {
if (panel.children[i] !== starterAsset && panel.children[i] !== starterText) {
panel.children[i].visible = true;
}
}
if (typeof updateTimerBar.timerNumber !== "undefined") {
updateTimerBar.timerNumber.visible = true;
}
timerBar.visible = false; // timerBar is always hidden, only timerNumber is shown
// Actually start the game
LK.playMusic('Run');
LK.setScore(0);
scoreText.setText('0');
startRound();
};
// Only start game on click/tap of Starter asset
starterAsset.down = function (x, y, obj) {
startGame();
};
It is like the back of a bomb, wires on the side. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
It's a screen, very chip like, light blue screen. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
“Top-down view of a steel box with a smooth metallic surface, subtle reflections, and sharp clean edges. The box should appear sturdy and industrial, with a slightly brushed texture on the steel. Lighting highlights the metal’s cool gray color and gives depth to the edges. Minimal shadows inside the box, set against a plain light background.”. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
it's a black wire. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
it's a blue wire. Don't cut it open, just blue nothing else. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
it's a green wire. Don't cut it open, just blue nothing else. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
it's a red wire. Don't cut it open, just blue nothing else. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
it's a yellow wire. Don't cut it open, just blue nothing else. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
paint it white
It's like back of a chip display. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Make it light greyish black
It is a black screen, like a glass pane. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Make it steel
That's a button, imagine a keyboard button. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make it as a perfect rectangle, screws on all the corners. no background, transparent background