/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Agent base class var Agent = Container.expand(function () { var self = Container.call(this); self.team = null; // 'CT' or 'T' self.isPlayer = false; self.speed = 12; self.radius = 60; self.targetX = null; self.targetY = null; self.canShoot = true; self.shootCooldown = 20; // frames self.shootTimer = 0; self.isAlive = true; self.hasBomb = false; self.isDefusing = false; self.isPlanting = false; self.defuseTimer = 0; self.plantTimer = 0; self.defuseTime = 90; // frames (1.5s) self.plantTime = 90; // frames (1.5s) self.asset = null; self.setTeam = function (team) { self.team = team; if (team === 'CT') { self.asset = self.attachAsset('ct_agent', { anchorX: 0.5, anchorY: 0.5 }); } else { self.asset = self.attachAsset('t_agent', { anchorX: 0.5, anchorY: 0.5 }); } }; self.setPlayer = function (isPlayer) { self.isPlayer = isPlayer; if (isPlayer) { // Add a white border for player self.asset.width += 10; self.asset.height += 10; } }; self.moveTo = function (x, y) { self.targetX = x; self.targetY = y; }; self.update = function () { if (!self.isAlive) return; // Movement if (self.targetX !== null && self.targetY !== null) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > self.speed) { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } else { self.x = self.targetX; self.y = self.targetY; self.targetX = null; self.targetY = null; } } // Shooting cooldown if (!self.canShoot) { self.shootTimer--; if (self.shootTimer <= 0) { self.canShoot = true; } } // Planting/defusing if (self.isPlanting) { self.plantTimer++; if (self.plantTimer >= self.plantTime) { self.isPlanting = false; self.plantTimer = 0; game.bombPlanted(self); } } if (self.isDefusing) { self.defuseTimer++; if (self.defuseTimer >= self.defuseTime) { self.isDefusing = false; self.defuseTimer = 0; game.bombDefused(self); } } }; self.shoot = function (tx, ty) { if (!self.canShoot || !self.isAlive) return; self.canShoot = false; self.shootTimer = self.shootCooldown; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; bullet.owner = self; var dx = tx - self.x; var dy = ty - self.y; var dist = Math.sqrt(dx * dx + dy * dy); bullet.vx = 36 * dx / dist; bullet.vy = 36 * dy / dist; game.addChild(bullet); game.bullets.push(bullet); LK.getSound('shoot').play(); }; self.die = function () { self.isAlive = false; self.visible = false; if (self.hasBomb) { // Drop bomb at death location game.dropBomb(self.x, self.y); self.hasBomb = false; } }; return self; }); // Bomb class var Bomb = Container.expand(function () { var self = Container.call(this); var asset = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.isPlanted = false; self.timer = 0; self.plantX = null; self.plantY = null; self.plantDuration = 600; // 10 seconds (60fps) self.update = function () { if (self.isPlanted) { self.timer++; if (self.timer >= self.plantDuration) { // Bomb explodes game.bombExploded(); } } }; return self; }); // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var asset = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.owner = null; self.lifetime = 40; // frames self.update = function () { self.x += self.vx; self.y += self.vy; self.lifetime--; if (self.lifetime <= 0) { self.destroy(); var idx = game.bullets.indexOf(self); if (idx !== -1) game.bullets.splice(idx, 1); } }; return self; }); // Wall class var Wall = Container.expand(function () { var self = Container.call(this); var asset = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // --- Game State --- // Agents // Bomb // Simple wall // Bullet // Plant/defuse zone // Buy zone // Sounds game.roundTime = 60 * 30; // 30 seconds per round game.roundTimer = 0; game.phase = 'buy'; // 'buy', 'play', 'plant', 'end' game.phaseTimer = 0; game.buyTime = 60 * 3; // 3 seconds game.ctScore = 0; game.tScore = 0; game.maxScore = 5; game.bullets = []; game.agents = []; game.walls = []; game.bombZones = []; game.buyZones = []; game.bomb = null; game.bombCarrier = null; game.bombZone = null; game.buyZoneCT = null; game.buyZoneT = null; game.player = null; game.isPlayerCT = true; // Player is CT by default game.tapState = 'move'; // 'move' or 'shoot' game.lastTap = 0; game.tapCooldown = 10; game.infoText = null; game.scoreText = null; game.phaseText = null; game.bombText = null; // --- Map Layout (Simple) --- function setupMap() { // Clear previous for (var i = 0; i < game.walls.length; ++i) game.walls[i].destroy(); for (var i = 0; i < game.bombZones.length; ++i) game.bombZones[i].destroy(); for (var i = 0; i < game.buyZones.length; ++i) game.buyZones[i].destroy(); game.walls = []; game.bombZones = []; game.buyZones = []; // Walls (simple rectangle arena) var wall1 = new Wall(); wall1.x = 2048 / 2; wall1.y = 400; wall1.width = 1200; wall1.height = 40; wall1.children[0].width = 1200; wall1.children[0].height = 40; game.addChild(wall1); game.walls.push(wall1); var wall2 = new Wall(); wall2.x = 2048 / 2; wall2.y = 2732 - 400; wall2.width = 1200; wall2.height = 40; wall2.children[0].width = 1200; wall2.children[0].height = 40; game.addChild(wall2); game.walls.push(wall2); var wall3 = new Wall(); wall3.x = 400; wall3.y = 2732 / 2; wall3.width = 40; wall3.height = 1200; wall3.children[0].width = 40; wall3.children[0].height = 1200; game.addChild(wall3); game.walls.push(wall3); var wall4 = new Wall(); wall4.x = 2048 - 400; wall4.y = 2732 / 2; wall4.width = 40; wall4.height = 1200; wall4.children[0].width = 40; wall4.children[0].height = 1200; game.addChild(wall4); game.walls.push(wall4); // Bomb zone (center) var bombZone = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); bombZone.alpha = 0.18; game.addChild(bombZone); game.bombZones.push(bombZone); game.bombZone = bombZone; // Buy zones (top and bottom) var buyZoneCT = LK.getAsset('buyzone', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 600 }); buyZoneCT.alpha = 0.13; game.addChild(buyZoneCT); game.buyZones.push(buyZoneCT); game.buyZoneCT = buyZoneCT; var buyZoneT = LK.getAsset('buyzone', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - 600 }); buyZoneT.alpha = 0.13; game.addChild(buyZoneT); game.buyZones.push(buyZoneT); game.buyZoneT = buyZoneT; } // --- UI --- function setupUI() { if (game.infoText) game.infoText.destroy(); if (game.scoreText) game.scoreText.destroy(); if (game.phaseText) game.phaseText.destroy(); if (game.bombText) game.bombText.destroy(); if (game.moveLeftBtn) game.moveLeftBtn.destroy(); if (game.moveRightBtn) game.moveRightBtn.destroy(); if (game.moveUpBtn) game.moveUpBtn.destroy(); if (game.moveDownBtn) game.moveDownBtn.destroy(); if (game.shootBtn) game.shootBtn.destroy(); // Info text (center) var infoText = new Text2('', { size: 90, fill: 0xFFFFFF }); infoText.anchor.set(0.5, 0.5); LK.gui.center.addChild(infoText); game.infoText = infoText; // Score text (top) var scoreText = new Text2('CT 0 : 0 T', { size: 90, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); game.scoreText = scoreText; // Phase text (bottom) var phaseText = new Text2('', { size: 70, fill: 0xFFFF00 }); phaseText.anchor.set(0.5, 1); LK.gui.bottom.addChild(phaseText); game.phaseText = phaseText; // Bomb status (top right) var bombText = new Text2('', { size: 70, fill: 0xFF4444 }); bombText.anchor.set(1, 0); LK.gui.topRight.addChild(bombText); game.bombText = bombText; // --- Mobile Touch Controls --- // Button size and margin var btnSize = 220; var btnMargin = 40; var btnAlpha = 0.22; var btnColor = 0xffffff; // Move Left var moveLeftBtn = new Container(); var leftShape = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, width: btnSize, height: btnSize, color: btnColor }); leftShape.alpha = btnAlpha; moveLeftBtn.addChild(leftShape); var leftTxt = new Text2('←', { size: 120, fill: 0x222222 }); leftTxt.anchor.set(0.5, 0.5); moveLeftBtn.addChild(leftTxt); moveLeftBtn.x = btnSize + btnMargin; moveLeftBtn.y = 2732 - btnSize - btnMargin; moveLeftBtn.interactive = true; moveLeftBtn.down = function () { if (game.phase !== 'play' || !game.player.isAlive) return; var nx = Math.max(game.player.x - 120, game.player.radius); game.player.moveTo(nx, game.player.y); }; LK.gui.addChild(moveLeftBtn); game.moveLeftBtn = moveLeftBtn; // Move Right var moveRightBtn = new Container(); var rightShape = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, width: btnSize, height: btnSize, color: btnColor }); rightShape.alpha = btnAlpha; moveRightBtn.addChild(rightShape); var rightTxt = new Text2('→', { size: 120, fill: 0x222222 }); rightTxt.anchor.set(0.5, 0.5); moveRightBtn.addChild(rightTxt); moveRightBtn.x = btnSize * 2 + btnMargin * 2; moveRightBtn.y = 2732 - btnSize - btnMargin; moveRightBtn.interactive = true; moveRightBtn.down = function () { if (game.phase !== 'play' || !game.player.isAlive) return; var nx = Math.min(game.player.x + 120, 2048 - game.player.radius); game.player.moveTo(nx, game.player.y); }; LK.gui.addChild(moveRightBtn); game.moveRightBtn = moveRightBtn; // Move Up var moveUpBtn = new Container(); var upShape = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, width: btnSize, height: btnSize, color: btnColor }); upShape.alpha = btnAlpha; moveUpBtn.addChild(upShape); var upTxt = new Text2('↑', { size: 120, fill: 0x222222 }); upTxt.anchor.set(0.5, 0.5); moveUpBtn.addChild(upTxt); moveUpBtn.x = btnSize * 1.5 + btnMargin * 1.5; moveUpBtn.y = 2732 - btnSize * 2 - btnMargin * 2; moveUpBtn.interactive = true; moveUpBtn.down = function () { if (game.phase !== 'play' || !game.player.isAlive) return; var ny = Math.max(game.player.y - 120, game.player.radius); game.player.moveTo(game.player.x, ny); }; LK.gui.addChild(moveUpBtn); game.moveUpBtn = moveUpBtn; // Move Down var moveDownBtn = new Container(); var downShape = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, width: btnSize, height: btnSize, color: btnColor }); downShape.alpha = btnAlpha; moveDownBtn.addChild(downShape); var downTxt = new Text2('↓', { size: 120, fill: 0x222222 }); downTxt.anchor.set(0.5, 0.5); moveDownBtn.addChild(downTxt); moveDownBtn.x = btnSize * 1.5 + btnMargin * 1.5; moveDownBtn.y = 2732 - btnMargin; moveDownBtn.interactive = true; moveDownBtn.down = function () { if (game.phase !== 'play' || !game.player.isAlive) return; var ny = Math.min(game.player.y + 120, 2732 - game.player.radius); game.player.moveTo(game.player.x, ny); }; LK.gui.addChild(moveDownBtn); game.moveDownBtn = moveDownBtn; // Shoot Button (bottom right) var shootBtn = new Container(); var shootShape = LK.getAsset('zone', { anchorX: 0.5, anchorY: 0.5, width: btnSize, height: btnSize, color: 0xff4444 }); shootShape.alpha = btnAlpha + 0.08; shootBtn.addChild(shootShape); var shootTxt = new Text2('SHOOT', { size: 60, fill: 0xffffff }); shootTxt.anchor.set(0.5, 0.5); shootBtn.addChild(shootTxt); shootBtn.x = 2048 - btnSize - btnMargin; shootBtn.y = 2732 - btnSize - btnMargin; shootBtn.interactive = true; shootBtn.down = function () { if (game.phase !== 'play' || !game.player.isAlive) return; // Shoot towards enemy if visible, else forward var tx = game.player.x, ty = game.player.y - 300; // Try to find nearest enemy var minDist = 99999, target = null; for (var i = 0; i < game.agents.length; ++i) { var ag = game.agents[i]; if (ag === game.player || !ag.isAlive || ag.team === game.player.team) continue; var dx = ag.x - game.player.x; var dy = ag.y - game.player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; target = ag; } } if (target) { tx = target.x; ty = target.y; } game.player.shoot(tx, ty); }; LK.gui.addChild(shootBtn); game.shootBtn = shootBtn; } // --- Agents --- function setupAgents() { // Remove previous for (var i = 0; i < game.agents.length; ++i) game.agents[i].destroy(); game.agents = []; // Player var player = new Agent(); player.setTeam(game.isPlayerCT ? 'CT' : 'T'); player.setPlayer(true); if (game.isPlayerCT) { player.x = 2048 / 2; player.y = 700; } else { player.x = 2048 / 2; player.y = 2732 - 700; } game.addChild(player); game.agents.push(player); game.player = player; // AI teammates and enemies (1v1 for MVP, can expand) var ai = new Agent(); ai.setTeam(game.isPlayerCT ? 'T' : 'CT'); ai.setPlayer(false); if (game.isPlayerCT) { ai.x = 2048 / 2; ai.y = 2732 - 700; } else { ai.x = 2048 / 2; ai.y = 700; } game.addChild(ai); game.agents.push(ai); // Assign bomb to T at start for (var i = 0; i < game.agents.length; ++i) { game.agents[i].hasBomb = false; } if (!game.isPlayerCT) { player.hasBomb = true; game.bombCarrier = player; } else { ai.hasBomb = true; game.bombCarrier = ai; } } // --- Bomb --- function setupBomb() { if (game.bomb) game.bomb.destroy(); var bomb = new Bomb(); bomb.visible = false; game.addChild(bomb); game.bomb = bomb; } // --- Round Start --- function startRound() { game.phase = 'buy'; game.phaseTimer = 0; game.roundTimer = 0; game.tapState = 'move'; setupMap(); setupAgents(); setupBomb(); setupUI(); game.infoText.setText('Buy Phase'); game.phaseText.setText('Tap to move. Double tap to shoot.'); game.bombText.setText(''); game.bullets = []; } // --- Round End --- function endRound(winner) { game.phase = 'end'; game.phaseTimer = 0; if (winner === 'CT') { game.ctScore++; game.infoText.setText('Counter-Terrorists Win!'); LK.getSound('win').play(); } else if (winner === 'T') { game.tScore++; game.infoText.setText('Terrorists Win!'); LK.getSound('lose').play(); } else { game.infoText.setText('Draw!'); } game.scoreText.setText('CT ' + game.ctScore + ' : ' + game.tScore + ' T'); if (game.ctScore >= game.maxScore) { LK.showYouWin(); } else if (game.tScore >= game.maxScore) { LK.showGameOver(); } } // --- Bomb Plant/Defuse/Explode --- game.bombPlanted = function (planter) { game.bomb.isPlanted = true; game.bomb.visible = true; game.bomb.x = game.bombZone.x; game.bomb.y = game.bombZone.y; game.bomb.timer = 0; game.bombCarrier = null; game.infoText.setText('Bomb Planted!'); game.bombText.setText('Bomb: ' + ((game.bomb.plantDuration - game.bomb.timer) / 60).toFixed(1) + 's'); LK.getSound('plant').play(); }; game.bombDefused = function (defuser) { game.bomb.isPlanted = false; game.bomb.visible = false; game.bomb.timer = 0; game.bombText.setText(''); endRound('CT'); LK.getSound('defuse').play(); }; game.bombExploded = function () { game.bomb.isPlanted = false; game.bomb.visible = false; game.bomb.timer = 0; game.bombText.setText(''); endRound('T'); }; // --- Bomb Drop --- game.dropBomb = function (x, y) { game.bomb.visible = true; game.bomb.x = x; game.bomb.y = y; game.bomb.isPlanted = false; game.bomb.timer = 0; game.bombCarrier = null; game.bombText.setText('Bomb dropped!'); }; // --- Tap Handler --- game.down = function (x, y, obj) { if (game.phase === 'end') return; if (!game.player.isAlive) return; if (game.phase === 'buy') return; // Tap to move or shoot var now = LK.ticks; if (now - game.lastTap < game.tapCooldown) { // Double tap: shoot game.tapState = 'shoot'; } else { game.tapState = 'move'; } game.lastTap = now; if (game.tapState === 'move') { // Move player game.player.moveTo(x, y); } else if (game.tapState === 'shoot') { // Shoot towards tap game.player.shoot(x, y); } }; // --- Update Handler --- game.update = function () { // --- Phase Management --- if (game.phase === 'buy') { game.phaseTimer++; game.infoText.setText('Buy Phase'); game.phaseText.setText('Tap to move. Double tap to shoot.'); if (game.phaseTimer >= game.buyTime) { game.phase = 'play'; game.infoText.setText(''); game.phaseText.setText('Eliminate enemy or plant/defuse bomb!'); } return; } if (game.phase === 'end') { game.phaseTimer++; if (game.phaseTimer > 90) { startRound(); } return; } // --- Round Timer --- game.roundTimer++; var timeLeft = Math.max(0, Math.floor((game.roundTime - game.roundTimer) / 60)); game.phaseText.setText('Time: ' + timeLeft + 's'); if (game.roundTimer >= game.roundTime) { endRound('Draw'); return; } // --- Update Agents --- for (var i = 0; i < game.agents.length; ++i) { var agent = game.agents[i]; agent.update(); } // --- Update Bullets --- for (var i = game.bullets.length - 1; i >= 0; --i) { var bullet = game.bullets[i]; bullet.update(); // Remove if out of bounds if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) { bullet.destroy(); game.bullets.splice(i, 1); continue; } // Check collision with agents for (var j = 0; j < game.agents.length; ++j) { var target = game.agents[j]; if (!target.isAlive) continue; if (target === bullet.owner) continue; var dx = bullet.x - target.x; var dy = bullet.y - target.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < target.radius) { // Hit! target.die(); bullet.destroy(); game.bullets.splice(i, 1); break; } } } // --- Update Bomb --- if (game.bomb) { game.bomb.update(); if (game.bomb.isPlanted) { game.bombText.setText('Bomb: ' + ((game.bomb.plantDuration - game.bomb.timer) / 60).toFixed(1) + 's'); } } // --- Win/Lose Check --- var ctAlive = false, tAlive = false; for (var i = 0; i < game.agents.length; ++i) { if (!game.agents[i].isAlive) continue; if (game.agents[i].team === 'CT') ctAlive = true; if (game.agents[i].team === 'T') tAlive = true; } if (!ctAlive) { endRound('T'); return; } if (!tAlive) { endRound('CT'); return; } // --- Bomb Pickup --- if (game.bomb && !game.bomb.isPlanted && !game.bombCarrier && game.bomb.visible) { for (var i = 0; i < game.agents.length; ++i) { var agent = game.agents[i]; if (!agent.isAlive) continue; if (agent.team !== 'T') continue; var dx = agent.x - game.bomb.x; var dy = agent.y - game.bomb.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < agent.radius + 40) { agent.hasBomb = true; game.bombCarrier = agent; game.bomb.visible = false; game.bombText.setText('Bomb picked up!'); } } } // --- Bomb Planting --- if (game.bombCarrier && game.bombCarrier.isAlive && !game.bomb.isPlanted) { var agent = game.bombCarrier; var dx = agent.x - game.bombZone.x; var dy = agent.y - game.bombZone.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 110) { if (!agent.isPlanting) { agent.isPlanting = true; agent.plantTimer = 0; game.infoText.setText('Planting...'); } } else { agent.isPlanting = false; agent.plantTimer = 0; } } // --- Bomb Defusing --- if (game.bomb.isPlanted) { for (var i = 0; i < game.agents.length; ++i) { var agent = game.agents[i]; if (!agent.isAlive) continue; if (agent.team !== 'CT') continue; var dx = agent.x - game.bomb.x; var dy = agent.y - game.bomb.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 110) { if (!agent.isDefusing) { agent.isDefusing = true; agent.defuseTimer = 0; game.infoText.setText('Defusing...'); } } else { agent.isDefusing = false; agent.defuseTimer = 0; } } } // --- Simple AI --- for (var i = 0; i < game.agents.length; ++i) { var agent = game.agents[i]; if (agent.isPlayer || !agent.isAlive) continue; // If has bomb, go to bomb zone if (agent.hasBomb && !game.bomb.isPlanted) { if (!agent.targetX || Math.abs(agent.x - game.bombZone.x) > 10 || Math.abs(agent.y - game.bombZone.y) > 10) { agent.moveTo(game.bombZone.x, game.bombZone.y); } } else if (game.bomb.isPlanted && agent.team === 'CT') { // Go to bomb to defuse if (!agent.targetX || Math.abs(agent.x - game.bomb.x) > 10 || Math.abs(agent.y - game.bomb.y) > 10) { agent.moveTo(game.bomb.x, game.bomb.y); } } else { // Seek enemy var target = null; for (var j = 0; j < game.agents.length; ++j) { if (game.agents[j].team !== agent.team && game.agents[j].isAlive) { target = game.agents[j]; break; } } if (target) { var dx = target.x - agent.x; var dy = target.y - agent.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 200) { agent.moveTo(target.x, target.y); } else { // Shoot at enemy agent.shoot(target.x, target.y); } } } } }; // --- Start Game --- startRound();
===================================================================
--- original.js
+++ change.js
@@ -188,16 +188,16 @@
/****
* Game Code
****/
-// Sounds
-// Buy zone
-// Plant/defuse zone
-// Bullet
-// Simple wall
-// Bomb
-// Agents
// --- Game State ---
+// Agents
+// Bomb
+// Simple wall
+// Bullet
+// Plant/defuse zone
+// Buy zone
+// Sounds
game.roundTime = 60 * 30; // 30 seconds per round
game.roundTimer = 0;
game.phase = 'buy'; // 'buy', 'play', 'plant', 'end'
game.phaseTimer = 0;
@@ -308,8 +308,13 @@
if (game.infoText) game.infoText.destroy();
if (game.scoreText) game.scoreText.destroy();
if (game.phaseText) game.phaseText.destroy();
if (game.bombText) game.bombText.destroy();
+ if (game.moveLeftBtn) game.moveLeftBtn.destroy();
+ if (game.moveRightBtn) game.moveRightBtn.destroy();
+ if (game.moveUpBtn) game.moveUpBtn.destroy();
+ if (game.moveDownBtn) game.moveDownBtn.destroy();
+ if (game.shootBtn) game.shootBtn.destroy();
// Info text (center)
var infoText = new Text2('', {
size: 90,
fill: 0xFFFFFF
@@ -340,8 +345,169 @@
});
bombText.anchor.set(1, 0);
LK.gui.topRight.addChild(bombText);
game.bombText = bombText;
+ // --- Mobile Touch Controls ---
+ // Button size and margin
+ var btnSize = 220;
+ var btnMargin = 40;
+ var btnAlpha = 0.22;
+ var btnColor = 0xffffff;
+ // Move Left
+ var moveLeftBtn = new Container();
+ var leftShape = LK.getAsset('zone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: btnSize,
+ height: btnSize,
+ color: btnColor
+ });
+ leftShape.alpha = btnAlpha;
+ moveLeftBtn.addChild(leftShape);
+ var leftTxt = new Text2('←', {
+ size: 120,
+ fill: 0x222222
+ });
+ leftTxt.anchor.set(0.5, 0.5);
+ moveLeftBtn.addChild(leftTxt);
+ moveLeftBtn.x = btnSize + btnMargin;
+ moveLeftBtn.y = 2732 - btnSize - btnMargin;
+ moveLeftBtn.interactive = true;
+ moveLeftBtn.down = function () {
+ if (game.phase !== 'play' || !game.player.isAlive) return;
+ var nx = Math.max(game.player.x - 120, game.player.radius);
+ game.player.moveTo(nx, game.player.y);
+ };
+ LK.gui.addChild(moveLeftBtn);
+ game.moveLeftBtn = moveLeftBtn;
+ // Move Right
+ var moveRightBtn = new Container();
+ var rightShape = LK.getAsset('zone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: btnSize,
+ height: btnSize,
+ color: btnColor
+ });
+ rightShape.alpha = btnAlpha;
+ moveRightBtn.addChild(rightShape);
+ var rightTxt = new Text2('→', {
+ size: 120,
+ fill: 0x222222
+ });
+ rightTxt.anchor.set(0.5, 0.5);
+ moveRightBtn.addChild(rightTxt);
+ moveRightBtn.x = btnSize * 2 + btnMargin * 2;
+ moveRightBtn.y = 2732 - btnSize - btnMargin;
+ moveRightBtn.interactive = true;
+ moveRightBtn.down = function () {
+ if (game.phase !== 'play' || !game.player.isAlive) return;
+ var nx = Math.min(game.player.x + 120, 2048 - game.player.radius);
+ game.player.moveTo(nx, game.player.y);
+ };
+ LK.gui.addChild(moveRightBtn);
+ game.moveRightBtn = moveRightBtn;
+ // Move Up
+ var moveUpBtn = new Container();
+ var upShape = LK.getAsset('zone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: btnSize,
+ height: btnSize,
+ color: btnColor
+ });
+ upShape.alpha = btnAlpha;
+ moveUpBtn.addChild(upShape);
+ var upTxt = new Text2('↑', {
+ size: 120,
+ fill: 0x222222
+ });
+ upTxt.anchor.set(0.5, 0.5);
+ moveUpBtn.addChild(upTxt);
+ moveUpBtn.x = btnSize * 1.5 + btnMargin * 1.5;
+ moveUpBtn.y = 2732 - btnSize * 2 - btnMargin * 2;
+ moveUpBtn.interactive = true;
+ moveUpBtn.down = function () {
+ if (game.phase !== 'play' || !game.player.isAlive) return;
+ var ny = Math.max(game.player.y - 120, game.player.radius);
+ game.player.moveTo(game.player.x, ny);
+ };
+ LK.gui.addChild(moveUpBtn);
+ game.moveUpBtn = moveUpBtn;
+ // Move Down
+ var moveDownBtn = new Container();
+ var downShape = LK.getAsset('zone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: btnSize,
+ height: btnSize,
+ color: btnColor
+ });
+ downShape.alpha = btnAlpha;
+ moveDownBtn.addChild(downShape);
+ var downTxt = new Text2('↓', {
+ size: 120,
+ fill: 0x222222
+ });
+ downTxt.anchor.set(0.5, 0.5);
+ moveDownBtn.addChild(downTxt);
+ moveDownBtn.x = btnSize * 1.5 + btnMargin * 1.5;
+ moveDownBtn.y = 2732 - btnMargin;
+ moveDownBtn.interactive = true;
+ moveDownBtn.down = function () {
+ if (game.phase !== 'play' || !game.player.isAlive) return;
+ var ny = Math.min(game.player.y + 120, 2732 - game.player.radius);
+ game.player.moveTo(game.player.x, ny);
+ };
+ LK.gui.addChild(moveDownBtn);
+ game.moveDownBtn = moveDownBtn;
+ // Shoot Button (bottom right)
+ var shootBtn = new Container();
+ var shootShape = LK.getAsset('zone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: btnSize,
+ height: btnSize,
+ color: 0xff4444
+ });
+ shootShape.alpha = btnAlpha + 0.08;
+ shootBtn.addChild(shootShape);
+ var shootTxt = new Text2('SHOOT', {
+ size: 60,
+ fill: 0xffffff
+ });
+ shootTxt.anchor.set(0.5, 0.5);
+ shootBtn.addChild(shootTxt);
+ shootBtn.x = 2048 - btnSize - btnMargin;
+ shootBtn.y = 2732 - btnSize - btnMargin;
+ shootBtn.interactive = true;
+ shootBtn.down = function () {
+ if (game.phase !== 'play' || !game.player.isAlive) return;
+ // Shoot towards enemy if visible, else forward
+ var tx = game.player.x,
+ ty = game.player.y - 300;
+ // Try to find nearest enemy
+ var minDist = 99999,
+ target = null;
+ for (var i = 0; i < game.agents.length; ++i) {
+ var ag = game.agents[i];
+ if (ag === game.player || !ag.isAlive || ag.team === game.player.team) continue;
+ var dx = ag.x - game.player.x;
+ var dy = ag.y - game.player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < minDist) {
+ minDist = dist;
+ target = ag;
+ }
+ }
+ if (target) {
+ tx = target.x;
+ ty = target.y;
+ }
+ game.player.shoot(tx, ty);
+ };
+ LK.gui.addChild(shootBtn);
+ game.shootBtn = shootBtn;
}
// --- Agents ---
function setupAgents() {
// Remove previous
@@ -361,51 +527,30 @@
game.addChild(player);
game.agents.push(player);
game.player = player;
// AI teammates and enemies (1v1 for MVP, can expand)
- var aiAgents = [];
- var tCount = 0;
- var ctCount = 0;
- var totalT = 5;
- var totalCT = 1; // Only 1 CT AI if player is T, else all others are T
- // Place AI agents in a spread formation
- for (var i = 0; i < 5; ++i) {
- var ai = new Agent();
- // If player is CT, add 5 T agents. If player is T, add 5 CT agents.
- if (game.isPlayerCT) {
- ai.setTeam('T');
- tCount++;
- // Spread spawn positions for T
- ai.x = 2048 / 2 + (i - 2) * 120;
- ai.y = 2732 - 700 + i % 2 * 80;
- } else {
- ai.setTeam('CT');
- ctCount++;
- // Spread spawn positions for CT
- ai.x = 2048 / 2 + (i - 2) * 120;
- ai.y = 700 + i % 2 * 80;
- }
- ai.setPlayer(false);
- game.addChild(ai);
- game.agents.push(ai);
- aiAgents.push(ai);
+ var ai = new Agent();
+ ai.setTeam(game.isPlayerCT ? 'T' : 'CT');
+ ai.setPlayer(false);
+ if (game.isPlayerCT) {
+ ai.x = 2048 / 2;
+ ai.y = 2732 - 700;
+ } else {
+ ai.x = 2048 / 2;
+ ai.y = 700;
}
- // Assign bomb to a random T at start
+ game.addChild(ai);
+ game.agents.push(ai);
+ // Assign bomb to T at start
for (var i = 0; i < game.agents.length; ++i) {
game.agents[i].hasBomb = false;
}
if (!game.isPlayerCT) {
player.hasBomb = true;
game.bombCarrier = player;
} else {
- // Pick a random T agent to carry the bomb
- var tAgents = [];
- for (var i = 0; i < aiAgents.length; ++i) {
- if (aiAgents[i].team === 'T') tAgents.push(aiAgents[i]);
- }
- var bombCarrierIdx = Math.floor(Math.random() * tAgents.length);
- tAgents[bombCarrierIdx].hasBomb = true;
- game.bombCarrier = tAgents[bombCarrierIdx];
+ ai.hasBomb = true;
+ game.bombCarrier = ai;
}
}
// --- Bomb ---
function setupBomb() {