/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var HazardArm = Container.expand(function (centerX, centerY) {
var self = Container.call(this);
var armGraphics = self.attachAsset('hazardArm', {
anchorX: 0,
anchorY: 0.5
});
self.x = centerX;
self.y = centerY;
self.rotationSpeed = 0.02;
self.isActive = true;
self.update = function () {
if (!self.isActive) return;
self.rotation += self.rotationSpeed;
// Check collision with players
for (var i = 0; i < players.length; i++) {
var player = players[i];
if (!player.isAlive || player.powerUpType === 'invincibility') continue;
var armEndX = self.x + Math.cos(self.rotation) * 600;
var armEndY = self.y + Math.sin(self.rotation) * 600;
// Simple line-point collision
var distToArm = Math.abs((armEndY - self.y) * player.x - (armEndX - self.x) * player.y + armEndX * self.y - armEndY * self.x) / Math.sqrt((armEndY - self.y) * (armEndY - self.y) + (armEndX - self.x) * (armEndX - self.x));
if (distToArm < 60) {
var distFromCenter = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y));
if (distFromCenter < 600) {
player.eliminate();
LK.getSound('hazard').play();
}
}
}
};
return self;
});
var Player = Container.expand(function (isBot, startX, startY) {
var self = Container.call(this);
var playerGraphics = self.attachAsset(isBot ? 'bot' : 'player', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.isBot = isBot;
self.speed = 3;
self.isAlive = true;
self.powerUpType = null;
self.powerUpTimer = 0;
self.botDirection = Math.random() * Math.PI * 2;
self.botChangeTime = 0;
self.pushForceX = 0;
self.pushForceY = 0;
self.originalScale = 1;
self.update = function () {
if (!self.isAlive) return;
// Handle power-up effects
if (self.powerUpTimer > 0) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.removePowerUp();
}
}
// Apply push force
if (self.pushForceX !== 0 || self.pushForceY !== 0) {
self.x += self.pushForceX;
self.y += self.pushForceY;
self.pushForceX *= 0.9;
self.pushForceY *= 0.9;
if (Math.abs(self.pushForceX) < 0.1) self.pushForceX = 0;
if (Math.abs(self.pushForceY) < 0.1) self.pushForceY = 0;
}
// Bot AI movement
if (self.isBot) {
self.botChangeTime++;
if (self.botChangeTime > 60) {
self.botDirection += (Math.random() - 0.5) * 0.5;
self.botChangeTime = 0;
// Avoid arena edges
var distFromCenter = Math.sqrt((self.x - arenaX) * (self.x - arenaX) + (self.y - arenaY) * (self.y - arenaY));
if (distFromCenter > 600) {
var angleToCenter = Math.atan2(arenaY - self.y, arenaX - self.x);
self.botDirection = angleToCenter + (Math.random() - 0.5) * 0.5;
}
// Move away from lava
if (self.y > lavaY - 100) {
self.botDirection = -Math.PI / 2 + (Math.random() - 0.5) * 0.5;
}
}
var moveSpeed = self.speed;
if (self.powerUpType === 'speed') moveSpeed *= 2;
self.x += Math.cos(self.botDirection) * moveSpeed;
self.y += Math.sin(self.botDirection) * moveSpeed;
}
// Keep in arena bounds
var distFromCenter = Math.sqrt((self.x - arenaX) * (self.x - arenaX) + (self.y - arenaY) * (self.y - arenaY));
if (distFromCenter > 680) {
var angle = Math.atan2(self.y - arenaY, self.x - arenaX);
self.x = arenaX + Math.cos(angle) * 680;
self.y = arenaY + Math.sin(angle) * 680;
}
// Check lava collision
if (self.y > lavaY - 40 && self.powerUpType !== 'invincibility') {
self.eliminate();
}
};
self.applyPowerUp = function (type) {
self.powerUpType = type;
self.powerUpTimer = 300; // 5 seconds at 60fps
if (type === 'speed') {
playerGraphics.tint = 0xffff00;
} else if (type === 'size') {
self.scaleX = 1.5;
self.scaleY = 1.5;
} else if (type === 'invincibility') {
playerGraphics.tint = 0xffffff;
playerGraphics.alpha = 0.7;
}
};
self.removePowerUp = function () {
if (self.powerUpType === 'size') {
self.scaleX = self.originalScale;
self.scaleY = self.originalScale;
}
playerGraphics.tint = 0xffffff;
playerGraphics.alpha = 1.0;
self.powerUpType = null;
};
self.eliminate = function () {
if (!self.isAlive) return;
self.isAlive = false;
aliveCount--;
LK.getSound('elimination').play();
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 500
});
};
self.pushAway = function (fromX, fromY, force) {
var dx = self.x - fromX;
var dy = self.y - fromY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.pushForceX = dx / dist * force;
self.pushForceY = dy / dist * force;
}
};
return self;
});
var PowerUp = Container.expand(function (type, x, y) {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset(type + 'PowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.type = type;
self.collected = false;
self.update = function () {
if (self.collected) return;
// Floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check collection
for (var i = 0; i < players.length; i++) {
var player = players[i];
if (!player.isAlive) continue;
var dist = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y));
if (dist < 50) {
player.applyPowerUp(self.type);
self.collected = true;
self.alpha = 0;
LK.getSound('powerup').play();
if (self.type === 'push') {
// Push nearby players
for (var j = 0; j < players.length; j++) {
if (players[j] !== player && players[j].isAlive) {
var pushDist = Math.sqrt((players[j].x - self.x) * (players[j].x - self.x) + (players[j].y - self.y) * (players[j].y - self.y));
if (pushDist < 200) {
players[j].pushAway(self.x, self.y, 15);
}
}
}
}
break;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var arenaX = 2048 / 2;
var arenaY = 2732 / 2;
var gameTimer = 3600; // 60 seconds at 60fps
var lavaY = 2732 + 100; // Start below screen
var players = [];
var hazardArms = [];
var powerUps = [];
var aliveCount = 0;
var gameEnded = false;
var playerCharacter = null;
var dragActive = false;
// Create arena
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: arenaX,
y: arenaY
}));
// Create lava
var lava = game.addChild(LK.getAsset('lava', {
anchorX: 0.5,
anchorY: 0.5,
x: arenaX,
y: lavaY
}));
// Create timer display
var timerText = new Text2('60', {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
// Create alive counter
var aliveText = new Text2('20 Players', {
size: 60,
fill: 0xFFFFFF
});
aliveText.anchor.set(1, 0);
LK.gui.topRight.addChild(aliveText);
// Create players (1 human + 19 bots)
for (var i = 0; i < 20; i++) {
var angle = i / 20 * Math.PI * 2;
var radius = 400 + Math.random() * 200;
var startX = arenaX + Math.cos(angle) * radius;
var startY = arenaY + Math.sin(angle) * radius;
var player = new Player(i > 0, startX, startY);
players.push(player);
game.addChild(player);
if (i === 0) {
playerCharacter = player;
}
}
aliveCount = 20;
// Create hazard arms
for (var i = 0; i < 3; i++) {
var arm = new HazardArm(arenaX, arenaY);
arm.rotation = i / 3 * Math.PI * 2;
arm.rotationSpeed = 0.015 + Math.random() * 0.01;
hazardArms.push(arm);
game.addChild(arm);
}
// Spawn initial power-ups
function spawnPowerUp() {
if (powerUps.length >= 5) return;
var types = ['speed', 'push', 'size', 'invincibility'];
var type = types[Math.floor(Math.random() * types.length)];
var angle = Math.random() * Math.PI * 2;
var radius = 200 + Math.random() * 400;
var x = arenaX + Math.cos(angle) * radius;
var y = arenaY + Math.sin(angle) * radius;
var powerUp = new PowerUp(type, x, y);
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Touch controls
game.down = function (x, y, obj) {
if (!playerCharacter || !playerCharacter.isAlive) return;
dragActive = true;
};
game.move = function (x, y, obj) {
if (!playerCharacter || !playerCharacter.isAlive || !dragActive) return;
var moveSpeed = playerCharacter.speed;
if (playerCharacter.powerUpType === 'speed') moveSpeed *= 2;
var dx = x - playerCharacter.x;
var dy = y - playerCharacter.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 20) {
playerCharacter.x += dx / dist * moveSpeed;
playerCharacter.y += dy / dist * moveSpeed;
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game loop
game.update = function () {
if (gameEnded) return;
// Update timer
gameTimer--;
var seconds = Math.ceil(gameTimer / 60);
timerText.setText(seconds.toString());
// Update alive counter
aliveText.setText(aliveCount + ' Players');
// Raise lava progressively
if (gameTimer < 3000) {
// Last 50 seconds
lavaY -= 2;
lava.y = lavaY;
}
// Spawn power-ups
if (LK.ticks % 180 === 0) {
// Every 3 seconds
spawnPowerUp();
}
// Remove collected power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i].collected) {
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
// Check win/lose conditions
if (aliveCount <= 1 || gameTimer <= 0) {
gameEnded = true;
if (playerCharacter && playerCharacter.isAlive && aliveCount === 1) {
LK.showYouWin();
} else {
LK.showGameOver();
}
}
// Increase hazard intensity over time
if (gameTimer < 1800) {
// Last 30 seconds
for (var i = 0; i < hazardArms.length; i++) {
hazardArms[i].rotationSpeed = 0.025 + Math.random() * 0.015;
}
}
};
// Start background music
LK.playMusic('battleMusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var HazardArm = Container.expand(function (centerX, centerY) {
var self = Container.call(this);
var armGraphics = self.attachAsset('hazardArm', {
anchorX: 0,
anchorY: 0.5
});
self.x = centerX;
self.y = centerY;
self.rotationSpeed = 0.02;
self.isActive = true;
self.update = function () {
if (!self.isActive) return;
self.rotation += self.rotationSpeed;
// Check collision with players
for (var i = 0; i < players.length; i++) {
var player = players[i];
if (!player.isAlive || player.powerUpType === 'invincibility') continue;
var armEndX = self.x + Math.cos(self.rotation) * 600;
var armEndY = self.y + Math.sin(self.rotation) * 600;
// Simple line-point collision
var distToArm = Math.abs((armEndY - self.y) * player.x - (armEndX - self.x) * player.y + armEndX * self.y - armEndY * self.x) / Math.sqrt((armEndY - self.y) * (armEndY - self.y) + (armEndX - self.x) * (armEndX - self.x));
if (distToArm < 60) {
var distFromCenter = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y));
if (distFromCenter < 600) {
player.eliminate();
LK.getSound('hazard').play();
}
}
}
};
return self;
});
var Player = Container.expand(function (isBot, startX, startY) {
var self = Container.call(this);
var playerGraphics = self.attachAsset(isBot ? 'bot' : 'player', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.isBot = isBot;
self.speed = 3;
self.isAlive = true;
self.powerUpType = null;
self.powerUpTimer = 0;
self.botDirection = Math.random() * Math.PI * 2;
self.botChangeTime = 0;
self.pushForceX = 0;
self.pushForceY = 0;
self.originalScale = 1;
self.update = function () {
if (!self.isAlive) return;
// Handle power-up effects
if (self.powerUpTimer > 0) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.removePowerUp();
}
}
// Apply push force
if (self.pushForceX !== 0 || self.pushForceY !== 0) {
self.x += self.pushForceX;
self.y += self.pushForceY;
self.pushForceX *= 0.9;
self.pushForceY *= 0.9;
if (Math.abs(self.pushForceX) < 0.1) self.pushForceX = 0;
if (Math.abs(self.pushForceY) < 0.1) self.pushForceY = 0;
}
// Bot AI movement
if (self.isBot) {
self.botChangeTime++;
if (self.botChangeTime > 60) {
self.botDirection += (Math.random() - 0.5) * 0.5;
self.botChangeTime = 0;
// Avoid arena edges
var distFromCenter = Math.sqrt((self.x - arenaX) * (self.x - arenaX) + (self.y - arenaY) * (self.y - arenaY));
if (distFromCenter > 600) {
var angleToCenter = Math.atan2(arenaY - self.y, arenaX - self.x);
self.botDirection = angleToCenter + (Math.random() - 0.5) * 0.5;
}
// Move away from lava
if (self.y > lavaY - 100) {
self.botDirection = -Math.PI / 2 + (Math.random() - 0.5) * 0.5;
}
}
var moveSpeed = self.speed;
if (self.powerUpType === 'speed') moveSpeed *= 2;
self.x += Math.cos(self.botDirection) * moveSpeed;
self.y += Math.sin(self.botDirection) * moveSpeed;
}
// Keep in arena bounds
var distFromCenter = Math.sqrt((self.x - arenaX) * (self.x - arenaX) + (self.y - arenaY) * (self.y - arenaY));
if (distFromCenter > 680) {
var angle = Math.atan2(self.y - arenaY, self.x - arenaX);
self.x = arenaX + Math.cos(angle) * 680;
self.y = arenaY + Math.sin(angle) * 680;
}
// Check lava collision
if (self.y > lavaY - 40 && self.powerUpType !== 'invincibility') {
self.eliminate();
}
};
self.applyPowerUp = function (type) {
self.powerUpType = type;
self.powerUpTimer = 300; // 5 seconds at 60fps
if (type === 'speed') {
playerGraphics.tint = 0xffff00;
} else if (type === 'size') {
self.scaleX = 1.5;
self.scaleY = 1.5;
} else if (type === 'invincibility') {
playerGraphics.tint = 0xffffff;
playerGraphics.alpha = 0.7;
}
};
self.removePowerUp = function () {
if (self.powerUpType === 'size') {
self.scaleX = self.originalScale;
self.scaleY = self.originalScale;
}
playerGraphics.tint = 0xffffff;
playerGraphics.alpha = 1.0;
self.powerUpType = null;
};
self.eliminate = function () {
if (!self.isAlive) return;
self.isAlive = false;
aliveCount--;
LK.getSound('elimination').play();
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 500
});
};
self.pushAway = function (fromX, fromY, force) {
var dx = self.x - fromX;
var dy = self.y - fromY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.pushForceX = dx / dist * force;
self.pushForceY = dy / dist * force;
}
};
return self;
});
var PowerUp = Container.expand(function (type, x, y) {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset(type + 'PowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.type = type;
self.collected = false;
self.update = function () {
if (self.collected) return;
// Floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check collection
for (var i = 0; i < players.length; i++) {
var player = players[i];
if (!player.isAlive) continue;
var dist = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y));
if (dist < 50) {
player.applyPowerUp(self.type);
self.collected = true;
self.alpha = 0;
LK.getSound('powerup').play();
if (self.type === 'push') {
// Push nearby players
for (var j = 0; j < players.length; j++) {
if (players[j] !== player && players[j].isAlive) {
var pushDist = Math.sqrt((players[j].x - self.x) * (players[j].x - self.x) + (players[j].y - self.y) * (players[j].y - self.y));
if (pushDist < 200) {
players[j].pushAway(self.x, self.y, 15);
}
}
}
}
break;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var arenaX = 2048 / 2;
var arenaY = 2732 / 2;
var gameTimer = 3600; // 60 seconds at 60fps
var lavaY = 2732 + 100; // Start below screen
var players = [];
var hazardArms = [];
var powerUps = [];
var aliveCount = 0;
var gameEnded = false;
var playerCharacter = null;
var dragActive = false;
// Create arena
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: arenaX,
y: arenaY
}));
// Create lava
var lava = game.addChild(LK.getAsset('lava', {
anchorX: 0.5,
anchorY: 0.5,
x: arenaX,
y: lavaY
}));
// Create timer display
var timerText = new Text2('60', {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
// Create alive counter
var aliveText = new Text2('20 Players', {
size: 60,
fill: 0xFFFFFF
});
aliveText.anchor.set(1, 0);
LK.gui.topRight.addChild(aliveText);
// Create players (1 human + 19 bots)
for (var i = 0; i < 20; i++) {
var angle = i / 20 * Math.PI * 2;
var radius = 400 + Math.random() * 200;
var startX = arenaX + Math.cos(angle) * radius;
var startY = arenaY + Math.sin(angle) * radius;
var player = new Player(i > 0, startX, startY);
players.push(player);
game.addChild(player);
if (i === 0) {
playerCharacter = player;
}
}
aliveCount = 20;
// Create hazard arms
for (var i = 0; i < 3; i++) {
var arm = new HazardArm(arenaX, arenaY);
arm.rotation = i / 3 * Math.PI * 2;
arm.rotationSpeed = 0.015 + Math.random() * 0.01;
hazardArms.push(arm);
game.addChild(arm);
}
// Spawn initial power-ups
function spawnPowerUp() {
if (powerUps.length >= 5) return;
var types = ['speed', 'push', 'size', 'invincibility'];
var type = types[Math.floor(Math.random() * types.length)];
var angle = Math.random() * Math.PI * 2;
var radius = 200 + Math.random() * 400;
var x = arenaX + Math.cos(angle) * radius;
var y = arenaY + Math.sin(angle) * radius;
var powerUp = new PowerUp(type, x, y);
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Touch controls
game.down = function (x, y, obj) {
if (!playerCharacter || !playerCharacter.isAlive) return;
dragActive = true;
};
game.move = function (x, y, obj) {
if (!playerCharacter || !playerCharacter.isAlive || !dragActive) return;
var moveSpeed = playerCharacter.speed;
if (playerCharacter.powerUpType === 'speed') moveSpeed *= 2;
var dx = x - playerCharacter.x;
var dy = y - playerCharacter.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 20) {
playerCharacter.x += dx / dist * moveSpeed;
playerCharacter.y += dy / dist * moveSpeed;
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game loop
game.update = function () {
if (gameEnded) return;
// Update timer
gameTimer--;
var seconds = Math.ceil(gameTimer / 60);
timerText.setText(seconds.toString());
// Update alive counter
aliveText.setText(aliveCount + ' Players');
// Raise lava progressively
if (gameTimer < 3000) {
// Last 50 seconds
lavaY -= 2;
lava.y = lavaY;
}
// Spawn power-ups
if (LK.ticks % 180 === 0) {
// Every 3 seconds
spawnPowerUp();
}
// Remove collected power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i].collected) {
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
// Check win/lose conditions
if (aliveCount <= 1 || gameTimer <= 0) {
gameEnded = true;
if (playerCharacter && playerCharacter.isAlive && aliveCount === 1) {
LK.showYouWin();
} else {
LK.showGameOver();
}
}
// Increase hazard intensity over time
if (gameTimer < 1800) {
// Last 30 seconds
for (var i = 0; i < hazardArms.length; i++) {
hazardArms[i].rotationSpeed = 0.025 + Math.random() * 0.015;
}
}
};
// Start background music
LK.playMusic('battleMusic');