User prompt
fix sound assets
User prompt
make 0,5 second player shoot interval
User prompt
auto shooter
User prompt
delete shiled asset
User prompt
delete image green health bar
User prompt
multiple fire balls
User prompt
add background asset
User prompt
ada blue background
User prompt
dragon falls spinning when hit by defeat shot
User prompt
dragon gone after dead hit
User prompt
dragon fall rolling after dead hit
User prompt
fix dragon appreance
User prompt
fix dragon are gone
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(dragon, {' Line Number: 332 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(dragon).to({' Line Number: 332
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(dragon, {' Line Number: 332
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(dragon).to({' Line Number: 332
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(dragon, {' Line Number: 332
User prompt
make dragon explode after hit dead
User prompt
dragob can attack targeting player position
User prompt
dragon can attack multiple fire
User prompt
player can attack manualy
Code edit (1 edits merged)
Please save this source code
User prompt
Medieval Fortress: Dragon Defense
Initial prompt
vertical defense game Medieval Fortress vs Fire Dragon Game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Arrow class (player projectile)
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowSprite = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -32; // Upwards
self.update = function () {
self.y += self.speed;
};
return self;
});
// Dragon class (enemy)
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonSprite = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = 1; // 1: right, -1: left
self.speed = 10;
self.attackCooldown = 0;
self.update = function () {
// Move left/right
self.x += self.speed * self.direction;
// Bounce at screen edges
if (self.x < 160) {
self.x = 160;
self.direction = 1;
}
if (self.x > 2048 - 160) {
self.x = 2048 - 160;
self.direction = -1;
}
// Attack cooldown
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
// Dragon fires a fireball
self.shoot = function () {
if (self.attackCooldown === 0) {
// Fire multiple fireballs in a spread, each targeting the fortress position
var numFireballs = 3 + Math.floor(LK.getScore() / 10); // Increase number as score increases
if (numFireballs > 5) numFireballs = 5;
var spread = 120; // total spread in pixels
var startX = self.x - (numFireballs - 1) * spread / 2;
for (var i = 0; i < numFireballs; i++) {
var fireball = new Fireball();
fireball.x = startX + i * spread;
fireball.y = self.y + 90;
fireball.lastY = fireball.y;
fireball.lastIntersecting = false;
// Calculate direction vector from fireball to fortress at fire time
var dx = fortress.x - fireball.x;
var dy = fortress.y - 60 - fireball.y; // aim slightly above fortress center
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) {
fireball.vx = 0;
fireball.vy = fireball.speed;
} else {
fireball.vx = dx / dist * fireball.speed;
fireball.vy = dy / dist * fireball.speed;
}
fireballs.push(fireball);
game.addChild(fireball);
}
LK.getSound('fireball_shoot').play();
self.attackCooldown = Math.max(30, 120 - Math.floor(LK.getScore() / 5) * 10); // Faster as score increases
}
};
return self;
});
// Fireball class (enemy projectile)
var Fireball = Container.expand(function () {
var self = Container.call(this);
var fireballSprite = self.attachAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 18;
self.update = function () {
// If vx/vy are set, use them (targeted), else default straight down
if (typeof self.vx === "number" && typeof self.vy === "number") {
self.x += self.vx;
self.y += self.vy;
} else {
self.y += self.speed;
}
};
return self;
});
// Fortress class (player)
var Fortress = Container.expand(function () {
var self = Container.call(this);
var fortressSprite = self.attachAsset('fortress', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {};
return self;
});
// Shield class (player deployable)
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldSprite = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
self.duration = 60; // frames
self.update = function () {
self.duration--;
if (self.duration <= 0) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222244
});
/****
* Game Code
****/
// Music
// Sound effects
// Fortress health bar
// Fireball (enemy projectile)
// Dragon (enemy)
// Shield (player deployable)
// Arrow (player projectile)
// Fortress (player) at the bottom
// Game variables
var arrows = [];
var fireballs = [];
var shields = [];
var fortressHealth = 5;
var fortressMaxHealth = 5;
var canShoot = true;
var shootCooldown = 0;
var canShield = true;
var shieldCooldown = 0;
var dragNode = null;
var lastFortressX = 0;
// Add music
LK.playMusic('castle_theme');
// Add fortress (player) at bottom center
var fortress = new Fortress();
fortress.x = 2048 / 2;
fortress.y = 2732 - 120;
game.addChild(fortress);
// Add dragon at top center
var dragon = new Dragon();
dragon.x = 2048 / 2;
dragon.y = 220;
game.addChild(dragon);
// Health bar
var healthBar = LK.getAsset('healthbar', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 60
});
game.addChild(healthBar);
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Fortress health text
var healthTxt = new Text2('♥♥♥♥♥', {
size: 90,
fill: 0x44DD44
});
healthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(healthTxt);
healthTxt.y = 120;
healthTxt.x = 2048 / 2 / (2048 / LK.gui.top.width);
// Helper: update health bar and text
function updateHealthDisplay() {
// Health bar width
healthBar.width = 400 * (fortressHealth / fortressMaxHealth);
// Health text
var hearts = '';
for (var i = 0; i < fortressHealth; i++) hearts += '♥';
for (var i = fortressHealth; i < fortressMaxHealth; i++) hearts += '♡';
healthTxt.setText(hearts);
if (fortressHealth <= 2) {
healthTxt.setStyle({
fill: 0xFF4444
});
} else {
healthTxt.setStyle({
fill: 0x44DD44
});
}
}
// Initial health display
updateHealthDisplay();
// Touch/mouse controls
game.down = function (x, y, obj) {
// If touch is in lower 1/3, drag fortress
if (y > 2732 * 2 / 3) {
dragNode = fortress;
lastFortressX = fortress.x;
// Deploy shield if available and not on cooldown (secondary tap in lower 1/3)
if (canShield && shieldCooldown === 0) {
var shield = new Shield();
shield.x = fortress.x;
shield.y = fortress.y - 100;
shields.push(shield);
game.addChild(shield);
LK.getSound('shield_block').play();
canShield = false;
shieldCooldown = 90; // 1.5s
}
} else if (y <= 2732 * 2 / 3 && canShoot && shootCooldown === 0) {
// Shoot arrow if tap is in upper 2/3
var arrow = new Arrow();
arrow.x = fortress.x;
arrow.y = fortress.y - 80;
arrow.lastY = arrow.y;
arrow.lastIntersecting = false;
arrows.push(arrow);
game.addChild(arrow);
LK.getSound('arrow_shoot').play();
canShoot = false;
shootCooldown = 12; // 0.2s
}
};
game.move = function (x, y, obj) {
if (dragNode === fortress) {
// Move fortress horizontally, clamp to screen
fortress.x = Math.max(160, Math.min(2048 - 160, x));
// Move health bar and shield with fortress
healthBar.x = fortress.x;
for (var i = 0; i < shields.length; i++) {
shields[i].x = fortress.x;
}
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
// Cooldowns
if (!canShoot) {
shootCooldown--;
if (shootCooldown <= 0) {
canShoot = true;
shootCooldown = 0;
}
}
if (!canShield) {
shieldCooldown--;
if (shieldCooldown <= 0) {
canShield = true;
shieldCooldown = 0;
}
}
// Update dragon
dragon.update();
// Dragon attacks
if (LK.ticks % Math.max(60, 180 - Math.floor(LK.getScore() / 5) * 10) === 0) {
dragon.shoot();
}
// Update arrows
for (var i = arrows.length - 1; i >= 0; i--) {
var arrow = arrows[i];
arrow.update();
// Remove if off screen
if (arrow.y < -100) {
arrow.destroy();
arrows.splice(i, 1);
continue;
}
// Hit dragon?
var hitDragon = arrow.intersects(dragon);
if (!arrow.lastIntersecting && hitDragon) {
// Score up
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Flash dragon
LK.effects.flashObject(dragon, 0xFFFF00, 300);
arrow.destroy();
arrows.splice(i, 1);
continue;
}
arrow.lastIntersecting = hitDragon;
}
// Update fireballs
for (var j = fireballs.length - 1; j >= 0; j--) {
var fireball = fireballs[j];
fireball.update();
// Remove if off screen
if (fireball.y > 2732 + 100) {
fireball.destroy();
fireballs.splice(j, 1);
continue;
}
// Hit shield?
var blocked = false;
for (var s = shields.length - 1; s >= 0; s--) {
var shield = shields[s];
if (fireball.intersects(shield)) {
LK.effects.flashObject(shield, 0x99FFFF, 200);
fireball.destroy();
fireballs.splice(j, 1);
blocked = true;
break;
}
}
if (blocked) continue;
// Hit fortress?
var hitFortress = fireball.intersects(fortress);
if (!fireball.lastIntersecting && hitFortress) {
fortressHealth--;
updateHealthDisplay();
LK.effects.flashObject(fortress, 0xFF0000, 400);
LK.getSound('fortress_hit').play();
fireball.destroy();
fireballs.splice(j, 1);
if (fortressHealth <= 0) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
continue;
}
fireball.lastIntersecting = hitFortress;
}
// Update shields
for (var k = shields.length - 1; k >= 0; k--) {
var shield = shields[k];
shield.update();
if (shield.duration <= 0) {
shield.destroy();
shields.splice(k, 1);
}
}
// Win condition: survive to score 30
if (LK.getScore() >= 30) {
LK.showYouWin();
return;
}
};
// Initial score
scoreTxt.setText(LK.getScore()); ===================================================================
--- original.js
+++ change.js
@@ -48,9 +48,9 @@
};
// Dragon fires a fireball
self.shoot = function () {
if (self.attackCooldown === 0) {
- // Fire multiple fireballs in a spread
+ // Fire multiple fireballs in a spread, each targeting the fortress position
var numFireballs = 3 + Math.floor(LK.getScore() / 10); // Increase number as score increases
if (numFireballs > 5) numFireballs = 5;
var spread = 120; // total spread in pixels
var startX = self.x - (numFireballs - 1) * spread / 2;
@@ -59,8 +59,19 @@
fireball.x = startX + i * spread;
fireball.y = self.y + 90;
fireball.lastY = fireball.y;
fireball.lastIntersecting = false;
+ // Calculate direction vector from fireball to fortress at fire time
+ var dx = fortress.x - fireball.x;
+ var dy = fortress.y - 60 - fireball.y; // aim slightly above fortress center
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist === 0) {
+ fireball.vx = 0;
+ fireball.vy = fireball.speed;
+ } else {
+ fireball.vx = dx / dist * fireball.speed;
+ fireball.vy = dy / dist * fireball.speed;
+ }
fireballs.push(fireball);
game.addChild(fireball);
}
LK.getSound('fireball_shoot').play();
@@ -77,9 +88,15 @@
anchorY: 0.5
});
self.speed = 18;
self.update = function () {
- self.y += self.speed;
+ // If vx/vy are set, use them (targeted), else default straight down
+ if (typeof self.vx === "number" && typeof self.vy === "number") {
+ self.x += self.vx;
+ self.y += self.vy;
+ } else {
+ self.y += self.speed;
+ }
};
return self;
});
// Fortress class (player)
vertical top down balista medieval. In-Game asset. 2d. High contrast. No shadows
big balista arrow vertical imagw. In-Game asset. 2d. High contrast. No shadows
fronf view flying image dragon with 3 In-Game asset. 2d. High contrast. No shadows
plain battlefield of defense burning medieval fortres at bottom anime image style. blue sky at upper. far distance a mountain In-Game asset. 2d. High contrast. No shadows