User prompt
all demons appear in 60 seconds
User prompt
los demonios aparezcan dentro de 12 segundos
User prompt
los demonios se tarden 12 segundos en aparecer
User prompt
haz que los demonios aparezcan en 12 segundo y aumenta en 1 casilla en rango de todos los golems y que el heavy golem cueste 250 Stones y que las Stones aparezcan mas rapido
User prompt
haz que los demonios ignoren al spikeGolem y que los golems solo puedan atacar en su propia fila y que los demonios aparezcan en 12 segundos y que el basicGolem cueste 100 Stones y que las Stones desaparescan en 5 segundos despues de aparecer ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
mejor haz que los demonios aguanten 12 disparos
User prompt
haz que los demonios puedan comerse a los golems mordiendolos 15 veces y que los demonios tarden 12 segundos en aparecer y que salgan Stones del suelo que los puedas recoger y te den 5 Stones ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz el rango del basicGolem sea de 3 casillas y los demonios aguanten 10 disparos
User prompt
haz que el spikeGolem no mate al instante a los demonios
User prompt
haz que el spikeGolem haga poco daño y que los zombies lo ignoren
User prompt
añade a un golem que sea como la pincho hierba de pvz y que los demonios sean mas resistentes
User prompt
haz que el crystalGolem haga menos daño, pero dispare mas rapido y tenga mas rango
User prompt
haz las casillas de pasto mas grandes y aumenta un poco el rango de los golems
User prompt
haz a los iconos de colocar golems mucho mas grandes y mas separados
User prompt
haz el icono de los golems mas grandes y añade una pala para quitar a los golems
User prompt
reduce la velocidad de los demonios y aumenta el rango de los golems
Code edit (1 edits merged)
Please save this source code
User prompt
Stone Guardians vs Demons
Initial prompt
puedes hacer un juego estilo plantas versus zombies, pero que sea golems de piedra versus demonio
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Demon = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'basic';
self.health = 80;
self.maxHealth = 80;
self.speed = 0.5;
self.reward = 10;
var assetName = 'basicDemon';
if (self.type === 'fast') {
assetName = 'fastDemon';
self.health = 60;
self.maxHealth = 60;
self.speed = 1;
self.reward = 15;
} else if (self.type === 'tank') {
assetName = 'tankDemon';
self.health = 200;
self.maxHealth = 200;
self.speed = 0.25;
self.reward = 25;
}
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Check for barrier collision
var blocked = false;
for (var i = 0; i < golems.length; i++) {
var golem = golems[i];
if (golem.type === 'barrier' && self.intersects(golem)) {
blocked = true;
break;
}
}
if (!blocked) {
self.x -= self.speed;
}
// Update health bar color
var healthPercent = self.health / self.maxHealth;
if (healthPercent < 0.3) {
graphics.tint = 0xFF0000;
} else if (healthPercent < 0.6) {
graphics.tint = 0xFF6600;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('hit').play();
if (self.health <= 0) {
self.shouldRemove = true;
stones += self.reward;
score += self.reward;
updateUI();
}
};
return self;
});
var Golem = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'basic';
self.lastShot = 0;
self.range = 250;
self.damage = 25;
self.shootDelay = 60; // frames
var assetName = 'basicGolem';
if (self.type === 'heavy') {
assetName = 'heavyGolem';
self.damage = 50;
self.range = 230;
self.shootDelay = 90;
} else if (self.type === 'crystal') {
assetName = 'crystalGolem';
self.damage = 20;
self.range = 350;
self.shootDelay = 30;
} else if (self.type === 'barrier') {
assetName = 'barrierGolem';
self.damage = 0;
self.range = 0;
self.shootDelay = 0;
} else if (self.type === 'spike') {
assetName = 'spikeGolem';
self.damage = 10;
self.range = 0;
self.shootDelay = 0;
}
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.type === 'barrier') return;
if (self.type === 'spike') {
// Check for contact damage with cooldown
if (!self.damageCooldown) self.damageCooldown = {};
for (var i = 0; i < demons.length; i++) {
var demon = demons[i];
if (self.intersects(demon)) {
var demonId = demon.id || i; // Use demon id or index as identifier
var currentTime = LK.ticks;
if (!self.damageCooldown[demonId] || currentTime - self.damageCooldown[demonId] > 60) {
demon.takeDamage(self.damage);
self.damageCooldown[demonId] = currentTime;
}
}
}
return;
}
if (LK.ticks - self.lastShot > self.shootDelay) {
var target = self.findTarget();
if (target) {
self.shoot(target);
self.lastShot = LK.ticks;
}
}
};
self.findTarget = function () {
var closestDemon = null;
var closestDistance = self.range;
for (var i = 0; i < demons.length; i++) {
var demon = demons[i];
var dx = demon.x - self.x;
var dy = demon.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDistance) {
closestDistance = distance;
closestDemon = demon;
}
}
return closestDemon;
};
self.shoot = function (target) {
var projectile = new Projectile();
projectile.x = self.x;
projectile.y = self.y;
projectile.targetX = target.x;
projectile.targetY = target.y;
projectile.damage = self.damage;
projectiles.push(projectile);
game.addChild(projectile);
LK.getSound('shoot').play();
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 25;
self.speed = 8;
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 < 10) {
self.shouldRemove = true;
return;
}
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F5233
});
/****
* Game Code
****/
// Game variables
var stones = 100;
var score = 0;
var lives = 10;
var wave = 1;
var nextWaveTimer = 0;
var waveDelay = 300; // frames between waves
// Game arrays
var golems = [];
var demons = [];
var projectiles = [];
// Grid system
var gridCols = 8;
var gridRows = 5;
var gridStartX = 400;
var gridStartY = 800;
var cellSize = 160;
// Golem costs
var golemCosts = {
basic: 50,
heavy: 100,
crystal: 75,
barrier: 80,
spike: 60,
shovel: 0
};
// Selected golem type
var selectedGolemType = 'basic';
// UI elements
var stonesText = new Text2('Stones: 100', {
size: 40,
fill: 0xFFFFFF
});
stonesText.anchor.set(0, 0);
LK.gui.topLeft.addChild(stonesText);
stonesText.x = 120;
stonesText.y = 20;
var livesText = new Text2('Lives: 10', {
size: 40,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0);
LK.gui.topLeft.addChild(livesText);
livesText.x = 120;
livesText.y = 70;
var waveText = new Text2('Wave: 1', {
size: 40,
fill: 0xFFFFFF
});
waveText.anchor.set(0, 0);
LK.gui.topLeft.addChild(waveText);
waveText.x = 120;
waveText.y = 120;
var scoreText = new Text2('Score: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -20;
scoreText.y = 20;
// Golem selection buttons
var buttonY = 200;
var buttonSpacing = 100;
var basicButton = LK.getAsset('basicGolem', {
scaleX: 1.2,
scaleY: 1.2
});
basicButton.x = 80;
basicButton.y = buttonY;
LK.gui.topLeft.addChild(basicButton);
var heavyButton = LK.getAsset('heavyGolem', {
scaleX: 1.0,
scaleY: 1.0
});
heavyButton.x = 80;
heavyButton.y = buttonY + buttonSpacing;
LK.gui.topLeft.addChild(heavyButton);
var crystalButton = LK.getAsset('crystalGolem', {
scaleX: 1.1,
scaleY: 1.1
});
crystalButton.x = 80;
crystalButton.y = buttonY + buttonSpacing * 2;
LK.gui.topLeft.addChild(crystalButton);
var barrierButton = LK.getAsset('barrierGolem', {
scaleX: 0.9,
scaleY: 1.0
});
barrierButton.x = 80;
barrierButton.y = buttonY + buttonSpacing * 3;
LK.gui.topLeft.addChild(barrierButton);
var spikeButton = LK.getAsset('spikeGolem', {
scaleX: 1.2,
scaleY: 1.2
});
spikeButton.x = 80;
spikeButton.y = buttonY + buttonSpacing * 4;
LK.gui.topLeft.addChild(spikeButton);
var shovelButton = LK.getAsset('shovel', {
scaleX: 1.0,
scaleY: 1.0
});
shovelButton.x = 80;
shovelButton.y = buttonY + buttonSpacing * 5;
LK.gui.topLeft.addChild(shovelButton);
// Cost labels
var basicCostText = new Text2('50', {
size: 24,
fill: 0xFFFF00
});
basicCostText.x = 150;
basicCostText.y = buttonY + 20;
LK.gui.topLeft.addChild(basicCostText);
var heavyCostText = new Text2('100', {
size: 24,
fill: 0xFFFF00
});
heavyCostText.x = 150;
heavyCostText.y = buttonY + buttonSpacing + 20;
LK.gui.topLeft.addChild(heavyCostText);
var crystalCostText = new Text2('75', {
size: 24,
fill: 0xFFFF00
});
crystalCostText.x = 150;
crystalCostText.y = buttonY + buttonSpacing * 2 + 20;
LK.gui.topLeft.addChild(crystalCostText);
var barrierCostText = new Text2('80', {
size: 24,
fill: 0xFFFF00
});
barrierCostText.x = 150;
barrierCostText.y = buttonY + buttonSpacing * 3 + 20;
LK.gui.topLeft.addChild(barrierCostText);
var spikeCostText = new Text2('60', {
size: 24,
fill: 0xFFFF00
});
spikeCostText.x = 150;
spikeCostText.y = buttonY + buttonSpacing * 4 + 20;
LK.gui.topLeft.addChild(spikeCostText);
var shovelCostText = new Text2('Remove', {
size: 20,
fill: 0xFFFF00
});
shovelCostText.x = 150;
shovelCostText.y = buttonY + buttonSpacing * 5 + 20;
LK.gui.topLeft.addChild(shovelCostText);
// Create grid visualization
var gridCells = [];
for (var row = 0; row < gridRows; row++) {
gridCells[row] = [];
for (var col = 0; col < gridCols; col++) {
var cell = LK.getAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
cell.x = gridStartX + col * cellSize;
cell.y = gridStartY + row * cellSize;
cell.gridX = col;
cell.gridY = row;
gridCells[row][col] = cell;
game.addChild(cell);
}
}
// Grid occupied tracking
var gridOccupied = [];
for (var row = 0; row < gridRows; row++) {
gridOccupied[row] = [];
for (var col = 0; col < gridCols; col++) {
gridOccupied[row][col] = false;
}
}
function updateUI() {
stonesText.setText('Stones: ' + stones);
livesText.setText('Lives: ' + lives);
waveText.setText('Wave: ' + wave);
scoreText.setText('Score: ' + score);
// Update button availability
basicButton.alpha = stones >= golemCosts.basic ? 1.0 : 0.5;
heavyButton.alpha = stones >= golemCosts.heavy ? 1.0 : 0.5;
crystalButton.alpha = stones >= golemCosts.crystal ? 1.0 : 0.5;
barrierButton.alpha = stones >= golemCosts.barrier ? 1.0 : 0.5;
spikeButton.alpha = stones >= golemCosts.spike ? 1.0 : 0.5;
shovelButton.alpha = 1.0; // Shovel is always available
}
function spawnWave() {
var demonsToSpawn = Math.min(3 + Math.floor(wave / 2), 8);
var spawnDelay = 0;
for (var i = 0; i < demonsToSpawn; i++) {
LK.setTimeout(function () {
var demonType = 'basic';
if (wave > 2 && Math.random() < 0.3) demonType = 'fast';
if (wave > 4 && Math.random() < 0.2) demonType = 'tank';
var demon = new Demon(demonType);
demon.x = 2048;
demon.y = gridStartY + Math.floor(Math.random() * gridRows) * cellSize;
demons.push(demon);
game.addChild(demon);
}, spawnDelay);
spawnDelay += 1000 + Math.random() * 500;
}
}
function getGridPosition(x, y) {
var col = Math.floor((x - gridStartX + cellSize / 2) / cellSize);
var row = Math.floor((y - gridStartY + cellSize / 2) / cellSize);
if (col >= 0 && col < gridCols && row >= 0 && row < gridRows) {
return {
col: col,
row: row
};
}
return null;
}
// Button click handlers
basicButton.down = function () {
if (stones >= golemCosts.basic) {
selectedGolemType = 'basic';
updateButtonSelection();
}
};
heavyButton.down = function () {
if (stones >= golemCosts.heavy) {
selectedGolemType = 'heavy';
updateButtonSelection();
}
};
crystalButton.down = function () {
if (stones >= golemCosts.crystal) {
selectedGolemType = 'crystal';
updateButtonSelection();
}
};
barrierButton.down = function () {
if (stones >= golemCosts.barrier) {
selectedGolemType = 'barrier';
updateButtonSelection();
}
};
spikeButton.down = function () {
if (stones >= golemCosts.spike) {
selectedGolemType = 'spike';
updateButtonSelection();
}
};
shovelButton.down = function () {
selectedGolemType = 'shovel';
updateButtonSelection();
};
function updateButtonSelection() {
basicButton.tint = selectedGolemType === 'basic' ? 0x00FF00 : 0xFFFFFF;
heavyButton.tint = selectedGolemType === 'heavy' ? 0x00FF00 : 0xFFFFFF;
crystalButton.tint = selectedGolemType === 'crystal' ? 0x00FF00 : 0xFFFFFF;
barrierButton.tint = selectedGolemType === 'barrier' ? 0x00FF00 : 0xFFFFFF;
spikeButton.tint = selectedGolemType === 'spike' ? 0x00FF00 : 0xFFFFFF;
shovelButton.tint = selectedGolemType === 'shovel' ? 0x00FF00 : 0xFFFFFF;
}
// Initialize button selection
updateButtonSelection();
// Game click handler
game.down = function (x, y, obj) {
var gridPos = getGridPosition(x, y);
if (gridPos) {
if (selectedGolemType === 'shovel') {
// Remove golem if one exists at this position
if (gridOccupied[gridPos.row][gridPos.col]) {
for (var i = golems.length - 1; i >= 0; i--) {
var golem = golems[i];
var golemGridCol = Math.floor((golem.x - gridStartX + cellSize / 2) / cellSize);
var golemGridRow = Math.floor((golem.y - gridStartY + cellSize / 2) / cellSize);
if (golemGridCol === gridPos.col && golemGridRow === gridPos.row) {
golem.destroy();
golems.splice(i, 1);
gridOccupied[gridPos.row][gridPos.col] = false;
LK.getSound('remove').play();
break;
}
}
}
} else if (!gridOccupied[gridPos.row][gridPos.col]) {
var cost = golemCosts[selectedGolemType];
if (stones >= cost) {
var golem = new Golem(selectedGolemType);
golem.x = gridStartX + gridPos.col * cellSize;
golem.y = gridStartY + gridPos.row * cellSize;
golems.push(golem);
game.addChild(golem);
gridOccupied[gridPos.row][gridPos.col] = true;
stones -= cost;
updateUI();
LK.getSound('place').play();
}
}
}
};
// Initial wave spawn
LK.setTimeout(function () {
spawnWave();
}, 2000);
game.update = function () {
// Update golems
for (var i = golems.length - 1; i >= 0; i--) {
var golem = golems[i];
if (golem.update) golem.update();
}
// Update demons
for (var i = demons.length - 1; i >= 0; i--) {
var demon = demons[i];
demon.update();
// Check if demon reached left side
if (demon.x < 300) {
lives--;
demon.destroy();
demons.splice(i, 1);
updateUI();
if (lives <= 0) {
LK.setScore(score);
LK.showGameOver();
return;
}
} else if (demon.shouldRemove) {
demon.destroy();
demons.splice(i, 1);
}
}
// Update projectiles
for (var i = projectiles.length - 1; i >= 0; i--) {
var projectile = projectiles[i];
projectile.update();
if (projectile.shouldRemove) {
projectile.destroy();
projectiles.splice(i, 1);
continue;
}
// Check projectile vs demon collision
for (var j = demons.length - 1; j >= 0; j--) {
var demon = demons[j];
if (projectile.intersects(demon)) {
demon.takeDamage(projectile.damage);
projectile.destroy();
projectiles.splice(i, 1);
break;
}
}
}
// Wave management
if (demons.length === 0) {
nextWaveTimer++;
if (nextWaveTimer >= waveDelay) {
wave++;
nextWaveTimer = 0;
spawnWave();
updateUI();
// Victory condition
if (wave > 10) {
LK.setScore(score);
LK.showYouWin();
return;
}
}
}
};
// Initialize UI
updateUI(); ===================================================================
--- original.js
+++ change.js
@@ -99,13 +99,19 @@
});
self.update = function () {
if (self.type === 'barrier') return;
if (self.type === 'spike') {
- // Check for contact damage
+ // Check for contact damage with cooldown
+ if (!self.damageCooldown) self.damageCooldown = {};
for (var i = 0; i < demons.length; i++) {
var demon = demons[i];
if (self.intersects(demon)) {
- demon.takeDamage(self.damage);
+ var demonId = demon.id || i; // Use demon id or index as identifier
+ var currentTime = LK.ticks;
+ if (!self.damageCooldown[demonId] || currentTime - self.damageCooldown[demonId] > 60) {
+ demon.takeDamage(self.damage);
+ self.damageCooldown[demonId] = currentTime;
+ }
}
}
return;
}
un demonio bola grande 2d y semi realista con muchos cuernos y que sus ojos sean negros con pupilas blancas. In-Game asset. 2d. High contrast. No shadows
haz a este personaje mas realista
haz a este personaje mucho mas realista
recrea este personaje mucho mas realista
un golem de cristal muy realista con un cañon en la mano. In-Game asset. 2d. High contrast. No shadows
una roca circular muy realista. In-Game asset. 2d. High contrast. No shadows
haz a este personaje mas realista
una pala de madera realista. In-Game asset. 2d. High contrast. No shadows
un golem de piedra con puas plano en horizontal en 3d muy realista. In-Game asset. 2d. High contrast. No shadows
un golem de piedra que parezca un minero y que se vea ultra realista. In-Game asset. 2d. High contrast. No shadows
un demonio bola ultra realista con una peluca y traje de bailarin con lentes de sol y una sonrisa con colmillos afilados. In-Game asset. 2d. High contrast. No shadows
un golem de piedra listo para pelear con puños con puas ultra realista. In-Game asset. 2d. High contrast. No shadows
un golem de piedra ultra realista con una bomba en la espalda. In-Game asset. 2d. High contrast. No shadows
un demonio bola con un casco de jugador de futbol americano ultra realista. In-Game asset. 2d. High contrast. No shadows
haz esta imagen muy, muy, muy, muy, muy realista, es una piedra con ruedas. In-Game asset. 2d. High contrast. No shadows
una piedra con ojos muy realista con una granada encima. In-Game asset. 2d. High contrast. No shadows
un arbusto ultra realista. In-Game asset. 2d. High contrast. No shadows
una roca ultra realista. In-Game asset. 2d. High contrast. No shadows