User prompt
Kill karakteri takip etsin
User prompt
Aynı renkten iki tane olmasın
User prompt
Oyuncunun ismindeki renk ne ise karakterinin rengi o olsun
User prompt
Temas ettiğim kişi ölsün
User prompt
Kill emergency butonumun altın da olsun
User prompt
Kill ekranın sağ alt köşesinde olsun
User prompt
Kill butonu ekranın sağ alt köşesinde olsun
User prompt
Görev barı ortada olsun
User prompt
Adı hangi renkse rengi o olsun
User prompt
Aşı hangi renkse rengi o olsun
User prompt
Oyuncunun adındaki 123456 sayıları olmasın
User prompt
Kill butonu ekranın sağ alt köşesinde olsun
User prompt
Görevler bitince kazanmayalım kaybedelim
User prompt
Kill butonu oyuncuyu takıp etsin
User prompt
Kill butonu kameranın sağ alt köşesinde olsun
User prompt
Görevler bitince kaybedelim
User prompt
Kill butonuna basmadan öldürmesin
User prompt
Kill butonu olsun ve ona basınca temas etiği kişiyi öldürsün
User prompt
Alan daha büyük olsun ve kamera oyuncuyu takip etsin ve oyuncu hızını düşür
User prompt
İmposter kazanırsa kazanmış olalım
User prompt
İmposter biz olalım
User prompt
İmposter oyuncu olsun
Code edit (1 edits merged)
Please save this source code
User prompt
Among Us: Micro Impostor
Initial prompt
Among us
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Emergency meeting button var EmergencyBtn = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('emergencybtn', { anchorX: 0.5, anchorY: 0.5 }); self.txt = new Text2('EMERGENCY', { size: 48, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.txt.x = 0; self.txt.y = 0; self.addChild(self.txt); self.down = function (x, y, obj) { if (game.state === 'playing' && !game.meetingCalled) { game.callMeeting(); } }; return self; }); // Player class (Crewmate or Impostor) var Player = Container.expand(function () { var self = Container.call(this); // Properties self.isImpostor = false; self.isAlive = true; self.playerId = null; self.name = ''; self.avatar = null; self.isLocal = false; // Is this the local player? self.isVoted = false; self.voteTarget = null; self.showName = function () { if (!self.nameTxt) { self.nameTxt = new Text2(self.name, { size: 48, fill: "#fff" }); self.nameTxt.anchor.set(0.5, 0); self.addChild(self.nameTxt); self.nameTxt.y = self.avatar.height / 2 + 10; } }; // Set up avatar self.setRole = function (isImpostor) { self.isImpostor = isImpostor; if (self.avatar) { self.removeChild(self.avatar); } if (isImpostor) { self.avatar = self.attachAsset('impostor', { anchorX: 0.5, anchorY: 0.5 }); } else { self.avatar = self.attachAsset('crewmate', { anchorX: 0.5, anchorY: 0.5 }); } }; // Show dead body self.showDead = function () { if (self.avatar) self.avatar.visible = false; if (!self.deadBody) { self.deadBody = self.attachAsset('deadbody', { anchorX: 0.5, anchorY: 0.5 }); } self.isAlive = false; }; // Hide dead body, show alive self.revive = function () { if (self.deadBody) self.deadBody.visible = false; if (self.avatar) self.avatar.visible = true; self.isAlive = true; }; // For touch/click events self.down = function (x, y, obj) { // Used for voting if (game.state === 'voting' && !game.localPlayer.isVoted && self.isAlive && self !== game.localPlayer) { game.voteFor(self); } }; return self; }); // Sabotage node class var SabotageNode = Container.expand(function () { var self = Container.call(this); self.active = false; self.asset = self.attachAsset('sabotagenode', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { if (game.state === 'playing' && game.localPlayer.isImpostor && !self.active) { // Activate sabotage self.active = true; self.asset.alpha = 0.5; game.sabotageTriggered(self); } }; return self; }); // Task node class var TaskNode = Container.expand(function () { var self = Container.call(this); self.done = false; self.taskId = null; self.ownerId = null; // Which player this task belongs to (for local tasks) self.asset = self.attachAsset('tasknode', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { if (game.state === 'playing' && !self.done && self.ownerId === game.localPlayer.playerId) { // Complete task self.done = true; self.asset.alpha = 0.3; LK.getSound('taskdone').play(); game.completeTask(self); } }; return self; }); // Voting button (for skip or confirm) var VoteBtn = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('votebtn', { anchorX: 0.5, anchorY: 0.5 }); self.txt = new Text2('SKIP', { size: 48, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.txt.x = 0; self.txt.y = 0; self.addChild(self.txt); self.down = function (x, y, obj) { if (game.state === 'voting' && !game.localPlayer.isVoted) { game.voteFor(null); // skip } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Simple sound for vote // Simple sound for meeting // Simple sound for kill // Simple sound for task complete // Voting button (red) // Voting button (blue) // Button for emergency meeting // Dead body (gray ellipse) // Sabotage node (yellow box) // Task node (small green box) // Crewmate and Impostor avatars (simple colored ellipses) // Game state: 'playing', 'meeting', 'voting', 'ended' game.state = 'playing'; // Game variables var playerCount = 6; // For MVP, fixed at 6 (1 impostor, 5 crewmates) var impostorCount = 1; var players = []; var tasks = []; var sabotageNodes = []; var deadBodies = []; var votingBtns = []; var votes = {}; var voteResults = {}; var meetingTimer = null; var votingTimer = null; var taskGoal = 4; // Number of tasks per crewmate var sabotageActive = false; var sabotageTimer = null; var sabotageDuration = 6000; // ms var emergencyBtn = null; var skipBtn = null; var infoTxt = null; var taskBar = null; var taskBarBg = null; var meetingCalled = false; var localPlayer = null; // Helper: Random name generator function randomName() { var names = ['Red', 'Blue', 'Green', 'Yellow', 'Pink', 'Orange', 'Cyan', 'Lime', 'Purple', 'Brown']; return names[Math.floor(Math.random() * names.length)]; } // Helper: Shuffle array function shuffle(arr) { 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; } // Initialize players function setupPlayers() { players = []; var roles = []; for (var i = 0; i < impostorCount; i++) roles.push(true); for (var i = impostorCount; i < playerCount; i++) roles.push(false); shuffle(roles); for (var i = 0; i < playerCount; i++) { var p = new Player(); p.playerId = i; p.name = randomName() + " " + (i + 1); p.setRole(roles[i]); p.isAlive = true; p.x = 400 + i % 3 * 600; p.y = 600 + Math.floor(i / 3) * 500; p.showName(); p.isLocal = i === 0; // For MVP, player 0 is local if (p.isLocal) { localPlayer = p; } players.push(p); game.addChild(p); } game.localPlayer = localPlayer; } // Initialize tasks function setupTasks() { tasks = []; var spacing = 2048 / (taskGoal + 1); for (var i = 0; i < taskGoal; i++) { var t = new TaskNode(); t.taskId = i; t.ownerId = localPlayer.playerId; t.x = spacing * (i + 1); t.y = 350; tasks.push(t); game.addChild(t); } } // Initialize sabotage nodes function setupSabotage() { sabotageNodes = []; for (var i = 0; i < 2; i++) { var s = new SabotageNode(); s.x = 600 + i * 800; s.y = 2000; sabotageNodes.push(s); game.addChild(s); } } // Emergency meeting button function setupEmergencyBtn() { emergencyBtn = new EmergencyBtn(); emergencyBtn.x = 2048 / 2; emergencyBtn.y = 2732 - 200; game.addChild(emergencyBtn); } // Task bar function setupTaskBar() { if (!taskBarBg) { taskBarBg = LK.getAsset('tasknode', { anchorX: 0, anchorY: 0 }); taskBarBg.width = 800; taskBarBg.height = 40; taskBarBg.tint = 0x222222; taskBarBg.x = 624; taskBarBg.y = 80; LK.gui.top.addChild(taskBarBg); } if (!taskBar) { taskBar = LK.getAsset('tasknode', { anchorX: 0, anchorY: 0 }); taskBar.width = 0; taskBar.height = 40; taskBar.tint = 0x83de44; taskBar.x = 624; taskBar.y = 80; LK.gui.top.addChild(taskBar); } } // Info text function setupInfoTxt() { if (!infoTxt) { infoTxt = new Text2('', { size: 64, fill: "#fff" }); infoTxt.anchor.set(0.5, 0); LK.gui.top.addChild(infoTxt); infoTxt.x = 2048 / 2; infoTxt.y = 160; } } // Voting skip button function setupSkipBtn() { skipBtn = new VoteBtn(); skipBtn.x = 2048 / 2; skipBtn.y = 2732 - 300; skipBtn.visible = false; game.addChild(skipBtn); } // Update task bar function updateTaskBar() { var done = 0; for (var i = 0; i < tasks.length; i++) { if (tasks[i].done) done++; } var percent = done / taskGoal; taskBar.width = 800 * percent; } // Complete a task game.completeTask = function (task) { updateTaskBar(); // Check win var allDone = true; for (var i = 0; i < tasks.length; i++) { if (!tasks[i].done) allDone = false; } if (allDone) { gameEnd('crewmates'); } }; // Sabotage triggered game.sabotageTriggered = function (node) { sabotageActive = true; sabotageTimer = LK.setTimeout(function () { sabotageActive = false; node.active = false; node.asset.alpha = 1; // If sabotage not fixed, impostors win gameEnd('impostors'); }, sabotageDuration); // Show info infoTxt.setText('Sabotage! Fix it!'); tween(infoTxt, { alpha: 1 }, { duration: 200 }); }; // Call emergency meeting game.callMeeting = function () { if (meetingCalled) return; meetingCalled = true; LK.getSound('meeting').play(); game.state = 'meeting'; infoTxt.setText('Emergency Meeting!'); // Remove all dead bodies for (var i = 0; i < players.length; i++) { if (!players[i].isAlive && players[i].deadBody) { players[i].deadBody.visible = false; } } // After 2 seconds, go to voting meetingTimer = LK.setTimeout(function () { game.startVoting(); }, 2000); }; // Start voting phase game.startVoting = function () { game.state = 'voting'; infoTxt.setText('Vote: Who is the Impostor?'); // Show voting buttons for each player for (var i = 0; i < votingBtns.length; i++) { votingBtns[i].destroy(); } votingBtns = []; var alivePlayers = []; for (var i = 0; i < players.length; i++) { if (players[i].isAlive) alivePlayers.push(players[i]); } var spacing = 2048 / (alivePlayers.length + 1); for (var i = 0; i < alivePlayers.length; i++) { var btn = new Container(); var asset = btn.attachAsset(alivePlayers[i].isImpostor ? 'votebtnred' : 'votebtn', { anchorX: 0.5, anchorY: 0.5 }); btn.x = spacing * (i + 1); btn.y = 1200; var txt = new Text2(alivePlayers[i].name, { size: 48, fill: "#fff" }); txt.anchor.set(0.5, 0.5); btn.addChild(txt); btn.down = function (targetPlayer) { return function (x, y, obj) { if (game.state === 'voting' && !game.localPlayer.isVoted && targetPlayer.isAlive && targetPlayer !== game.localPlayer) { game.voteFor(targetPlayer); } }; }(alivePlayers[i]); votingBtns.push(btn); game.addChild(btn); } // Show skip button skipBtn.visible = true; // Voting timer (auto skip after 10s) votingTimer = LK.setTimeout(function () { if (!game.localPlayer.isVoted) { game.voteFor(null); } }, 10000); }; // Vote for a player (or skip) game.voteFor = function (targetPlayer) { if (game.localPlayer.isVoted) return; game.localPlayer.isVoted = true; game.localPlayer.voteTarget = targetPlayer ? targetPlayer.playerId : null; LK.getSound('vote').play(); // Show confirmation infoTxt.setText('Voted!'); // Wait for all votes (MVP: AI votes randomly) var allVoted = true; for (var i = 0; i < players.length; i++) { if (players[i].isAlive && !players[i].isVoted) allVoted = false; } if (!allVoted) { // Simulate AI votes after 1s LK.setTimeout(function () { for (var i = 0; i < players.length; i++) { if (players[i].isAlive && !players[i].isVoted) { // AI votes randomly (not self) var choices = []; for (var j = 0; j < players.length; j++) { if (players[j].isAlive && players[j] !== players[i]) choices.push(players[j]); } if (Math.random() < 0.2) { // 20% skip players[i].voteTarget = null; } else { players[i].voteTarget = choices[Math.floor(Math.random() * choices.length)].playerId; } players[i].isVoted = true; } } game.tallyVotes(); }, 1000); } else { game.tallyVotes(); } }; // Tally votes and resolve game.tallyVotes = function () { // Clear voting timer if (votingTimer) { LK.clearTimeout(votingTimer); votingTimer = null; } // Hide voting buttons for (var i = 0; i < votingBtns.length; i++) { votingBtns[i].destroy(); } votingBtns = []; skipBtn.visible = false; // Count votes var counts = {}; var skipCount = 0; for (var i = 0; i < players.length; i++) { if (players[i].isAlive) { var v = players[i].voteTarget; if (v === null) { skipCount++; } else { if (!counts[v]) counts[v] = 0; counts[v]++; } } } // Find max var maxVotes = 0; var maxPlayerId = null; for (var pid in counts) { if (counts[pid] > maxVotes) { maxVotes = counts[pid]; maxPlayerId = parseInt(pid); } } // If tie or skip, no one ejected var tie = false; var totalVotes = 0; for (var pid in counts) { if (counts[pid] === maxVotes && parseInt(pid) !== maxPlayerId) tie = true; totalVotes += counts[pid]; } if (skipCount >= maxVotes || tie || maxPlayerId === null) { infoTxt.setText('No one was ejected.'); } else { // Eject player var ejected = null; for (var i = 0; i < players.length; i++) { if (players[i].playerId === maxPlayerId) { ejected = players[i]; break; } } if (ejected) { ejected.showDead(); infoTxt.setText(ejected.name + ' was ejected!'); // Check win var impostorsLeft = 0, crewmatesLeft = 0; for (var i = 0; i < players.length; i++) { if (players[i].isAlive) { if (players[i].isImpostor) impostorsLeft++;else crewmatesLeft++; } } if (impostorsLeft === 0) { gameEnd('crewmates'); return; } if (impostorsLeft >= crewmatesLeft) { gameEnd('impostors'); return; } } } // Reset votes for (var i = 0; i < players.length; i++) { players[i].isVoted = false; players[i].voteTarget = null; } // Resume play after 2s LK.setTimeout(function () { infoTxt.setText(''); game.state = 'playing'; meetingCalled = false; }, 2000); }; // End game function gameEnd(winner) { game.state = 'ended'; if (winner === 'crewmates') { LK.showYouWin(); } else { LK.showGameOver(); } } // Kill action (impostor only) function tryKill(target) { if (!game.localPlayer.isImpostor || !target.isAlive || !game.localPlayer.isAlive) return; // Must be close var dx = target.x - game.localPlayer.x; var dy = target.y - game.localPlayer.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 200) { target.showDead(); LK.getSound('kill').play(); // Show dead body if (target.deadBody) target.deadBody.visible = true; // Check win var impostorsLeft = 0, crewmatesLeft = 0; for (var i = 0; i < players.length; i++) { if (players[i].isAlive) { if (players[i].isImpostor) impostorsLeft++;else crewmatesLeft++; } } if (impostorsLeft === 0) { gameEnd('crewmates'); return; } if (impostorsLeft >= crewmatesLeft) { gameEnd('impostors'); return; } } } // Move handler (drag local player) var dragNode = null; function handleMove(x, y, obj) { if (game.state !== 'playing') return; if (dragNode) { // Clamp to game area var nx = Math.max(100, Math.min(2048 - 100, x)); var ny = Math.max(200, Math.min(2732 - 200, y)); dragNode.x = nx; dragNode.y = ny; } // If impostor, check for kill if (game.localPlayer.isImpostor && game.localPlayer.isAlive) { for (var i = 0; i < players.length; i++) { if (players[i] !== game.localPlayer && players[i].isAlive) { tryKill(players[i]); } } } } game.move = handleMove; // Down handler (start drag or interact) game.down = function (x, y, obj) { if (game.state !== 'playing') return; // Only drag local player if touch is on them var lp = game.localPlayer; var dx = x - lp.x; var dy = y - lp.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100 && lp.isAlive) { dragNode = lp; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Game update loop game.update = function () { // AI players move randomly if (game.state === 'playing') { for (var i = 0; i < players.length; i++) { var p = players[i]; if (!p.isLocal && p.isAlive) { // Random walk if (LK.ticks % (60 + i * 7) === 0) { var tx = 200 + Math.random() * (2048 - 400); var ty = 500 + Math.random() * (2732 - 1000); tween(p, { x: tx, y: ty }, { duration: 1200 + Math.random() * 800, easing: tween.easeInOut }); } // AI crewmates complete tasks if (!p.isImpostor) { for (var j = 0; j < tasks.length; j++) { var t = tasks[j]; if (!t.done && t.ownerId === p.playerId) { var dx = t.x - p.x; var dy = t.y - p.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { t.done = true; t.asset.alpha = 0.3; updateTaskBar(); } } } } // AI impostor kills if (p.isImpostor) { for (var j = 0; j < players.length; j++) { var target = players[j]; if (target !== p && target.isAlive && !target.isImpostor) { var dx = target.x - p.x; var dy = target.y - p.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 180 && Math.random() < 0.01) { target.showDead(); if (target.deadBody) target.deadBody.visible = true; } } } } } } } }; // Initial setup setupPlayers(); setupTasks(); setupSabotage(); setupEmergencyBtn(); setupTaskBar(); setupInfoTxt(); setupSkipBtn(); updateTaskBar();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,693 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Emergency meeting button
+var EmergencyBtn = Container.expand(function () {
+ var self = Container.call(this);
+ self.asset = self.attachAsset('emergencybtn', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.txt = new Text2('EMERGENCY', {
+ size: 48,
+ fill: "#fff"
+ });
+ self.txt.anchor.set(0.5, 0.5);
+ self.txt.x = 0;
+ self.txt.y = 0;
+ self.addChild(self.txt);
+ self.down = function (x, y, obj) {
+ if (game.state === 'playing' && !game.meetingCalled) {
+ game.callMeeting();
+ }
+ };
+ return self;
+});
+// Player class (Crewmate or Impostor)
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ // Properties
+ self.isImpostor = false;
+ self.isAlive = true;
+ self.playerId = null;
+ self.name = '';
+ self.avatar = null;
+ self.isLocal = false; // Is this the local player?
+ self.isVoted = false;
+ self.voteTarget = null;
+ self.showName = function () {
+ if (!self.nameTxt) {
+ self.nameTxt = new Text2(self.name, {
+ size: 48,
+ fill: "#fff"
+ });
+ self.nameTxt.anchor.set(0.5, 0);
+ self.addChild(self.nameTxt);
+ self.nameTxt.y = self.avatar.height / 2 + 10;
+ }
+ };
+ // Set up avatar
+ self.setRole = function (isImpostor) {
+ self.isImpostor = isImpostor;
+ if (self.avatar) {
+ self.removeChild(self.avatar);
+ }
+ if (isImpostor) {
+ self.avatar = self.attachAsset('impostor', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else {
+ self.avatar = self.attachAsset('crewmate', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ };
+ // Show dead body
+ self.showDead = function () {
+ if (self.avatar) self.avatar.visible = false;
+ if (!self.deadBody) {
+ self.deadBody = self.attachAsset('deadbody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ self.isAlive = false;
+ };
+ // Hide dead body, show alive
+ self.revive = function () {
+ if (self.deadBody) self.deadBody.visible = false;
+ if (self.avatar) self.avatar.visible = true;
+ self.isAlive = true;
+ };
+ // For touch/click events
+ self.down = function (x, y, obj) {
+ // Used for voting
+ if (game.state === 'voting' && !game.localPlayer.isVoted && self.isAlive && self !== game.localPlayer) {
+ game.voteFor(self);
+ }
+ };
+ return self;
+});
+// Sabotage node class
+var SabotageNode = Container.expand(function () {
+ var self = Container.call(this);
+ self.active = false;
+ self.asset = self.attachAsset('sabotagenode', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.down = function (x, y, obj) {
+ if (game.state === 'playing' && game.localPlayer.isImpostor && !self.active) {
+ // Activate sabotage
+ self.active = true;
+ self.asset.alpha = 0.5;
+ game.sabotageTriggered(self);
+ }
+ };
+ return self;
+});
+// Task node class
+var TaskNode = Container.expand(function () {
+ var self = Container.call(this);
+ self.done = false;
+ self.taskId = null;
+ self.ownerId = null; // Which player this task belongs to (for local tasks)
+ self.asset = self.attachAsset('tasknode', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.down = function (x, y, obj) {
+ if (game.state === 'playing' && !self.done && self.ownerId === game.localPlayer.playerId) {
+ // Complete task
+ self.done = true;
+ self.asset.alpha = 0.3;
+ LK.getSound('taskdone').play();
+ game.completeTask(self);
+ }
+ };
+ return self;
+});
+// Voting button (for skip or confirm)
+var VoteBtn = Container.expand(function () {
+ var self = Container.call(this);
+ self.asset = self.attachAsset('votebtn', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.txt = new Text2('SKIP', {
+ size: 48,
+ fill: "#fff"
+ });
+ self.txt.anchor.set(0.5, 0.5);
+ self.txt.x = 0;
+ self.txt.y = 0;
+ self.addChild(self.txt);
+ self.down = function (x, y, obj) {
+ if (game.state === 'voting' && !game.localPlayer.isVoted) {
+ game.voteFor(null); // skip
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x1a1a2e
+});
+
+/****
+* Game Code
+****/
+// Simple sound for vote
+// Simple sound for meeting
+// Simple sound for kill
+// Simple sound for task complete
+// Voting button (red)
+// Voting button (blue)
+// Button for emergency meeting
+// Dead body (gray ellipse)
+// Sabotage node (yellow box)
+// Task node (small green box)
+// Crewmate and Impostor avatars (simple colored ellipses)
+// Game state: 'playing', 'meeting', 'voting', 'ended'
+game.state = 'playing';
+// Game variables
+var playerCount = 6; // For MVP, fixed at 6 (1 impostor, 5 crewmates)
+var impostorCount = 1;
+var players = [];
+var tasks = [];
+var sabotageNodes = [];
+var deadBodies = [];
+var votingBtns = [];
+var votes = {};
+var voteResults = {};
+var meetingTimer = null;
+var votingTimer = null;
+var taskGoal = 4; // Number of tasks per crewmate
+var sabotageActive = false;
+var sabotageTimer = null;
+var sabotageDuration = 6000; // ms
+var emergencyBtn = null;
+var skipBtn = null;
+var infoTxt = null;
+var taskBar = null;
+var taskBarBg = null;
+var meetingCalled = false;
+var localPlayer = null;
+// Helper: Random name generator
+function randomName() {
+ var names = ['Red', 'Blue', 'Green', 'Yellow', 'Pink', 'Orange', 'Cyan', 'Lime', 'Purple', 'Brown'];
+ return names[Math.floor(Math.random() * names.length)];
+}
+// Helper: Shuffle array
+function shuffle(arr) {
+ 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;
+}
+// Initialize players
+function setupPlayers() {
+ players = [];
+ var roles = [];
+ for (var i = 0; i < impostorCount; i++) roles.push(true);
+ for (var i = impostorCount; i < playerCount; i++) roles.push(false);
+ shuffle(roles);
+ for (var i = 0; i < playerCount; i++) {
+ var p = new Player();
+ p.playerId = i;
+ p.name = randomName() + " " + (i + 1);
+ p.setRole(roles[i]);
+ p.isAlive = true;
+ p.x = 400 + i % 3 * 600;
+ p.y = 600 + Math.floor(i / 3) * 500;
+ p.showName();
+ p.isLocal = i === 0; // For MVP, player 0 is local
+ if (p.isLocal) {
+ localPlayer = p;
+ }
+ players.push(p);
+ game.addChild(p);
+ }
+ game.localPlayer = localPlayer;
+}
+// Initialize tasks
+function setupTasks() {
+ tasks = [];
+ var spacing = 2048 / (taskGoal + 1);
+ for (var i = 0; i < taskGoal; i++) {
+ var t = new TaskNode();
+ t.taskId = i;
+ t.ownerId = localPlayer.playerId;
+ t.x = spacing * (i + 1);
+ t.y = 350;
+ tasks.push(t);
+ game.addChild(t);
+ }
+}
+// Initialize sabotage nodes
+function setupSabotage() {
+ sabotageNodes = [];
+ for (var i = 0; i < 2; i++) {
+ var s = new SabotageNode();
+ s.x = 600 + i * 800;
+ s.y = 2000;
+ sabotageNodes.push(s);
+ game.addChild(s);
+ }
+}
+// Emergency meeting button
+function setupEmergencyBtn() {
+ emergencyBtn = new EmergencyBtn();
+ emergencyBtn.x = 2048 / 2;
+ emergencyBtn.y = 2732 - 200;
+ game.addChild(emergencyBtn);
+}
+// Task bar
+function setupTaskBar() {
+ if (!taskBarBg) {
+ taskBarBg = LK.getAsset('tasknode', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ taskBarBg.width = 800;
+ taskBarBg.height = 40;
+ taskBarBg.tint = 0x222222;
+ taskBarBg.x = 624;
+ taskBarBg.y = 80;
+ LK.gui.top.addChild(taskBarBg);
+ }
+ if (!taskBar) {
+ taskBar = LK.getAsset('tasknode', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ taskBar.width = 0;
+ taskBar.height = 40;
+ taskBar.tint = 0x83de44;
+ taskBar.x = 624;
+ taskBar.y = 80;
+ LK.gui.top.addChild(taskBar);
+ }
+}
+// Info text
+function setupInfoTxt() {
+ if (!infoTxt) {
+ infoTxt = new Text2('', {
+ size: 64,
+ fill: "#fff"
+ });
+ infoTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(infoTxt);
+ infoTxt.x = 2048 / 2;
+ infoTxt.y = 160;
+ }
+}
+// Voting skip button
+function setupSkipBtn() {
+ skipBtn = new VoteBtn();
+ skipBtn.x = 2048 / 2;
+ skipBtn.y = 2732 - 300;
+ skipBtn.visible = false;
+ game.addChild(skipBtn);
+}
+// Update task bar
+function updateTaskBar() {
+ var done = 0;
+ for (var i = 0; i < tasks.length; i++) {
+ if (tasks[i].done) done++;
+ }
+ var percent = done / taskGoal;
+ taskBar.width = 800 * percent;
+}
+// Complete a task
+game.completeTask = function (task) {
+ updateTaskBar();
+ // Check win
+ var allDone = true;
+ for (var i = 0; i < tasks.length; i++) {
+ if (!tasks[i].done) allDone = false;
+ }
+ if (allDone) {
+ gameEnd('crewmates');
+ }
+};
+// Sabotage triggered
+game.sabotageTriggered = function (node) {
+ sabotageActive = true;
+ sabotageTimer = LK.setTimeout(function () {
+ sabotageActive = false;
+ node.active = false;
+ node.asset.alpha = 1;
+ // If sabotage not fixed, impostors win
+ gameEnd('impostors');
+ }, sabotageDuration);
+ // Show info
+ infoTxt.setText('Sabotage! Fix it!');
+ tween(infoTxt, {
+ alpha: 1
+ }, {
+ duration: 200
+ });
+};
+// Call emergency meeting
+game.callMeeting = function () {
+ if (meetingCalled) return;
+ meetingCalled = true;
+ LK.getSound('meeting').play();
+ game.state = 'meeting';
+ infoTxt.setText('Emergency Meeting!');
+ // Remove all dead bodies
+ for (var i = 0; i < players.length; i++) {
+ if (!players[i].isAlive && players[i].deadBody) {
+ players[i].deadBody.visible = false;
+ }
+ }
+ // After 2 seconds, go to voting
+ meetingTimer = LK.setTimeout(function () {
+ game.startVoting();
+ }, 2000);
+};
+// Start voting phase
+game.startVoting = function () {
+ game.state = 'voting';
+ infoTxt.setText('Vote: Who is the Impostor?');
+ // Show voting buttons for each player
+ for (var i = 0; i < votingBtns.length; i++) {
+ votingBtns[i].destroy();
+ }
+ votingBtns = [];
+ var alivePlayers = [];
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive) alivePlayers.push(players[i]);
+ }
+ var spacing = 2048 / (alivePlayers.length + 1);
+ for (var i = 0; i < alivePlayers.length; i++) {
+ var btn = new Container();
+ var asset = btn.attachAsset(alivePlayers[i].isImpostor ? 'votebtnred' : 'votebtn', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ btn.x = spacing * (i + 1);
+ btn.y = 1200;
+ var txt = new Text2(alivePlayers[i].name, {
+ size: 48,
+ fill: "#fff"
+ });
+ txt.anchor.set(0.5, 0.5);
+ btn.addChild(txt);
+ btn.down = function (targetPlayer) {
+ return function (x, y, obj) {
+ if (game.state === 'voting' && !game.localPlayer.isVoted && targetPlayer.isAlive && targetPlayer !== game.localPlayer) {
+ game.voteFor(targetPlayer);
+ }
+ };
+ }(alivePlayers[i]);
+ votingBtns.push(btn);
+ game.addChild(btn);
+ }
+ // Show skip button
+ skipBtn.visible = true;
+ // Voting timer (auto skip after 10s)
+ votingTimer = LK.setTimeout(function () {
+ if (!game.localPlayer.isVoted) {
+ game.voteFor(null);
+ }
+ }, 10000);
+};
+// Vote for a player (or skip)
+game.voteFor = function (targetPlayer) {
+ if (game.localPlayer.isVoted) return;
+ game.localPlayer.isVoted = true;
+ game.localPlayer.voteTarget = targetPlayer ? targetPlayer.playerId : null;
+ LK.getSound('vote').play();
+ // Show confirmation
+ infoTxt.setText('Voted!');
+ // Wait for all votes (MVP: AI votes randomly)
+ var allVoted = true;
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive && !players[i].isVoted) allVoted = false;
+ }
+ if (!allVoted) {
+ // Simulate AI votes after 1s
+ LK.setTimeout(function () {
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive && !players[i].isVoted) {
+ // AI votes randomly (not self)
+ var choices = [];
+ for (var j = 0; j < players.length; j++) {
+ if (players[j].isAlive && players[j] !== players[i]) choices.push(players[j]);
+ }
+ if (Math.random() < 0.2) {
+ // 20% skip
+ players[i].voteTarget = null;
+ } else {
+ players[i].voteTarget = choices[Math.floor(Math.random() * choices.length)].playerId;
+ }
+ players[i].isVoted = true;
+ }
+ }
+ game.tallyVotes();
+ }, 1000);
+ } else {
+ game.tallyVotes();
+ }
+};
+// Tally votes and resolve
+game.tallyVotes = function () {
+ // Clear voting timer
+ if (votingTimer) {
+ LK.clearTimeout(votingTimer);
+ votingTimer = null;
+ }
+ // Hide voting buttons
+ for (var i = 0; i < votingBtns.length; i++) {
+ votingBtns[i].destroy();
+ }
+ votingBtns = [];
+ skipBtn.visible = false;
+ // Count votes
+ var counts = {};
+ var skipCount = 0;
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive) {
+ var v = players[i].voteTarget;
+ if (v === null) {
+ skipCount++;
+ } else {
+ if (!counts[v]) counts[v] = 0;
+ counts[v]++;
+ }
+ }
+ }
+ // Find max
+ var maxVotes = 0;
+ var maxPlayerId = null;
+ for (var pid in counts) {
+ if (counts[pid] > maxVotes) {
+ maxVotes = counts[pid];
+ maxPlayerId = parseInt(pid);
+ }
+ }
+ // If tie or skip, no one ejected
+ var tie = false;
+ var totalVotes = 0;
+ for (var pid in counts) {
+ if (counts[pid] === maxVotes && parseInt(pid) !== maxPlayerId) tie = true;
+ totalVotes += counts[pid];
+ }
+ if (skipCount >= maxVotes || tie || maxPlayerId === null) {
+ infoTxt.setText('No one was ejected.');
+ } else {
+ // Eject player
+ var ejected = null;
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].playerId === maxPlayerId) {
+ ejected = players[i];
+ break;
+ }
+ }
+ if (ejected) {
+ ejected.showDead();
+ infoTxt.setText(ejected.name + ' was ejected!');
+ // Check win
+ var impostorsLeft = 0,
+ crewmatesLeft = 0;
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive) {
+ if (players[i].isImpostor) impostorsLeft++;else crewmatesLeft++;
+ }
+ }
+ if (impostorsLeft === 0) {
+ gameEnd('crewmates');
+ return;
+ }
+ if (impostorsLeft >= crewmatesLeft) {
+ gameEnd('impostors');
+ return;
+ }
+ }
+ }
+ // Reset votes
+ for (var i = 0; i < players.length; i++) {
+ players[i].isVoted = false;
+ players[i].voteTarget = null;
+ }
+ // Resume play after 2s
+ LK.setTimeout(function () {
+ infoTxt.setText('');
+ game.state = 'playing';
+ meetingCalled = false;
+ }, 2000);
+};
+// End game
+function gameEnd(winner) {
+ game.state = 'ended';
+ if (winner === 'crewmates') {
+ LK.showYouWin();
+ } else {
+ LK.showGameOver();
+ }
+}
+// Kill action (impostor only)
+function tryKill(target) {
+ if (!game.localPlayer.isImpostor || !target.isAlive || !game.localPlayer.isAlive) return;
+ // Must be close
+ var dx = target.x - game.localPlayer.x;
+ var dy = target.y - game.localPlayer.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 200) {
+ target.showDead();
+ LK.getSound('kill').play();
+ // Show dead body
+ if (target.deadBody) target.deadBody.visible = true;
+ // Check win
+ var impostorsLeft = 0,
+ crewmatesLeft = 0;
+ for (var i = 0; i < players.length; i++) {
+ if (players[i].isAlive) {
+ if (players[i].isImpostor) impostorsLeft++;else crewmatesLeft++;
+ }
+ }
+ if (impostorsLeft === 0) {
+ gameEnd('crewmates');
+ return;
+ }
+ if (impostorsLeft >= crewmatesLeft) {
+ gameEnd('impostors');
+ return;
+ }
+ }
+}
+// Move handler (drag local player)
+var dragNode = null;
+function handleMove(x, y, obj) {
+ if (game.state !== 'playing') return;
+ if (dragNode) {
+ // Clamp to game area
+ var nx = Math.max(100, Math.min(2048 - 100, x));
+ var ny = Math.max(200, Math.min(2732 - 200, y));
+ dragNode.x = nx;
+ dragNode.y = ny;
+ }
+ // If impostor, check for kill
+ if (game.localPlayer.isImpostor && game.localPlayer.isAlive) {
+ for (var i = 0; i < players.length; i++) {
+ if (players[i] !== game.localPlayer && players[i].isAlive) {
+ tryKill(players[i]);
+ }
+ }
+ }
+}
+game.move = handleMove;
+// Down handler (start drag or interact)
+game.down = function (x, y, obj) {
+ if (game.state !== 'playing') return;
+ // Only drag local player if touch is on them
+ var lp = game.localPlayer;
+ var dx = x - lp.x;
+ var dy = y - lp.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 100 && lp.isAlive) {
+ dragNode = lp;
+ handleMove(x, y, obj);
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Game update loop
+game.update = function () {
+ // AI players move randomly
+ if (game.state === 'playing') {
+ for (var i = 0; i < players.length; i++) {
+ var p = players[i];
+ if (!p.isLocal && p.isAlive) {
+ // Random walk
+ if (LK.ticks % (60 + i * 7) === 0) {
+ var tx = 200 + Math.random() * (2048 - 400);
+ var ty = 500 + Math.random() * (2732 - 1000);
+ tween(p, {
+ x: tx,
+ y: ty
+ }, {
+ duration: 1200 + Math.random() * 800,
+ easing: tween.easeInOut
+ });
+ }
+ // AI crewmates complete tasks
+ if (!p.isImpostor) {
+ for (var j = 0; j < tasks.length; j++) {
+ var t = tasks[j];
+ if (!t.done && t.ownerId === p.playerId) {
+ var dx = t.x - p.x;
+ var dy = t.y - p.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 120) {
+ t.done = true;
+ t.asset.alpha = 0.3;
+ updateTaskBar();
+ }
+ }
+ }
+ }
+ // AI impostor kills
+ if (p.isImpostor) {
+ for (var j = 0; j < players.length; j++) {
+ var target = players[j];
+ if (target !== p && target.isAlive && !target.isImpostor) {
+ var dx = target.x - p.x;
+ var dy = target.y - p.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 180 && Math.random() < 0.01) {
+ target.showDead();
+ if (target.deadBody) target.deadBody.visible = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+};
+// Initial setup
+setupPlayers();
+setupTasks();
+setupSabotage();
+setupEmergencyBtn();
+setupTaskBar();
+setupInfoTxt();
+setupSkipBtn();
+updateTaskBar();
\ No newline at end of file