User prompt
Please add automatic bullet firing to the player character with a simple default bullet that deals basic damage.
User prompt
KARAKTER OYUNCUNUN YÖNLENDİRMESİNE GÖRE DEĞİL NERYEE BAKIYORSA ORAYA ATEŞ ETSİN
User prompt
Karekter hangi yöne doğru bakıyorsa o yöne doğru ateş etsin
User prompt
Otomatik ateş etmeyi kaldır oyuncu sadece baktığı yöne ateş etsin
User prompt
Please modify the character shooting system as follows: - The character should always fire bullets in the same direction it is currently moving or being controlled toward. - Add a directional arrow indicator in front of the character to show the current aiming direction, similar to how it is displayed in games like snake.io. - The arrow should smoothly rotate to match the player's facing direction and move with the player, providing a clear visual indicator of the current firing direction. - Ensure that while the player moves in one direction, the bullets are continuously fired in that same direction, matching the direction shown by the arrow. - Test to confirm the arrow and bullet direction stay consistent with the player's movement input. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mermilerimiz hepsi tutmasın rakiplerimiz mermilerden kaçınabilsğn
User prompt
Please upgrade the survivor battle arena game with the following advanced features: 1. Add a skill upgrade system where players can choose from random skills after each wave, such as attack speed, health regeneration, or area damage. 2. Include multiple unique characters with different starting weapons and stats, giving players strategic variety. 3. Introduce elite enemies and boss fights every 5 waves, with special attack patterns. 4. Create a combo multiplier mechanic that rewards players for quickly defeating enemies without getting hit. 5. Add a dynamic soundtrack that intensifies as waves progress, increasing the adrenaline and sense of urgency. 6. Include visual particle effects for explosions, skills, and critical hits to make combat feel more impactful. 7. Make sure the game supports smooth performance on mobile devices by optimizing all assets and keeping frame rates stable. 8. Test the entire gameplay loop after these additions to confirm no bugs and enjoyable flow. Implement these advanced features to create a highly engaging, replayable, and polished survivor battle arena experience. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Hayır sadece başta gelen yazıyı rengarenk yap geri kalan herşey geri kendi haline gelsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make it rainbow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyun başlarken "Move by dragging" yazısı gözüksün yazı 2sn durup fade efekti ile yok olsun sonra rakipler gelemue başlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Karalterimiz dokunduğumuz yere ışınlanmasın dokunduğumuz yerden sürükleyelim neryee sürüklüyorsak oraya yönlensin karakter
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'healthText.style.fill = "#4CAF50";' Line Number: 399
Code edit (1 edits merged)
Please save this source code
User prompt
Survivor Arena
Initial prompt
Create a 2D top-down survivor arena game where the player fights endless waves of enemies, collects powerups, and upgrades weapons to survive as long as possible.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 500;
self.maxHealth = 500;
self.speed = 1.5;
self.damage = 30;
self.lastPlayerDistance = 0;
self.attackCooldown = 0;
self.attackPhase = 0;
self.isBoss = true;
self.update = function () {
// Check for nearby bullets and evade (bosses have moderate evasion)
var evadeX = 0;
var evadeY = 0;
var shouldEvade = false;
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
var bulletDx = bullet.x - self.x;
var bulletDy = bullet.y - self.y;
var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
// Bosses detect bullets from medium range
if (bulletDistance < 100) {
var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY);
if (bulletSpeed > 0) {
// Calculate if bullet is heading towards enemy
var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX);
var enemyDirection = Math.atan2(bulletDy, bulletDx);
var angleDiff = Math.abs(bulletDirection - enemyDirection);
if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff;
// Bosses have narrow detection angle but good reaction
if (angleDiff < Math.PI / 6) {
shouldEvade = true;
// Calculate perpendicular evasion direction
evadeX += -bulletDy / bulletDistance * (100 - bulletDistance) / 100;
evadeY += bulletDx / bulletDistance * (100 - bulletDistance) / 100;
}
}
}
}
// Move towards player slowly
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 100) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Apply evasion if needed (bosses have moderate dodge chance)
if (shouldEvade) {
// 50% chance to successfully evade
if (Math.random() < 0.5) {
moveX += evadeX * 1.5;
moveY += evadeY * 1.5;
}
}
self.x += moveX;
self.y += moveY;
}
// Attack patterns
if (self.attackCooldown > 0) {
self.attackCooldown--;
} else {
self.performAttack();
self.attackCooldown = 120; // 2 seconds
}
// Check collision with player
var currentPlayerDistance = distance;
if (self.lastPlayerDistance > 80 && currentPlayerDistance <= 80) {
player.takeDamage(self.damage);
}
self.lastPlayerDistance = currentPlayerDistance;
};
self.performAttack = function () {
switch (self.attackPhase) {
case 0:
self.circularAttack();
break;
case 1:
self.chargeAttack();
break;
case 2:
self.areaAttack();
break;
}
self.attackPhase = (self.attackPhase + 1) % 3;
};
self.circularAttack = function () {
for (var i = 0; i < 8; i++) {
var angle = i * Math.PI / 4;
var projectile = new EnemyProjectile();
projectile.x = self.x;
projectile.y = self.y;
projectile.velocityX = Math.cos(angle) * 8;
projectile.velocityY = Math.sin(angle) * 8;
enemyProjectiles.push(projectile);
game.addChild(projectile);
}
};
self.chargeAttack = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
tween(self, {
x: self.x + dx / distance * 200,
y: self.y + dy / distance * 200
}, {
duration: 500,
easing: tween.easeOut
});
}
};
self.areaAttack = function () {
createExplosion(self.x, self.y, 150);
LK.getSound('explosion').play();
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
player.takeDamage(self.damage);
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
} else {
LK.effects.flashObject(self, 0xFFFFFF, 100);
}
};
self.die = function () {
createExplosion(self.x, self.y, 200);
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 200);
player.addCombo();
// Boss defeated - show upgrade screen
showUpgradeScreen();
// Remove from enemies array
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] === self) {
enemies.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.isCritical = false;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
var finalDamage = self.damage;
if (self.isCritical) {
finalDamage *= 2;
createExplosion(self.x, self.y, 50);
}
enemy.takeDamage(finalDamage);
player.addCombo();
self.destroy();
// Remove from bullets array
for (var j = 0; j < bullets.length; j++) {
if (bullets[j] === self) {
bullets.splice(j, 1);
break;
}
}
return;
}
}
// Remove if out of bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.destroy();
for (var k = 0; k < bullets.length; k++) {
if (bullets[k] === self) {
bullets.splice(k, 1);
break;
}
}
}
};
return self;
});
var Character = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'warrior';
var characterGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
// Set stats based on character type
switch (self.type) {
case 'warrior':
self.health = 120;
self.maxHealth = 120;
self.damage = 30;
self.fireRate = 18;
self.speed = 7;
self.weaponType = 'sword';
break;
case 'archer':
self.health = 80;
self.maxHealth = 80;
self.damage = 20;
self.fireRate = 10;
self.speed = 10;
self.weaponType = 'bow';
break;
case 'mage':
self.health = 60;
self.maxHealth = 60;
self.damage = 35;
self.fireRate = 25;
self.speed = 8;
self.weaponType = 'staff';
break;
}
self.fireCooldown = 0;
self.comboMultiplier = 1;
self.comboTimer = 0;
self.comboCount = 0;
self.update = function () {
if (self.fireCooldown > 0) {
self.fireCooldown--;
}
if (self.comboTimer > 0) {
self.comboTimer--;
} else {
self.comboMultiplier = 1;
self.comboCount = 0;
}
// Auto-fire at nearest enemy with simple bullets
if (self.fireCooldown <= 0 && enemies.length > 0) {
var nearestEnemy = self.findNearestEnemy();
if (nearestEnemy) {
// Create simple bullet
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * 15;
bullet.velocityY = dy / distance * 15;
bullet.damage = 25; // Basic damage
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.fireCooldown = self.fireRate;
}
}
// Keep player within arena bounds
var arenaLeft = arena.x - arena.width / 2;
var arenaRight = arena.x + arena.width / 2;
var arenaTop = arena.y - arena.height / 2;
var arenaBottom = arena.y + arena.height / 2;
if (self.x < arenaLeft + 40) self.x = arenaLeft + 40;
if (self.x > arenaRight - 40) self.x = arenaRight - 40;
if (self.y < arenaTop + 40) self.y = arenaTop + 40;
if (self.y > arenaBottom - 40) self.y = arenaBottom - 40;
};
self.findNearestEnemy = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = enemy;
}
}
return nearest;
};
self.fireAt = function (target) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * 15;
bullet.velocityY = dy / distance * 15;
bullet.damage = self.damage * self.comboMultiplier;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
self.takeDamage = function (damage) {
self.health -= damage;
self.comboMultiplier = 1;
self.comboCount = 0;
self.comboTimer = 0;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.effects.flashObject(self, 0xFF0000, 200);
};
self.addCombo = function () {
self.comboCount++;
self.comboTimer = 180; // 3 seconds
if (self.comboCount >= 5) {
self.comboMultiplier = Math.min(self.comboMultiplier + 0.1, 3);
}
};
return self;
});
var Player = Character.expand(function (type) {
var self = Character.call(this, type);
// Add critical hit chance
self.criticalChance = 0.1;
// Override fireAt to add critical hits
var originalFireAt = self.fireAt;
self.fireAt = function (target) {
originalFireAt.call(self, target);
// Add critical hit chance
var lastBullet = bullets[bullets.length - 1];
if (lastBullet && Math.random() < self.criticalChance) {
lastBullet.isCritical = true;
lastBullet.children[0].tint = 0xFF4444;
}
};
return self;
});
var EliteEnemy = Container.expand(function () {
var self = Container.call(this);
var eliteGraphics = self.attachAsset('eliteEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 150;
self.maxHealth = 150;
self.speed = 3;
self.damage = 20;
self.lastPlayerDistance = 0;
self.specialCooldown = 0;
self.isElite = true;
self.update = function () {
// Check for nearby bullets and evade (elite enemies are better at dodging)
var evadeX = 0;
var evadeY = 0;
var shouldEvade = false;
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
var bulletDx = bullet.x - self.x;
var bulletDy = bullet.y - self.y;
var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
// Elite enemies detect bullets from further away
if (bulletDistance < 150) {
var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY);
if (bulletSpeed > 0) {
// Calculate if bullet is heading towards enemy
var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX);
var enemyDirection = Math.atan2(bulletDy, bulletDx);
var angleDiff = Math.abs(bulletDirection - enemyDirection);
if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff;
// Elite enemies have wider detection angle
if (angleDiff < Math.PI / 3) {
shouldEvade = true;
// Calculate perpendicular evasion direction
evadeX += -bulletDy / bulletDistance * (150 - bulletDistance) / 150;
evadeY += bulletDx / bulletDistance * (150 - bulletDistance) / 150;
}
}
}
}
// Move towards player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Apply evasion if needed (elite enemies are better at dodging)
if (shouldEvade) {
// 85% chance to successfully evade
if (Math.random() < 0.85) {
moveX += evadeX * 2.5;
moveY += evadeY * 2.5;
}
}
self.x += moveX;
self.y += moveY;
}
// Special ability - dash attack
if (self.specialCooldown > 0) {
self.specialCooldown--;
} else if (distance < 200 && distance > 80) {
self.specialCooldown = 300; // 5 seconds
self.dashAttack();
}
// Check collision with player
var currentPlayerDistance = distance;
if (self.lastPlayerDistance > 50 && currentPlayerDistance <= 50) {
player.takeDamage(self.damage);
}
self.lastPlayerDistance = currentPlayerDistance;
};
self.dashAttack = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
tween(self, {
x: self.x + dx / distance * 150,
y: self.y + dy / distance * 150
}, {
duration: 300,
easing: tween.easeOut
});
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
} else {
LK.effects.flashObject(self, 0xFFFFFF, 100);
}
};
self.die = function () {
createExplosion(self.x, self.y);
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 50);
player.addCombo();
// Higher chance for power-up
if (Math.random() < 0.6) {
var powerup = new PowerUp();
powerup.x = self.x;
powerup.y = self.y;
powerups.push(powerup);
game.addChild(powerup);
}
// Remove from enemies array
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
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 = 2;
self.damage = 10;
self.lastPlayerDistance = 0;
self.update = function () {
// Check for nearby bullets and evade
var evadeX = 0;
var evadeY = 0;
var shouldEvade = false;
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
var bulletDx = bullet.x - self.x;
var bulletDy = bullet.y - self.y;
var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
// If bullet is close (within 120 pixels) and moving towards enemy
if (bulletDistance < 120) {
var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY);
if (bulletSpeed > 0) {
// Calculate if bullet is heading towards enemy
var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX);
var enemyDirection = Math.atan2(bulletDy, bulletDx);
var angleDiff = Math.abs(bulletDirection - enemyDirection);
if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff;
// If bullet is heading towards enemy (within 45 degrees)
if (angleDiff < Math.PI / 4) {
shouldEvade = true;
// Calculate perpendicular evasion direction
evadeX += -bulletDy / bulletDistance * (120 - bulletDistance) / 120;
evadeY += bulletDx / bulletDistance * (120 - bulletDistance) / 120;
}
}
}
}
// Move towards player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Apply evasion if needed
if (shouldEvade) {
// 70% chance to successfully evade
if (Math.random() < 0.7) {
moveX += evadeX * 2;
moveY += evadeY * 2;
}
}
self.x += moveX;
self.y += moveY;
}
// Check collision with player
var currentPlayerDistance = distance;
if (self.lastPlayerDistance > 50 && currentPlayerDistance <= 50) {
player.takeDamage(self.damage);
}
self.lastPlayerDistance = currentPlayerDistance;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
} else {
LK.effects.flashObject(self, 0xFFFFFF, 100);
}
};
self.die = function () {
createExplosion(self.x, self.y);
LK.getSound('enemyHit').play();
LK.setScore(LK.getScore() + 10);
player.addCombo();
// Chance to drop power-up
if (Math.random() < 0.3) {
var powerup = new PowerUp();
powerup.x = self.x;
powerup.y = self.y;
powerups.push(powerup);
game.addChild(powerup);
}
// Remove from enemies array
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var EnemyProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
projectileGraphics.tint = 0xFF0000;
self.velocityX = 0;
self.velocityY = 0;
self.damage = 15;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with player
if (self.intersects(player)) {
player.takeDamage(self.damage);
self.destroy();
for (var i = 0; i < enemyProjectiles.length; i++) {
if (enemyProjectiles[i] === self) {
enemyProjectiles.splice(i, 1);
break;
}
}
return;
}
// Remove if out of bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.destroy();
for (var j = 0; j < enemyProjectiles.length; j++) {
if (enemyProjectiles[j] === self) {
enemyProjectiles.splice(j, 1);
break;
}
}
}
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 30;
explosionGraphics.alpha = 0.8;
self.update = function () {
self.lifetime--;
explosionGraphics.alpha = self.lifetime / 30;
explosionGraphics.scaleX = explosionGraphics.scaleY = (30 - self.lifetime) / 30 * 2;
if (self.lifetime <= 0) {
self.destroy();
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = Math.floor(Math.random() * 4); // 0: health, 1: damage, 2: fire rate, 3: speed
self.lifetime = 600; // 10 seconds at 60fps
// Color based on type
var colors = [0x4CAF50, 0xFF5722, 0x2196F3, 0xFFEB3B];
powerupGraphics.tint = colors[self.type];
self.update = function () {
self.lifetime--;
// Fade out near end of lifetime
if (self.lifetime < 120) {
powerupGraphics.alpha = self.lifetime / 120;
}
// Remove if expired
if (self.lifetime <= 0) {
self.destroy();
for (var i = 0; i < powerups.length; i++) {
if (powerups[i] === self) {
powerups.splice(i, 1);
break;
}
}
return;
}
// Check collision with player
if (self.intersects(player)) {
self.applyEffect();
LK.getSound('powerupCollect').play();
self.destroy();
for (var j = 0; j < powerups.length; j++) {
if (powerups[j] === self) {
powerups.splice(j, 1);
break;
}
}
}
};
self.applyEffect = function () {
switch (self.type) {
case 0:
// Health
player.health = Math.min(player.health + 30, player.maxHealth);
break;
case 1:
// Damage
player.damage += 5;
break;
case 2:
// Fire rate
player.fireRate = Math.max(player.fireRate - 2, 5);
break;
case 3:
// Speed
player.speed = Math.min(player.speed + 1, 15);
break;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C2C2C
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var bullets = [];
var powerups = [];
var enemyProjectiles = [];
var explosions = [];
var arena;
var waveNumber = 1;
var enemySpawnTimer = 0;
var enemySpawnRate = 120; // 2 seconds at 60fps
var gameTime = 0;
var selectedCharacter = storage.selectedCharacter || 'warrior';
var upgradeScreenActive = false;
var currentMusicTrack = 'battleMusic';
var musicIntensity = 0;
// Create arena
arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create player
player = game.addChild(new Player(selectedCharacter));
player.x = 1024;
player.y = 1366;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -300;
scoreText.y = 50;
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0x4CAF50
});
healthText.anchor.set(0, 0);
LK.gui.topRight.addChild(healthText);
healthText.x = -300;
healthText.y = 120;
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0, 0);
LK.gui.topRight.addChild(waveText);
waveText.x = -300;
waveText.y = 190;
var comboText = new Text2('Combo: x1', {
size: 50,
fill: 0xFFEB3B
});
comboText.anchor.set(0, 0);
LK.gui.topRight.addChild(comboText);
comboText.x = -300;
comboText.y = 260;
// Tutorial text
var tutorialText = new Text2('Move by dragging', {
size: 80,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 1366;
game.addChild(tutorialText);
// Add rainbow cycling to tutorial text
var tutorialColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x9400D3];
var tutorialColorIndex = 0;
function cycleTutorialRainbow() {
var nextColor = tutorialColors[(tutorialColorIndex + 1) % tutorialColors.length];
tween(tutorialText, {
tint: nextColor
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tutorialColorIndex = (tutorialColorIndex + 1) % tutorialColors.length;
cycleTutorialRainbow();
}
});
}
cycleTutorialRainbow();
// Fade out tutorial text after 2 seconds
LK.setTimeout(function () {
tween(tutorialText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
tutorialText.destroy();
}
});
}, 2000);
// Touch controls
var isDragging = false;
var dragOffsetX = 0;
var dragOffsetY = 0;
var gameStarted = false;
game.down = function (x, y, obj) {
isDragging = true;
// Calculate offset from touch point to player center
dragOffsetX = player.x - x;
dragOffsetY = player.y - y;
};
game.move = function (x, y, obj) {
if (isDragging) {
// Move player by maintaining the offset from touch point
player.x = x + dragOffsetX;
player.y = y + dragOffsetY;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Utility functions
function createExplosion(x, y, size) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
if (size) {
explosion.children[0].scaleX = explosion.children[0].scaleY = size / 100;
}
explosions.push(explosion);
game.addChild(explosion);
}
function showUpgradeScreen() {
upgradeScreenActive = true;
var upgradePanel = LK.getAsset('skillPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
game.addChild(upgradePanel);
var upgradeTitle = new Text2('Choose an Upgrade', {
size: 60,
fill: 0xFFFFFF
});
upgradeTitle.anchor.set(0.5, 0.5);
upgradeTitle.x = 1024;
upgradeTitle.y = 1200;
game.addChild(upgradeTitle);
var upgrades = [{
name: 'Attack Speed',
desc: 'Faster firing rate'
}, {
name: 'Health Boost',
desc: 'Increase max health'
}, {
name: 'Critical Hit',
desc: 'Higher crit chance'
}];
for (var i = 0; i < 3; i++) {
var button = LK.getAsset('skillButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 700 + i * 200,
y: 1366
});
game.addChild(button);
var buttonText = new Text2(upgrades[i].name, {
size: 30,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 700 + i * 200;
buttonText.y = 1366;
game.addChild(buttonText);
button.down = function (x, y, obj) {
applyUpgrade(i);
upgradePanel.destroy();
upgradeTitle.destroy();
for (var j = 0; j < 3; j++) {
game.children[game.children.length - 1].destroy();
game.children[game.children.length - 1].destroy();
}
upgradeScreenActive = false;
};
}
}
function applyUpgrade(type) {
switch (type) {
case 0:
// Attack Speed
player.fireRate = Math.max(player.fireRate - 3, 5);
break;
case 1:
// Health Boost
player.maxHealth += 30;
player.health = Math.min(player.health + 30, player.maxHealth);
break;
case 2:
// Critical Hit
player.criticalChance = Math.min(player.criticalChance + 0.1, 0.5);
break;
}
}
// Spawn enemy function
function spawnEnemy() {
var enemy;
// Boss every 5 waves
if (waveNumber % 5 === 0 && enemies.length === 0) {
enemy = new Boss();
LK.getSound('bossSpawn').play();
LK.playMusic('bossMusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
} else if (Math.random() < 0.2) {
// 20% chance for elite enemy
enemy = new EliteEnemy();
} else {
enemy = new Enemy();
}
// Spawn from arena edges
var side = Math.floor(Math.random() * 4);
var arenaLeft = arena.x - arena.width / 2;
var arenaRight = arena.x + arena.width / 2;
var arenaTop = arena.y - arena.height / 2;
var arenaBottom = arena.y + arena.height / 2;
switch (side) {
case 0:
// Top
enemy.x = arenaLeft + Math.random() * arena.width;
enemy.y = arenaTop;
break;
case 1:
// Right
enemy.x = arenaRight;
enemy.y = arenaTop + Math.random() * arena.height;
break;
case 2:
// Bottom
enemy.x = arenaLeft + Math.random() * arena.width;
enemy.y = arenaBottom;
break;
case 3:
// Left
enemy.x = arenaLeft;
enemy.y = arenaTop + Math.random() * arena.height;
break;
}
// Scale enemy stats with wave number
if (!enemy.isBoss) {
enemy.health += Math.floor(waveNumber * 5);
enemy.speed += Math.floor(waveNumber * 0.2);
enemy.damage += Math.floor(waveNumber * 2);
}
enemies.push(enemy);
game.addChild(enemy);
}
// Main game loop
game.update = function () {
// Start game logic after 3 seconds (tutorial display time)
if (gameTime < 180) {
// 3 seconds at 60fps
gameTime++;
return;
}
if (!gameStarted) {
gameStarted = true;
LK.playMusic('battleMusic');
}
if (upgradeScreenActive) {
return;
}
gameTime++;
// Update wave number based on time
var newWave = Math.floor(gameTime / 1800) + 1; // New wave every 30 seconds
if (newWave > waveNumber) {
waveNumber = newWave;
enemySpawnRate = Math.max(enemySpawnRate - 10, 30); // Increase spawn rate
// Dynamic music intensity
musicIntensity = Math.min(waveNumber / 10, 1);
if (waveNumber % 5 !== 0) {
LK.playMusic('battleMusic', {
fade: {
start: 0.5,
end: 0.5 + musicIntensity * 0.5,
duration: 500
}
});
}
}
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
var enemiesToSpawn = Math.min(waveNumber, 8);
for (var i = 0; i < enemiesToSpawn; i++) {
spawnEnemy();
}
enemySpawnTimer = 0;
}
// Update explosions
for (var e = explosions.length - 1; e >= 0; e--) {
var explosion = explosions[e];
if (explosion.lifetime <= 0) {
explosions.splice(e, 1);
}
}
// Update UI
scoreText.setText('Score: ' + LK.getScore());
healthText.setText('Health: ' + player.health);
waveText.setText('Wave: ' + waveNumber);
comboText.setText('Combo: x' + player.comboMultiplier.toFixed(1));
// Update health text color based on health percentage
var healthPercent = player.health / player.maxHealth;
if (healthPercent > 0.6) {
healthText.tint = 0x4CAF50;
} else if (healthPercent > 0.3) {
healthText.tint = 0xFF9800;
} else {
healthText.tint = 0xF44336;
}
// Update combo text color
if (player.comboMultiplier > 2) {
comboText.tint = 0xFF4444;
} else if (player.comboMultiplier > 1.5) {
comboText.tint = 0xFFAA00;
} else {
comboText.tint = 0xFFEB3B;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -243,40 +243,9 @@
self.fireCooldown = 0;
self.comboMultiplier = 1;
self.comboTimer = 0;
self.comboCount = 0;
- self.lastX = 0;
- self.lastY = 0;
- self.aimDirection = 0;
- self.movementDirection = 0;
- // Create arrow indicator
- self.arrowIndicator = self.attachAsset('arrow', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.arrowIndicator.x = 0;
- self.arrowIndicator.y = -50;
self.update = function () {
- // Track movement for visual rotation only
- var deltaX = self.x - self.lastX;
- var deltaY = self.y - self.lastY;
- var movementSpeed = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- // Update character's facing direction based on movement
- if (movementSpeed > 0.5) {
- self.movementDirection = Math.atan2(deltaY, deltaX);
- // Character faces the direction it's moving
- self.aimDirection = self.movementDirection;
- // Smoothly rotate arrow to match facing direction
- tween(self.arrowIndicator, {
- rotation: self.aimDirection
- }, {
- duration: 100,
- easing: tween.easeOut
- });
- }
- // Update last position
- self.lastX = self.x;
- self.lastY = self.y;
if (self.fireCooldown > 0) {
self.fireCooldown--;
}
if (self.comboTimer > 0) {
@@ -284,12 +253,27 @@
} else {
self.comboMultiplier = 1;
self.comboCount = 0;
}
- // Manual firing - fire continuously in current facing direction
- if (self.fireCooldown <= 0) {
- self.fireAt(null); // Fire in current facing direction
- self.fireCooldown = self.fireRate;
+ // Auto-fire at nearest enemy with simple bullets
+ if (self.fireCooldown <= 0 && enemies.length > 0) {
+ var nearestEnemy = self.findNearestEnemy();
+ if (nearestEnemy) {
+ // Create simple bullet
+ var bullet = new Bullet();
+ bullet.x = self.x;
+ bullet.y = self.y;
+ var dx = nearestEnemy.x - self.x;
+ var dy = nearestEnemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ bullet.velocityX = dx / distance * 15;
+ bullet.velocityY = dy / distance * 15;
+ bullet.damage = 25; // Basic damage
+ bullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('shoot').play();
+ self.fireCooldown = self.fireRate;
+ }
}
// Keep player within arena bounds
var arenaLeft = arena.x - arena.width / 2;
var arenaRight = arena.x + arena.width / 2;
@@ -299,16 +283,32 @@
if (self.x > arenaRight - 40) self.x = arenaRight - 40;
if (self.y < arenaTop + 40) self.y = arenaTop + 40;
if (self.y > arenaBottom - 40) self.y = arenaBottom - 40;
};
- // findNearestEnemy method removed - no longer needed for manual firing
+ self.findNearestEnemy = function () {
+ var nearest = null;
+ var nearestDistance = Infinity;
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - self.x;
+ var dy = enemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < nearestDistance) {
+ nearestDistance = distance;
+ nearest = enemy;
+ }
+ }
+ return nearest;
+ };
self.fireAt = function (target) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
- // Fire in the current aim direction instead of towards target
- bullet.velocityX = Math.cos(self.aimDirection) * 15;
- bullet.velocityY = Math.sin(self.aimDirection) * 15;
+ var dx = target.x - self.x;
+ var dy = target.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ bullet.velocityX = dx / distance * 15;
+ bullet.velocityY = dy / distance * 15;
bullet.damage = self.damage * self.comboMultiplier;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
@@ -722,11 +722,8 @@
// Create player
player = game.addChild(new Player(selectedCharacter));
player.x = 1024;
player.y = 1366;
-// Initialize last position for movement tracking
-player.lastX = player.x;
-player.lastY = player.y;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
An arow white. In-Game asset. 2d. High contrast. No shadows
Post apocalyptic man pixel art less pixel. In-Game asset. 2d. High contrast. No shadows. Pixel art
Kamp ateşi ve etrafındaki taşlar daha küçük olsun ve harita daha büyük olsun(daha da yukarıdan bakıyormuş gibi)
Post apocalyptic zombie pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Post Apocalyptic boss zombie pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Pixel art shotgun less pixel. In-Game asset. 2d. High contrast. No shadows. Pixel art
Particles are scattered around scattered particles pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Pistol post apocalyptic world pixel art less pixel. In-Game asset. 2d. High contrast. No shadows