User prompt
Elimina las texturas del suelo
User prompt
Ponerles texturas al suelo también
User prompt
Aumenta la velocidad de movimiento del jugador
User prompt
Hacer un perro ciborg aliado q nos va a ayudar a eliminar a los enemigos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Elimina algunas estructuras si es necesario para que el rendimiento no se vea afectado
User prompt
Aumenta la velocidad del jugador y has que sea cómodo de controlar y puedas moverte y disparar a la vez ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mejorar el rendimiento del jugador y su velocidad, añadir un botón circular para el moverlo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mejorar el movimiento del jugador ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Elimina alguna estructuras del mapa
User prompt
Optimizar el rendimiento
User prompt
Vamos a añadir estructuras al mapa con colisiones y texturas, añadir cosas como árboles, coches destruidos, rocas y así
User prompt
Agregar las texturas para los nuevo tipos de enemigos también
User prompt
Vamos a agregar mayor variedad de enemigos 2 o 3 más
Code edit (1 edits merged)
Please save this source code
User prompt
Cyborg Vengeance: Crystal Defense
Initial prompt
Un mundo **posapocalíptico** donde las máquinas se revelaron para acabar con los humanos, controlamos a un ciborg el cual quiere vengarse de las máquinas, entonces tendremos que sobrevivir a oleadas de enemigos diversos todos con características y patrones de ataques únicos, en un entorno interactivo inspirado en una ciudad en ruinas. Al morir los enemigos nos darán engranaje y algunos darán partes como: brazos, piernas y otras cosas que el jugador se podrá equipar pagando engranajes. Estas piezas mejorarán cosas como el ataque, la defensa, velocidad entre otras cosas. Todo esto mientras defiende un cristal en el centro de la ciudad el cual tiene una barrera y usaremos las baterías de los enemigos que nos atacan para recuperar la energía de la barrera, también estando cerca del cristal podremos curarnos
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Barrier = Container.expand(function () {
var self = Container.call(this);
var barrierGraphics = self.attachAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Update barrier visibility based on energy
var energyPercent = crystal.barrierEnergy / crystal.maxBarrierEnergy;
barrierGraphics.alpha = energyPercent * 0.3;
if (energyPercent > 0.5) {
barrierGraphics.tint = 0x00FFFF;
} else if (energyPercent > 0.25) {
barrierGraphics.tint = 0xFFFF00;
} else {
barrierGraphics.tint = 0xFF4500;
}
};
return self;
});
var Battery = Container.expand(function () {
var self = Container.call(this);
var batteryGraphics = self.attachAsset('battery', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Check if cyborg is close enough to collect
var distToCyborg = Math.sqrt(Math.pow(self.x - cyborg.x, 2) + Math.pow(self.y - cyborg.y, 2));
if (distToCyborg < 40) {
crystal.restoreBarrier(20);
LK.getSound('collect').play();
// Remove from batteries array
for (var i = batteries.length - 1; i >= 0; i--) {
if (batteries[i] === self) {
batteries.splice(i, 1);
break;
}
}
self.destroy();
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = 25;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
enemy.takeDamage(self.damage);
// Remove bullet
for (var j = bullets.length - 1; j >= 0; j--) {
if (bullets[j] === self) {
bullets.splice(j, 1);
break;
}
}
self.destroy();
return;
}
}
// Check collision with structures
for (var s = structures.length - 1; s >= 0; s--) {
if (self.intersects(structures[s])) {
// Remove bullet
for (var p = bullets.length - 1; p >= 0; p--) {
if (bullets[p] === self) {
bullets.splice(p, 1);
break;
}
}
self.destroy();
return;
}
}
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
for (var k = bullets.length - 1; k >= 0; k--) {
if (bullets[k] === self) {
bullets.splice(k, 1);
break;
}
}
self.destroy();
}
};
return self;
});
var Crystal = Container.expand(function () {
var self = Container.call(this);
var crystalGraphics = self.attachAsset('crystal', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 500;
self.maxHealth = 500;
self.barrierEnergy = 100;
self.maxBarrierEnergy = 100;
self.takeDamage = function (damage) {
if (self.barrierEnergy > 0) {
self.barrierEnergy -= damage;
if (self.barrierEnergy < 0) {
var overflow = -self.barrierEnergy;
self.barrierEnergy = 0;
self.health -= overflow;
}
} else {
self.health -= damage;
}
crystalHealthText.setText('Crystal: ' + Math.floor(self.health));
barrierText.setText('Barrier: ' + Math.floor(self.barrierEnergy));
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
LK.showGameOver();
}
};
self.restoreBarrier = function (amount) {
self.barrierEnergy += amount;
if (self.barrierEnergy > self.maxBarrierEnergy) {
self.barrierEnergy = self.maxBarrierEnergy;
}
barrierText.setText('Barrier: ' + Math.floor(self.barrierEnergy));
};
return self;
});
var Cyborg = Container.expand(function () {
var self = Container.call(this);
var cyborgGraphics = self.attachAsset('cyborg', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 3;
self.attackDamage = 25;
self.shootCooldown = 0;
self.isNearCrystal = false;
self.update = function () {
// Check if near crystal for healing
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
self.isNearCrystal = distToCrystal < 150;
// Heal when near crystal
if (self.isNearCrystal && self.health < self.maxHealth) {
self.health += 0.5;
if (self.health > self.maxHealth) self.health = self.maxHealth;
healthText.setText('Health: ' + Math.floor(self.health));
}
// Reduce shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Visual feedback when near crystal
if (self.isNearCrystal) {
cyborgGraphics.tint = 0x90EE90;
} else {
cyborgGraphics.tint = 0xFFFFFF;
}
};
self.shoot = function (targetX, targetY) {
if (self.shootCooldown <= 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(targetY - self.y, targetX - self.x);
bullet.velocityX = Math.cos(angle) * 8;
bullet.velocityY = Math.sin(angle) * 8;
bullets.push(bullet);
game.addChild(bullet);
self.shootCooldown = 20;
LK.getSound('shoot').play();
}
};
self.takeDamage = function (damage) {
self.health -= damage;
healthText.setText('Health: ' + Math.floor(self.health));
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 1;
self.attackDamage = 15;
self.attackCooldown = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move towards crystal
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
var newX = self.x + Math.cos(angle) * self.speed;
var newY = self.y + Math.sin(angle) * self.speed;
// Check structure collision
if (!checkStructureCollision(self, newX, newY)) {
self.x = newX;
self.y = newY;
} else {
// Try to move around obstacle
var sideAngle = angle + Math.PI / 2;
var sideX = self.x + Math.cos(sideAngle) * self.speed;
var sideY = self.y + Math.sin(sideAngle) * self.speed;
if (!checkStructureCollision(self, sideX, sideY)) {
self.x = sideX;
self.y = sideY;
}
}
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
self.attackCooldown = 60;
LK.effects.flashObject(self, 0xFFFFFF, 200);
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Drop gear
var gear = new Gear();
gear.x = self.x;
gear.y = self.y;
gears.push(gear);
game.addChild(gear);
// Sometimes drop battery
if (Math.random() < 0.3) {
var battery = new Battery();
battery.x = self.x + (Math.random() - 0.5) * 40;
battery.y = self.y + (Math.random() - 0.5) * 40;
batteries.push(battery);
game.addChild(battery);
}
LK.getSound('enemyHit').play();
// Remove from enemies array
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xFF0000; // Red tint for enemy bullets
self.velocityX = 0;
self.velocityY = 0;
self.damage = 20;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with cyborg
if (self.intersects(cyborg)) {
cyborg.takeDamage(self.damage);
// Remove bullet
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
self.destroy();
return;
}
// Check collision with structures
for (var s = structures.length - 1; s >= 0; s--) {
if (self.intersects(structures[s])) {
// Remove bullet
for (var p = enemyBullets.length - 1; p >= 0; p--) {
if (enemyBullets[p] === self) {
enemyBullets.splice(p, 1);
break;
}
}
self.destroy();
return;
}
}
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
for (var j = enemyBullets.length - 1; j >= 0; j--) {
if (enemyBullets[j] === self) {
enemyBullets.splice(j, 1);
break;
}
}
self.destroy();
}
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 30;
self.speed = 2.5;
self.attackDamage = 10;
self.attackCooldown = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move towards crystal with erratic movement
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
var wobble = Math.sin(LK.ticks * 0.1) * 0.5;
var newX = self.x + Math.cos(angle + wobble) * self.speed;
var newY = self.y + Math.sin(angle + wobble) * self.speed;
// Check structure collision
if (!checkStructureCollision(self, newX, newY)) {
self.x = newX;
self.y = newY;
} else {
// Try to move around obstacle
var sideAngle = angle + Math.PI / 2;
var sideX = self.x + Math.cos(sideAngle) * self.speed;
var sideY = self.y + Math.sin(sideAngle) * self.speed;
if (!checkStructureCollision(self, sideX, sideY)) {
self.x = sideX;
self.y = sideY;
}
}
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
self.attackCooldown = 40;
LK.effects.flashObject(self, 0xFFFFFF, 200);
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Drop gear
var gear = new Gear();
gear.x = self.x;
gear.y = self.y;
gears.push(gear);
game.addChild(gear);
// Sometimes drop battery
if (Math.random() < 0.25) {
var battery = new Battery();
battery.x = self.x + (Math.random() - 0.5) * 40;
battery.y = self.y + (Math.random() - 0.5) * 40;
batteries.push(battery);
game.addChild(battery);
}
LK.getSound('enemyHit').play();
// Remove from enemies array
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var Gear = Container.expand(function () {
var self = Container.call(this);
var gearGraphics = self.attachAsset('gear', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
gearGraphics.rotation += 0.1;
// Check if cyborg is close enough to collect
var distToCyborg = Math.sqrt(Math.pow(self.x - cyborg.x, 2) + Math.pow(self.y - cyborg.y, 2));
if (distToCyborg < 40) {
gearCount++;
gearsText.setText('Gears: ' + gearCount);
LK.getSound('collect').play();
// Remove from gears array
for (var i = gears.length - 1; i >= 0; i--) {
if (gears[i] === self) {
gears.splice(i, 1);
break;
}
}
self.destroy();
}
};
return self;
});
var RangedEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('rangedEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 40;
self.speed = 1.2;
self.attackDamage = 12;
self.attackCooldown = 0;
self.shootCooldown = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Stay at medium distance from crystal
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
if (distToCrystal > 400) {
// Move closer
var newX = self.x + Math.cos(angle) * self.speed;
var newY = self.y + Math.sin(angle) * self.speed;
if (!checkStructureCollision(self, newX, newY)) {
self.x = newX;
self.y = newY;
}
} else if (distToCrystal < 300) {
// Move away
var newX = self.x - Math.cos(angle) * self.speed;
var newY = self.y - Math.sin(angle) * self.speed;
if (!checkStructureCollision(self, newX, newY)) {
self.x = newX;
self.y = newY;
}
}
// Shoot at cyborg
if (self.shootCooldown <= 0) {
var distToCyborg = Math.sqrt(Math.pow(self.x - cyborg.x, 2) + Math.pow(self.y - cyborg.y, 2));
if (distToCyborg < 500) {
self.shootAtCyborg();
self.shootCooldown = 120;
}
}
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Attack crystal if close enough
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
self.attackCooldown = 60;
LK.effects.flashObject(self, 0xFFFFFF, 200);
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
self.shootAtCyborg = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(cyborg.y - self.y, cyborg.x - self.x);
bullet.velocityX = Math.cos(angle) * 4;
bullet.velocityY = Math.sin(angle) * 4;
enemyBullets.push(bullet);
game.addChild(bullet);
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Drop gear
var gear = new Gear();
gear.x = self.x;
gear.y = self.y;
gears.push(gear);
game.addChild(gear);
// Sometimes drop battery
if (Math.random() < 0.3) {
var battery = new Battery();
battery.x = self.x + (Math.random() - 0.5) * 40;
battery.y = self.y + (Math.random() - 0.5) * 40;
batteries.push(battery);
game.addChild(battery);
}
LK.getSound('enemyHit').play();
// Remove from enemies array
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var Structure = Container.expand(function (type) {
var self = Container.call(this);
var structureGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.structureType = type;
return self;
});
var TankEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 120;
self.speed = 0.7;
self.attackDamage = 30;
self.attackCooldown = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move towards crystal steadily
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
var newX = self.x + Math.cos(angle) * self.speed;
var newY = self.y + Math.sin(angle) * self.speed;
// Check structure collision
if (!checkStructureCollision(self, newX, newY)) {
self.x = newX;
self.y = newY;
} else {
// Try to move around obstacle
var sideAngle = angle + Math.PI / 2;
var sideX = self.x + Math.cos(sideAngle) * self.speed;
var sideY = self.y + Math.sin(sideAngle) * self.speed;
if (!checkStructureCollision(self, sideX, sideY)) {
self.x = sideX;
self.y = sideY;
}
}
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
self.attackCooldown = 90;
LK.effects.flashObject(self, 0xFFFFFF, 300);
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
self.takeDamage = function (damage) {
self.health -= Math.floor(damage * 0.7); // Reduced damage
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Drop more gear
var gear = new Gear();
gear.x = self.x;
gear.y = self.y;
gears.push(gear);
game.addChild(gear);
// Drop extra gear
if (Math.random() < 0.6) {
var gear2 = new Gear();
gear2.x = self.x + (Math.random() - 0.5) * 30;
gear2.y = self.y + (Math.random() - 0.5) * 30;
gears.push(gear2);
game.addChild(gear2);
}
// Sometimes drop battery
if (Math.random() < 0.4) {
var battery = new Battery();
battery.x = self.x + (Math.random() - 0.5) * 40;
battery.y = self.y + (Math.random() - 0.5) * 40;
batteries.push(battery);
game.addChild(battery);
}
LK.getSound('enemyHit').play();
// Remove from enemies array
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F2F2F
});
/****
* Game Code
****/
// Game variables
var cyborg;
var crystal;
var barrier;
var enemies = [];
var bullets = [];
var enemyBullets = [];
var gears = [];
var batteries = [];
var structures = [];
var gearCount = 0;
var waveNumber = 1;
var enemySpawnTimer = 0;
var enemiesPerWave = 5;
var waveTimer = 0;
var waveDelay = 300;
// UI elements
var healthText = new Text2('Health: 100', {
size: 40,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
healthText.x = 120;
healthText.y = 50;
LK.gui.topLeft.addChild(healthText);
var crystalHealthText = new Text2('Crystal: 500', {
size: 40,
fill: 0x00FFFF
});
crystalHealthText.anchor.set(0.5, 0);
crystalHealthText.x = 1024;
crystalHealthText.y = 50;
LK.gui.top.addChild(crystalHealthText);
var barrierText = new Text2('Barrier: 100', {
size: 40,
fill: 0x00FFFF
});
barrierText.anchor.set(1, 0);
barrierText.x = 1928;
barrierText.y = 50;
LK.gui.topRight.addChild(barrierText);
var gearsText = new Text2('Gears: 0', {
size: 40,
fill: 0xFFD700
});
gearsText.anchor.set(0, 0);
gearsText.x = 120;
gearsText.y = 100;
LK.gui.topLeft.addChild(gearsText);
var waveText = new Text2('Wave: 1', {
size: 40,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.x = 1024;
waveText.y = 100;
LK.gui.top.addChild(waveText);
// Initialize game objects
crystal = game.addChild(new Crystal());
crystal.x = 1024;
crystal.y = 1366;
barrier = game.addChild(new Barrier());
barrier.x = crystal.x;
barrier.y = crystal.y;
cyborg = game.addChild(new Cyborg());
cyborg.x = 1024;
cyborg.y = 1200;
// Create map structures
createMapStructures();
// Event handlers
game.down = function (x, y, obj) {
cyborg.shoot(x, y);
};
game.move = function (x, y, obj) {
var dx = x - cyborg.x;
var dy = y - cyborg.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var newX = cyborg.x + dx / distance * cyborg.speed;
var newY = cyborg.y + dy / distance * cyborg.speed;
// Check structure collision
if (!checkStructureCollision(cyborg, newX, newY)) {
cyborg.x = newX;
cyborg.y = newY;
}
// Keep cyborg within screen bounds
if (cyborg.x < 40) cyborg.x = 40;
if (cyborg.x > 2008) cyborg.x = 2008;
if (cyborg.y < 40) cyborg.y = 40;
if (cyborg.y > 2692) cyborg.y = 2692;
}
};
function createMapStructures() {
// Create trees
var treePositions = [{
x: 300,
y: 400
}, {
x: 800,
y: 600
}, {
x: 1500,
y: 800
}, {
x: 400,
y: 1200
}, {
x: 1700,
y: 1100
}, {
x: 200,
y: 1800
}, {
x: 1200,
y: 2000
}, {
x: 1800,
y: 2200
}];
for (var i = 0; i < treePositions.length; i++) {
var tree = new Structure('tree');
tree.x = treePositions[i].x;
tree.y = treePositions[i].y;
structures.push(tree);
game.addChild(tree);
}
// Create destroyed cars
var carPositions = [{
x: 600,
y: 500
}, {
x: 1400,
y: 700
}, {
x: 900,
y: 1500
}, {
x: 1600,
y: 1800
}, {
x: 500,
y: 2100
}];
for (var j = 0; j < carPositions.length; j++) {
var car = new Structure('destroyedCar');
car.x = carPositions[j].x;
car.y = carPositions[j].y;
structures.push(car);
game.addChild(car);
}
// Create rocks
var rockPositions = [{
x: 250,
y: 600
}, {
x: 700,
y: 900
}, {
x: 1300,
y: 1200
}, {
x: 1800,
y: 1500
}, {
x: 400,
y: 1900
}, {
x: 1100,
y: 2300
}];
for (var k = 0; k < rockPositions.length; k++) {
var rock = new Structure('rock');
rock.x = rockPositions[k].x;
rock.y = rockPositions[k].y;
structures.push(rock);
game.addChild(rock);
}
}
function spawnEnemy() {
var enemy;
// Randomly choose enemy type based on wave number
var enemyType = Math.random();
if (enemyType < 0.4) {
enemy = new Enemy();
} else if (enemyType < 0.7) {
enemy = new FastEnemy();
} else if (enemyType < 0.9) {
enemy = new RangedEnemy();
} else {
enemy = new TankEnemy();
}
// Spawn from random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -30;
break;
case 1:
// Right
enemy.x = 2078;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2762;
break;
case 3:
// Left
enemy.x = -30;
enemy.y = Math.random() * 2732;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
function checkStructureCollision(obj, newX, newY) {
var tempX = obj.x;
var tempY = obj.y;
obj.x = newX;
obj.y = newY;
for (var i = 0; i < structures.length; i++) {
if (obj.intersects(structures[i])) {
obj.x = tempX;
obj.y = tempY;
return true;
}
}
return false;
}
function startNewWave() {
waveNumber++;
waveText.setText('Wave: ' + waveNumber);
enemiesPerWave = Math.floor(5 + waveNumber * 1.5);
waveTimer = 0;
// Spawn enemies for this wave
for (var i = 0; i < enemiesPerWave; i++) {
LK.setTimeout(function () {
spawnEnemy();
}, i * 1000);
}
}
// Main game loop
game.update = function () {
// Update wave timer
waveTimer++;
// Check if wave is complete (no enemies left and enough time passed)
if (enemies.length === 0 && waveTimer > waveDelay) {
startNewWave();
}
// Update all bullets
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
}
// Update all enemy bullets
for (var m = enemyBullets.length - 1; m >= 0; m--) {
enemyBullets[m].update();
}
// Update all enemies
for (var j = enemies.length - 1; j >= 0; j--) {
enemies[j].update();
}
// Update all gears
for (var k = gears.length - 1; k >= 0; k--) {
gears[k].update();
}
// Update all batteries
for (var l = batteries.length - 1; l >= 0; l--) {
batteries[l].update();
}
// Update cyborg
cyborg.update();
// Update barrier
barrier.update();
};
// Start first wave
LK.setTimeout(function () {
startNewWave();
}, 2000); ===================================================================
--- original.js
+++ change.js
@@ -77,8 +77,22 @@
self.destroy();
return;
}
}
+ // Check collision with structures
+ for (var s = structures.length - 1; s >= 0; s--) {
+ if (self.intersects(structures[s])) {
+ // Remove bullet
+ for (var p = bullets.length - 1; p >= 0; p--) {
+ if (bullets[p] === self) {
+ bullets.splice(p, 1);
+ break;
+ }
+ }
+ self.destroy();
+ return;
+ }
+ }
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
for (var k = bullets.length - 1; k >= 0; k--) {
if (bullets[k] === self) {
@@ -201,10 +215,24 @@
self.lastX = self.x;
self.lastY = self.y;
// Move towards crystal
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
- self.x += Math.cos(angle) * self.speed;
- self.y += Math.sin(angle) * self.speed;
+ var newX = self.x + Math.cos(angle) * self.speed;
+ var newY = self.y + Math.sin(angle) * self.speed;
+ // Check structure collision
+ if (!checkStructureCollision(self, newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ } else {
+ // Try to move around obstacle
+ var sideAngle = angle + Math.PI / 2;
+ var sideX = self.x + Math.cos(sideAngle) * self.speed;
+ var sideY = self.y + Math.sin(sideAngle) * self.speed;
+ if (!checkStructureCollision(self, sideX, sideY)) {
+ self.x = sideX;
+ self.y = sideY;
+ }
+ }
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
@@ -274,8 +302,22 @@
}
self.destroy();
return;
}
+ // Check collision with structures
+ for (var s = structures.length - 1; s >= 0; s--) {
+ if (self.intersects(structures[s])) {
+ // Remove bullet
+ for (var p = enemyBullets.length - 1; p >= 0; p--) {
+ if (enemyBullets[p] === self) {
+ enemyBullets.splice(p, 1);
+ break;
+ }
+ }
+ self.destroy();
+ return;
+ }
+ }
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
for (var j = enemyBullets.length - 1; j >= 0; j--) {
if (enemyBullets[j] === self) {
@@ -305,10 +347,24 @@
self.lastY = self.y;
// Move towards crystal with erratic movement
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
var wobble = Math.sin(LK.ticks * 0.1) * 0.5;
- self.x += Math.cos(angle + wobble) * self.speed;
- self.y += Math.sin(angle + wobble) * self.speed;
+ var newX = self.x + Math.cos(angle + wobble) * self.speed;
+ var newY = self.y + Math.sin(angle + wobble) * self.speed;
+ // Check structure collision
+ if (!checkStructureCollision(self, newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ } else {
+ // Try to move around obstacle
+ var sideAngle = angle + Math.PI / 2;
+ var sideX = self.x + Math.cos(sideAngle) * self.speed;
+ var sideY = self.y + Math.sin(sideAngle) * self.speed;
+ if (!checkStructureCollision(self, sideX, sideY)) {
+ self.x = sideX;
+ self.y = sideY;
+ }
+ }
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
@@ -399,14 +455,22 @@
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
if (distToCrystal > 400) {
// Move closer
- self.x += Math.cos(angle) * self.speed;
- self.y += Math.sin(angle) * self.speed;
+ var newX = self.x + Math.cos(angle) * self.speed;
+ var newY = self.y + Math.sin(angle) * self.speed;
+ if (!checkStructureCollision(self, newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ }
} else if (distToCrystal < 300) {
// Move away
- self.x -= Math.cos(angle) * self.speed;
- self.y -= Math.sin(angle) * self.speed;
+ var newX = self.x - Math.cos(angle) * self.speed;
+ var newY = self.y - Math.sin(angle) * self.speed;
+ if (!checkStructureCollision(self, newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ }
}
// Shoot at cyborg
if (self.shootCooldown <= 0) {
var distToCyborg = Math.sqrt(Math.pow(self.x - cyborg.x, 2) + Math.pow(self.y - cyborg.y, 2));
@@ -471,8 +535,17 @@
self.destroy();
};
return self;
});
+var Structure = Container.expand(function (type) {
+ var self = Container.call(this);
+ var structureGraphics = self.attachAsset(type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.structureType = type;
+ return self;
+});
var TankEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
@@ -488,10 +561,24 @@
self.lastX = self.x;
self.lastY = self.y;
// Move towards crystal steadily
var angle = Math.atan2(crystal.y - self.y, crystal.x - self.x);
- self.x += Math.cos(angle) * self.speed;
- self.y += Math.sin(angle) * self.speed;
+ var newX = self.x + Math.cos(angle) * self.speed;
+ var newY = self.y + Math.sin(angle) * self.speed;
+ // Check structure collision
+ if (!checkStructureCollision(self, newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ } else {
+ // Try to move around obstacle
+ var sideAngle = angle + Math.PI / 2;
+ var sideX = self.x + Math.cos(sideAngle) * self.speed;
+ var sideY = self.y + Math.sin(sideAngle) * self.speed;
+ if (!checkStructureCollision(self, sideX, sideY)) {
+ self.x = sideX;
+ self.y = sideY;
+ }
+ }
// Attack crystal if close enough
var distToCrystal = Math.sqrt(Math.pow(self.x - crystal.x, 2) + Math.pow(self.y - crystal.y, 2));
if (distToCrystal < 160 && self.attackCooldown <= 0) {
crystal.takeDamage(self.attackDamage);
@@ -563,8 +650,9 @@
var bullets = [];
var enemyBullets = [];
var gears = [];
var batteries = [];
+var structures = [];
var gearCount = 0;
var waveNumber = 1;
var enemySpawnTimer = 0;
var enemiesPerWave = 5;
@@ -620,8 +708,10 @@
barrier.y = crystal.y;
cyborg = game.addChild(new Cyborg());
cyborg.x = 1024;
cyborg.y = 1200;
+// Create map structures
+createMapStructures();
// Event handlers
game.down = function (x, y, obj) {
cyborg.shoot(x, y);
};
@@ -629,17 +719,108 @@
var dx = x - cyborg.x;
var dy = y - cyborg.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
- cyborg.x += dx / distance * cyborg.speed;
- cyborg.y += dy / distance * cyborg.speed;
+ var newX = cyborg.x + dx / distance * cyborg.speed;
+ var newY = cyborg.y + dy / distance * cyborg.speed;
+ // Check structure collision
+ if (!checkStructureCollision(cyborg, newX, newY)) {
+ cyborg.x = newX;
+ cyborg.y = newY;
+ }
// Keep cyborg within screen bounds
if (cyborg.x < 40) cyborg.x = 40;
if (cyborg.x > 2008) cyborg.x = 2008;
if (cyborg.y < 40) cyborg.y = 40;
if (cyborg.y > 2692) cyborg.y = 2692;
}
};
+function createMapStructures() {
+ // Create trees
+ var treePositions = [{
+ x: 300,
+ y: 400
+ }, {
+ x: 800,
+ y: 600
+ }, {
+ x: 1500,
+ y: 800
+ }, {
+ x: 400,
+ y: 1200
+ }, {
+ x: 1700,
+ y: 1100
+ }, {
+ x: 200,
+ y: 1800
+ }, {
+ x: 1200,
+ y: 2000
+ }, {
+ x: 1800,
+ y: 2200
+ }];
+ for (var i = 0; i < treePositions.length; i++) {
+ var tree = new Structure('tree');
+ tree.x = treePositions[i].x;
+ tree.y = treePositions[i].y;
+ structures.push(tree);
+ game.addChild(tree);
+ }
+ // Create destroyed cars
+ var carPositions = [{
+ x: 600,
+ y: 500
+ }, {
+ x: 1400,
+ y: 700
+ }, {
+ x: 900,
+ y: 1500
+ }, {
+ x: 1600,
+ y: 1800
+ }, {
+ x: 500,
+ y: 2100
+ }];
+ for (var j = 0; j < carPositions.length; j++) {
+ var car = new Structure('destroyedCar');
+ car.x = carPositions[j].x;
+ car.y = carPositions[j].y;
+ structures.push(car);
+ game.addChild(car);
+ }
+ // Create rocks
+ var rockPositions = [{
+ x: 250,
+ y: 600
+ }, {
+ x: 700,
+ y: 900
+ }, {
+ x: 1300,
+ y: 1200
+ }, {
+ x: 1800,
+ y: 1500
+ }, {
+ x: 400,
+ y: 1900
+ }, {
+ x: 1100,
+ y: 2300
+ }];
+ for (var k = 0; k < rockPositions.length; k++) {
+ var rock = new Structure('rock');
+ rock.x = rockPositions[k].x;
+ rock.y = rockPositions[k].y;
+ structures.push(rock);
+ game.addChild(rock);
+ }
+}
function spawnEnemy() {
var enemy;
// Randomly choose enemy type based on wave number
var enemyType = Math.random();
@@ -678,8 +859,22 @@
}
enemies.push(enemy);
game.addChild(enemy);
}
+function checkStructureCollision(obj, newX, newY) {
+ var tempX = obj.x;
+ var tempY = obj.y;
+ obj.x = newX;
+ obj.y = newY;
+ for (var i = 0; i < structures.length; i++) {
+ if (obj.intersects(structures[i])) {
+ obj.x = tempX;
+ obj.y = tempY;
+ return true;
+ }
+ }
+ return false;
+}
function startNewWave() {
waveNumber++;
waveText.setText('Wave: ' + waveNumber);
enemiesPerWave = Math.floor(5 + waveNumber * 1.5);
Un cibor visto desde arriba con una escopeta en las manos. In-Game asset. 2d. High contrast. No shadows
Cristal magico visto desde arriba. In-Game asset. 2d. High contrast. No shadows
Roca vista desde arriba. In-Game asset. 2d. High contrast. No shadows
Arbol visto desde arriba algo oscuro. In-Game asset. 2d. High contrast. No shadows
Coche destruido, algo retro visto desde arriba y en posición horizontal. In-Game asset. 2d. High contrast. No shadows
Perro ciborg visto desde arriba. In-Game asset. 2d. High contrast. No shadows