/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Device: a cyberpunk device/friend to energize var Device = Container.expand(function () { var self = Container.call(this); var deviceAsset = self.attachAsset('device', { anchorX: 0.5, anchorY: 0.5 }); // Energy state self.energized = false; self.energy = 1; // 1 = full, 0 = empty // For pulsing effect when energized self.update = function () { if (self.energized) { deviceAsset.alpha = 0.95 + 0.05 * Math.sin(LK.ticks / 6 + self.x * 0.01); } else { deviceAsset.alpha = 0.7; } }; // Flash when energized self.flash = function () { tween(deviceAsset, { tint: 0xffffff }, { duration: 120, onFinish: function onFinish() { tween(deviceAsset, { tint: 0xff00c8 }, { duration: 200 }); } }); }; return self; }); // NeonLine: a segment between two points, visually a rotated rectangle var NeonLine = Container.expand(function () { var self = Container.call(this); // Set up endpoints self.x1 = 0; self.y1 = 0; self.x2 = 0; self.y2 = 0; // The visual line asset var lineAsset = self.attachAsset('neonLine', { anchorX: 0.5, anchorY: 0.5 }); // Set endpoints and update position/rotation/length self.setEndpoints = function (x1, y1, x2, y2) { self.x1 = x1; self.y1 = y1; self.x2 = x2; self.y2 = y2; // Center of the line self.x = (x1 + x2) / 2; self.y = (y1 + y2) / 2; // Angle var dx = x2 - x1; var dy = y2 - y1; var len = Math.sqrt(dx * dx + dy * dy); self.rotation = Math.atan2(dy, dx); // Set length lineAsset.width = len; // Simulate glow by alpha pulse lineAsset.alpha = 0.85 + 0.15 * Math.sin(LK.ticks / 8); }; // For update pulse self.update = function () { // Animate glow var lineAsset = self.children[0]; lineAsset.alpha = 0.85 + 0.15 * Math.sin(LK.ticks / 8 + self.x * 0.01 + self.y * 0.01); }; return self; }); // PowerSource: the starting node for power lines var PowerSource = Container.expand(function () { var self = Container.call(this); var sourceAsset = self.attachAsset('powerSource', { anchorX: 0.5, anchorY: 0.5 }); // Pulse effect self.update = function () { sourceAsset.alpha = 0.95 + 0.05 * Math.sin(LK.ticks / 8); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a1a }); /**** * Game Code ****/ // Tutorial button // Power source node // Device node (cyberpunk device/friend) // Neon line segment (glowing effect simulated by color) // --- Game constants --- var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var DEVICE_COUNT = 5; var POWER_DRAIN_PER_PIXEL = 0.00012; // Power cost per pixel of line var POWER_REGEN_PER_TICK = 0.0002; // Power regen per tick (if desired) var DEVICE_ENERGY_LOSS_PER_TICK = 0.0012; // How fast devices lose energy var DEVICE_ENERGIZE_RADIUS = 100; // px, how close a line endpoint must be to energize var POWER_MIN = 0; var POWER_MAX = 1; // --- Game state --- var power = 1; // Shared power meter (0-1) var devices = []; var lines = []; var powerSource = null; var drawing = false; var drawStart = null; // {x, y} var drawLine = null; // NeonLine being drawn var drawFromSource = false; var energizedDevices = 0; var tutorialOpen = false; // --- UI elements --- var powerBarBg = null; var powerBarFg = null; var tutorialBtn = null; var tutorialText = null; var winText = null; // --- Helper functions --- // Clamp value between min and max function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Distance between two points function dist(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } // Check if a point is inside a device (for connecting) function pointInDevice(x, y, device) { var dx = x - device.x; var dy = y - device.y; var r = device.children[0].width / 2; return dx * dx + dy * dy <= r * r; } // --- UI Setup --- // Power bar (top center, not in top left 100x100) powerBarBg = new Container(); var bgBar = LK.getAsset('neonLine', { width: 600, height: 36, anchorX: 0, anchorY: 0.5 }); bgBar.tint = 0x222244; powerBarBg.addChild(bgBar); powerBarFg = LK.getAsset('neonLine', { width: 600, height: 36, anchorX: 0, anchorY: 0.5 }); powerBarFg.tint = 0x00fff7; powerBarBg.addChild(powerBarFg); powerBarBg.x = (LK.gui.width - 600) / 2; powerBarBg.y = 110; LK.gui.top.addChild(powerBarBg); // Tutorial button (top right, not in top left) tutorialBtn = LK.getAsset('tutorialBtn', { anchorX: 0.5, anchorY: 0.5 }); tutorialBtn.x = LK.gui.width - 120; tutorialBtn.y = 110; LK.gui.top.addChild(tutorialBtn); var tutorialBtnText = new Text2('?', { size: 60, fill: 0xFFFFFF }); tutorialBtnText.anchor.set(0.5, 0.5); tutorialBtnText.x = tutorialBtn.x; tutorialBtnText.y = tutorialBtn.y; LK.gui.top.addChild(tutorialBtnText); // Tutorial popup (hidden by default) tutorialText = new Text2("How to Play:\n\n" + "1. Draw neon lines from the green power source to pink devices (your friends).\n" + "2. Every line drains the shared power meter at the top.\n" + "3. Connect all devices before power runs out!\n" + "4. Lines must touch a device to energize it.\n\n" + "Tip: Plan your path to use as little power as possible.\n\n" + "Tap the '?' button anytime for help.", { size: 70, fill: 0x00FFF7, align: "center", wordWrap: true, wordWrapWidth: 1200 }); tutorialText.anchor.set(0.5, 0.5); tutorialText.x = LK.gui.width / 2; tutorialText.y = LK.gui.height / 2; tutorialText.visible = false; LK.gui.center.addChild(tutorialText); // Win text (hidden by default) winText = new Text2("All friends powered up!\nYou win!", { size: 120, fill: 0xFF00C8, align: "center" }); winText.anchor.set(0.5, 0.5); winText.x = LK.gui.width / 2; winText.y = LK.gui.height / 2; winText.visible = false; LK.gui.center.addChild(winText); // --- Game Setup --- // Place power source (bottom center) powerSource = new PowerSource(); powerSource.x = GAME_WIDTH / 2; powerSource.y = GAME_HEIGHT - 300; game.addChild(powerSource); // Place devices (scattered, not overlapping, not too close to power source) devices = []; var placed = 0; while (placed < DEVICE_COUNT) { var angle = Math.PI * (0.3 + 1.4 * placed / DEVICE_COUNT); var radius = 700 + 400 * (placed % 2); var x = GAME_WIDTH / 2 + Math.cos(angle) * radius + (Math.random() - 0.5) * 120; var y = 600 + Math.sin(angle) * radius + (Math.random() - 0.5) * 120; // Don't overlap with other devices or power source var ok = true; for (var i = 0; i < devices.length; i++) { if (dist(x, y, devices[i].x, devices[i].y) < 220) ok = false; } if (dist(x, y, powerSource.x, powerSource.y) < 400) ok = false; if (ok) { var d = new Device(); d.x = x; d.y = y; devices.push(d); game.addChild(d); placed++; } } // --- Drawing logic --- // Helper: find device at (x, y) function findDeviceAt(x, y) { for (var i = 0; i < devices.length; i++) { if (pointInDevice(x, y, devices[i])) return devices[i]; } return null; } // Helper: check if a line endpoint is close enough to a device to energize function deviceInRadius(x, y) { for (var i = 0; i < devices.length; i++) { if (!devices[i].energized && dist(x, y, devices[i].x, devices[i].y) < DEVICE_ENERGIZE_RADIUS) { return devices[i]; } } return null; } // Helper: check if a point is close to the power source function pointNearPowerSource(x, y) { var dx = x - powerSource.x; var dy = y - powerSource.y; var r = powerSource.children[0].width / 2 + 30; return dx * dx + dy * dy <= r * r; } // --- Input handlers --- // Only allow drawing if not in tutorial or win function canDraw() { return !tutorialOpen && !winText.visible && power > 0; } // Start drawing: must start from power source or an energized device game.down = function (x, y, obj) { if (!canDraw()) return; // Convert to game coordinates var gx = x, gy = y; // Start from power source? if (pointNearPowerSource(gx, gy)) { drawFromSource = true; drawStart = { x: powerSource.x, y: powerSource.y }; } else { // Start from energized device? for (var i = 0; i < devices.length; i++) { if (devices[i].energized && pointInDevice(gx, gy, devices[i])) { drawFromSource = false; drawStart = { x: devices[i].x, y: devices[i].y }; break; } } } if (drawStart) { drawing = true; drawLine = new NeonLine(); drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy); game.addChild(drawLine); } }; // Drawing in progress game.move = function (x, y, obj) { if (!drawing || !drawLine) return; if (!canDraw()) return; var gx = x, gy = y; drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy); // Show line in real time, but don't finalize until up }; // Finish drawing: if endpoint is on an unenergized device, connect and energize game.up = function (x, y, obj) { if (!drawing || !drawLine) { drawing = false; drawStart = null; return; } if (!canDraw()) { // Remove preview line if (drawLine) { drawLine.destroy(); drawLine = null; } drawing = false; drawStart = null; return; } var gx = x, gy = y; drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy); // Check if endpoint is close to an unenergized device var targetDevice = deviceInRadius(gx, gy); // Only allow connecting to unenergized device if (targetDevice) { // Calculate line length var len = dist(drawStart.x, drawStart.y, targetDevice.x, targetDevice.y); var cost = len * POWER_DRAIN_PER_PIXEL; if (power >= cost) { // Snap endpoint to device center drawLine.setEndpoints(drawStart.x, drawStart.y, targetDevice.x, targetDevice.y); lines.push(drawLine); // Drain power power = clamp(power - cost, POWER_MIN, POWER_MAX); // Energize device targetDevice.energized = true; targetDevice.energy = 1; targetDevice.flash(); energizedDevices++; // Win condition if (energizedDevices === devices.length) { winText.visible = true; LK.effects.flashScreen(0x00fff7, 1200); LK.setTimeout(function () { LK.showYouWin(); }, 1800); } drawLine = null; drawing = false; drawStart = null; return; } else { // Not enough power, flash bar LK.effects.flashObject(powerBarFg, 0xff0000, 400); } } // Not a valid connection, remove preview line if (drawLine) { drawLine.destroy(); drawLine = null; } drawing = false; drawStart = null; }; // --- Tutorial button handler --- tutorialBtn.down = function (x, y, obj) { if (tutorialOpen) { tutorialText.visible = false; tutorialOpen = false; } else { tutorialText.visible = true; tutorialOpen = true; } }; tutorialBtnText.down = tutorialBtn.down; // --- Game update loop --- game.update = function () { // Update power bar var barW = 600 * power; powerBarFg.width = barW; if (power < 0.18) { powerBarFg.tint = 0xff0033; } else { powerBarFg.tint = 0x00fff7; } // Devices lose energy if not energized for (var i = 0; i < devices.length; i++) { var d = devices[i]; if (!d.energized) { d.energy = clamp(d.energy - DEVICE_ENERGY_LOSS_PER_TICK, 0, 1); // If energy runs out, game over if (d.energy <= 0) { LK.effects.flashScreen(0xff0033, 1200); LK.setTimeout(function () { LK.showGameOver(); }, 1200); return; } } } // Power regen (optional, comment out to disable) // power = clamp(power + POWER_REGEN_PER_TICK, POWER_MIN, POWER_MAX); // Animate lines for (var i = 0; i < lines.length; i++) { if (lines[i].update) lines[i].update(); } // Animate devices and power source for (var i = 0; i < devices.length; i++) { if (devices[i].update) devices[i].update(); } if (powerSource && powerSource.update) powerSource.update(); if (drawLine && drawLine.update) drawLine.update(); }; // --- End of file ---
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,431 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Device: a cyberpunk device/friend to energize
+var Device = Container.expand(function () {
+ var self = Container.call(this);
+ var deviceAsset = self.attachAsset('device', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Energy state
+ self.energized = false;
+ self.energy = 1; // 1 = full, 0 = empty
+ // For pulsing effect when energized
+ self.update = function () {
+ if (self.energized) {
+ deviceAsset.alpha = 0.95 + 0.05 * Math.sin(LK.ticks / 6 + self.x * 0.01);
+ } else {
+ deviceAsset.alpha = 0.7;
+ }
+ };
+ // Flash when energized
+ self.flash = function () {
+ tween(deviceAsset, {
+ tint: 0xffffff
+ }, {
+ duration: 120,
+ onFinish: function onFinish() {
+ tween(deviceAsset, {
+ tint: 0xff00c8
+ }, {
+ duration: 200
+ });
+ }
+ });
+ };
+ return self;
+});
+// NeonLine: a segment between two points, visually a rotated rectangle
+var NeonLine = Container.expand(function () {
+ var self = Container.call(this);
+ // Set up endpoints
+ self.x1 = 0;
+ self.y1 = 0;
+ self.x2 = 0;
+ self.y2 = 0;
+ // The visual line asset
+ var lineAsset = self.attachAsset('neonLine', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set endpoints and update position/rotation/length
+ self.setEndpoints = function (x1, y1, x2, y2) {
+ self.x1 = x1;
+ self.y1 = y1;
+ self.x2 = x2;
+ self.y2 = y2;
+ // Center of the line
+ self.x = (x1 + x2) / 2;
+ self.y = (y1 + y2) / 2;
+ // Angle
+ var dx = x2 - x1;
+ var dy = y2 - y1;
+ var len = Math.sqrt(dx * dx + dy * dy);
+ self.rotation = Math.atan2(dy, dx);
+ // Set length
+ lineAsset.width = len;
+ // Simulate glow by alpha pulse
+ lineAsset.alpha = 0.85 + 0.15 * Math.sin(LK.ticks / 8);
+ };
+ // For update pulse
+ self.update = function () {
+ // Animate glow
+ var lineAsset = self.children[0];
+ lineAsset.alpha = 0.85 + 0.15 * Math.sin(LK.ticks / 8 + self.x * 0.01 + self.y * 0.01);
+ };
+ return self;
+});
+// PowerSource: the starting node for power lines
+var PowerSource = Container.expand(function () {
+ var self = Container.call(this);
+ var sourceAsset = self.attachAsset('powerSource', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Pulse effect
+ self.update = function () {
+ sourceAsset.alpha = 0.95 + 0.05 * Math.sin(LK.ticks / 8);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x0a0a1a
+});
+
+/****
+* Game Code
+****/
+// Tutorial button
+// Power source node
+// Device node (cyberpunk device/friend)
+// Neon line segment (glowing effect simulated by color)
+// --- Game constants ---
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var DEVICE_COUNT = 5;
+var POWER_DRAIN_PER_PIXEL = 0.00012; // Power cost per pixel of line
+var POWER_REGEN_PER_TICK = 0.0002; // Power regen per tick (if desired)
+var DEVICE_ENERGY_LOSS_PER_TICK = 0.0012; // How fast devices lose energy
+var DEVICE_ENERGIZE_RADIUS = 100; // px, how close a line endpoint must be to energize
+var POWER_MIN = 0;
+var POWER_MAX = 1;
+// --- Game state ---
+var power = 1; // Shared power meter (0-1)
+var devices = [];
+var lines = [];
+var powerSource = null;
+var drawing = false;
+var drawStart = null; // {x, y}
+var drawLine = null; // NeonLine being drawn
+var drawFromSource = false;
+var energizedDevices = 0;
+var tutorialOpen = false;
+// --- UI elements ---
+var powerBarBg = null;
+var powerBarFg = null;
+var tutorialBtn = null;
+var tutorialText = null;
+var winText = null;
+// --- Helper functions ---
+// Clamp value between min and max
+function clamp(val, min, max) {
+ return Math.max(min, Math.min(max, val));
+}
+// Distance between two points
+function dist(x1, y1, x2, y2) {
+ var dx = x2 - x1;
+ var dy = y2 - y1;
+ return Math.sqrt(dx * dx + dy * dy);
+}
+// Check if a point is inside a device (for connecting)
+function pointInDevice(x, y, device) {
+ var dx = x - device.x;
+ var dy = y - device.y;
+ var r = device.children[0].width / 2;
+ return dx * dx + dy * dy <= r * r;
+}
+// --- UI Setup ---
+// Power bar (top center, not in top left 100x100)
+powerBarBg = new Container();
+var bgBar = LK.getAsset('neonLine', {
+ width: 600,
+ height: 36,
+ anchorX: 0,
+ anchorY: 0.5
+});
+bgBar.tint = 0x222244;
+powerBarBg.addChild(bgBar);
+powerBarFg = LK.getAsset('neonLine', {
+ width: 600,
+ height: 36,
+ anchorX: 0,
+ anchorY: 0.5
+});
+powerBarFg.tint = 0x00fff7;
+powerBarBg.addChild(powerBarFg);
+powerBarBg.x = (LK.gui.width - 600) / 2;
+powerBarBg.y = 110;
+LK.gui.top.addChild(powerBarBg);
+// Tutorial button (top right, not in top left)
+tutorialBtn = LK.getAsset('tutorialBtn', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+tutorialBtn.x = LK.gui.width - 120;
+tutorialBtn.y = 110;
+LK.gui.top.addChild(tutorialBtn);
+var tutorialBtnText = new Text2('?', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+tutorialBtnText.anchor.set(0.5, 0.5);
+tutorialBtnText.x = tutorialBtn.x;
+tutorialBtnText.y = tutorialBtn.y;
+LK.gui.top.addChild(tutorialBtnText);
+// Tutorial popup (hidden by default)
+tutorialText = new Text2("How to Play:\n\n" + "1. Draw neon lines from the green power source to pink devices (your friends).\n" + "2. Every line drains the shared power meter at the top.\n" + "3. Connect all devices before power runs out!\n" + "4. Lines must touch a device to energize it.\n\n" + "Tip: Plan your path to use as little power as possible.\n\n" + "Tap the '?' button anytime for help.", {
+ size: 70,
+ fill: 0x00FFF7,
+ align: "center",
+ wordWrap: true,
+ wordWrapWidth: 1200
+});
+tutorialText.anchor.set(0.5, 0.5);
+tutorialText.x = LK.gui.width / 2;
+tutorialText.y = LK.gui.height / 2;
+tutorialText.visible = false;
+LK.gui.center.addChild(tutorialText);
+// Win text (hidden by default)
+winText = new Text2("All friends powered up!\nYou win!", {
+ size: 120,
+ fill: 0xFF00C8,
+ align: "center"
+});
+winText.anchor.set(0.5, 0.5);
+winText.x = LK.gui.width / 2;
+winText.y = LK.gui.height / 2;
+winText.visible = false;
+LK.gui.center.addChild(winText);
+// --- Game Setup ---
+// Place power source (bottom center)
+powerSource = new PowerSource();
+powerSource.x = GAME_WIDTH / 2;
+powerSource.y = GAME_HEIGHT - 300;
+game.addChild(powerSource);
+// Place devices (scattered, not overlapping, not too close to power source)
+devices = [];
+var placed = 0;
+while (placed < DEVICE_COUNT) {
+ var angle = Math.PI * (0.3 + 1.4 * placed / DEVICE_COUNT);
+ var radius = 700 + 400 * (placed % 2);
+ var x = GAME_WIDTH / 2 + Math.cos(angle) * radius + (Math.random() - 0.5) * 120;
+ var y = 600 + Math.sin(angle) * radius + (Math.random() - 0.5) * 120;
+ // Don't overlap with other devices or power source
+ var ok = true;
+ for (var i = 0; i < devices.length; i++) {
+ if (dist(x, y, devices[i].x, devices[i].y) < 220) ok = false;
+ }
+ if (dist(x, y, powerSource.x, powerSource.y) < 400) ok = false;
+ if (ok) {
+ var d = new Device();
+ d.x = x;
+ d.y = y;
+ devices.push(d);
+ game.addChild(d);
+ placed++;
+ }
+}
+// --- Drawing logic ---
+// Helper: find device at (x, y)
+function findDeviceAt(x, y) {
+ for (var i = 0; i < devices.length; i++) {
+ if (pointInDevice(x, y, devices[i])) return devices[i];
+ }
+ return null;
+}
+// Helper: check if a line endpoint is close enough to a device to energize
+function deviceInRadius(x, y) {
+ for (var i = 0; i < devices.length; i++) {
+ if (!devices[i].energized && dist(x, y, devices[i].x, devices[i].y) < DEVICE_ENERGIZE_RADIUS) {
+ return devices[i];
+ }
+ }
+ return null;
+}
+// Helper: check if a point is close to the power source
+function pointNearPowerSource(x, y) {
+ var dx = x - powerSource.x;
+ var dy = y - powerSource.y;
+ var r = powerSource.children[0].width / 2 + 30;
+ return dx * dx + dy * dy <= r * r;
+}
+// --- Input handlers ---
+// Only allow drawing if not in tutorial or win
+function canDraw() {
+ return !tutorialOpen && !winText.visible && power > 0;
+}
+// Start drawing: must start from power source or an energized device
+game.down = function (x, y, obj) {
+ if (!canDraw()) return;
+ // Convert to game coordinates
+ var gx = x,
+ gy = y;
+ // Start from power source?
+ if (pointNearPowerSource(gx, gy)) {
+ drawFromSource = true;
+ drawStart = {
+ x: powerSource.x,
+ y: powerSource.y
+ };
+ } else {
+ // Start from energized device?
+ for (var i = 0; i < devices.length; i++) {
+ if (devices[i].energized && pointInDevice(gx, gy, devices[i])) {
+ drawFromSource = false;
+ drawStart = {
+ x: devices[i].x,
+ y: devices[i].y
+ };
+ break;
+ }
+ }
+ }
+ if (drawStart) {
+ drawing = true;
+ drawLine = new NeonLine();
+ drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy);
+ game.addChild(drawLine);
+ }
+};
+// Drawing in progress
+game.move = function (x, y, obj) {
+ if (!drawing || !drawLine) return;
+ if (!canDraw()) return;
+ var gx = x,
+ gy = y;
+ drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy);
+ // Show line in real time, but don't finalize until up
+};
+// Finish drawing: if endpoint is on an unenergized device, connect and energize
+game.up = function (x, y, obj) {
+ if (!drawing || !drawLine) {
+ drawing = false;
+ drawStart = null;
+ return;
+ }
+ if (!canDraw()) {
+ // Remove preview line
+ if (drawLine) {
+ drawLine.destroy();
+ drawLine = null;
+ }
+ drawing = false;
+ drawStart = null;
+ return;
+ }
+ var gx = x,
+ gy = y;
+ drawLine.setEndpoints(drawStart.x, drawStart.y, gx, gy);
+ // Check if endpoint is close to an unenergized device
+ var targetDevice = deviceInRadius(gx, gy);
+ // Only allow connecting to unenergized device
+ if (targetDevice) {
+ // Calculate line length
+ var len = dist(drawStart.x, drawStart.y, targetDevice.x, targetDevice.y);
+ var cost = len * POWER_DRAIN_PER_PIXEL;
+ if (power >= cost) {
+ // Snap endpoint to device center
+ drawLine.setEndpoints(drawStart.x, drawStart.y, targetDevice.x, targetDevice.y);
+ lines.push(drawLine);
+ // Drain power
+ power = clamp(power - cost, POWER_MIN, POWER_MAX);
+ // Energize device
+ targetDevice.energized = true;
+ targetDevice.energy = 1;
+ targetDevice.flash();
+ energizedDevices++;
+ // Win condition
+ if (energizedDevices === devices.length) {
+ winText.visible = true;
+ LK.effects.flashScreen(0x00fff7, 1200);
+ LK.setTimeout(function () {
+ LK.showYouWin();
+ }, 1800);
+ }
+ drawLine = null;
+ drawing = false;
+ drawStart = null;
+ return;
+ } else {
+ // Not enough power, flash bar
+ LK.effects.flashObject(powerBarFg, 0xff0000, 400);
+ }
+ }
+ // Not a valid connection, remove preview line
+ if (drawLine) {
+ drawLine.destroy();
+ drawLine = null;
+ }
+ drawing = false;
+ drawStart = null;
+};
+// --- Tutorial button handler ---
+tutorialBtn.down = function (x, y, obj) {
+ if (tutorialOpen) {
+ tutorialText.visible = false;
+ tutorialOpen = false;
+ } else {
+ tutorialText.visible = true;
+ tutorialOpen = true;
+ }
+};
+tutorialBtnText.down = tutorialBtn.down;
+// --- Game update loop ---
+game.update = function () {
+ // Update power bar
+ var barW = 600 * power;
+ powerBarFg.width = barW;
+ if (power < 0.18) {
+ powerBarFg.tint = 0xff0033;
+ } else {
+ powerBarFg.tint = 0x00fff7;
+ }
+ // Devices lose energy if not energized
+ for (var i = 0; i < devices.length; i++) {
+ var d = devices[i];
+ if (!d.energized) {
+ d.energy = clamp(d.energy - DEVICE_ENERGY_LOSS_PER_TICK, 0, 1);
+ // If energy runs out, game over
+ if (d.energy <= 0) {
+ LK.effects.flashScreen(0xff0033, 1200);
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1200);
+ return;
+ }
+ }
+ }
+ // Power regen (optional, comment out to disable)
+ // power = clamp(power + POWER_REGEN_PER_TICK, POWER_MIN, POWER_MAX);
+ // Animate lines
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].update) lines[i].update();
+ }
+ // Animate devices and power source
+ for (var i = 0; i < devices.length; i++) {
+ if (devices[i].update) devices[i].update();
+ }
+ if (powerSource && powerSource.update) powerSource.update();
+ if (drawLine && drawLine.update) drawLine.update();
+};
+// --- End of file ---
\ No newline at end of file
bullets arranged from top to bottom. In-Game asset. 2d. High contrast. No shadows
a topdown policeman and he's pointing a gun. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows
topdown thief. In-Game asset. 2d. High contrast. No shadows
a top down white black theme prison. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows