/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); self.speed = 3; self.direction = 0; self.lastX = 0; self.lastY = 0; var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.lastX = self.x; self.lastY = self.y; self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.health = 3; self.maxHealth = 3; self.attackTimer = 0; self.attackPattern = 0; self.mercyProgress = 0; self.currentWave = 1; self.bulletsInCurrentWave = 0; self.maxBulletsPerWave = 1; self.hitCount = 0; self.name = "Lost Soul"; self.dialogue = ["Kaportacı Taner Sana Sinirlendi!", "Acı Çektiğini Anladı!", "Sana Üzülmeye Başladı!", "Taner Özürünü Kabul Etti!"]; var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function () { self.health--; self.hitCount++; // Calculate bullets: start with 1, double every 2 hits self.maxBulletsPerWave = Math.pow(2, Math.floor(self.hitCount / 2)); LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.defeat(); } }; self.showMercy = function () { self.mercyProgress++; LK.getSound('mercy').play(); if (self.mercyProgress >= 3) { self.pacify(); } }; self.defeat = function () { LK.getSound('defeat').play(); LK.setScore(LK.getScore() + 10); self.destroy(); currentEnemy = null; gameState = 'victory'; showVictoryMessage("TANERİ YENDİN!"); }; self.pacify = function () { LK.setScore(LK.getScore() + 25); tween(self, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); currentEnemy = null; gameState = 'victory'; showVictoryMessage("Taner Özürünü Kabul Edip Gitti!"); }; self.attack = function () { self.attackTimer++; // Bullets spawn faster over time - starts at every 60 frames, reduces to every 30 frames var spawnInterval = Math.max(30, 60 - Math.floor(self.attackPattern / 10)); if (self.attackTimer % spawnInterval === 0) { self.createBulletPattern(); } }; self.createBulletPattern = function () { // Calculate bullets to spawn this wave - increases over time var bulletsToSpawn = Math.min(1 + Math.floor(self.attackPattern / 5), self.maxBulletsPerWave * 2); for (var i = 0; i < bulletsToSpawn; i++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var baseAngle = Math.atan2(soul.y - self.y, soul.x - self.x); if (bulletsToSpawn === 1) { bullet.direction = baseAngle; } else { bullet.direction = baseAngle + (i - (bulletsToSpawn - 1) / 2) * 0.4; } bullet.speed = (2 + bulletsToSpawn * 0.1) * currentBulletSpeedMultiplier; bullets.push(bullet); game.addChild(bullet); } self.attackPattern++; }; self.update = function () { if (gameState === 'combat') { self.attack(); } }; return self; }); var Soul = Container.expand(function () { var self = Container.call(this); self.health = 3; self.maxHealth = 3; self.speed = 8; var soulGraphics = self.attachAsset('soul', { anchorX: 0.5, anchorY: 0.5, scaleY: 1.2 }); self.takeDamage = function () { self.health--; LK.effects.flashObject(self, 0xff0000, 500); LK.getSound('hit').play(); if (self.health <= 0) { LK.showGameOver(); } }; self.update = function () { // Keep soul within battle area bounds if (self.x < battleArea.x + 50) self.x = battleArea.x + 50; if (self.x > battleArea.x + battleArea.width - 50) self.x = battleArea.x + battleArea.width - 50; if (self.y < battleArea.y + 50) self.y = battleArea.y + 50; if (self.y > battleArea.y + battleArea.height - 50) self.y = battleArea.y + battleArea.height - 50; }; return self; }); var WarningShape = Container.expand(function () { var self = Container.call(this); self.lifetime = 0; self.maxLifetime = 180; // 3 seconds at 60fps var warningGraphics = self.attachAsset('gfd', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); warningGraphics.tint = 0xff0000; // Red color self.update = function () { self.lifetime++; // Pulsing animation var scale = 1.5 + Math.sin(self.lifetime * 0.2) * 0.3; self.scaleX = scale; self.scaleY = scale; // Remove after lifetime expires if (self.lifetime >= self.maxLifetime) { for (var i = warningShapes.length - 1; i >= 0; i--) { if (warningShapes[i] === self) { warningShapes.splice(i, 1); break; } } self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state management var gameState = 'combat'; // 'combat', 'dialogue', 'victory' var soul; var currentEnemy; var bullets = []; var battleArea; var dialogueUI; var currentDialogueIndex = 0; var warningShapes = []; var warningTimer = 0; var WARNING_INTERVAL = 300; // 5 seconds at 60fps var bulletSpeedTimer = 0; var SPEED_INCREASE_INTERVAL = 300; // 5 seconds at 60fps var currentBulletSpeedMultiplier = 1.0; // Battle area definition battleArea = { x: 400, y: 1500, width: 1248, height: 800 }; // Create battle area border var battleBorder = LK.getAsset('dialogBox', { width: battleArea.width + 20, height: battleArea.height + 20, anchorX: 0.5, anchorY: 0.5, x: battleArea.x + battleArea.width / 2, y: battleArea.y + battleArea.height / 2 }); battleBorder.alpha = 0.3; game.addChild(battleBorder); // Create soul soul = game.addChild(new Soul()); soul.x = battleArea.x + battleArea.width / 2; soul.y = battleArea.y + battleArea.height / 2; // Create enemy currentEnemy = game.addChild(new Enemy()); currentEnemy.x = 1024; currentEnemy.y = 800; // Create UI elements var healthText = new Text2('Health: 3/3', { size: 60, fill: 0xFF4444 }); healthText.anchor.set(0, 0); LK.gui.topLeft.addChild(healthText); healthText.x = 120; healthText.y = 20; var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Dialogue system dialogueUI = LK.getAsset('dialogBox', { anchorX: 0.5, anchorY: 0, x: 1024, y: 100 }); dialogueUI.alpha = 0.8; game.addChild(dialogueUI); var dialogueText = new Text2('', { size: 50, fill: 0xFFFFFF }); dialogueText.anchor.set(0.5, 0); dialogueText.x = 1024; dialogueText.y = 150; game.addChild(dialogueText); // Action buttons var fightButton = new Text2('Tanere Vur!', { size: 80, fill: 0xFF4444 }); fightButton.anchor.set(0.5, 0.5); fightButton.x = 700; fightButton.y = 350; game.addChild(fightButton); var mercyButton = new Text2('Özür Dile!', { size: 80, fill: 0x44FF44 }); mercyButton.anchor.set(0.5, 0.5); mercyButton.x = 1348; mercyButton.y = 350; game.addChild(mercyButton); // Initialize dialogue function updateDialogue() { if (currentEnemy && currentDialogueIndex < currentEnemy.dialogue.length) { dialogueText.setText(currentEnemy.dialogue[currentDialogueIndex]); } } function showVictoryMessage(message) { dialogueText.setText(message); fightButton.alpha = 0.3; mercyButton.alpha = 0.3; LK.setTimeout(function () { // Spawn new enemy after victory spawnNewEnemy(); }, 2000); } function spawnNewEnemy() { // Clear all bullets for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].destroy(); bullets.splice(i, 1); } // Create new enemy currentEnemy = game.addChild(new Enemy()); currentEnemy.x = 1024; currentEnemy.y = 800; currentEnemy.currentWave = 1; currentEnemy.bulletsInCurrentWave = 0; currentEnemy.maxBulletsPerWave = 1; currentEnemy.hitCount = 0; bulletSpeedTimer = 0; currentBulletSpeedMultiplier = 1.0; gameState = 'combat'; currentDialogueIndex = 0; updateDialogue(); fightButton.alpha = 1; mercyButton.alpha = 1; } // Initialize first dialogue updateDialogue(); // Touch controls for soul movement var isDragging = false; game.down = function (x, y, obj) { var soulPos = game.toLocal(soul.parent.toGlobal(soul.position)); var distance = Math.sqrt(Math.pow(x - soulPos.x, 2) + Math.pow(y - soulPos.y, 2)); if (distance < 100) { isDragging = true; } }; game.move = function (x, y, obj) { if (isDragging && gameState === 'combat') { soul.x = x; soul.y = y; } }; game.up = function (x, y, obj) { isDragging = false; }; // Button interactions fightButton.down = function (x, y, obj) { if (currentEnemy && gameState === 'combat') { currentEnemy.takeDamage(); if (currentEnemy && currentEnemy.dialogue) { currentDialogueIndex = Math.min(currentDialogueIndex + 1, currentEnemy.dialogue.length - 1); updateDialogue(); } } }; mercyButton.down = function (x, y, obj) { if (currentEnemy && gameState === 'combat') { currentEnemy.showMercy(); if (currentEnemy && currentEnemy.dialogue) { currentDialogueIndex = Math.min(currentDialogueIndex + 1, currentEnemy.dialogue.length - 1); updateDialogue(); } } }; // Main game loop game.update = function () { // Update UI healthText.setText('Kalan Can: ' + soul.health + '/' + soul.maxHealth); scoreText.setText('Puan: ' + LK.getScore()); // Bullet speed acceleration system if (gameState === 'combat') { bulletSpeedTimer++; if (bulletSpeedTimer >= SPEED_INCREASE_INTERVAL) { bulletSpeedTimer = 0; var newSpeedMultiplier = currentBulletSpeedMultiplier + 0.3; // Smoothly accelerate all existing bullets for (var b = 0; b < bullets.length; b++) { var bullet = bullets[b]; var currentSpeed = bullet.speed; var newSpeed = currentSpeed * (newSpeedMultiplier / currentBulletSpeedMultiplier); tween(bullet, { speed: newSpeed }, { duration: 1000, easing: tween.easeOut }); } currentBulletSpeedMultiplier = newSpeedMultiplier; } } // Warning shape spawning system if (gameState === 'combat') { warningTimer++; if (warningTimer >= WARNING_INTERVAL) { warningTimer = 0; // Spawn warning shape at random position in battle area var warning = new WarningShape(); warning.x = battleArea.x + Math.random() * battleArea.width; warning.y = battleArea.y + Math.random() * battleArea.height; warningShapes.push(warning); game.addChild(warning); // Animate warning appearance tween(warning, { scaleX: 2.0, scaleY: 2.0 }, { duration: 500, easing: tween.easeOut }); } } // Check warning shape collisions with soul for (var w = warningShapes.length - 1; w >= 0; w--) { var warning = warningShapes[w]; if (warning.intersects(soul)) { soul.takeDamage(); warning.destroy(); warningShapes.splice(w, 1); } } if (gameState === 'combat') { // Check bullet collisions with soul for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Check if bullet is out of bounds if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with soul if (bullet.intersects(soul)) { soul.takeDamage(); bullet.destroy(); bullets.splice(i, 1); continue; } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 3;
self.direction = 0;
self.lastX = 0;
self.lastY = 0;
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.health = 3;
self.maxHealth = 3;
self.attackTimer = 0;
self.attackPattern = 0;
self.mercyProgress = 0;
self.currentWave = 1;
self.bulletsInCurrentWave = 0;
self.maxBulletsPerWave = 1;
self.hitCount = 0;
self.name = "Lost Soul";
self.dialogue = ["Kaportacı Taner Sana Sinirlendi!", "Acı Çektiğini Anladı!", "Sana Üzülmeye Başladı!", "Taner Özürünü Kabul Etti!"];
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function () {
self.health--;
self.hitCount++;
// Calculate bullets: start with 1, double every 2 hits
self.maxBulletsPerWave = Math.pow(2, Math.floor(self.hitCount / 2));
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.defeat();
}
};
self.showMercy = function () {
self.mercyProgress++;
LK.getSound('mercy').play();
if (self.mercyProgress >= 3) {
self.pacify();
}
};
self.defeat = function () {
LK.getSound('defeat').play();
LK.setScore(LK.getScore() + 10);
self.destroy();
currentEnemy = null;
gameState = 'victory';
showVictoryMessage("TANERİ YENDİN!");
};
self.pacify = function () {
LK.setScore(LK.getScore() + 25);
tween(self, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
currentEnemy = null;
gameState = 'victory';
showVictoryMessage("Taner Özürünü Kabul Edip Gitti!");
};
self.attack = function () {
self.attackTimer++;
// Bullets spawn faster over time - starts at every 60 frames, reduces to every 30 frames
var spawnInterval = Math.max(30, 60 - Math.floor(self.attackPattern / 10));
if (self.attackTimer % spawnInterval === 0) {
self.createBulletPattern();
}
};
self.createBulletPattern = function () {
// Calculate bullets to spawn this wave - increases over time
var bulletsToSpawn = Math.min(1 + Math.floor(self.attackPattern / 5), self.maxBulletsPerWave * 2);
for (var i = 0; i < bulletsToSpawn; i++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var baseAngle = Math.atan2(soul.y - self.y, soul.x - self.x);
if (bulletsToSpawn === 1) {
bullet.direction = baseAngle;
} else {
bullet.direction = baseAngle + (i - (bulletsToSpawn - 1) / 2) * 0.4;
}
bullet.speed = (2 + bulletsToSpawn * 0.1) * currentBulletSpeedMultiplier;
bullets.push(bullet);
game.addChild(bullet);
}
self.attackPattern++;
};
self.update = function () {
if (gameState === 'combat') {
self.attack();
}
};
return self;
});
var Soul = Container.expand(function () {
var self = Container.call(this);
self.health = 3;
self.maxHealth = 3;
self.speed = 8;
var soulGraphics = self.attachAsset('soul', {
anchorX: 0.5,
anchorY: 0.5,
scaleY: 1.2
});
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('hit').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
self.update = function () {
// Keep soul within battle area bounds
if (self.x < battleArea.x + 50) self.x = battleArea.x + 50;
if (self.x > battleArea.x + battleArea.width - 50) self.x = battleArea.x + battleArea.width - 50;
if (self.y < battleArea.y + 50) self.y = battleArea.y + 50;
if (self.y > battleArea.y + battleArea.height - 50) self.y = battleArea.y + battleArea.height - 50;
};
return self;
});
var WarningShape = Container.expand(function () {
var self = Container.call(this);
self.lifetime = 0;
self.maxLifetime = 180; // 3 seconds at 60fps
var warningGraphics = self.attachAsset('gfd', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
warningGraphics.tint = 0xff0000; // Red color
self.update = function () {
self.lifetime++;
// Pulsing animation
var scale = 1.5 + Math.sin(self.lifetime * 0.2) * 0.3;
self.scaleX = scale;
self.scaleY = scale;
// Remove after lifetime expires
if (self.lifetime >= self.maxLifetime) {
for (var i = warningShapes.length - 1; i >= 0; i--) {
if (warningShapes[i] === self) {
warningShapes.splice(i, 1);
break;
}
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state management
var gameState = 'combat'; // 'combat', 'dialogue', 'victory'
var soul;
var currentEnemy;
var bullets = [];
var battleArea;
var dialogueUI;
var currentDialogueIndex = 0;
var warningShapes = [];
var warningTimer = 0;
var WARNING_INTERVAL = 300; // 5 seconds at 60fps
var bulletSpeedTimer = 0;
var SPEED_INCREASE_INTERVAL = 300; // 5 seconds at 60fps
var currentBulletSpeedMultiplier = 1.0;
// Battle area definition
battleArea = {
x: 400,
y: 1500,
width: 1248,
height: 800
};
// Create battle area border
var battleBorder = LK.getAsset('dialogBox', {
width: battleArea.width + 20,
height: battleArea.height + 20,
anchorX: 0.5,
anchorY: 0.5,
x: battleArea.x + battleArea.width / 2,
y: battleArea.y + battleArea.height / 2
});
battleBorder.alpha = 0.3;
game.addChild(battleBorder);
// Create soul
soul = game.addChild(new Soul());
soul.x = battleArea.x + battleArea.width / 2;
soul.y = battleArea.y + battleArea.height / 2;
// Create enemy
currentEnemy = game.addChild(new Enemy());
currentEnemy.x = 1024;
currentEnemy.y = 800;
// Create UI elements
var healthText = new Text2('Health: 3/3', {
size: 60,
fill: 0xFF4444
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Dialogue system
dialogueUI = LK.getAsset('dialogBox', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 100
});
dialogueUI.alpha = 0.8;
game.addChild(dialogueUI);
var dialogueText = new Text2('', {
size: 50,
fill: 0xFFFFFF
});
dialogueText.anchor.set(0.5, 0);
dialogueText.x = 1024;
dialogueText.y = 150;
game.addChild(dialogueText);
// Action buttons
var fightButton = new Text2('Tanere Vur!', {
size: 80,
fill: 0xFF4444
});
fightButton.anchor.set(0.5, 0.5);
fightButton.x = 700;
fightButton.y = 350;
game.addChild(fightButton);
var mercyButton = new Text2('Özür Dile!', {
size: 80,
fill: 0x44FF44
});
mercyButton.anchor.set(0.5, 0.5);
mercyButton.x = 1348;
mercyButton.y = 350;
game.addChild(mercyButton);
// Initialize dialogue
function updateDialogue() {
if (currentEnemy && currentDialogueIndex < currentEnemy.dialogue.length) {
dialogueText.setText(currentEnemy.dialogue[currentDialogueIndex]);
}
}
function showVictoryMessage(message) {
dialogueText.setText(message);
fightButton.alpha = 0.3;
mercyButton.alpha = 0.3;
LK.setTimeout(function () {
// Spawn new enemy after victory
spawnNewEnemy();
}, 2000);
}
function spawnNewEnemy() {
// Clear all bullets
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].destroy();
bullets.splice(i, 1);
}
// Create new enemy
currentEnemy = game.addChild(new Enemy());
currentEnemy.x = 1024;
currentEnemy.y = 800;
currentEnemy.currentWave = 1;
currentEnemy.bulletsInCurrentWave = 0;
currentEnemy.maxBulletsPerWave = 1;
currentEnemy.hitCount = 0;
bulletSpeedTimer = 0;
currentBulletSpeedMultiplier = 1.0;
gameState = 'combat';
currentDialogueIndex = 0;
updateDialogue();
fightButton.alpha = 1;
mercyButton.alpha = 1;
}
// Initialize first dialogue
updateDialogue();
// Touch controls for soul movement
var isDragging = false;
game.down = function (x, y, obj) {
var soulPos = game.toLocal(soul.parent.toGlobal(soul.position));
var distance = Math.sqrt(Math.pow(x - soulPos.x, 2) + Math.pow(y - soulPos.y, 2));
if (distance < 100) {
isDragging = true;
}
};
game.move = function (x, y, obj) {
if (isDragging && gameState === 'combat') {
soul.x = x;
soul.y = y;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Button interactions
fightButton.down = function (x, y, obj) {
if (currentEnemy && gameState === 'combat') {
currentEnemy.takeDamage();
if (currentEnemy && currentEnemy.dialogue) {
currentDialogueIndex = Math.min(currentDialogueIndex + 1, currentEnemy.dialogue.length - 1);
updateDialogue();
}
}
};
mercyButton.down = function (x, y, obj) {
if (currentEnemy && gameState === 'combat') {
currentEnemy.showMercy();
if (currentEnemy && currentEnemy.dialogue) {
currentDialogueIndex = Math.min(currentDialogueIndex + 1, currentEnemy.dialogue.length - 1);
updateDialogue();
}
}
};
// Main game loop
game.update = function () {
// Update UI
healthText.setText('Kalan Can: ' + soul.health + '/' + soul.maxHealth);
scoreText.setText('Puan: ' + LK.getScore());
// Bullet speed acceleration system
if (gameState === 'combat') {
bulletSpeedTimer++;
if (bulletSpeedTimer >= SPEED_INCREASE_INTERVAL) {
bulletSpeedTimer = 0;
var newSpeedMultiplier = currentBulletSpeedMultiplier + 0.3;
// Smoothly accelerate all existing bullets
for (var b = 0; b < bullets.length; b++) {
var bullet = bullets[b];
var currentSpeed = bullet.speed;
var newSpeed = currentSpeed * (newSpeedMultiplier / currentBulletSpeedMultiplier);
tween(bullet, {
speed: newSpeed
}, {
duration: 1000,
easing: tween.easeOut
});
}
currentBulletSpeedMultiplier = newSpeedMultiplier;
}
}
// Warning shape spawning system
if (gameState === 'combat') {
warningTimer++;
if (warningTimer >= WARNING_INTERVAL) {
warningTimer = 0;
// Spawn warning shape at random position in battle area
var warning = new WarningShape();
warning.x = battleArea.x + Math.random() * battleArea.width;
warning.y = battleArea.y + Math.random() * battleArea.height;
warningShapes.push(warning);
game.addChild(warning);
// Animate warning appearance
tween(warning, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 500,
easing: tween.easeOut
});
}
}
// Check warning shape collisions with soul
for (var w = warningShapes.length - 1; w >= 0; w--) {
var warning = warningShapes[w];
if (warning.intersects(soul)) {
soul.takeDamage();
warning.destroy();
warningShapes.splice(w, 1);
}
}
if (gameState === 'combat') {
// Check bullet collisions with soul
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check if bullet is out of bounds
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with soul
if (bullet.intersects(soul)) {
soul.takeDamage();
bullet.destroy();
bullets.splice(i, 1);
continue;
}
}
}
};