/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ArmedScientist = Container.expand(function () { var self = Container.call(this); var scientistGraphics = self.attachAsset('scientist', { anchorX: 0.5, anchorY: 0.5 }); scientistGraphics.tint = 0xFF0000; // Red tint to distinguish armed scientists self.speed = 2.5; self.health = 7; self.points = 4; self.targetX = 0; self.targetY = 0; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { // Mark as exploding to prevent multiple explosions if (self.exploding) return true; self.exploding = true; // Check for ALL scientists to kill BEFORE starting animation for (var i = scientists.length - 1; i >= 0; i--) { var otherScientist = scientists[i]; if (otherScientist !== self && !otherScientist.exploding) { // Kill ALL scientists on screen regardless of distance if (otherScientist.constructor === Scientist || otherScientist.constructor === FastScientist || otherScientist.constructor === SteelBallScientist) { LK.setScore(LK.getScore() + otherScientist.points); updateScore(); spawnLoot(otherScientist.x, otherScientist.y); scientistResidues++; updateResidue(); // Track normal scientist deaths if (otherScientist.constructor === Scientist) { normalScientistDeaths++; } else if (otherScientist.constructor === FastScientist) { fastScientistDeaths++; } otherScientist.destroy(); scientists.splice(i, 1); LK.getSound('hit').play(); } } } // Check if dog is in explosion range var dogDx = dog.x - self.x; var dogDy = dog.y - self.y; var dogDistance = Math.sqrt(dogDx * dogDx + dogDy * dogDy); if (dogDistance <= explosionRange) { // Reduce score by 20 points for being caught in explosion LK.setScore(Math.max(0, LK.getScore() - 20)); updateScore(); // Kill the dog when caught in explosion dog.health = 0; LK.showGameOver(); } // Give 50 score for detonating armed scientist LK.setScore(LK.getScore() + 50); updateScore(); // Create explosion animation tween(self, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); return true; } return false; }; return self; }); var Chest = Container.expand(function () { var self = Container.call(this); var chestGraphics = self.attachAsset('chest', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'chest'; self.value = 20; self.update = function () { self.rotation += 0.03; }; return self; }); var DirectionalButton = Container.expand(function (direction) { var self = Container.call(this); var buttonGraphics = self.attachAsset('dirButton', { anchorX: 0.5, anchorY: 0.5 }); self.direction = direction; self.alpha = 0.7; // Create arrow text based on direction var arrowText = new Text2('', { size: 90, fill: 0xFFFFFF }); arrowText.anchor.set(0.5, 0.5); switch (direction) { case 'up': arrowText.setText('↑'); break; case 'down': arrowText.setText('↓'); break; case 'left': arrowText.setText('←'); break; case 'right': arrowText.setText('→'); break; } self.addChild(arrowText); self.down = function (x, y, obj) { currentShootDirection = self.direction; self.alpha = 1.0; // Reset other buttons for (var i = 0; i < dirButtons.length; i++) { if (dirButtons[i] !== self) { dirButtons[i].alpha = 0.7; } } // Fire bullet immediately when button is pressed dog.shoot(); }; return self; }); var Dog = Container.expand(function () { var self = Container.call(this); var dogGraphics = self.attachAsset('dog', { anchorX: 0.5, anchorY: 0.5 }); // Add gun icon var gunIcon = self.attachAsset('dogBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 60, y: 0 }); gunIcon.tint = 0x888888; // Gray tint for gun icon self.health = 3; self.maxHealth = 3; self.shootCooldown = 0; self.shootRate = 20; self.speed = 5; self.powerUpActive = false; self.powerUpEndTime = 0; self.weaponType = 'knife'; self.weaponLevel = 1; self.gold = 0; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } if (self.powerUpActive && LK.now > self.powerUpEndTime) { self.powerUpActive = false; self.speed = 5; self.shootRate = 20; } }; self.shoot = function () { if (self.shootCooldown <= 0) { var bullet = new DogBullet(); bullet.x = self.x; bullet.y = self.y; bullet.weaponType = self.weaponType; bullet.weaponLevel = self.weaponLevel; // Set direction based on current shoot direction switch (currentShootDirection) { case 'up': bullet.dirX = 0; bullet.dirY = -1; bullet.y -= 60; break; case 'down': bullet.dirX = 0; bullet.dirY = 1; bullet.y += 60; break; case 'left': bullet.dirX = -1; bullet.dirY = 0; bullet.x -= 60; break; case 'right': bullet.dirX = 1; bullet.dirY = 0; bullet.x += 60; break; } bullets.push(bullet); game.addChild(bullet); self.shootCooldown = self.shootRate; LK.getSound('shoot').play(); } }; self.takeDamage = function () { self.health--; LK.effects.flashObject(self, 0xFF0000, 500); if (self.health <= 0) { LK.showGameOver(); } }; self.activatePowerUp = function () { self.powerUpActive = true; self.powerUpEndTime = LK.now + 5000; self.speed = 8; self.shootRate = 11; }; self.upgradeWeapon = function () { if (self.weaponLevel < 3) { self.weaponLevel++; if (self.weaponLevel === 2 && (scientistResidues >= 1000 || LK.getScore() >= 2000)) { self.weaponType = 'laser'; self.shootRate = 13; } else if (self.weaponLevel === 3) { self.shootRate = 7; } } }; return self; }); var DogBullet = Container.expand(function () { var self = Container.call(this); self.speed = 8; self.damage = 1; self.dirX = 0; self.dirY = -1; self.weaponType = 'knife'; self.weaponLevel = 1; var bulletGraphics; self.update = function () { // Update graphics based on weapon type if not set if (!bulletGraphics) { if (self.weaponType === 'laser') { bulletGraphics = self.attachAsset('laser', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 2; } else { bulletGraphics = self.attachAsset('knife', { anchorX: 0.5, anchorY: 0.5 }); } // Set rotation based on direction if (self.dirX === 1) bulletGraphics.rotation = Math.PI / 2;else if (self.dirX === -1) bulletGraphics.rotation = -Math.PI / 2;else if (self.dirY === 1) bulletGraphics.rotation = Math.PI; } self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; }; return self; }); var FastScientist = Container.expand(function () { var self = Container.call(this); var scientistGraphics = self.attachAsset('fastScientist', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 7.0; self.health = 10; self.points = 5; self.targetX = 0; self.targetY = 0; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { return true; } return false; }; return self; }); var Gold = Container.expand(function () { var self = Container.call(this); var goldGraphics = self.attachAsset('gold', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'gold'; self.value = 10; self.update = function () { self.rotation += 0.06; }; return self; }); var Metal = Container.expand(function () { var self = Container.call(this); var metalGraphics = self.attachAsset('metal', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'metal'; self.value = 5; self.update = function () { self.rotation += 0.05; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'speed'; self.duration = 5000; self.update = function () { self.rotation += 0.1; }; return self; }); var Scientist = Container.expand(function () { var self = Container.call(this); var scientistGraphics = self.attachAsset('scientist', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.health = 5; self.points = 3; self.targetX = 0; self.targetY = 0; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { return true; } return false; }; return self; }); var SteelBall = Container.expand(function () { var self = Container.call(this); var steelBallGraphics = self.attachAsset('dogBullet', { anchorX: 0.5, anchorY: 0.5 }); steelBallGraphics.tint = 0x808080; // Gray color for steel self.speed = 4; self.damage = 1; self.dirX = 0; self.dirY = 0; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; }; return self; }); var SteelBallScientist = Container.expand(function () { var self = Container.call(this); var scientistGraphics = self.attachAsset('scientist', { anchorX: 0.5, anchorY: 0.5 }); scientistGraphics.tint = 0x4169E1; // Blue tint to distinguish steel ball scientists self.speed = 2.5; self.health = 8; // 8 hits with knife, 5 with laser (damage 2) self.points = 6; self.targetX = 0; self.targetY = 0; self.shootCooldown = 0; self.shootRate = 60; // Shoot every 60 frames (1 second) self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Shooting logic if (self.shootCooldown > 0) { self.shootCooldown--; } else { // Shoot at dog var steelBall = new SteelBall(); steelBall.x = self.x; steelBall.y = self.y; // Calculate direction to dog var shootDistance = Math.sqrt(dx * dx + dy * dy); if (shootDistance > 0) { steelBall.dirX = dx / shootDistance; steelBall.dirY = dy / shootDistance; } steelBalls.push(steelBall); game.addChild(steelBall); self.shootCooldown = self.shootRate; } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { return true; } return false; }; return self; }); var Technology = Container.expand(function () { var self = Container.call(this); var technologyGraphics = self.attachAsset('technology', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'technology'; self.value = 50; self.update = function () { self.rotation += 0.08; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var dog = new Dog(); var bullets = []; var scientists = []; var powerUps = []; var metals = []; var chests = []; var technologies = []; var golds = []; var dirButtons = []; var steelBalls = []; var currentShootDirection = 'up'; var spawnTimer = 0; var waveTimer = 0; var difficultyLevel = 1; var lastSpawnRate = 120; var scientistResidues = 0; var scientistCount = 0; var normalScientistHits = 0; var fastScientistHits = 0; var fastScientistSpawned = 0; var normalScientistDeaths = 0; var fastScientistDeaths = 0; var explosionRange = 200; // Range for armed scientist explosions // Add laboratory background var labBackground = LK.getAsset('labBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(labBackground); dog.x = 1024; dog.y = 2200; game.addChild(dog); var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var goldTxt = new Text2('Gold: 0', { size: 60, fill: 0xFFD700 }); goldTxt.anchor.set(0, 0); goldTxt.x = 150; goldTxt.y = 120; LK.gui.topLeft.addChild(goldTxt); var weaponTxt = new Text2('Weapon: Knife Lv.1', { size: 50, fill: 0xFFFFFF }); weaponTxt.anchor.set(0, 0); weaponTxt.x = 150; weaponTxt.y = 190; LK.gui.topLeft.addChild(weaponTxt); var residueTxt = new Text2('Residues: 0/1000 (Laser: 1000 residues or 2000 score)', { size: 45, fill: 0x00FF00 }); residueTxt.anchor.set(0, 0); residueTxt.x = 150; residueTxt.y = 250; LK.gui.topLeft.addChild(residueTxt); // Create directional buttons in main game area with proper spacing var upBtn = new DirectionalButton('up'); upBtn.x = 300; upBtn.y = 2350; game.addChild(upBtn); dirButtons.push(upBtn); var downBtn = new DirectionalButton('down'); downBtn.x = 300; downBtn.y = 2650; game.addChild(downBtn); dirButtons.push(downBtn); var leftBtn = new DirectionalButton('left'); leftBtn.x = 150; leftBtn.y = 2500; game.addChild(leftBtn); dirButtons.push(leftBtn); var rightBtn = new DirectionalButton('right'); rightBtn.x = 450; rightBtn.y = 2500; game.addChild(rightBtn); dirButtons.push(rightBtn); // Set initial button state upBtn.alpha = 1.0; var dragNode = null; function updateScore() { scoreTxt.setText('Score: ' + LK.getScore()); } function updateGold() { goldTxt.setText('Gold: ' + dog.gold); } function updateWeapon() { var weaponName = dog.weaponType === 'knife' ? 'Knife' : 'Laser'; weaponTxt.setText('Weapon: ' + weaponName + ' Lv.' + dog.weaponLevel); } function updateResidue() { // Give 20 score for each scientist residue collected LK.setScore(LK.getScore() + 20); updateScore(); var laserUnlocked = scientistResidues >= 1000 || LK.getScore() >= 2000; if (laserUnlocked) { residueTxt.setText('Residues: ' + scientistResidues + '/1000 (LASER UNLOCKED!)'); } else { residueTxt.setText('Residues: ' + scientistResidues + '/1000 (Laser: 1000 residues or 2000 score)'); } } function spawnScientist() { var scientist; scientistCount++; if (fastScientistDeaths >= 6 && fastScientistDeaths % 6 === 0) { scientist = new ArmedScientist(); fastScientistDeaths++; // Increment to avoid spawning multiple in a row } else if (scientistCount % 10 === 0) { scientist = new FastScientist(); fastScientistSpawned++; // Spawn SteelBallScientist after every 5 fast scientists if (fastScientistSpawned % 5 === 0) { scientist = new SteelBallScientist(); } } else { scientist = new Scientist(); } var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top scientist.x = Math.random() * 2048; scientist.y = -40; break; case 1: // Right scientist.x = 2088; scientist.y = Math.random() * 2732; break; case 2: // Bottom scientist.x = Math.random() * 2048; scientist.y = 2772; break; case 3: // Left scientist.x = -40; scientist.y = Math.random() * 2732; break; } scientist.targetX = dog.x; scientist.targetY = dog.y; scientists.push(scientist); game.addChild(scientist); } function spawnPowerUp() { if (Math.random() < 0.02 && powerUps.length < 2) { var powerUp = new PowerUp(); powerUp.x = Math.random() * 1800 + 124; powerUp.y = Math.random() * 2400 + 166; powerUps.push(powerUp); game.addChild(powerUp); } } function spawnLoot(x, y) { var lootChance = Math.random(); var loot; if (lootChance < 0.5) { // 50% chance for metal loot = new Metal(); metals.push(loot); } else if (lootChance < 0.8) { // 30% chance for chest loot = new Chest(); chests.push(loot); } else { // 20% chance for technology loot = new Technology(); technologies.push(loot); } loot.x = x; loot.y = y; game.addChild(loot); } function spawnGoldFromChest(x, y) { // Spawn 2-3 gold pieces from chest var goldCount = Math.floor(Math.random() * 2) + 2; for (var i = 0; i < goldCount; i++) { var gold = new Gold(); gold.x = x + (Math.random() - 0.5) * 60; gold.y = y + (Math.random() - 0.5) * 60; golds.push(gold); game.addChild(gold); } } function handleMove(x, y, obj) { if (dragNode) { dragNode.x = Math.max(60, Math.min(1988, x)); dragNode.y = Math.max(60, Math.min(2672, y)); } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = dog; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { spawnTimer++; waveTimer++; if (waveTimer % 1800 === 0) { difficultyLevel++; lastSpawnRate = Math.max(30, lastSpawnRate - 10); } if (spawnTimer >= lastSpawnRate) { spawnScientist(); spawnTimer = 0; } spawnPowerUp(); for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.y < -50 || bullet.y > 2782 || bullet.x < -50 || bullet.x > 2098) { bullet.destroy(); bullets.splice(i, 1); continue; } for (var j = scientists.length - 1; j >= 0; j--) { var scientist = scientists[j]; if (bullet.intersects(scientist)) { if (scientist.takeDamage(bullet.damage)) { LK.setScore(LK.getScore() + scientist.points); updateScore(); spawnLoot(scientist.x, scientist.y); scientistResidues++; updateResidue(); // Track normal scientist deaths if (scientist.constructor === Scientist) { normalScientistDeaths++; } else if (scientist.constructor === FastScientist) { fastScientistDeaths++; } scientist.destroy(); scientists.splice(j, 1); LK.getSound('hit').play(); } bullet.destroy(); bullets.splice(i, 1); break; } } } for (var k = scientists.length - 1; k >= 0; k--) { var scientist = scientists[k]; if (!scientist) continue; // Skip if scientist is undefined scientist.targetX = dog.x; scientist.targetY = dog.y; if (scientist.intersects(dog)) { // Deduct half the score that the enemy would give when killed var scoreDeduction = Math.floor(scientist.points / 2); LK.setScore(Math.max(0, LK.getScore() - scoreDeduction)); updateScore(); // Check if it's an armed scientist (red) - trigger explosion if (scientist.constructor === ArmedScientist) { scientist.takeDamage(999); // Force explosion by dealing massive damage scientists.splice(k, 1); continue; } // Track hits by scientist type if (scientist.constructor === FastScientist) { fastScientistHits++; } else if (scientist.constructor === Scientist) { normalScientistHits++; } // Check death conditions if (normalScientistHits >= 5 || fastScientistHits >= 3) { LK.showGameOver(); } scientist.destroy(); scientists.splice(k, 1); continue; } var distanceToEdge = Math.min(scientist.x, 2048 - scientist.x, scientist.y, 2732 - scientist.y); if (distanceToEdge < -100) { scientist.destroy(); scientists.splice(k, 1); } } for (var l = powerUps.length - 1; l >= 0; l--) { var powerUp = powerUps[l]; if (powerUp.intersects(dog)) { LK.setScore(LK.getScore() + 2); updateScore(); dog.activatePowerUp(); LK.getSound('powerup').play(); powerUp.destroy(); powerUps.splice(l, 1); } } // Check metal collection for (var m = metals.length - 1; m >= 0; m--) { var metal = metals[m]; if (metal.intersects(dog)) { LK.setScore(LK.getScore() + metal.value); updateScore(); metal.destroy(); metals.splice(m, 1); } } // Check chest collection for (var c = chests.length - 1; c >= 0; c--) { var chest = chests[c]; if (chest.intersects(dog)) { LK.setScore(LK.getScore() + chest.value); updateScore(); // Spawn gold from chest spawnGoldFromChest(chest.x, chest.y); // Random chance for weapon upgrade if (Math.random() < 0.3) { dog.upgradeWeapon(); updateWeapon(); } chest.destroy(); chests.splice(c, 1); } } // Check technology collection for (var t = technologies.length - 1; t >= 0; t--) { var technology = technologies[t]; if (technology.intersects(dog)) { LK.setScore(LK.getScore() + technology.value); updateScore(); technology.destroy(); technologies.splice(t, 1); } } // Check gold collection for (var g = golds.length - 1; g >= 0; g--) { var gold = golds[g]; if (gold.intersects(dog)) { dog.gold += gold.value; updateGold(); gold.destroy(); golds.splice(g, 1); } } // Check steel ball collisions with dog for (var s = steelBalls.length - 1; s >= 0; s--) { var steelBall = steelBalls[s]; if (steelBall.y < -50 || steelBall.y > 2782 || steelBall.x < -50 || steelBall.x > 2098) { steelBall.destroy(); steelBalls.splice(s, 1); continue; } if (steelBall.intersects(dog)) { dog.takeDamage(); steelBall.destroy(); steelBalls.splice(s, 1); } } if (LK.ticks % 10 === 0 && dog.powerUpActive) { dog.shoot(); } }; LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ArmedScientist = Container.expand(function () {
var self = Container.call(this);
var scientistGraphics = self.attachAsset('scientist', {
anchorX: 0.5,
anchorY: 0.5
});
scientistGraphics.tint = 0xFF0000; // Red tint to distinguish armed scientists
self.speed = 2.5;
self.health = 7;
self.points = 4;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
// Mark as exploding to prevent multiple explosions
if (self.exploding) return true;
self.exploding = true;
// Check for ALL scientists to kill BEFORE starting animation
for (var i = scientists.length - 1; i >= 0; i--) {
var otherScientist = scientists[i];
if (otherScientist !== self && !otherScientist.exploding) {
// Kill ALL scientists on screen regardless of distance
if (otherScientist.constructor === Scientist || otherScientist.constructor === FastScientist || otherScientist.constructor === SteelBallScientist) {
LK.setScore(LK.getScore() + otherScientist.points);
updateScore();
spawnLoot(otherScientist.x, otherScientist.y);
scientistResidues++;
updateResidue();
// Track normal scientist deaths
if (otherScientist.constructor === Scientist) {
normalScientistDeaths++;
} else if (otherScientist.constructor === FastScientist) {
fastScientistDeaths++;
}
otherScientist.destroy();
scientists.splice(i, 1);
LK.getSound('hit').play();
}
}
}
// Check if dog is in explosion range
var dogDx = dog.x - self.x;
var dogDy = dog.y - self.y;
var dogDistance = Math.sqrt(dogDx * dogDx + dogDy * dogDy);
if (dogDistance <= explosionRange) {
// Reduce score by 20 points for being caught in explosion
LK.setScore(Math.max(0, LK.getScore() - 20));
updateScore();
// Kill the dog when caught in explosion
dog.health = 0;
LK.showGameOver();
}
// Give 50 score for detonating armed scientist
LK.setScore(LK.getScore() + 50);
updateScore();
// Create explosion animation
tween(self, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return true;
}
return false;
};
return self;
});
var Chest = Container.expand(function () {
var self = Container.call(this);
var chestGraphics = self.attachAsset('chest', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'chest';
self.value = 20;
self.update = function () {
self.rotation += 0.03;
};
return self;
});
var DirectionalButton = Container.expand(function (direction) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('dirButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = direction;
self.alpha = 0.7;
// Create arrow text based on direction
var arrowText = new Text2('', {
size: 90,
fill: 0xFFFFFF
});
arrowText.anchor.set(0.5, 0.5);
switch (direction) {
case 'up':
arrowText.setText('↑');
break;
case 'down':
arrowText.setText('↓');
break;
case 'left':
arrowText.setText('←');
break;
case 'right':
arrowText.setText('→');
break;
}
self.addChild(arrowText);
self.down = function (x, y, obj) {
currentShootDirection = self.direction;
self.alpha = 1.0;
// Reset other buttons
for (var i = 0; i < dirButtons.length; i++) {
if (dirButtons[i] !== self) {
dirButtons[i].alpha = 0.7;
}
}
// Fire bullet immediately when button is pressed
dog.shoot();
};
return self;
});
var Dog = Container.expand(function () {
var self = Container.call(this);
var dogGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
// Add gun icon
var gunIcon = self.attachAsset('dogBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
x: 60,
y: 0
});
gunIcon.tint = 0x888888; // Gray tint for gun icon
self.health = 3;
self.maxHealth = 3;
self.shootCooldown = 0;
self.shootRate = 20;
self.speed = 5;
self.powerUpActive = false;
self.powerUpEndTime = 0;
self.weaponType = 'knife';
self.weaponLevel = 1;
self.gold = 0;
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.powerUpActive && LK.now > self.powerUpEndTime) {
self.powerUpActive = false;
self.speed = 5;
self.shootRate = 20;
}
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new DogBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.weaponType = self.weaponType;
bullet.weaponLevel = self.weaponLevel;
// Set direction based on current shoot direction
switch (currentShootDirection) {
case 'up':
bullet.dirX = 0;
bullet.dirY = -1;
bullet.y -= 60;
break;
case 'down':
bullet.dirX = 0;
bullet.dirY = 1;
bullet.y += 60;
break;
case 'left':
bullet.dirX = -1;
bullet.dirY = 0;
bullet.x -= 60;
break;
case 'right':
bullet.dirX = 1;
bullet.dirY = 0;
bullet.x += 60;
break;
}
bullets.push(bullet);
game.addChild(bullet);
self.shootCooldown = self.shootRate;
LK.getSound('shoot').play();
}
};
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xFF0000, 500);
if (self.health <= 0) {
LK.showGameOver();
}
};
self.activatePowerUp = function () {
self.powerUpActive = true;
self.powerUpEndTime = LK.now + 5000;
self.speed = 8;
self.shootRate = 11;
};
self.upgradeWeapon = function () {
if (self.weaponLevel < 3) {
self.weaponLevel++;
if (self.weaponLevel === 2 && (scientistResidues >= 1000 || LK.getScore() >= 2000)) {
self.weaponType = 'laser';
self.shootRate = 13;
} else if (self.weaponLevel === 3) {
self.shootRate = 7;
}
}
};
return self;
});
var DogBullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 8;
self.damage = 1;
self.dirX = 0;
self.dirY = -1;
self.weaponType = 'knife';
self.weaponLevel = 1;
var bulletGraphics;
self.update = function () {
// Update graphics based on weapon type if not set
if (!bulletGraphics) {
if (self.weaponType === 'laser') {
bulletGraphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 2;
} else {
bulletGraphics = self.attachAsset('knife', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Set rotation based on direction
if (self.dirX === 1) bulletGraphics.rotation = Math.PI / 2;else if (self.dirX === -1) bulletGraphics.rotation = -Math.PI / 2;else if (self.dirY === 1) bulletGraphics.rotation = Math.PI;
}
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
var FastScientist = Container.expand(function () {
var self = Container.call(this);
var scientistGraphics = self.attachAsset('fastScientist', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 7.0;
self.health = 10;
self.points = 5;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var Gold = Container.expand(function () {
var self = Container.call(this);
var goldGraphics = self.attachAsset('gold', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'gold';
self.value = 10;
self.update = function () {
self.rotation += 0.06;
};
return self;
});
var Metal = Container.expand(function () {
var self = Container.call(this);
var metalGraphics = self.attachAsset('metal', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'metal';
self.value = 5;
self.update = function () {
self.rotation += 0.05;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'speed';
self.duration = 5000;
self.update = function () {
self.rotation += 0.1;
};
return self;
});
var Scientist = Container.expand(function () {
var self = Container.call(this);
var scientistGraphics = self.attachAsset('scientist', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 5;
self.points = 3;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var SteelBall = Container.expand(function () {
var self = Container.call(this);
var steelBallGraphics = self.attachAsset('dogBullet', {
anchorX: 0.5,
anchorY: 0.5
});
steelBallGraphics.tint = 0x808080; // Gray color for steel
self.speed = 4;
self.damage = 1;
self.dirX = 0;
self.dirY = 0;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
var SteelBallScientist = Container.expand(function () {
var self = Container.call(this);
var scientistGraphics = self.attachAsset('scientist', {
anchorX: 0.5,
anchorY: 0.5
});
scientistGraphics.tint = 0x4169E1; // Blue tint to distinguish steel ball scientists
self.speed = 2.5;
self.health = 8; // 8 hits with knife, 5 with laser (damage 2)
self.points = 6;
self.targetX = 0;
self.targetY = 0;
self.shootCooldown = 0;
self.shootRate = 60; // Shoot every 60 frames (1 second)
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Shooting logic
if (self.shootCooldown > 0) {
self.shootCooldown--;
} else {
// Shoot at dog
var steelBall = new SteelBall();
steelBall.x = self.x;
steelBall.y = self.y;
// Calculate direction to dog
var shootDistance = Math.sqrt(dx * dx + dy * dy);
if (shootDistance > 0) {
steelBall.dirX = dx / shootDistance;
steelBall.dirY = dy / shootDistance;
}
steelBalls.push(steelBall);
game.addChild(steelBall);
self.shootCooldown = self.shootRate;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var Technology = Container.expand(function () {
var self = Container.call(this);
var technologyGraphics = self.attachAsset('technology', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'technology';
self.value = 50;
self.update = function () {
self.rotation += 0.08;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var dog = new Dog();
var bullets = [];
var scientists = [];
var powerUps = [];
var metals = [];
var chests = [];
var technologies = [];
var golds = [];
var dirButtons = [];
var steelBalls = [];
var currentShootDirection = 'up';
var spawnTimer = 0;
var waveTimer = 0;
var difficultyLevel = 1;
var lastSpawnRate = 120;
var scientistResidues = 0;
var scientistCount = 0;
var normalScientistHits = 0;
var fastScientistHits = 0;
var fastScientistSpawned = 0;
var normalScientistDeaths = 0;
var fastScientistDeaths = 0;
var explosionRange = 200; // Range for armed scientist explosions
// Add laboratory background
var labBackground = LK.getAsset('labBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(labBackground);
dog.x = 1024;
dog.y = 2200;
game.addChild(dog);
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var goldTxt = new Text2('Gold: 0', {
size: 60,
fill: 0xFFD700
});
goldTxt.anchor.set(0, 0);
goldTxt.x = 150;
goldTxt.y = 120;
LK.gui.topLeft.addChild(goldTxt);
var weaponTxt = new Text2('Weapon: Knife Lv.1', {
size: 50,
fill: 0xFFFFFF
});
weaponTxt.anchor.set(0, 0);
weaponTxt.x = 150;
weaponTxt.y = 190;
LK.gui.topLeft.addChild(weaponTxt);
var residueTxt = new Text2('Residues: 0/1000 (Laser: 1000 residues or 2000 score)', {
size: 45,
fill: 0x00FF00
});
residueTxt.anchor.set(0, 0);
residueTxt.x = 150;
residueTxt.y = 250;
LK.gui.topLeft.addChild(residueTxt);
// Create directional buttons in main game area with proper spacing
var upBtn = new DirectionalButton('up');
upBtn.x = 300;
upBtn.y = 2350;
game.addChild(upBtn);
dirButtons.push(upBtn);
var downBtn = new DirectionalButton('down');
downBtn.x = 300;
downBtn.y = 2650;
game.addChild(downBtn);
dirButtons.push(downBtn);
var leftBtn = new DirectionalButton('left');
leftBtn.x = 150;
leftBtn.y = 2500;
game.addChild(leftBtn);
dirButtons.push(leftBtn);
var rightBtn = new DirectionalButton('right');
rightBtn.x = 450;
rightBtn.y = 2500;
game.addChild(rightBtn);
dirButtons.push(rightBtn);
// Set initial button state
upBtn.alpha = 1.0;
var dragNode = null;
function updateScore() {
scoreTxt.setText('Score: ' + LK.getScore());
}
function updateGold() {
goldTxt.setText('Gold: ' + dog.gold);
}
function updateWeapon() {
var weaponName = dog.weaponType === 'knife' ? 'Knife' : 'Laser';
weaponTxt.setText('Weapon: ' + weaponName + ' Lv.' + dog.weaponLevel);
}
function updateResidue() {
// Give 20 score for each scientist residue collected
LK.setScore(LK.getScore() + 20);
updateScore();
var laserUnlocked = scientistResidues >= 1000 || LK.getScore() >= 2000;
if (laserUnlocked) {
residueTxt.setText('Residues: ' + scientistResidues + '/1000 (LASER UNLOCKED!)');
} else {
residueTxt.setText('Residues: ' + scientistResidues + '/1000 (Laser: 1000 residues or 2000 score)');
}
}
function spawnScientist() {
var scientist;
scientistCount++;
if (fastScientistDeaths >= 6 && fastScientistDeaths % 6 === 0) {
scientist = new ArmedScientist();
fastScientistDeaths++; // Increment to avoid spawning multiple in a row
} else if (scientistCount % 10 === 0) {
scientist = new FastScientist();
fastScientistSpawned++;
// Spawn SteelBallScientist after every 5 fast scientists
if (fastScientistSpawned % 5 === 0) {
scientist = new SteelBallScientist();
}
} else {
scientist = new Scientist();
}
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
scientist.x = Math.random() * 2048;
scientist.y = -40;
break;
case 1:
// Right
scientist.x = 2088;
scientist.y = Math.random() * 2732;
break;
case 2:
// Bottom
scientist.x = Math.random() * 2048;
scientist.y = 2772;
break;
case 3:
// Left
scientist.x = -40;
scientist.y = Math.random() * 2732;
break;
}
scientist.targetX = dog.x;
scientist.targetY = dog.y;
scientists.push(scientist);
game.addChild(scientist);
}
function spawnPowerUp() {
if (Math.random() < 0.02 && powerUps.length < 2) {
var powerUp = new PowerUp();
powerUp.x = Math.random() * 1800 + 124;
powerUp.y = Math.random() * 2400 + 166;
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
function spawnLoot(x, y) {
var lootChance = Math.random();
var loot;
if (lootChance < 0.5) {
// 50% chance for metal
loot = new Metal();
metals.push(loot);
} else if (lootChance < 0.8) {
// 30% chance for chest
loot = new Chest();
chests.push(loot);
} else {
// 20% chance for technology
loot = new Technology();
technologies.push(loot);
}
loot.x = x;
loot.y = y;
game.addChild(loot);
}
function spawnGoldFromChest(x, y) {
// Spawn 2-3 gold pieces from chest
var goldCount = Math.floor(Math.random() * 2) + 2;
for (var i = 0; i < goldCount; i++) {
var gold = new Gold();
gold.x = x + (Math.random() - 0.5) * 60;
gold.y = y + (Math.random() - 0.5) * 60;
golds.push(gold);
game.addChild(gold);
}
}
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = Math.max(60, Math.min(1988, x));
dragNode.y = Math.max(60, Math.min(2672, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = dog;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
spawnTimer++;
waveTimer++;
if (waveTimer % 1800 === 0) {
difficultyLevel++;
lastSpawnRate = Math.max(30, lastSpawnRate - 10);
}
if (spawnTimer >= lastSpawnRate) {
spawnScientist();
spawnTimer = 0;
}
spawnPowerUp();
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.y < -50 || bullet.y > 2782 || bullet.x < -50 || bullet.x > 2098) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
for (var j = scientists.length - 1; j >= 0; j--) {
var scientist = scientists[j];
if (bullet.intersects(scientist)) {
if (scientist.takeDamage(bullet.damage)) {
LK.setScore(LK.getScore() + scientist.points);
updateScore();
spawnLoot(scientist.x, scientist.y);
scientistResidues++;
updateResidue();
// Track normal scientist deaths
if (scientist.constructor === Scientist) {
normalScientistDeaths++;
} else if (scientist.constructor === FastScientist) {
fastScientistDeaths++;
}
scientist.destroy();
scientists.splice(j, 1);
LK.getSound('hit').play();
}
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
for (var k = scientists.length - 1; k >= 0; k--) {
var scientist = scientists[k];
if (!scientist) continue; // Skip if scientist is undefined
scientist.targetX = dog.x;
scientist.targetY = dog.y;
if (scientist.intersects(dog)) {
// Deduct half the score that the enemy would give when killed
var scoreDeduction = Math.floor(scientist.points / 2);
LK.setScore(Math.max(0, LK.getScore() - scoreDeduction));
updateScore();
// Check if it's an armed scientist (red) - trigger explosion
if (scientist.constructor === ArmedScientist) {
scientist.takeDamage(999); // Force explosion by dealing massive damage
scientists.splice(k, 1);
continue;
}
// Track hits by scientist type
if (scientist.constructor === FastScientist) {
fastScientistHits++;
} else if (scientist.constructor === Scientist) {
normalScientistHits++;
}
// Check death conditions
if (normalScientistHits >= 5 || fastScientistHits >= 3) {
LK.showGameOver();
}
scientist.destroy();
scientists.splice(k, 1);
continue;
}
var distanceToEdge = Math.min(scientist.x, 2048 - scientist.x, scientist.y, 2732 - scientist.y);
if (distanceToEdge < -100) {
scientist.destroy();
scientists.splice(k, 1);
}
}
for (var l = powerUps.length - 1; l >= 0; l--) {
var powerUp = powerUps[l];
if (powerUp.intersects(dog)) {
LK.setScore(LK.getScore() + 2);
updateScore();
dog.activatePowerUp();
LK.getSound('powerup').play();
powerUp.destroy();
powerUps.splice(l, 1);
}
}
// Check metal collection
for (var m = metals.length - 1; m >= 0; m--) {
var metal = metals[m];
if (metal.intersects(dog)) {
LK.setScore(LK.getScore() + metal.value);
updateScore();
metal.destroy();
metals.splice(m, 1);
}
}
// Check chest collection
for (var c = chests.length - 1; c >= 0; c--) {
var chest = chests[c];
if (chest.intersects(dog)) {
LK.setScore(LK.getScore() + chest.value);
updateScore();
// Spawn gold from chest
spawnGoldFromChest(chest.x, chest.y);
// Random chance for weapon upgrade
if (Math.random() < 0.3) {
dog.upgradeWeapon();
updateWeapon();
}
chest.destroy();
chests.splice(c, 1);
}
}
// Check technology collection
for (var t = technologies.length - 1; t >= 0; t--) {
var technology = technologies[t];
if (technology.intersects(dog)) {
LK.setScore(LK.getScore() + technology.value);
updateScore();
technology.destroy();
technologies.splice(t, 1);
}
}
// Check gold collection
for (var g = golds.length - 1; g >= 0; g--) {
var gold = golds[g];
if (gold.intersects(dog)) {
dog.gold += gold.value;
updateGold();
gold.destroy();
golds.splice(g, 1);
}
}
// Check steel ball collisions with dog
for (var s = steelBalls.length - 1; s >= 0; s--) {
var steelBall = steelBalls[s];
if (steelBall.y < -50 || steelBall.y > 2782 || steelBall.x < -50 || steelBall.x > 2098) {
steelBall.destroy();
steelBalls.splice(s, 1);
continue;
}
if (steelBall.intersects(dog)) {
dog.takeDamage();
steelBall.destroy();
steelBalls.splice(s, 1);
}
}
if (LK.ticks % 10 === 0 && dog.powerUpActive) {
dog.shoot();
}
};
LK.playMusic('bgmusic');
Cabeza de perro labrador. In-Game asset. 2d. High contrast. No shadows
Láser azul. In-Game asset. 2d. High contrast. No shadows
Perrobala. In-Game asset. 2d. High contrast. No shadows
Huella de perro. In-Game asset. 2d. High contrast. No shadows
Vista desde arriba de un laboratorio. In-Game asset. 2d. High contrast. No shadows