/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var ArtifactFragment = Container.expand(function () {
var self = Container.call(this);
var fragmentGraphics = self.attachAsset('artifactFragment', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.rotationSpeed = 0.05;
self.update = function () {
// Rotation animation
fragmentGraphics.rotation += self.rotationSpeed;
// Check collection
if (!self.collected && self.intersects(player)) {
self.collected = true;
player.collectFragment();
self.visible = false;
}
};
return self;
});
var EnergyBlast = Container.expand(function () {
var self = Container.call(this);
var blastGraphics = self.attachAsset('energyBlast', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 30;
self.directionX = 0;
self.directionY = 0;
self.active = true;
self.setTarget = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance * self.speed;
self.directionY = dy / distance * self.speed;
}
};
self.update = function () {
if (self.active) {
self.x += self.directionX;
self.y += self.directionY;
// Check bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.active = false;
}
}
};
return self;
});
var EnergyCrystal = Container.expand(function () {
var self = Container.call(this);
var crystalGraphics = self.attachAsset('energyCrystal', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.pulseTime = 0;
self.update = function () {
// Pulsing animation
self.pulseTime += 0.1;
crystalGraphics.scaleX = 1 + Math.sin(self.pulseTime) * 0.2;
crystalGraphics.scaleY = 1 + Math.sin(self.pulseTime) * 0.2;
// Check collection
if (!self.collected && self.intersects(player)) {
self.collected = true;
player.collectCrystal();
self.visible = false;
}
};
return self;
});
var EnergyShield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('energyShield', {
anchorX: 0.5,
anchorY: 0.5
});
self.alpha = 0.3;
self.pulseTime = 0;
self.update = function () {
// Follow player
self.x = player.x;
self.y = player.y;
// Pulsing effect
self.pulseTime += 0.2;
shieldGraphics.alpha = 0.3 + Math.sin(self.pulseTime) * 0.1;
// Visibility based on shield status
self.visible = player.shieldActive;
};
return self;
});
var Mutant = Container.expand(function () {
var self = Container.call(this);
var mutantGraphics = self.attachAsset('mutant', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 2;
self.lastAttackTime = 0;
self.attackCooldown = 120; // 2 seconds
self.aggroRange = 200;
self.attackRange = 64;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.aggroRange) {
// Move towards player
if (distance > self.attackRange) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
}
// Attack if in range
if (distance < self.attackRange && LK.ticks - self.lastAttackTime > self.attackCooldown) {
self.lastAttackTime = LK.ticks;
var playerDied = player.takeDamage(20);
if (playerDied) {
LK.showGameOver();
}
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.getSound('mutantDeath').play();
return true; // Mutant died
}
return false;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.energy = 100;
self.maxEnergy = 100;
self.speed = 4;
self.lastShieldTime = 0;
self.shieldActive = false;
self.artifactFragments = 0;
self.moralAlignment = 0; // -100 to 100, negative = destructive, positive = constructive
self.moveLeft = function () {
if (self.x > 32) {
self.x -= self.speed;
}
};
self.moveRight = function () {
if (self.x < 2048 - 32) {
self.x += self.speed;
}
};
self.moveUp = function () {
if (self.y > 32) {
self.y -= self.speed;
}
};
self.moveDown = function () {
if (self.y < 2732 - 32) {
self.y += self.speed;
}
};
self.createEnergyBlast = function (targetX, targetY) {
if (self.energy >= 20) {
self.energy -= 20;
return {
x: self.x,
y: self.y,
targetX: targetX,
targetY: targetY,
active: true
};
}
return null;
};
self.activateShield = function () {
if (self.energy >= 30 && !self.shieldActive) {
self.energy -= 30;
self.shieldActive = true;
self.lastShieldTime = LK.ticks;
return true;
}
return false;
};
self.takeDamage = function (damage) {
if (!self.shieldActive) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // Player died
}
}
return false;
};
self.collectCrystal = function () {
self.energy = Math.min(self.maxEnergy, self.energy + 25);
LK.getSound('collect').play();
};
self.collectFragment = function () {
self.artifactFragments++;
LK.getSound('powerup').play();
};
self.update = function () {
// Shield duration
if (self.shieldActive && LK.ticks - self.lastShieldTime > 180) {
// 3 seconds
self.shieldActive = false;
}
// Energy regeneration
if (self.energy < self.maxEnergy) {
self.energy = Math.min(self.maxEnergy, self.energy + 0.1);
}
// Update visual based on moral alignment
if (self.moralAlignment > 50) {
playerGraphics.tint = 0x4169E1; // Royal blue for good
} else if (self.moralAlignment < -50) {
playerGraphics.tint = 0x8B0000; // Dark red for evil
} else {
playerGraphics.tint = 0xFFFFFF; // White for neutral
}
};
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var survivorGraphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
self.hasInteracted = false;
self.choiceType = 'shareFood'; // 'shareFood', 'helpRepair', 'defendBase'
self.down = function (x, y, obj) {
if (!self.hasInteracted && self.intersects(player)) {
self.hasInteracted = true;
self.presentChoice();
}
};
self.presentChoice = function () {
// Simple choice system - in a full game this would be a proper UI
if (self.choiceType === 'shareFood') {
// Positive choice: share food
player.moralAlignment += 20;
player.health = Math.min(100, player.health + 30);
} else if (self.choiceType === 'helpRepair') {
// Neutral choice: help repair
player.moralAlignment += 10;
player.maxEnergy += 20;
} else if (self.choiceType === 'defendBase') {
// Negative choice: take supplies
player.moralAlignment -= 15;
player.energy = player.maxEnergy;
}
survivorGraphics.tint = 0x808080; // Gray out after interaction
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F2F2F
});
/****
* Game Code
****/
// Game state variables
var player;
var mutants = [];
var energyBlasts = [];
var energyCrystals = [];
var artifactFragments = [];
var survivors = [];
var energyShield;
var gameStarted = false;
var spawnTimer = 0;
var crystalSpawnTimer = 0;
var fragmentSpawnTimer = 0;
var survivorSpawnTimer = 0;
// UI Elements
var healthBar;
var energyBar;
var fragmentCounter;
var alignmentIndicator;
// Initialize UI
function initializeUI() {
healthBar = new Text2('Health: 100', {
size: 48,
fill: '#FF0000'
});
healthBar.anchor.set(0, 0);
healthBar.x = 120;
healthBar.y = 50;
LK.gui.topLeft.addChild(healthBar);
energyBar = new Text2('Energy: 100', {
size: 48,
fill: '#00FFFF'
});
energyBar.anchor.set(0, 0);
energyBar.x = 120;
energyBar.y = 110;
LK.gui.topLeft.addChild(energyBar);
fragmentCounter = new Text2('Fragments: 0/10', {
size: 48,
fill: '#FFD700'
});
fragmentCounter.anchor.set(1, 0);
fragmentCounter.x = -50;
fragmentCounter.y = 50;
LK.gui.topRight.addChild(fragmentCounter);
alignmentIndicator = new Text2('Neutral', {
size: 48,
fill: '#FFFFFF'
});
alignmentIndicator.anchor.set(0.5, 0);
alignmentIndicator.x = 0;
alignmentIndicator.y = 50;
LK.gui.top.addChild(alignmentIndicator);
}
// Initialize game world
function initializeWorld() {
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Create energy shield
energyShield = game.addChild(new EnergyShield());
// Create some initial ground elements
for (var i = 0; i < 20; i++) {
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5
}));
ground.x = Math.random() * 2048;
ground.y = 2600 + Math.random() * 132;
}
// Create some walls
for (var i = 0; i < 15; i++) {
var wall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
}));
wall.x = Math.random() * 2048;
wall.y = Math.random() * 2732;
}
// Spawn initial crystals
for (var i = 0; i < 5; i++) {
spawnEnergyCrystal();
}
// Spawn initial fragments
for (var i = 0; i < 3; i++) {
spawnArtifactFragment();
}
// Spawn initial survivor
spawnSurvivor();
}
// Spawn functions
function spawnMutant() {
var mutant = game.addChild(new Mutant());
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
mutant.x = Math.random() * 2048;
mutant.y = 0;
break;
case 1:
// Right
mutant.x = 2048;
mutant.y = Math.random() * 2732;
break;
case 2:
// Bottom
mutant.x = Math.random() * 2048;
mutant.y = 2732;
break;
case 3:
// Left
mutant.x = 0;
mutant.y = Math.random() * 2732;
break;
}
mutants.push(mutant);
}
function spawnEnergyCrystal() {
var crystal = game.addChild(new EnergyCrystal());
crystal.x = Math.random() * 1800 + 124;
crystal.y = Math.random() * 2500 + 116;
energyCrystals.push(crystal);
}
function spawnArtifactFragment() {
var fragment = game.addChild(new ArtifactFragment());
fragment.x = Math.random() * 1800 + 124;
fragment.y = Math.random() * 2500 + 116;
artifactFragments.push(fragment);
}
function spawnSurvivor() {
var survivor = game.addChild(new Survivor());
survivor.x = Math.random() * 1800 + 124;
survivor.y = Math.random() * 2500 + 116;
var choiceTypes = ['shareFood', 'helpRepair', 'defendBase'];
survivor.choiceType = choiceTypes[Math.floor(Math.random() * choiceTypes.length)];
survivors.push(survivor);
}
// Update UI
function updateUI() {
healthBar.setText('Health: ' + Math.floor(player.health));
energyBar.setText('Energy: ' + Math.floor(player.energy));
fragmentCounter.setText('Fragments: ' + player.artifactFragments + '/10');
// Update alignment indicator
if (player.moralAlignment > 50) {
alignmentIndicator.setText('Savior');
alignmentIndicator.fill = '#4169E1';
} else if (player.moralAlignment < -50) {
alignmentIndicator.setText('Destroyer');
alignmentIndicator.fill = '#8B0000';
} else {
alignmentIndicator.setText('Neutral');
alignmentIndicator.fill = '#FFFFFF';
}
}
// Movement tracking
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
// Game controls
game.down = function (x, y, obj) {
// Check if clicking on survivor
for (var i = 0; i < survivors.length; i++) {
if (survivors[i].intersects(player)) {
survivors[i].down(x, y, obj);
return;
}
}
// Create energy blast
var blastData = player.createEnergyBlast(x, y);
if (blastData) {
var blast = game.addChild(new EnergyBlast());
blast.x = blastData.x;
blast.y = blastData.y;
blast.setTarget(blastData.targetX, blastData.targetY);
energyBlasts.push(blast);
LK.getSound('blast').play();
}
};
game.move = function (x, y, obj) {
// Simple movement - move towards touch/mouse position
var dx = x - player.x;
var dy = y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
// Dead zone
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) {
moveRight = true;
moveLeft = false;
} else {
moveLeft = true;
moveRight = false;
}
} else {
if (dy > 0) {
moveDown = true;
moveUp = false;
} else {
moveUp = true;
moveDown = false;
}
}
}
};
game.up = function (x, y, obj) {
// Stop movement
moveLeft = false;
moveRight = false;
moveUp = false;
moveDown = false;
// Try to activate shield
player.activateShield();
};
// Main game loop
game.update = function () {
if (!gameStarted) {
initializeUI();
initializeWorld();
gameStarted = true;
LK.playMusic('wastelandTheme');
}
// Handle movement
if (moveLeft) player.moveLeft();
if (moveRight) player.moveRight();
if (moveUp) player.moveUp();
if (moveDown) player.moveDown();
// Spawn enemies
spawnTimer++;
if (spawnTimer > 180) {
// Every 3 seconds
spawnMutant();
spawnTimer = 0;
}
// Spawn crystals
crystalSpawnTimer++;
if (crystalSpawnTimer > 600) {
// Every 10 seconds
spawnEnergyCrystal();
crystalSpawnTimer = 0;
}
// Spawn fragments
fragmentSpawnTimer++;
if (fragmentSpawnTimer > 900) {
// Every 15 seconds
spawnArtifactFragment();
fragmentSpawnTimer = 0;
}
// Spawn survivors
survivorSpawnTimer++;
if (survivorSpawnTimer > 1800) {
// Every 30 seconds
spawnSurvivor();
survivorSpawnTimer = 0;
}
// Update energy blasts and check collisions
for (var i = energyBlasts.length - 1; i >= 0; i--) {
var blast = energyBlasts[i];
if (!blast.active) {
blast.destroy();
energyBlasts.splice(i, 1);
continue;
}
// Check collision with mutants
for (var j = mutants.length - 1; j >= 0; j--) {
var mutant = mutants[j];
if (blast.intersects(mutant)) {
var mutantDied = mutant.takeDamage(blast.damage);
if (mutantDied) {
mutant.destroy();
mutants.splice(j, 1);
LK.setScore(LK.getScore() + 10);
}
blast.active = false;
break;
}
}
}
// Clean up collected crystals
for (var i = energyCrystals.length - 1; i >= 0; i--) {
if (energyCrystals[i].collected) {
energyCrystals[i].destroy();
energyCrystals.splice(i, 1);
}
}
// Clean up collected fragments
for (var i = artifactFragments.length - 1; i >= 0; i--) {
if (artifactFragments[i].collected) {
artifactFragments[i].destroy();
artifactFragments.splice(i, 1);
}
}
// Check win condition
if (player.artifactFragments >= 10) {
if (player.moralAlignment > 0) {
// Good ending - heal the world
LK.showYouWin();
} else {
// Bad ending - destroy the world
LK.showGameOver();
}
}
// Update UI
updateUI();
// Reset movement flags
moveLeft = false;
moveRight = false;
moveUp = false;
moveDown = false;
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var ArtifactFragment = Container.expand(function () {
var self = Container.call(this);
var fragmentGraphics = self.attachAsset('artifactFragment', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.rotationSpeed = 0.05;
self.update = function () {
// Rotation animation
fragmentGraphics.rotation += self.rotationSpeed;
// Check collection
if (!self.collected && self.intersects(player)) {
self.collected = true;
player.collectFragment();
self.visible = false;
}
};
return self;
});
var EnergyBlast = Container.expand(function () {
var self = Container.call(this);
var blastGraphics = self.attachAsset('energyBlast', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 30;
self.directionX = 0;
self.directionY = 0;
self.active = true;
self.setTarget = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance * self.speed;
self.directionY = dy / distance * self.speed;
}
};
self.update = function () {
if (self.active) {
self.x += self.directionX;
self.y += self.directionY;
// Check bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.active = false;
}
}
};
return self;
});
var EnergyCrystal = Container.expand(function () {
var self = Container.call(this);
var crystalGraphics = self.attachAsset('energyCrystal', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.pulseTime = 0;
self.update = function () {
// Pulsing animation
self.pulseTime += 0.1;
crystalGraphics.scaleX = 1 + Math.sin(self.pulseTime) * 0.2;
crystalGraphics.scaleY = 1 + Math.sin(self.pulseTime) * 0.2;
// Check collection
if (!self.collected && self.intersects(player)) {
self.collected = true;
player.collectCrystal();
self.visible = false;
}
};
return self;
});
var EnergyShield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('energyShield', {
anchorX: 0.5,
anchorY: 0.5
});
self.alpha = 0.3;
self.pulseTime = 0;
self.update = function () {
// Follow player
self.x = player.x;
self.y = player.y;
// Pulsing effect
self.pulseTime += 0.2;
shieldGraphics.alpha = 0.3 + Math.sin(self.pulseTime) * 0.1;
// Visibility based on shield status
self.visible = player.shieldActive;
};
return self;
});
var Mutant = Container.expand(function () {
var self = Container.call(this);
var mutantGraphics = self.attachAsset('mutant', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 2;
self.lastAttackTime = 0;
self.attackCooldown = 120; // 2 seconds
self.aggroRange = 200;
self.attackRange = 64;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.aggroRange) {
// Move towards player
if (distance > self.attackRange) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
}
// Attack if in range
if (distance < self.attackRange && LK.ticks - self.lastAttackTime > self.attackCooldown) {
self.lastAttackTime = LK.ticks;
var playerDied = player.takeDamage(20);
if (playerDied) {
LK.showGameOver();
}
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.getSound('mutantDeath').play();
return true; // Mutant died
}
return false;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.energy = 100;
self.maxEnergy = 100;
self.speed = 4;
self.lastShieldTime = 0;
self.shieldActive = false;
self.artifactFragments = 0;
self.moralAlignment = 0; // -100 to 100, negative = destructive, positive = constructive
self.moveLeft = function () {
if (self.x > 32) {
self.x -= self.speed;
}
};
self.moveRight = function () {
if (self.x < 2048 - 32) {
self.x += self.speed;
}
};
self.moveUp = function () {
if (self.y > 32) {
self.y -= self.speed;
}
};
self.moveDown = function () {
if (self.y < 2732 - 32) {
self.y += self.speed;
}
};
self.createEnergyBlast = function (targetX, targetY) {
if (self.energy >= 20) {
self.energy -= 20;
return {
x: self.x,
y: self.y,
targetX: targetX,
targetY: targetY,
active: true
};
}
return null;
};
self.activateShield = function () {
if (self.energy >= 30 && !self.shieldActive) {
self.energy -= 30;
self.shieldActive = true;
self.lastShieldTime = LK.ticks;
return true;
}
return false;
};
self.takeDamage = function (damage) {
if (!self.shieldActive) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // Player died
}
}
return false;
};
self.collectCrystal = function () {
self.energy = Math.min(self.maxEnergy, self.energy + 25);
LK.getSound('collect').play();
};
self.collectFragment = function () {
self.artifactFragments++;
LK.getSound('powerup').play();
};
self.update = function () {
// Shield duration
if (self.shieldActive && LK.ticks - self.lastShieldTime > 180) {
// 3 seconds
self.shieldActive = false;
}
// Energy regeneration
if (self.energy < self.maxEnergy) {
self.energy = Math.min(self.maxEnergy, self.energy + 0.1);
}
// Update visual based on moral alignment
if (self.moralAlignment > 50) {
playerGraphics.tint = 0x4169E1; // Royal blue for good
} else if (self.moralAlignment < -50) {
playerGraphics.tint = 0x8B0000; // Dark red for evil
} else {
playerGraphics.tint = 0xFFFFFF; // White for neutral
}
};
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var survivorGraphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
self.hasInteracted = false;
self.choiceType = 'shareFood'; // 'shareFood', 'helpRepair', 'defendBase'
self.down = function (x, y, obj) {
if (!self.hasInteracted && self.intersects(player)) {
self.hasInteracted = true;
self.presentChoice();
}
};
self.presentChoice = function () {
// Simple choice system - in a full game this would be a proper UI
if (self.choiceType === 'shareFood') {
// Positive choice: share food
player.moralAlignment += 20;
player.health = Math.min(100, player.health + 30);
} else if (self.choiceType === 'helpRepair') {
// Neutral choice: help repair
player.moralAlignment += 10;
player.maxEnergy += 20;
} else if (self.choiceType === 'defendBase') {
// Negative choice: take supplies
player.moralAlignment -= 15;
player.energy = player.maxEnergy;
}
survivorGraphics.tint = 0x808080; // Gray out after interaction
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F2F2F
});
/****
* Game Code
****/
// Game state variables
var player;
var mutants = [];
var energyBlasts = [];
var energyCrystals = [];
var artifactFragments = [];
var survivors = [];
var energyShield;
var gameStarted = false;
var spawnTimer = 0;
var crystalSpawnTimer = 0;
var fragmentSpawnTimer = 0;
var survivorSpawnTimer = 0;
// UI Elements
var healthBar;
var energyBar;
var fragmentCounter;
var alignmentIndicator;
// Initialize UI
function initializeUI() {
healthBar = new Text2('Health: 100', {
size: 48,
fill: '#FF0000'
});
healthBar.anchor.set(0, 0);
healthBar.x = 120;
healthBar.y = 50;
LK.gui.topLeft.addChild(healthBar);
energyBar = new Text2('Energy: 100', {
size: 48,
fill: '#00FFFF'
});
energyBar.anchor.set(0, 0);
energyBar.x = 120;
energyBar.y = 110;
LK.gui.topLeft.addChild(energyBar);
fragmentCounter = new Text2('Fragments: 0/10', {
size: 48,
fill: '#FFD700'
});
fragmentCounter.anchor.set(1, 0);
fragmentCounter.x = -50;
fragmentCounter.y = 50;
LK.gui.topRight.addChild(fragmentCounter);
alignmentIndicator = new Text2('Neutral', {
size: 48,
fill: '#FFFFFF'
});
alignmentIndicator.anchor.set(0.5, 0);
alignmentIndicator.x = 0;
alignmentIndicator.y = 50;
LK.gui.top.addChild(alignmentIndicator);
}
// Initialize game world
function initializeWorld() {
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Create energy shield
energyShield = game.addChild(new EnergyShield());
// Create some initial ground elements
for (var i = 0; i < 20; i++) {
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5
}));
ground.x = Math.random() * 2048;
ground.y = 2600 + Math.random() * 132;
}
// Create some walls
for (var i = 0; i < 15; i++) {
var wall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
}));
wall.x = Math.random() * 2048;
wall.y = Math.random() * 2732;
}
// Spawn initial crystals
for (var i = 0; i < 5; i++) {
spawnEnergyCrystal();
}
// Spawn initial fragments
for (var i = 0; i < 3; i++) {
spawnArtifactFragment();
}
// Spawn initial survivor
spawnSurvivor();
}
// Spawn functions
function spawnMutant() {
var mutant = game.addChild(new Mutant());
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
mutant.x = Math.random() * 2048;
mutant.y = 0;
break;
case 1:
// Right
mutant.x = 2048;
mutant.y = Math.random() * 2732;
break;
case 2:
// Bottom
mutant.x = Math.random() * 2048;
mutant.y = 2732;
break;
case 3:
// Left
mutant.x = 0;
mutant.y = Math.random() * 2732;
break;
}
mutants.push(mutant);
}
function spawnEnergyCrystal() {
var crystal = game.addChild(new EnergyCrystal());
crystal.x = Math.random() * 1800 + 124;
crystal.y = Math.random() * 2500 + 116;
energyCrystals.push(crystal);
}
function spawnArtifactFragment() {
var fragment = game.addChild(new ArtifactFragment());
fragment.x = Math.random() * 1800 + 124;
fragment.y = Math.random() * 2500 + 116;
artifactFragments.push(fragment);
}
function spawnSurvivor() {
var survivor = game.addChild(new Survivor());
survivor.x = Math.random() * 1800 + 124;
survivor.y = Math.random() * 2500 + 116;
var choiceTypes = ['shareFood', 'helpRepair', 'defendBase'];
survivor.choiceType = choiceTypes[Math.floor(Math.random() * choiceTypes.length)];
survivors.push(survivor);
}
// Update UI
function updateUI() {
healthBar.setText('Health: ' + Math.floor(player.health));
energyBar.setText('Energy: ' + Math.floor(player.energy));
fragmentCounter.setText('Fragments: ' + player.artifactFragments + '/10');
// Update alignment indicator
if (player.moralAlignment > 50) {
alignmentIndicator.setText('Savior');
alignmentIndicator.fill = '#4169E1';
} else if (player.moralAlignment < -50) {
alignmentIndicator.setText('Destroyer');
alignmentIndicator.fill = '#8B0000';
} else {
alignmentIndicator.setText('Neutral');
alignmentIndicator.fill = '#FFFFFF';
}
}
// Movement tracking
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
// Game controls
game.down = function (x, y, obj) {
// Check if clicking on survivor
for (var i = 0; i < survivors.length; i++) {
if (survivors[i].intersects(player)) {
survivors[i].down(x, y, obj);
return;
}
}
// Create energy blast
var blastData = player.createEnergyBlast(x, y);
if (blastData) {
var blast = game.addChild(new EnergyBlast());
blast.x = blastData.x;
blast.y = blastData.y;
blast.setTarget(blastData.targetX, blastData.targetY);
energyBlasts.push(blast);
LK.getSound('blast').play();
}
};
game.move = function (x, y, obj) {
// Simple movement - move towards touch/mouse position
var dx = x - player.x;
var dy = y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
// Dead zone
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) {
moveRight = true;
moveLeft = false;
} else {
moveLeft = true;
moveRight = false;
}
} else {
if (dy > 0) {
moveDown = true;
moveUp = false;
} else {
moveUp = true;
moveDown = false;
}
}
}
};
game.up = function (x, y, obj) {
// Stop movement
moveLeft = false;
moveRight = false;
moveUp = false;
moveDown = false;
// Try to activate shield
player.activateShield();
};
// Main game loop
game.update = function () {
if (!gameStarted) {
initializeUI();
initializeWorld();
gameStarted = true;
LK.playMusic('wastelandTheme');
}
// Handle movement
if (moveLeft) player.moveLeft();
if (moveRight) player.moveRight();
if (moveUp) player.moveUp();
if (moveDown) player.moveDown();
// Spawn enemies
spawnTimer++;
if (spawnTimer > 180) {
// Every 3 seconds
spawnMutant();
spawnTimer = 0;
}
// Spawn crystals
crystalSpawnTimer++;
if (crystalSpawnTimer > 600) {
// Every 10 seconds
spawnEnergyCrystal();
crystalSpawnTimer = 0;
}
// Spawn fragments
fragmentSpawnTimer++;
if (fragmentSpawnTimer > 900) {
// Every 15 seconds
spawnArtifactFragment();
fragmentSpawnTimer = 0;
}
// Spawn survivors
survivorSpawnTimer++;
if (survivorSpawnTimer > 1800) {
// Every 30 seconds
spawnSurvivor();
survivorSpawnTimer = 0;
}
// Update energy blasts and check collisions
for (var i = energyBlasts.length - 1; i >= 0; i--) {
var blast = energyBlasts[i];
if (!blast.active) {
blast.destroy();
energyBlasts.splice(i, 1);
continue;
}
// Check collision with mutants
for (var j = mutants.length - 1; j >= 0; j--) {
var mutant = mutants[j];
if (blast.intersects(mutant)) {
var mutantDied = mutant.takeDamage(blast.damage);
if (mutantDied) {
mutant.destroy();
mutants.splice(j, 1);
LK.setScore(LK.getScore() + 10);
}
blast.active = false;
break;
}
}
}
// Clean up collected crystals
for (var i = energyCrystals.length - 1; i >= 0; i--) {
if (energyCrystals[i].collected) {
energyCrystals[i].destroy();
energyCrystals.splice(i, 1);
}
}
// Clean up collected fragments
for (var i = artifactFragments.length - 1; i >= 0; i--) {
if (artifactFragments[i].collected) {
artifactFragments[i].destroy();
artifactFragments.splice(i, 1);
}
}
// Check win condition
if (player.artifactFragments >= 10) {
if (player.moralAlignment > 0) {
// Good ending - heal the world
LK.showYouWin();
} else {
// Bad ending - destroy the world
LK.showGameOver();
}
}
// Update UI
updateUI();
// Reset movement flags
moveLeft = false;
moveRight = false;
moveUp = false;
moveDown = false;
};