User prompt
karakterin boyutunu büyüt
User prompt
dron karaterin etrafında dönmesin karakterin bağımsız hareket etsin ve rasgele düşmanlara saldırsın
User prompt
kalkan 1 hit korusun
User prompt
çıkan her dron diğer dronun ters tarafında çıksın
User prompt
dron alındığı sürece 3 sefere kadar stacklenebilir
User prompt
dönen duron hasar versin
User prompt
arkaplan koy
User prompt
güçlendirmeler karakter hasar yiyene kadar kalıcı olsun
User prompt
ikili atış düz ilerlesin yayılmasın
User prompt
düşmanların ve karakterin hızını yavaşlat
User prompt
karakter kendisine en yakın düşmana doğru ateş etsin
Code edit (1 edits merged)
Please save this source code
User prompt
Rogue Wave Survival
Initial prompt
Create a top-down 2D rogue-like game where the player moves in the direction of input (e.g., arrow keys or WASD) and automatically shoots at approaching enemies. The game progresses in waves, with each wave increasing in difficulty by spawning more and stronger enemies. The player has a health bar; if it reaches zero, the game ends. Enemies spawn from outside the screen and move toward the player. There are three types of enemies: Normal enemy: balanced speed and health. Fast enemy: high speed, low health. Tank enemy: slow speed, high health. During gameplay, random power-ups spawn on the ground, including: Shield (adds temporary protection) Health (restores player HP) Dual Shot (fires two bullets at once) Enhanced Bullets (increased damage) Combat Drone (a drone that follows the player and shoots at enemies) The goal is to survive as many waves as possible, using movement, positioning, and power-ups to overcome the increasing enemy threat.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Drone class
var Drone = Container.expand(function (player) {
var self = Container.call(this);
var droneSprite = self.attachAsset('drone', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = droneSprite.width / 2;
self.player = player;
self.angle = 0;
self.orbitRadius = 220;
self.shootInterval = 30;
self.lastShotTick = 0;
self.update = function () {
self.angle += 0.07;
self.x = self.player.x + Math.cos(self.angle) * self.orbitRadius;
self.y = self.player.y + Math.sin(self.angle) * self.orbitRadius;
};
return self;
});
// Drone bullet class
var DroneBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('drone_bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bulletSprite.width / 2;
self.speed = 28;
self.damage = 1;
self.dirX = 0;
self.dirY = -1;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.type = 'normal'; // 'normal', 'fast', 'tank'
self.speed = 6;
self.health = 2;
self.radius = 50;
self.reward = 1;
self.target = null;
self.init = function (type) {
self.type = type;
if (type === 'normal') {
self.attachAsset('enemy_normal', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6 + Math.random() * 2;
self.health = 2;
self.radius = 50;
self.reward = 1;
} else if (type === 'fast') {
self.attachAsset('enemy_fast', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 11 + Math.random() * 2;
self.health = 1;
self.radius = 40;
self.reward = 2;
} else if (type === 'tank') {
self.attachAsset('enemy_tank', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3.5 + Math.random() * 1.5;
self.health = 6;
self.radius = 80;
self.reward = 4;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.getSound('enemy_hit').play();
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.destroyed = true;
}
};
self.update = function () {
if (!self.target) return;
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = playerSprite.width / 2;
self.speed = 18;
self.maxHealth = 8;
self.health = self.maxHealth;
self.shield = 0;
self.dualShot = false;
self.enhanced = false;
self.hasDrone = false;
self.drone = null;
self.lastShotTick = 0;
self.shootInterval = 18; // frames
self.invulnTicks = 0;
// For powerup timers
self.dualShotTicks = 0;
self.enhancedTicks = 0;
self.shieldTicks = 0;
// For touch drag
self.isDragging = false;
// Damage method
self.takeDamage = function (amount) {
if (self.invulnTicks > 0) return;
if (self.shield > 0) {
self.shield--;
self.shieldTicks = 0;
LK.effects.flashObject(self, 0x00e6e6, 400);
return;
}
self.health -= amount;
self.invulnTicks = 30;
LK.effects.flashObject(self, 0xff0000, 400);
LK.getSound('player_hit').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
// Powerup methods
self.applyPowerup = function (type) {
if (type === 'shield') {
self.shield = 1;
self.shieldTicks = 600;
} else if (type === 'health') {
self.health = Math.min(self.maxHealth, self.health + 3);
} else if (type === 'dual') {
self.dualShot = true;
self.dualShotTicks = 900;
} else if (type === 'enhanced') {
self.enhanced = true;
self.enhancedTicks = 900;
} else if (type === 'drone') {
if (!self.hasDrone) {
self.hasDrone = true;
self.drone = new Drone(self);
game.addChild(self.drone);
}
}
};
// Update powerup timers
self.updatePowerups = function () {
if (self.shield > 0) {
self.shieldTicks--;
if (self.shieldTicks <= 0) self.shield = 0;
}
if (self.dualShot) {
self.dualShotTicks--;
if (self.dualShotTicks <= 0) self.dualShot = false;
}
if (self.enhanced) {
self.enhancedTicks--;
if (self.enhancedTicks <= 0) self.enhanced = false;
}
};
// Update method
self.update = function () {
if (self.invulnTicks > 0) self.invulnTicks--;
self.updatePowerups();
// Keep player inside bounds
if (self.x < self.radius) self.x = self.radius;
if (self.x > 2048 - self.radius) self.x = 2048 - self.radius;
if (self.y < self.radius) self.y = self.radius;
if (self.y > 2732 - self.radius) self.y = 2732 - self.radius;
};
return self;
});
// Player bullet class
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('player_bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bulletSprite.width / 2;
self.speed = 32;
self.damage = 1;
self.dirX = 0;
self.dirY = -1;
self.fromDrone = false;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
self.type = 'shield';
self.radius = 40;
self.init = function (type) {
self.type = type;
if (type === 'shield') {
self.attachAsset('powerup_shield', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'health') {
self.attachAsset('powerup_health', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'dual') {
self.attachAsset('powerup_dual', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'enhanced') {
self.attachAsset('powerup_enhanced', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (type === 'drone') {
self.attachAsset('powerup_drone', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
self.update = function () {
// Float up and down
self.y += Math.sin(LK.ticks / 20 + self._floatPhase) * 1.2;
};
self._floatPhase = Math.random() * Math.PI * 2;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
// Music
// Sounds
// Drone
// Powerups
// Bullets
// Enemy types
// Player
// Game state variables
var player;
var enemies = [];
var bullets = [];
var droneBullets = [];
var powerups = [];
var wave = 1;
var waveTicks = 0;
var spawnTick = 0;
var nextPowerupTick = 0;
var dragging = false;
var dragOffsetX = 0;
var dragOffsetY = 0;
var score = 0;
var healthBar;
var shieldBar;
var waveText;
var scoreText;
var lastTouchX = 0;
var lastTouchY = 0;
// GUI
function createGUI() {
// Health bar
healthBar = new Text2('', {
size: 80,
fill: 0xFF3A3A
});
healthBar.anchor.set(0, 0);
LK.gui.top.addChild(healthBar);
// Shield bar
shieldBar = new Text2('', {
size: 60,
fill: 0x00E6E6
});
shieldBar.anchor.set(0, 0);
LK.gui.top.addChild(shieldBar);
// Score
scoreText = new Text2('Score: 0', {
size: 80,
fill: "#fff"
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
// Wave
waveText = new Text2('Wave 1', {
size: 70,
fill: 0xFFE066
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
// Position GUI
healthBar.x = 120;
healthBar.y = 20;
shieldBar.x = 120;
shieldBar.y = 110;
scoreText.x = -40;
scoreText.y = 20;
waveText.x = 1024;
waveText.y = 20;
}
function updateGUI() {
var hearts = '';
for (var i = 0; i < player.maxHealth; i++) {
hearts += i < player.health ? '♥ ' : '♡ ';
}
healthBar.setText('HP: ' + hearts.trim());
shieldBar.setText(player.shield > 0 ? 'Shield: ON' : '');
scoreText.setText('Score: ' + score);
waveText.setText('Wave ' + wave);
}
// Spawn player
function spawnPlayer() {
player = new Player();
player.x = 2048 / 2;
player.y = 2732 * 0.7;
game.addChild(player);
}
// Spawn enemies for current wave
function spawnEnemies() {
var num = 4 + wave * 2;
for (var i = 0; i < num; i++) {
var type;
if (wave >= 5 && Math.random() < 0.2) {
type = 'tank';
} else if (Math.random() < 0.3 + wave * 0.02) {
type = 'fast';
} else {
type = 'normal';
}
var enemy = new Enemy();
enemy.init(type);
// Spawn outside screen
var edge = Math.floor(Math.random() * 4);
var ex, ey;
if (edge === 0) {
// top
ex = Math.random() * 2048;
ey = -enemy.radius - 20;
} else if (edge === 1) {
// right
ex = 2048 + enemy.radius + 20;
ey = Math.random() * 2732;
} else if (edge === 2) {
// bottom
ex = Math.random() * 2048;
ey = 2732 + enemy.radius + 20;
} else {
// left
ex = -enemy.radius - 20;
ey = Math.random() * 2732;
}
enemy.x = ex;
enemy.y = ey;
enemy.target = player;
enemies.push(enemy);
game.addChild(enemy);
}
}
// Spawn a powerup at random location
function spawnPowerup() {
var types = ['shield', 'health', 'dual', 'enhanced', 'drone'];
var type = types[Math.floor(Math.random() * types.length)];
var powerup = new Powerup();
powerup.init(type);
powerup.x = 200 + Math.random() * (2048 - 400);
powerup.y = 400 + Math.random() * (2732 - 800);
powerups.push(powerup);
game.addChild(powerup);
}
// Fire player bullets
function firePlayerBullets() {
if (LK.ticks - player.lastShotTick < player.shootInterval) return;
player.lastShotTick = LK.ticks;
var angle = -Math.PI / 2;
var spread = player.dualShot ? 0.25 : 0;
var num = player.dualShot ? 2 : 1;
for (var i = 0; i < num; i++) {
var bullet = new PlayerBullet();
bullet.damage = player.enhanced ? 2 : 1;
var a = angle + (num === 2 ? i === 0 ? -spread : spread : 0);
bullet.dirX = Math.cos(a);
bullet.dirY = Math.sin(a);
bullet.x = player.x + bullet.dirX * (player.radius + 30);
bullet.y = player.y + bullet.dirY * (player.radius + 30);
bullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
}
// Fire drone bullets
function fireDroneBullets() {
if (!player.hasDrone || !player.drone) return;
if (LK.ticks - player.drone.lastShotTick < player.drone.shootInterval) return;
player.drone.lastShotTick = LK.ticks;
// Find nearest enemy
var nearest = null;
var minDist = 99999;
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - player.drone.x;
var dy = enemies[i].y - player.drone.y;
var d = dx * dx + dy * dy;
if (d < minDist) {
minDist = d;
nearest = enemies[i];
}
}
if (!nearest) return;
var dx = nearest.x - player.drone.x;
var dy = nearest.y - player.drone.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) return;
var bullet = new DroneBullet();
bullet.dirX = dx / dist;
bullet.dirY = dy / dist;
bullet.x = player.drone.x + bullet.dirX * (player.drone.radius + 20);
bullet.y = player.drone.y + bullet.dirY * (player.drone.radius + 20);
droneBullets.push(bullet);
game.addChild(bullet);
LK.getSound('drone_shoot').play();
}
// Handle dragging
function handleMove(x, y, obj) {
if (!dragging) return;
// Clamp to bounds
var nx = x - dragOffsetX;
var ny = y - dragOffsetY;
var r = player.radius;
if (nx < r) nx = r;
if (nx > 2048 - r) nx = 2048 - r;
if (ny < r) ny = r;
if (ny > 2732 - r) ny = 2732 - r;
player.x = nx;
player.y = ny;
lastTouchX = x;
lastTouchY = y;
}
// Touch events
game.down = function (x, y, obj) {
// Don't allow drag from top left 100x100
if (x < 100 && y < 100) return;
var dx = x - player.x;
var dy = y - player.y;
if (dx * dx + dy * dy < player.radius * player.radius * 2.5) {
dragging = true;
dragOffsetX = x - player.x;
dragOffsetY = y - player.y;
lastTouchX = x;
lastTouchY = y;
}
};
game.move = function (x, y, obj) {
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragging = false;
};
// Main update loop
game.update = function () {
// Player update
player.update();
// Player auto-fire
firePlayerBullets();
// Drone update and fire
if (player.hasDrone && player.drone) {
player.drone.update();
fireDroneBullets();
}
// Enemies update
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Check collision with player
var dx = e.x - player.x;
var dy = e.y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < e.radius + player.radius - 10) {
player.takeDamage(e.type === 'tank' ? 3 : 1);
e.destroyed = true;
}
// Remove if offscreen
if (e.x < -200 || e.x > 2248 || e.y < -200 || e.y > 2932) {
e.destroyed = true;
}
// Remove if destroyed
if (e.destroyed) {
e.destroy();
enemies.splice(i, 1);
score += e.reward;
LK.setScore(score);
}
}
// Bullets update
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
var hit = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
var dx = e.x - b.x;
var dy = e.y - b.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < e.radius + b.radius - 10) {
e.takeDamage(b.damage);
hit = true;
break;
}
}
// Remove if hit or offscreen
if (hit || b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
bullets.splice(i, 1);
}
}
// Drone bullets update
for (var i = droneBullets.length - 1; i >= 0; i--) {
var b = droneBullets[i];
b.update();
var hit = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
var dx = e.x - b.x;
var dy = e.y - b.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < e.radius + b.radius - 10) {
e.takeDamage(1);
hit = true;
break;
}
}
if (hit || b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
droneBullets.splice(i, 1);
}
}
// Powerups update
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
p.update();
var dx = p.x - player.x;
var dy = p.y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < p.radius + player.radius + 10) {
player.applyPowerup(p.type);
LK.getSound('powerup').play();
p.destroy();
powerups.splice(i, 1);
}
}
// Wave logic
waveTicks++;
if (enemies.length === 0 && waveTicks > 60) {
wave++;
waveTicks = 0;
spawnEnemies();
LK.effects.flashScreen(0x00ffcc, 400);
}
// Powerup spawn logic
if (LK.ticks > nextPowerupTick) {
spawnPowerup();
nextPowerupTick = LK.ticks + 600 + Math.floor(Math.random() * 600);
}
// Update GUI
updateGUI();
};
// Game start
function startGame() {
createGUI();
spawnPlayer();
spawnEnemies();
nextPowerupTick = LK.ticks + 300;
score = 0;
LK.setScore(0);
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1200
}
});
}
startGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,615 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Drone class
+var Drone = Container.expand(function (player) {
+ var self = Container.call(this);
+ var droneSprite = self.attachAsset('drone', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = droneSprite.width / 2;
+ self.player = player;
+ self.angle = 0;
+ self.orbitRadius = 220;
+ self.shootInterval = 30;
+ self.lastShotTick = 0;
+ self.update = function () {
+ self.angle += 0.07;
+ self.x = self.player.x + Math.cos(self.angle) * self.orbitRadius;
+ self.y = self.player.y + Math.sin(self.angle) * self.orbitRadius;
+ };
+ return self;
+});
+// Drone bullet class
+var DroneBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletSprite = self.attachAsset('drone_bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = bulletSprite.width / 2;
+ self.speed = 28;
+ self.damage = 1;
+ self.dirX = 0;
+ self.dirY = -1;
+ self.update = function () {
+ self.x += self.dirX * self.speed;
+ self.y += self.dirY * self.speed;
+ };
+ return self;
+});
+// Enemy class
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = 'normal'; // 'normal', 'fast', 'tank'
+ self.speed = 6;
+ self.health = 2;
+ self.radius = 50;
+ self.reward = 1;
+ self.target = null;
+ self.init = function (type) {
+ self.type = type;
+ if (type === 'normal') {
+ self.attachAsset('enemy_normal', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 6 + Math.random() * 2;
+ self.health = 2;
+ self.radius = 50;
+ self.reward = 1;
+ } else if (type === 'fast') {
+ self.attachAsset('enemy_fast', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 11 + Math.random() * 2;
+ self.health = 1;
+ self.radius = 40;
+ self.reward = 2;
+ } else if (type === 'tank') {
+ self.attachAsset('enemy_tank', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3.5 + Math.random() * 1.5;
+ self.health = 6;
+ self.radius = 80;
+ self.reward = 4;
+ }
+ };
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ LK.getSound('enemy_hit').play();
+ LK.effects.flashObject(self, 0xffffff, 200);
+ if (self.health <= 0) {
+ self.destroyed = true;
+ }
+ };
+ self.update = function () {
+ if (!self.target) return;
+ var dx = self.target.x - self.x;
+ var dy = self.target.y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ self.x += dx / dist * self.speed;
+ self.y += dy / dist * self.speed;
+ }
+ };
+ return self;
+});
+// Player class
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerSprite = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = playerSprite.width / 2;
+ self.speed = 18;
+ self.maxHealth = 8;
+ self.health = self.maxHealth;
+ self.shield = 0;
+ self.dualShot = false;
+ self.enhanced = false;
+ self.hasDrone = false;
+ self.drone = null;
+ self.lastShotTick = 0;
+ self.shootInterval = 18; // frames
+ self.invulnTicks = 0;
+ // For powerup timers
+ self.dualShotTicks = 0;
+ self.enhancedTicks = 0;
+ self.shieldTicks = 0;
+ // For touch drag
+ self.isDragging = false;
+ // Damage method
+ self.takeDamage = function (amount) {
+ if (self.invulnTicks > 0) return;
+ if (self.shield > 0) {
+ self.shield--;
+ self.shieldTicks = 0;
+ LK.effects.flashObject(self, 0x00e6e6, 400);
+ return;
+ }
+ self.health -= amount;
+ self.invulnTicks = 30;
+ LK.effects.flashObject(self, 0xff0000, 400);
+ LK.getSound('player_hit').play();
+ if (self.health <= 0) {
+ LK.showGameOver();
+ }
+ };
+ // Powerup methods
+ self.applyPowerup = function (type) {
+ if (type === 'shield') {
+ self.shield = 1;
+ self.shieldTicks = 600;
+ } else if (type === 'health') {
+ self.health = Math.min(self.maxHealth, self.health + 3);
+ } else if (type === 'dual') {
+ self.dualShot = true;
+ self.dualShotTicks = 900;
+ } else if (type === 'enhanced') {
+ self.enhanced = true;
+ self.enhancedTicks = 900;
+ } else if (type === 'drone') {
+ if (!self.hasDrone) {
+ self.hasDrone = true;
+ self.drone = new Drone(self);
+ game.addChild(self.drone);
+ }
+ }
+ };
+ // Update powerup timers
+ self.updatePowerups = function () {
+ if (self.shield > 0) {
+ self.shieldTicks--;
+ if (self.shieldTicks <= 0) self.shield = 0;
+ }
+ if (self.dualShot) {
+ self.dualShotTicks--;
+ if (self.dualShotTicks <= 0) self.dualShot = false;
+ }
+ if (self.enhanced) {
+ self.enhancedTicks--;
+ if (self.enhancedTicks <= 0) self.enhanced = false;
+ }
+ };
+ // Update method
+ self.update = function () {
+ if (self.invulnTicks > 0) self.invulnTicks--;
+ self.updatePowerups();
+ // Keep player inside bounds
+ if (self.x < self.radius) self.x = self.radius;
+ if (self.x > 2048 - self.radius) self.x = 2048 - self.radius;
+ if (self.y < self.radius) self.y = self.radius;
+ if (self.y > 2732 - self.radius) self.y = 2732 - self.radius;
+ };
+ return self;
+});
+// Player bullet class
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletSprite = self.attachAsset('player_bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = bulletSprite.width / 2;
+ self.speed = 32;
+ self.damage = 1;
+ self.dirX = 0;
+ self.dirY = -1;
+ self.fromDrone = false;
+ self.update = function () {
+ self.x += self.dirX * self.speed;
+ self.y += self.dirY * self.speed;
+ };
+ return self;
+});
+// Powerup class
+var Powerup = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = 'shield';
+ self.radius = 40;
+ self.init = function (type) {
+ self.type = type;
+ if (type === 'shield') {
+ self.attachAsset('powerup_shield', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (type === 'health') {
+ self.attachAsset('powerup_health', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (type === 'dual') {
+ self.attachAsset('powerup_dual', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (type === 'enhanced') {
+ self.attachAsset('powerup_enhanced', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (type === 'drone') {
+ self.attachAsset('powerup_drone', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ };
+ self.update = function () {
+ // Float up and down
+ self.y += Math.sin(LK.ticks / 20 + self._floatPhase) * 1.2;
+ };
+ self._floatPhase = Math.random() * Math.PI * 2;
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x181c24
+});
+
+/****
+* Game Code
+****/
+// Music
+// Sounds
+// Drone
+// Powerups
+// Bullets
+// Enemy types
+// Player
+// Game state variables
+var player;
+var enemies = [];
+var bullets = [];
+var droneBullets = [];
+var powerups = [];
+var wave = 1;
+var waveTicks = 0;
+var spawnTick = 0;
+var nextPowerupTick = 0;
+var dragging = false;
+var dragOffsetX = 0;
+var dragOffsetY = 0;
+var score = 0;
+var healthBar;
+var shieldBar;
+var waveText;
+var scoreText;
+var lastTouchX = 0;
+var lastTouchY = 0;
+// GUI
+function createGUI() {
+ // Health bar
+ healthBar = new Text2('', {
+ size: 80,
+ fill: 0xFF3A3A
+ });
+ healthBar.anchor.set(0, 0);
+ LK.gui.top.addChild(healthBar);
+ // Shield bar
+ shieldBar = new Text2('', {
+ size: 60,
+ fill: 0x00E6E6
+ });
+ shieldBar.anchor.set(0, 0);
+ LK.gui.top.addChild(shieldBar);
+ // Score
+ scoreText = new Text2('Score: 0', {
+ size: 80,
+ fill: "#fff"
+ });
+ scoreText.anchor.set(1, 0);
+ LK.gui.topRight.addChild(scoreText);
+ // Wave
+ waveText = new Text2('Wave 1', {
+ size: 70,
+ fill: 0xFFE066
+ });
+ waveText.anchor.set(0.5, 0);
+ LK.gui.top.addChild(waveText);
+ // Position GUI
+ healthBar.x = 120;
+ healthBar.y = 20;
+ shieldBar.x = 120;
+ shieldBar.y = 110;
+ scoreText.x = -40;
+ scoreText.y = 20;
+ waveText.x = 1024;
+ waveText.y = 20;
+}
+function updateGUI() {
+ var hearts = '';
+ for (var i = 0; i < player.maxHealth; i++) {
+ hearts += i < player.health ? '♥ ' : '♡ ';
+ }
+ healthBar.setText('HP: ' + hearts.trim());
+ shieldBar.setText(player.shield > 0 ? 'Shield: ON' : '');
+ scoreText.setText('Score: ' + score);
+ waveText.setText('Wave ' + wave);
+}
+// Spawn player
+function spawnPlayer() {
+ player = new Player();
+ player.x = 2048 / 2;
+ player.y = 2732 * 0.7;
+ game.addChild(player);
+}
+// Spawn enemies for current wave
+function spawnEnemies() {
+ var num = 4 + wave * 2;
+ for (var i = 0; i < num; i++) {
+ var type;
+ if (wave >= 5 && Math.random() < 0.2) {
+ type = 'tank';
+ } else if (Math.random() < 0.3 + wave * 0.02) {
+ type = 'fast';
+ } else {
+ type = 'normal';
+ }
+ var enemy = new Enemy();
+ enemy.init(type);
+ // Spawn outside screen
+ var edge = Math.floor(Math.random() * 4);
+ var ex, ey;
+ if (edge === 0) {
+ // top
+ ex = Math.random() * 2048;
+ ey = -enemy.radius - 20;
+ } else if (edge === 1) {
+ // right
+ ex = 2048 + enemy.radius + 20;
+ ey = Math.random() * 2732;
+ } else if (edge === 2) {
+ // bottom
+ ex = Math.random() * 2048;
+ ey = 2732 + enemy.radius + 20;
+ } else {
+ // left
+ ex = -enemy.radius - 20;
+ ey = Math.random() * 2732;
+ }
+ enemy.x = ex;
+ enemy.y = ey;
+ enemy.target = player;
+ enemies.push(enemy);
+ game.addChild(enemy);
+ }
+}
+// Spawn a powerup at random location
+function spawnPowerup() {
+ var types = ['shield', 'health', 'dual', 'enhanced', 'drone'];
+ var type = types[Math.floor(Math.random() * types.length)];
+ var powerup = new Powerup();
+ powerup.init(type);
+ powerup.x = 200 + Math.random() * (2048 - 400);
+ powerup.y = 400 + Math.random() * (2732 - 800);
+ powerups.push(powerup);
+ game.addChild(powerup);
+}
+// Fire player bullets
+function firePlayerBullets() {
+ if (LK.ticks - player.lastShotTick < player.shootInterval) return;
+ player.lastShotTick = LK.ticks;
+ var angle = -Math.PI / 2;
+ var spread = player.dualShot ? 0.25 : 0;
+ var num = player.dualShot ? 2 : 1;
+ for (var i = 0; i < num; i++) {
+ var bullet = new PlayerBullet();
+ bullet.damage = player.enhanced ? 2 : 1;
+ var a = angle + (num === 2 ? i === 0 ? -spread : spread : 0);
+ bullet.dirX = Math.cos(a);
+ bullet.dirY = Math.sin(a);
+ bullet.x = player.x + bullet.dirX * (player.radius + 30);
+ bullet.y = player.y + bullet.dirY * (player.radius + 30);
+ bullets.push(bullet);
+ game.addChild(bullet);
+ }
+ LK.getSound('shoot').play();
+}
+// Fire drone bullets
+function fireDroneBullets() {
+ if (!player.hasDrone || !player.drone) return;
+ if (LK.ticks - player.drone.lastShotTick < player.drone.shootInterval) return;
+ player.drone.lastShotTick = LK.ticks;
+ // Find nearest enemy
+ var nearest = null;
+ var minDist = 99999;
+ for (var i = 0; i < enemies.length; i++) {
+ var dx = enemies[i].x - player.drone.x;
+ var dy = enemies[i].y - player.drone.y;
+ var d = dx * dx + dy * dy;
+ if (d < minDist) {
+ minDist = d;
+ nearest = enemies[i];
+ }
+ }
+ if (!nearest) return;
+ var dx = nearest.x - player.drone.x;
+ var dy = nearest.y - player.drone.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist === 0) return;
+ var bullet = new DroneBullet();
+ bullet.dirX = dx / dist;
+ bullet.dirY = dy / dist;
+ bullet.x = player.drone.x + bullet.dirX * (player.drone.radius + 20);
+ bullet.y = player.drone.y + bullet.dirY * (player.drone.radius + 20);
+ droneBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('drone_shoot').play();
+}
+// Handle dragging
+function handleMove(x, y, obj) {
+ if (!dragging) return;
+ // Clamp to bounds
+ var nx = x - dragOffsetX;
+ var ny = y - dragOffsetY;
+ var r = player.radius;
+ if (nx < r) nx = r;
+ if (nx > 2048 - r) nx = 2048 - r;
+ if (ny < r) ny = r;
+ if (ny > 2732 - r) ny = 2732 - r;
+ player.x = nx;
+ player.y = ny;
+ lastTouchX = x;
+ lastTouchY = y;
+}
+// Touch events
+game.down = function (x, y, obj) {
+ // Don't allow drag from top left 100x100
+ if (x < 100 && y < 100) return;
+ var dx = x - player.x;
+ var dy = y - player.y;
+ if (dx * dx + dy * dy < player.radius * player.radius * 2.5) {
+ dragging = true;
+ dragOffsetX = x - player.x;
+ dragOffsetY = y - player.y;
+ lastTouchX = x;
+ lastTouchY = y;
+ }
+};
+game.move = function (x, y, obj) {
+ handleMove(x, y, obj);
+};
+game.up = function (x, y, obj) {
+ dragging = false;
+};
+// Main update loop
+game.update = function () {
+ // Player update
+ player.update();
+ // Player auto-fire
+ firePlayerBullets();
+ // Drone update and fire
+ if (player.hasDrone && player.drone) {
+ player.drone.update();
+ fireDroneBullets();
+ }
+ // Enemies update
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var e = enemies[i];
+ e.update();
+ // Check collision with player
+ var dx = e.x - player.x;
+ var dy = e.y - player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < e.radius + player.radius - 10) {
+ player.takeDamage(e.type === 'tank' ? 3 : 1);
+ e.destroyed = true;
+ }
+ // Remove if offscreen
+ if (e.x < -200 || e.x > 2248 || e.y < -200 || e.y > 2932) {
+ e.destroyed = true;
+ }
+ // Remove if destroyed
+ if (e.destroyed) {
+ e.destroy();
+ enemies.splice(i, 1);
+ score += e.reward;
+ LK.setScore(score);
+ }
+ }
+ // Bullets update
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var b = bullets[i];
+ b.update();
+ var hit = false;
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var e = enemies[j];
+ var dx = e.x - b.x;
+ var dy = e.y - b.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < e.radius + b.radius - 10) {
+ e.takeDamage(b.damage);
+ hit = true;
+ break;
+ }
+ }
+ // Remove if hit or offscreen
+ if (hit || b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
+ b.destroy();
+ bullets.splice(i, 1);
+ }
+ }
+ // Drone bullets update
+ for (var i = droneBullets.length - 1; i >= 0; i--) {
+ var b = droneBullets[i];
+ b.update();
+ var hit = false;
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var e = enemies[j];
+ var dx = e.x - b.x;
+ var dy = e.y - b.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < e.radius + b.radius - 10) {
+ e.takeDamage(1);
+ hit = true;
+ break;
+ }
+ }
+ if (hit || b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
+ b.destroy();
+ droneBullets.splice(i, 1);
+ }
+ }
+ // Powerups update
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ var p = powerups[i];
+ p.update();
+ var dx = p.x - player.x;
+ var dy = p.y - player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < p.radius + player.radius + 10) {
+ player.applyPowerup(p.type);
+ LK.getSound('powerup').play();
+ p.destroy();
+ powerups.splice(i, 1);
+ }
+ }
+ // Wave logic
+ waveTicks++;
+ if (enemies.length === 0 && waveTicks > 60) {
+ wave++;
+ waveTicks = 0;
+ spawnEnemies();
+ LK.effects.flashScreen(0x00ffcc, 400);
+ }
+ // Powerup spawn logic
+ if (LK.ticks > nextPowerupTick) {
+ spawnPowerup();
+ nextPowerupTick = LK.ticks + 600 + Math.floor(Math.random() * 600);
+ }
+ // Update GUI
+ updateGUI();
+};
+// Game start
+function startGame() {
+ createGUI();
+ spawnPlayer();
+ spawnEnemies();
+ nextPowerupTick = LK.ticks + 300;
+ score = 0;
+ LK.setScore(0);
+ LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 1,
+ duration: 1200
+ }
+ });
+}
+startGame();
\ No newline at end of file
Draw a chibi-style top-down (bird's-eye view) park field. The scene should be cute and colorful, with soft, rounded shapes typical of chibi environments. Include details like small patches of flowers, tiny rocks, and gentle variations in the grass. The overall style should be whimsical and simple, with clean lines and a bright, cheerful color palette. In-Game asset. 2d. High contrast. No shadows