User prompt
There is should be clickable language button And now, it only have English
User prompt
Language button should be clickable
User prompt
Language button should be clickable and should on the right bottom
User prompt
There is should be a language button and this button should have English
User prompt
Make "Saçılım mermi" to "Bölünen Mermi"
User prompt
"Boş" texts are should be "Boss"
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'mainMenu.destroy();' Line Number: 1615
User prompt
Game UI should be Turkish
User prompt
Game UI should be Spanish
User prompt
Skins button should be clickable
User prompt
Add skins button on the main menu.
User prompt
Wide bullet should not have be a wait time
User prompt
In both battle bosses should not have phase 2's.
User prompt
Make Zesty Pickle playable.
User prompt
Remove "Mega Orange Coming Soon" and Add "Zesty Pickle"
User prompt
Boss health and health texts should not appear in the main menu.
User prompt
There must be spaces between the bullet selection keys
User prompt
There must be a new bullet, this bullet should shoot backwards and deal 8 damage.
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'var savedLanguage = storage.getItem('selectedLanguage');' Line Number: 1946 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
There should be an option to change the language in the main menu.
User prompt
A mode should be added where we can fight Pineapple Horse and Monster Watermelon at the same time, and their health bars should be different.
User prompt
It doesn't work.
User prompt
When you defeat the Monster Watermelon in Marathon mode, "You Win!" screen should not appear. Instead, the player should start fighting the Pineapple Horse. When he defeats the Pineapple Horse, the "You Win" screen should appear.
User prompt
Something that resembles a new boss should be added and its name should be "Marathon". In Marathon, we fight the bosses present in the game. First, we start with the Monster Watermelon, and once you defeat it, it's the Pineapple Horse's turn. If we beat the Pineapple Horse, the marathon will be over. So in marathon mode we fight two bosses in a row. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Before fighting the boss, you should have the "Simple" and "Normal" buttons. In the simple version, bosses are slower and attack less frequently.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Banana = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('banana', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var gun = self.attachAsset('gun', {
anchorX: 0,
anchorY: 0.5
});
gun.x = 30;
gun.y = 0;
self.maxHealth = 100;
self.health = self.maxHealth;
self.shootCooldown = 0;
self.invulnerable = false;
self.invulnerableTimer = 0;
self.potionEffectActive = false;
self.potionEffectTimer = 0;
self.potionEffectDuration = 300; // 5 seconds at 60fps
self.horseshoeInvincible = false;
self.horseshoeInvincibleTimer = 0;
self.horseshoeInvincibleDuration = 300; // 5 seconds at 60fps
self.takeDamage = function (damage) {
if (self.invulnerable || self.horseshoeInvincible) return;
self.health -= damage;
self.invulnerable = true;
self.invulnerableTimer = 60; // 1 second at 60fps
// Flash effect
LK.effects.flashObject(self, 0xFF0000, 500);
LK.getSound('hit').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
self.activatePotionEffect = function () {
self.potionEffectActive = true;
self.potionEffectTimer = self.potionEffectDuration;
// Visual effect - purple tint
self.tint = 0xFF88FF;
// Flash effect
LK.effects.flashObject(self, 0x9932cc, 800);
};
self.activateHorseshoeInvincibility = function () {
self.horseshoeInvincible = true;
self.horseshoeInvincibleTimer = self.horseshoeInvincibleDuration;
// Visual effect - blue tint for invincibility
self.tint = 0x0080FF;
// Flash effect
LK.effects.flashObject(self, 0x0080FF, 1000);
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.invulnerable && self.invulnerableTimer > 0) {
self.invulnerableTimer--;
if (self.invulnerableTimer <= 0) {
self.invulnerable = false;
}
}
// Handle potion effect
if (self.potionEffectActive) {
self.potionEffectTimer--;
if (self.potionEffectTimer <= 0) {
self.potionEffectActive = false;
// Remove visual effect only if not invincible from horseshoe
if (!self.horseshoeInvincible) {
self.tint = 0xFFFFFF;
} else {
// If still horseshoe invincible, set blue tint
self.tint = 0x0080FF;
}
}
}
// Handle horseshoe invincibility effect
if (self.horseshoeInvincible) {
self.horseshoeInvincibleTimer--;
if (self.horseshoeInvincibleTimer <= 0) {
self.horseshoeInvincible = false;
// Remove visual effect only if potion effect is not active
if (!self.potionEffectActive) {
self.tint = 0xFFFFFF;
} else {
// If still potion effect active, set purple tint
self.tint = 0xFF88FF;
}
}
} else if (self.potionEffectActive) {
// Maintain blue tint while horseshoe invincible, even if potion is active
self.tint = 0x0080FF;
}
};
return self;
});
var BananaProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bananaProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 5;
self.enhanced = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudTypes = ['cloud1', 'cloud2', 'cloud3'];
var cloudType = cloudTypes[Math.floor(Math.random() * cloudTypes.length)];
var graphics = self.attachAsset(cloudType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.5 + Math.random() * 1.5; // Random speed between 0.5 and 2
self.update = function () {
self.x -= self.speed;
// Reset cloud position when it goes off screen
if (self.x < -200) {
self.x = 2248; // Reset to right side of screen
self.y = Math.random() * 1000 + 200; // Random height
}
};
return self;
});
var HomingProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('homingProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 3;
self.enhanced = false;
self.target = null;
self.update = function () {
if (self.target && self.target.health > 0) {
// Calculate angle to target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var angle = Math.atan2(dy, dx);
// Move towards target
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
} else {
// Move forward if no target
self.x += self.speed;
}
};
return self;
});
var Horseshoe = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('horseshoe', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.damage = 0; // No damage, just grants invincibility
self.rotationSpeed = 0.1; // Spinning effect
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.rotation += self.rotationSpeed;
};
return self;
});
var IceProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('iceProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 3;
self.enhanced = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
var LaserProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('laserProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 1;
self.enhanced = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
var PineappleHorseBoss = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('pineappleHorse', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
// Tint to make it look different (golden yellow for pineapple horse)
graphics.tint = 0xFFD700;
self.graphics = graphics; // Store reference to graphics
self.maxHealth = 400;
self.health = self.maxHealth;
self.attackTimer = 0;
self.attackCooldown = 90; // 1.5 seconds at 60fps
self.phase = 1;
self.moveDirection = 1;
self.moveSpeed = 2.5; // Faster movement than watermelon
self.chargeAttackCooldown = 0;
self.isCharging = false;
self.chargeTarget = {
x: 0,
y: 0
};
self.originalPosition = {
x: 0,
y: 0
};
self.takeDamage = function (damage, isIce) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
LK.getSound('bosshit').play();
// Handle ice bullet freeze effect
if (isIce) {
if (!self.iceHits) self.iceHits = 0;
self.iceHits++;
if (self.iceHits >= 5 && !self.frozen) {
self.frozen = true;
self.freezeTimer = 48; // 0.8 seconds at 60fps
self.originalTint = self.graphics.tint;
tween(self.graphics, {
tint: 0x87ceeb
}, {
duration: 100
});
self.iceHits = 0; // Reset ice hit counter
}
}
if (self.health <= 0) {
if (selectedBoss === 'both') {
// In both bosses mode, no phase 2 - just die
// Check if we should show win condition
var shouldWin = true;
if (watermelonBoss && watermelonBoss.health > 0) {
shouldWin = false; // Don't win until both bosses are defeated
}
if (shouldWin) {
// Final death - explosion animation before showing You Win
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showYouWin();
}
});
} else {
// Just explosion animation without winning
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Boss is defeated but don't show win yet
}
});
}
} else if (self.phase < 2) {
// If not in final phase yet and not in both bosses mode, transition to phase 2
self.phase = 2; // Move to phase 2
self.maxHealth = 400; // Set phase 2 max health
self.health = 400; // Reset health for phase 2
self.attackCooldown = 102; // 1.7 seconds at 60fps for spear attacks
self.moveSpeed = 3.5; // Even faster movement
// Switch to phase 2 asset
self.removeChild(self.graphics);
self.graphics = self.attachAsset('pineappleHorsePhase2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.56,
scaleY: 1.56
});
// Phase 2 uses natural colors, no tint needed
// Flash effect for phase transition
LK.effects.flashObject(self, 0x00FF00, 1000);
// Add dramatic animation for phase transition
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Keep the bigger size in phase 2
}
});
// Add rotation animation for phase transition
tween(self, {
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.rotation = 0;
}
});
} else {
// Check if we should show win condition
var shouldWin = true;
if (selectedBoss === 'both' && watermelonBoss && watermelonBoss.health > 0) {
shouldWin = false; // Don't win until both bosses are defeated
}
if (shouldWin) {
// Final death - explosion animation before showing You Win
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showYouWin();
}
});
} else {
// Just explosion animation without winning
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Boss is defeated but don't show win yet
}
});
}
}
}
};
self.spearAttack = function () {
var spear = new PineappleSpear();
// Spawn spear directly at boss position
spear.x = self.x;
spear.y = self.y;
// Set banana as target for seeking behavior
spear.target = banana;
// Calculate initial direction towards banana for rotation
var dx = banana.x - spear.x;
var dy = banana.y - spear.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
dx = dx / distance;
dy = dy / distance;
}
// Set initial rotation
spear.rotation = Math.atan2(dy, dx);
// Add fade-in effect for 3-second duration
tween(spear, {
alpha: 0.3
}, {
duration: 3000,
// 3 seconds
easing: tween.linear,
onFinish: function onFinish() {
// Spear will be destroyed by its own update method when lifeTime reaches 0
}
});
pineappleSpears.push(spear);
game.addChild(spear);
};
self.pineappleThrowAttack = function () {
var thrownPineapple = new PineappleThrow();
// Spawn pineapple at boss position
thrownPineapple.x = self.x;
thrownPineapple.y = self.y;
// Calculate trajectory towards banana's position
var dx = banana.x - thrownPineapple.x;
var dy = banana.y - thrownPineapple.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
dx = dx / distance;
dy = dy / distance;
}
// Set initial velocity
var throwSpeed = 6;
thrownPineapple.speedX = dx * throwSpeed;
thrownPineapple.speedY = dy * throwSpeed;
// Add throwing animation
tween(thrownPineapple, {
rotation: Math.PI * 4 // Spin while flying
}, {
duration: 2000,
easing: tween.linear
});
thrownPineapples.push(thrownPineapple);
game.addChild(thrownPineapple);
};
self.horseshoeAttack = function () {
var horseshoe = new Horseshoe();
// Spawn horseshoe at boss position
horseshoe.x = self.x;
horseshoe.y = self.y;
// Calculate trajectory towards banana's position
var dx = banana.x - horseshoe.x;
var dy = banana.y - horseshoe.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
dx = dx / distance;
dy = dy / distance;
}
// Set horseshoe velocity (slower than other projectiles)
var horseshoeSpeed = 4;
horseshoe.speedX = dx * horseshoeSpeed;
horseshoe.speedY = dy * horseshoeSpeed;
// Add spinning animation
tween(horseshoe, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.easeOut
});
horseshoes.push(horseshoe);
game.addChild(horseshoe);
};
self.chargeAttack = function () {
if (self.isCharging || self.chargeAttackCooldown > 0) return;
self.isCharging = true;
self.originalPosition.x = self.x;
self.originalPosition.y = self.y;
self.chargeTarget.x = banana.x;
self.chargeTarget.y = banana.y;
// Phase 1: Preparation phase - pull back and flash warning
// Flash to indicate charge preparation
LK.effects.flashObject(self, 0xFFFF00, 800);
// Calculate pullback position (opposite direction from banana)
var pullbackDistance = 100;
var dx = self.x - banana.x;
var dy = self.y - banana.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
dx = dx / distance;
dy = dy / distance;
}
var pullbackX = self.x + dx * pullbackDistance;
var pullbackY = self.y + dy * pullbackDistance;
// Clamp pullback position within screen bounds
pullbackX = Math.max(100, Math.min(1948, pullbackX));
pullbackY = Math.max(200, Math.min(2532, pullbackY));
// Phase 1: Pull back with anticipation
tween(self, {
x: pullbackX,
y: pullbackY,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
// Phase 2: Forward charge attack
// Flash brighter to indicate charge execution
LK.effects.flashObject(self, 0xFF4400, 400);
// Determine charge parameters based on phase
var chargeDuration = self.phase === 2 ? 150 : 300; // Phase 2: faster charge (150ms vs 300ms)
var chargeDistance = self.phase === 2 ? 300 : 0; // Phase 2: longer dash distance
// Calculate extended target position for phase 2
var finalTargetX = self.chargeTarget.x;
var finalTargetY = self.chargeTarget.y;
if (self.phase === 2) {
// Extend the charge beyond banana's position for longer dash
var dx = self.chargeTarget.x - self.x;
var dy = self.chargeTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
dx = dx / distance;
dy = dy / distance;
finalTargetX = self.chargeTarget.x + dx * chargeDistance;
finalTargetY = self.chargeTarget.y + dy * chargeDistance;
}
// Clamp extended position within screen bounds
finalTargetX = Math.max(100, Math.min(1948, finalTargetX));
finalTargetY = Math.max(200, Math.min(2532, finalTargetY));
}
// Quick charge towards target position (faster and longer in phase 2)
tween(self, {
x: finalTargetX,
y: finalTargetY,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: chargeDuration,
easing: tween.easeIn,
onFinish: function onFinish() {
// Check if hit banana during charge
if (self.intersects(banana)) {
banana.takeDamage(40);
}
// Return to original position
tween(self, {
x: self.originalPosition.x,
y: self.originalPosition.y
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isCharging = false;
self.chargeAttackCooldown = 180; // 3 second cooldown
}
});
}
});
}
});
};
self.update = function () {
// Handle freeze effect
if (self.frozen) {
self.freezeTimer--;
if (self.freezeTimer <= 0) {
self.frozen = false;
tween(self.graphics, {
tint: self.originalTint
}, {
duration: 100
});
}
return; // Skip all actions while frozen
}
// Only move when not charging
if (!self.isCharging) {
// Circular movement pattern
self.y += self.moveDirection * self.moveSpeed;
if (self.y <= 300 || self.y >= 2400) {
self.moveDirection *= -1;
}
// Add horizontal movement in figure-8 pattern
self.x += Math.sin(LK.ticks * 0.02) * 1.5;
}
// Update charge cooldown
if (self.chargeAttackCooldown > 0) {
self.chargeAttackCooldown--;
}
// Attack logic
self.attackTimer++;
if (self.attackTimer >= self.attackCooldown) {
var attackChoice = Math.random();
if (attackChoice < 0.2 && self.chargeAttackCooldown <= 0) {
// Charge attack (20% chance)
self.chargeAttack();
} else if (attackChoice < 0.25) {
// Pineapple throw attack (5% chance - reduced)
self.pineappleThrowAttack();
} else if (attackChoice < 0.27) {
// Horseshoe attack (2% chance - very rare attack)
self.horseshoeAttack();
} else {
// Spear attack (70% chance)
self.spearAttack();
}
self.attackTimer = 0;
}
};
return self;
});
var PineappleSlice = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('pineappleSpear', {
anchorX: 0.5,
anchorY: 0.5
});
// Different tint for slices to distinguish from spears
graphics.tint = 0xFFA500; // Orange tint
self.scaleX = 2.0;
self.scaleY = 2.0;
self.speedX = 0;
self.speedY = 0;
self.damage = 20;
self.lifeTime = 300; // 5 seconds at 60fps
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Keep constant movement - no slowing down
// Decrease lifetime
self.lifeTime--;
if (self.lifeTime <= 0) {
// Find and remove from pineappleSlices array
for (var i = pineappleSlices.length - 1; i >= 0; i--) {
if (pineappleSlices[i] === self) {
self.destroy();
pineappleSlices.splice(i, 1);
break;
}
}
}
};
return self;
});
var PineappleSpear = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('pineappleSpear', {
anchorX: 0.5,
anchorY: 0.5
});
// Golden yellow tint for pineapple spears
graphics.tint = 0xFFD700;
self.scaleX = 4.0;
self.scaleY = 4.0;
self.speedX = 0;
self.speedY = 0;
self.damage = 25;
self.seekSpeed = 5.5; // Speed for seeking behavior
self.target = null; // Target to seek
self.lifeTime = 180; // 3 seconds at 60fps
self.maxLifeTime = 180; // Store original lifetime
self.update = function () {
// Decrease lifetime
self.lifeTime--;
// If lifetime expired, destroy the spear
if (self.lifeTime <= 0) {
// Find and remove from pineappleSpears array
for (var i = pineappleSpears.length - 1; i >= 0; i--) {
if (pineappleSpears[i] === self) {
self.destroy();
pineappleSpears.splice(i, 1);
break;
}
}
return;
}
// Seeking behavior towards target (banana)
if (self.target && self.target.health > 0) {
// Calculate direction to target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Normalize direction and apply seek speed
var dirX = dx / distance;
var dirY = dy / distance;
// Use different speed based on boss phase - check if pineapple boss exists and is in phase 2
var currentSeekSpeed = self.seekSpeed;
if (pineappleBoss && pineappleBoss.phase === 2) {
currentSeekSpeed = 10;
}
self.x += dirX * currentSeekSpeed;
self.y += dirY * currentSeekSpeed;
// Update rotation to face target
self.rotation = Math.atan2(dy, dx);
}
} else {
// Fallback to original movement if no target
self.x += self.speedX;
self.y += self.speedY;
}
};
return self;
});
var PineappleThrow = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('pineappleHorse', {
anchorX: 0.5,
anchorY: 0.5
});
// Scale down to make it smaller than the boss
self.scaleX = 0.3;
self.scaleY = 0.3;
// Golden yellow tint for thrown pineapple
graphics.tint = 0xFFD700;
self.speedX = 0;
self.speedY = 0;
self.hitCount = 0; // Track number of bullet hits
self.maxHits = 2; // Explode after 2 hits
self.damaged = false; // Track if it's been hit
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Keep constant movement - no slowing down
};
self.takeDamage = function (damage) {
self.hitCount++;
// Flash effect when hit
LK.effects.flashObject(self, 0xFF0000, 200);
self.damaged = true;
if (self.hitCount >= self.maxHits) {
self.explode();
}
};
self.explode = function () {
// Create 8 pineapple slices in different directions
var numSlices = 8;
for (var i = 0; i < numSlices; i++) {
var slice = new PineappleSlice();
slice.x = self.x;
slice.y = self.y;
// Calculate angle for each slice (45 degrees apart)
var angle = i * Math.PI * 2 / numSlices;
var speed = 4 + Math.random() * 2; // Random speed variation
slice.speedX = Math.cos(angle) * speed;
slice.speedY = Math.sin(angle) * speed;
// Add slight rotation for visual effect
slice.rotation = angle;
pineappleSlices.push(slice);
game.addChild(slice);
}
// Remove this pineapple from the array and destroy it
for (var j = thrownPineapples.length - 1; j >= 0; j--) {
if (thrownPineapples[j] === self) {
self.destroy();
thrownPineapples.splice(j, 1);
break;
}
}
};
return self;
});
var SpreadProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('spreadProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 7;
self.damage = 3;
self.enhanced = false;
self.angle = 0; // Angle for spread direction
self.update = function () {
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
};
return self;
});
var WatermelonBoss = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('watermelon', {
anchorX: 0.5,
anchorY: 0.5
});
self.graphics = graphics; // Store reference to graphics for phase switching
self.maxHealth = 500;
self.health = self.maxHealth;
self.attackTimer = 0;
self.attackCooldown = 120; // 2 seconds - more frequent attacks in phase 1
self.phase = 1;
self.moveDirection = 1;
self.moveSpeed = 1;
self.potionsDroppedThisPhase = 0;
self.maxPotionsPerPhase = 1;
self.minPotionsPerPhase = 1;
self.mustDropPotion = false;
self.attacking = false;
self.divisionSlices = null;
self.divisionAttackTimer = 0;
self.currentAttackingSlice = 0;
self.takeDamage = function (damage, isIce) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
LK.getSound('bosshit').play();
// Handle ice bullet freeze effect
if (isIce) {
if (!self.iceHits) self.iceHits = 0;
self.iceHits++;
if (self.iceHits >= 5 && !self.frozen) {
self.frozen = true;
self.freezeTimer = 48; // 0.8 seconds at 60fps
self.originalTint = self.graphics.tint;
tween(self.graphics, {
tint: 0x87ceeb
}, {
duration: 100
});
self.iceHits = 0; // Reset ice hit counter
}
}
// Change phase based on health
if (self.health <= self.maxHealth * 0.66 && self.phase === 1) {
self.phase = 2;
self.attackCooldown = 135; // Faster attacks
self.moveSpeed = 2; // Faster movement in phase 2
// Reset potion counters for new phase
self.potionsDroppedThisPhase = 0;
self.mustDropPotion = false;
} else if (self.health <= self.maxHealth * 0.33 && self.phase === 2) {
self.phase = 3;
self.attackCooldown = 90; // Even faster attacks
// Reset potion counters for new phase
self.potionsDroppedThisPhase = 0;
self.mustDropPotion = false;
}
if (self.health <= 0) {
if (selectedBoss === 'both') {
// In both bosses mode, no phase 2 - just die
// Check if we should show win condition
var shouldWin = true;
if (pineappleBoss && pineappleBoss.health > 0) {
shouldWin = false; // Don't win until both bosses are defeated
}
if (shouldWin) {
// Explosion animation before showing You Win
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showYouWin();
}
});
} else {
// Just explosion animation without winning
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Boss is defeated but don't show win yet
}
});
}
} else if (self.phase < 4) {
// If not in final phase yet and not in both bosses mode
// Transition to second phase
self.phase = 4; // Mark as second phase
self.maxHealth = 500;
self.health = 500;
self.attackCooldown = 60; // Much faster attacks
// Reset potion counters for new phase
self.potionsDroppedThisPhase = 0;
self.mustDropPotion = false;
// Switch to phase 2 asset
self.removeChild(self.graphics);
self.graphics = self.attachAsset('watermelonPhase2', {
anchorX: 0.5,
anchorY: 0.5
});
// Play faster music for Phase 2
LK.playMusic('Aa', {
fade: {
start: 0,
end: 0.3,
duration: 500
}
});
// Flash effect for phase transition
LK.effects.flashObject(self, 0x00FF00, 1000);
// Add dramatic animation for phase transition
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Keep the bigger size in phase 2, don't scale back down
}
});
// Add rotation animation
tween(self, {
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.rotation = 0;
}
});
} else {
// Check if we should show win condition
var shouldWin = true;
if (selectedBoss === 'both' && pineappleBoss && pineappleBoss.health > 0) {
shouldWin = false; // Don't win until both bosses are defeated
}
if (shouldWin) {
// Explosion animation before showing You Win
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showYouWin();
}
});
} else {
// Just explosion animation without winning
tween(self, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Boss is defeated but don't show win yet
}
});
}
}
}
};
self.seedAttack = function () {
var numSeeds;
if (self.phase === 1) {
// Calculate damage percentage (0 to 1, where 1 is most damaged)
var damagePercent = 1 - self.health / self.maxHealth;
// Base seeds + bonus based on damage, with a higher limit in phase 1
var bonusSeeds = Math.floor(damagePercent * 8); // Up to 8 bonus seeds
numSeeds = Math.min(6 + bonusSeeds, 14); // Base 6, max 14 total
} else {
numSeeds = self.phase === 2 ? 5 : self.phase === 3 ? 8 : 10; // More seeds in second phase
}
for (var i = 0; i < numSeeds; i++) {
var seed = new WatermelonSeed();
seed.x = self.x + (Math.random() - 0.5) * 100;
seed.y = self.y + 50;
var angle = Math.random() * Math.PI * 2;
var baseSpeed = self.phase === 4 ? 5 : 2; // Faster in second phase
var speed = baseSpeed + Math.random() * (self.phase === 4 ? 5 : 3); // Higher speed range in second phase
seed.speedX = Math.cos(angle) * speed;
seed.speedY = Math.sin(angle) * speed;
// Make seeds bigger in phase 1 and even bigger in second phase
if (self.phase === 4) {
seed.scaleX = 2.0;
seed.scaleY = 2.0;
} else {
seed.scaleX = 1.5;
seed.scaleY = 1.5;
}
watermelonSeeds.push(seed);
game.addChild(seed);
}
};
self.sliceAttack = function () {
var numSlices = 2; // Only 2 slices in phase 1
for (var i = 0; i < numSlices; i++) {
var slice = new WatermelonSlice();
// Spawn from outside screen edges
var side = Math.random() < 0.5 ? 'left' : 'right';
if (side === 'left') {
slice.x = -100; // Start from left edge
slice.y = Math.random() * 1500 + 400;
} else {
slice.x = 2148; // Start from right edge
slice.y = Math.random() * 1500 + 400;
}
// Calculate angle towards banana
var dx = banana.x - slice.x;
var dy = banana.y - slice.y;
var angle = Math.atan2(dy, dx);
var speed = 3 + Math.random() * 2; // Slower than seeds but still threatening
slice.speedX = Math.cos(angle) * speed;
slice.speedY = Math.sin(angle) * speed;
// Make slices bigger than seeds, even bigger in phase 4
if (self.phase === 4) {
slice.scaleX = 3.0;
slice.scaleY = 3.0;
} else {
slice.scaleX = 2.0;
slice.scaleY = 2.0;
}
watermelonSlices.push(slice);
game.addChild(slice);
}
};
self.divisionAttack = function () {
// Only available in phase 1
if (self.phase !== 1) return;
// Hide the main watermelon temporarily
self.alpha = 0;
self.attacking = true;
self.divisionSlices = [];
// Store the current watermelon position at the time of division
var divisionCenterX = self.x;
var divisionCenterY = self.y;
// Create 4 slices positioned around the watermelon's division position
var slicePositions = [{
x: divisionCenterX - 150,
y: divisionCenterY - 150
},
// Top-left
{
x: divisionCenterX + 150,
y: divisionCenterY - 150
},
// Top-right
{
x: divisionCenterX - 150,
y: divisionCenterY + 150
},
// Bottom-left
{
x: divisionCenterX + 150,
y: divisionCenterY + 150
} // Bottom-right
];
for (var i = 0; i < 4; i++) {
var sliceType = i + 1; // Use slice types 1, 2, 3, 4
var slice = new WatermelonDivisionSlice(sliceType);
slice.x = slicePositions[i].x;
slice.y = slicePositions[i].y;
slice.scaleX = 1.5;
slice.scaleY = 1.5;
slice.alpha = 0;
slice.sliceIndex = i;
slice.isAttacking = false;
slice.hasAttacked = false;
slice.originalX = slice.x;
slice.originalY = slice.y;
self.divisionSlices.push(slice);
game.addChild(slice);
// Fade in each slice with a delay
tween(slice, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
// Start the sequential attack after all slices are visible
self.divisionAttackTimer = 120; // 2 seconds delay
self.currentAttackingSlice = 0;
};
self.updateDivisionAttack = function () {
if (!self.attacking || !self.divisionSlices) return;
if (self.divisionAttackTimer > 0) {
self.divisionAttackTimer--;
return;
}
// Check if current slice should start attacking
if (self.currentAttackingSlice < self.divisionSlices.length) {
var currentSlice = self.divisionSlices[self.currentAttackingSlice];
if (!currentSlice.isAttacking && !currentSlice.hasAttacked) {
// Start attacking with current slice
currentSlice.isAttacking = true;
// Calculate attack trajectory towards banana
var dx = banana.x - currentSlice.x;
var dy = banana.y - currentSlice.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var attackDuration = Math.min(1000, distance * 2); // Dynamic duration based on distance
// Animate slice towards banana
tween(currentSlice, {
x: banana.x,
y: banana.y
}, {
duration: attackDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Check if slice hit banana
if (currentSlice.intersects(banana)) {
banana.takeDamage(25);
// Calculate knockback direction from slice to banana
var knockbackX = banana.x - currentSlice.x;
var knockbackY = banana.y - currentSlice.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
}
// Calculate knockback destination (140 pixels away from slice)
var knockbackDistance = 140;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 230,
easing: tween.easeOut
});
}
// Return slice to original position
tween(currentSlice, {
x: currentSlice.originalX,
y: currentSlice.originalY
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
currentSlice.hasAttacked = true;
currentSlice.isAttacking = false;
}
});
}
});
self.currentAttackingSlice++;
self.divisionAttackTimer = 90; // 1.5 second delay before next slice
}
}
// Check if all slices have finished attacking
var allFinished = true;
for (var i = 0; i < self.divisionSlices.length; i++) {
if (!self.divisionSlices[i].hasAttacked) {
allFinished = false;
break;
}
}
if (allFinished) {
// All slices have attacked, return to original state
for (var j = 0; j < self.divisionSlices.length; j++) {
var slice = self.divisionSlices[j];
tween(slice, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
slice.destroy();
}
});
}
// Return watermelon to the center of where the slices were positioned
var returnX = self.divisionSlices[0].originalX + 150; // Center position
var returnY = self.divisionSlices[0].originalY + 150; // Center position
self.x = returnX;
self.y = returnY;
// Show main watermelon again
tween(self, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.attacking = false;
self.divisionSlices = null;
self.currentAttackingSlice = 0;
}
});
}
};
self.potionAttack = function () {
var numPotions = self.phase === 4 ? 3 : 2; // More potions in second phase
for (var i = 0; i < numPotions; i++) {
var potion = new WatermelonPotion();
potion.x = self.x + (Math.random() - 0.5) * 80;
potion.y = self.y + 50;
// Calculate angle towards banana
var dx = banana.x - potion.x;
var dy = banana.y - potion.y;
var angle = Math.atan2(dy, dx);
var baseSpeed = self.phase === 4 ? 4 : 2;
var speed = baseSpeed + Math.random() * 2;
potion.speedX = Math.cos(angle) * speed;
potion.speedY = Math.sin(angle) * speed;
// Make potions bigger in second phase
if (self.phase === 4) {
potion.scaleX = 3.5;
potion.scaleY = 3.5;
} else {
potion.scaleX = 3.0;
potion.scaleY = 3.0;
}
// Add glowing effect to potions
tween(potion, {
alpha: 0.6
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(potion, {
alpha: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
watermelonPotions.push(potion);
game.addChild(potion);
}
};
self.update = function () {
// Handle freeze effect
if (self.frozen) {
self.freezeTimer--;
if (self.freezeTimer <= 0) {
self.frozen = false;
tween(self.graphics, {
tint: self.originalTint
}, {
duration: 100
});
}
return; // Skip all actions while frozen
}
// Movement - both vertical and horizontal
self.y += self.moveDirection * self.moveSpeed;
self.x += self.moveDirection * self.moveSpeed * 0.5; // Horizontal movement at half speed
if (self.y <= 300 || self.y >= 2400) {
self.moveDirection *= -1;
}
// No horizontal boundary restrictions - watermelon can move freely
// Update division attack if active
self.updateDivisionAttack();
// Skip normal attacks if currently performing division attack
if (self.attacking) return;
// Attack logic
self.attackTimer++;
if (self.attackTimer >= self.attackCooldown) {
// Check if we need to force a potion drop
var healthPercent = self.health / self.maxHealth;
var shouldDropPotion = false;
// Force potion if we haven't dropped one yet and health is getting low
if (self.potionsDroppedThisPhase < self.minPotionsPerPhase && healthPercent < 0.3) {
self.mustDropPotion = true;
}
// Decide whether to drop potion (only if we haven't dropped one yet)
if (self.potionsDroppedThisPhase < self.maxPotionsPerPhase && (self.mustDropPotion || Math.random() < 0.05)) {
shouldDropPotion = true;
}
if (shouldDropPotion) {
self.potionAttack();
self.potionsDroppedThisPhase++;
self.mustDropPotion = false;
} else if (self.phase === 1 && Math.random() < 0.15) {
// In phase 1, occasionally use division attack
self.divisionAttack();
} else if (self.phase === 1 && Math.random() < 0.25) {
// In phase 1, throw larger watermelon slices more frequently instead of seeds
self.sliceAttack();
} else if (self.phase === 2 && Math.random() < 0.25) {
// In phase 2, also throw watermelon slices frequently
self.sliceAttack();
} else if (self.phase === 4 && Math.random() < 0.1) {
// In phase 4, throw watermelon slices very frequently
self.sliceAttack();
} else {
self.seedAttack();
}
self.attackTimer = 0;
}
};
return self;
});
var WatermelonDivisionSlice = Container.expand(function (sliceType) {
var self = Container.call(this);
// Default to slice 1 if no type specified
var assetName = 'watermelonDivisionSlice' + (sliceType || 1);
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.damage = 25; // Division slices do less damage than regular slices
self.sliceType = sliceType || 1;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
var WatermelonPotion = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('potion', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
var WatermelonSeed = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('watermelonSeed', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.damage = 20;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
var WatermelonSlice = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('watermelonSlice', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.damage = 35; // Higher damage than seeds
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
var WideProjectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('wideProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.damage = 10;
self.enhanced = false;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Music
// Sound effects
// Projectile assets
// Character assets
// Game variables
var banana;
var watermelonBoss;
var pineappleBoss;
var bananaProjectiles = [];
var watermelonSeeds = [];
var watermelonSlices = [];
var watermelonPotions = [];
var pineappleSpears = [];
var thrownPineapples = [];
var pineappleSlices = [];
var horseshoes = [];
var clouds = [];
var dragNode = null;
// Game state variables
var gameState = 'mainMenu'; // 'mainMenu', 'bossSelection', 'bulletSelection', 'playing'
var mainMenu = null;
var bossSelectionScreen = null;
var selectedBoss = 'watermelon'; // 'watermelon', 'boss2', 'boss3', etc.
// Bullet selection variables
var gameStarted = false;
var selectedBulletType = 'normal'; // 'normal', 'homing', 'wide', 'laser', or 'spread'
var selectionScreen = null;
var normalBulletButton = null;
var homingBulletButton = null;
var wideBulletButton = null;
var laserBulletButton = null;
var spreadBulletButton = null;
var selectionTitle = null;
var bulletDescription = null;
// Wide bullet specific cooldown
var wideBulletCooldown = 0;
var laserBulletCooldown = 0;
var spreadBulletCooldown = 0;
var mousePressed = false;
var laserUsageTimer = 0; // Timer for 1.5 second intervals
var laserUsageDuration = 0; // Timer for 0.3 second usage
var laserCanUse = true; // Flag to control when laser can be used
var laserPressUsed = false; // Flag to track if current press has been used for laser
var holdTimer = 0; // Timer to track how long mouse has been held down
var miscBulletTypes = ['normal', 'homing', 'wide', 'laser', 'spread', 'ice']; // Array of bullet types for miscellaneous
var currentMiscBulletIndex = 0; // Index to track current bullet type in miscellaneous mode
// Create skins coming soon screen
function createSkinsComingSoonScreen() {
var skinsScreen = new Container();
game.addChild(skinsScreen);
// Semi-transparent background
var background = LK.getAsset('shape', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.9
});
background.tint = 0x001122;
skinsScreen.addChild(background);
// Title
var skinsTitle = new Text2('GÖRÜNÜMLER', {
size: 150,
fill: 0xFF6600
});
skinsTitle.anchor.set(0.5, 0.5);
skinsTitle.x = 1024;
skinsTitle.y = 800;
skinsScreen.addChild(skinsTitle);
// Coming soon message
var comingSoonText = new Text2('YAKINDA GELİYOR!', {
size: 100,
fill: 0xFFFFFF
});
comingSoonText.anchor.set(0.5, 0.5);
comingSoonText.x = 1024;
comingSoonText.y = 1200;
skinsScreen.addChild(comingSoonText);
// Description
var descriptionText = new Text2('Bananjohn\'u farklı görünümler\nve tasarımlarla özelleştirin!', {
size: 60,
fill: 0xCCCCCC
});
descriptionText.anchor.set(0.5, 0.5);
descriptionText.x = 1024;
descriptionText.y = 1400;
skinsScreen.addChild(descriptionText);
// Back button
var backButton = LK.getAsset('shape', {
width: 400,
height: 120,
anchorX: 0.5,
anchorY: 0.5
});
backButton.tint = 0x666666;
backButton.x = 1024;
backButton.y = 1800;
skinsScreen.addChild(backButton);
var backText = new Text2('GERİ', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 1800;
skinsScreen.addChild(backText);
// Back button event handler
backButton.down = function (x, y, obj) {
skinsScreen.destroy();
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
createMainMenu();
};
}
// Create main menu screen
function createMainMenu() {
mainMenu = new Container();
game.addChild(mainMenu);
// Semi-transparent background
var background = LK.getAsset('shape', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.9
});
background.tint = 0x001122;
mainMenu.addChild(background);
// Game Title
var gameTitle = new Text2('BANANJOHN', {
size: 150,
fill: 0xFFE135
});
gameTitle.anchor.set(0.5, 0.5);
gameTitle.x = 1024;
gameTitle.y = 600;
mainMenu.addChild(gameTitle);
// Subtitle
var subtitle = new Text2('CANAVAR KARPUZU YEN!', {
size: 80,
fill: 0xFFFFFF
});
subtitle.anchor.set(0.5, 0.5);
subtitle.x = 1024;
subtitle.y = 800;
mainMenu.addChild(subtitle);
// Play Button
var playButton = LK.getAsset('shape', {
width: 500,
height: 150,
anchorX: 0.5,
anchorY: 0.5
});
playButton.tint = 0x44FF44;
playButton.x = 1024;
playButton.y = 1200;
mainMenu.addChild(playButton);
var playText = new Text2('OYNA', {
size: 100,
fill: 0x000000
});
playText.anchor.set(0.5, 0.5);
playText.x = 1024;
playText.y = 1200;
mainMenu.addChild(playText);
// Instructions
var instructions = new Text2('Bananjohn\'u hareket ettirmek için sürükleyin!\nSilahınızı akıllıca seçin!', {
size: 60,
fill: 0xCCCCCC
});
instructions.anchor.set(0.5, 0.5);
instructions.x = 1024;
instructions.y = 1700;
mainMenu.addChild(instructions);
// Skins Button
var skinsButton = LK.getAsset('shape', {
width: 500,
height: 150,
anchorX: 0.5,
anchorY: 0.5
});
skinsButton.tint = 0xFF6600;
skinsButton.x = 1024;
skinsButton.y = 1400;
mainMenu.addChild(skinsButton);
var skinsText = new Text2('GÖRÜNÜMLER', {
size: 100,
fill: 0x000000
});
skinsText.anchor.set(0.5, 0.5);
skinsText.x = 1024;
skinsText.y = 1400;
mainMenu.addChild(skinsText);
// Language Button
var languageButton = LK.getAsset('shape', {
width: 400,
height: 120,
anchorX: 0.5,
anchorY: 0.5
});
languageButton.tint = 0x0088CC;
languageButton.x = 1024;
languageButton.y = 1600;
mainMenu.addChild(languageButton);
var languageText = new Text2('English', {
size: 80,
fill: 0xFFFFFF
});
languageText.anchor.set(0.5, 0.5);
languageText.x = 1024;
languageText.y = 1600;
mainMenu.addChild(languageText);
// Play button event handler
playButton.down = function (x, y, obj) {
gameState = 'bossSelection';
mainMenu.destroy();
mainMenu = null;
createBossSelectionScreen();
};
// Skins button event handler
skinsButton.down = function (x, y, obj) {
// Show coming soon screen for skins
createSkinsComingSoonScreen();
};
// Language button event handler
languageButton.down = function (x, y, obj) {
// Toggle between Turkish and English
if (languageText.text === 'English') {
// Switch to English
gameTitle.setText('BANANJOHN');
subtitle.setText('DEFEAT THE MONSTER WATERMELON!');
playText.setText('PLAY');
instructions.setText('Drag Bananjohn to move!\nChoose your weapon wisely!');
skinsText.setText('SKINS');
languageText.setText('Türkçe');
} else {
// Switch back to Turkish
gameTitle.setText('BANANJOHN');
subtitle.setText('CANAVAR KARPUZU YEN!');
playText.setText('OYNA');
instructions.setText('Bananjohn\'u hareket ettirmek için sürükleyin!\nSilahınızı akıllıca seçin!');
skinsText.setText('GÖRÜNÜMLER');
languageText.setText('English');
}
};
}
// Create boss selection screen
function createBossSelectionScreen() {
bossSelectionScreen = new Container();
game.addChild(bossSelectionScreen);
// Semi-transparent background
var background = LK.getAsset('shape', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.8
});
background.tint = 0x001122;
bossSelectionScreen.addChild(background);
// Title
var bossSelectionTitle = new Text2('BOSS SEÇ', {
size: 120,
fill: 0xFFFFFF
});
bossSelectionTitle.anchor.set(0.5, 0.5);
bossSelectionTitle.x = 1024;
bossSelectionTitle.y = 600;
bossSelectionScreen.addChild(bossSelectionTitle);
// Watermelon Boss button
var watermelonBossButton = LK.getAsset('shape', {
width: 700,
height: 250,
anchorX: 0.5,
anchorY: 0.5
});
watermelonBossButton.tint = 0xFF4444;
watermelonBossButton.x = 1024;
watermelonBossButton.y = 1000;
bossSelectionScreen.addChild(watermelonBossButton);
var watermelonText = new Text2('CANAVAR KARPUZ', {
size: 80,
fill: 0xFFFFFF
});
watermelonText.anchor.set(0.5, 0.5);
watermelonText.x = 1024;
watermelonText.y = 970;
bossSelectionScreen.addChild(watermelonText);
var watermelonDesc = new Text2('Orijinal tehdit! Çoklu fazlar ve saldırılar', {
size: 50,
fill: 0xCCCCCC
});
watermelonDesc.anchor.set(0.5, 0.5);
watermelonDesc.x = 1024;
watermelonDesc.y = 1030;
bossSelectionScreen.addChild(watermelonDesc);
// Coming Soon Boss 2 button
var boss2Button = LK.getAsset('shape', {
width: 700,
height: 250,
anchorX: 0.5,
anchorY: 0.5
});
boss2Button.tint = 0xFFD700;
boss2Button.x = 1024;
boss2Button.y = 1400;
bossSelectionScreen.addChild(boss2Button);
var boss2Text = new Text2('ANANAS ATI', {
size: 80,
fill: 0xFFFFFF
});
boss2Text.anchor.set(0.5, 0.5);
boss2Text.x = 1024;
boss2Text.y = 1370;
bossSelectionScreen.addChild(boss2Text);
var boss2Desc = new Text2('Mızrak saldırıları ve hücumlarla hızlı ve çevik!', {
size: 50,
fill: 0xCCCCCC
});
boss2Desc.anchor.set(0.5, 0.5);
boss2Desc.x = 1024;
boss2Desc.y = 1430;
bossSelectionScreen.addChild(boss2Desc);
// Both Bosses button
var bothBossesButton = LK.getAsset('shape', {
width: 700,
height: 250,
anchorX: 0.5,
anchorY: 0.5
});
bothBossesButton.tint = 0xFF8800;
bothBossesButton.x = 1024;
bothBossesButton.y = 1800;
bossSelectionScreen.addChild(bothBossesButton);
var bothBossesText = new Text2('HER İKİ BOSS', {
size: 80,
fill: 0xFFFFFF
});
bothBossesText.anchor.set(0.5, 0.5);
bothBossesText.x = 1024;
bothBossesText.y = 1770;
bossSelectionScreen.addChild(bothBossesText);
var bothBossesDesc = new Text2('Nihai meydan okuma - ikisiyle aynı anda savaş!', {
size: 50,
fill: 0xCCCCCC
});
bothBossesDesc.anchor.set(0.5, 0.5);
bothBossesDesc.x = 1024;
bothBossesDesc.y = 1830;
bossSelectionScreen.addChild(bothBossesDesc);
// Coming Soon Boss 3 button
var boss3Button = LK.getAsset('shape', {
width: 700,
height: 250,
anchorX: 0.5,
anchorY: 0.5
});
boss3Button.tint = 0x666666;
boss3Button.x = 1024;
boss3Button.y = 2100;
bossSelectionScreen.addChild(boss3Button);
var boss3Text = new Text2('LEZZETLI TURŞU', {
size: 80,
fill: 0x888888
});
boss3Text.anchor.set(0.5, 0.5);
boss3Text.x = 1024;
boss3Text.y = 2070;
bossSelectionScreen.addChild(boss3Text);
var boss3Desc = new Text2('Yakında Geliyor!', {
size: 50,
fill: 0x888888
});
boss3Desc.anchor.set(0.5, 0.5);
boss3Desc.x = 1024;
boss3Desc.y = 2130;
bossSelectionScreen.addChild(boss3Desc);
// Button event handlers
watermelonBossButton.down = function (x, y, obj) {
selectedBoss = 'watermelon';
gameState = 'bulletSelection';
bossSelectionScreen.destroy();
bossSelectionScreen = null;
createBulletSelectionScreen();
};
boss2Button.down = function (x, y, obj) {
selectedBoss = 'pineapple';
gameState = 'bulletSelection';
bossSelectionScreen.destroy();
bossSelectionScreen = null;
createBulletSelectionScreen();
};
bothBossesButton.down = function (x, y, obj) {
selectedBoss = 'both';
gameState = 'bulletSelection';
bossSelectionScreen.destroy();
bossSelectionScreen = null;
createBulletSelectionScreen();
};
boss3Button.down = function (x, y, obj) {
// Do nothing - coming soon
};
}
// Create bullet selection screen
function createBulletSelectionScreen() {
selectionScreen = new Container();
game.addChild(selectionScreen);
// Semi-transparent background
var background = LK.getAsset('shape', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.8
});
background.tint = 0x000000;
selectionScreen.addChild(background);
// Title
selectionTitle = new Text2('MERMI TİPİNİ SEÇ', {
size: 120,
fill: 0xFFFFFF
});
selectionTitle.anchor.set(0.5, 0.5);
selectionTitle.x = 1024;
selectionTitle.y = 600;
selectionScreen.addChild(selectionTitle);
// Normal bullet button
normalBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
normalBulletButton.tint = 0x4444FF;
normalBulletButton.x = 1024;
normalBulletButton.y = 800;
selectionScreen.addChild(normalBulletButton);
var normalText = new Text2('NORMAL MERMİ', {
size: 80,
fill: 0xFFFFFF
});
normalText.anchor.set(0.5, 0.5);
normalText.x = 1024;
normalText.y = 770;
selectionScreen.addChild(normalText);
var normalDesc = new Text2('5 Hasar, Hızlı', {
size: 50,
fill: 0xCCCCCC
});
normalDesc.anchor.set(0.5, 0.5);
normalDesc.x = 1024;
normalDesc.y = 830;
selectionScreen.addChild(normalDesc);
// Homing bullet button
homingBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
homingBulletButton.tint = 0xFF4444;
homingBulletButton.x = 1024;
homingBulletButton.y = 1100;
selectionScreen.addChild(homingBulletButton);
var homingText = new Text2('GÜDÜMLÜ MERMİ', {
size: 80,
fill: 0xFFFFFF
});
homingText.anchor.set(0.5, 0.5);
homingText.x = 1024;
homingText.y = 1070;
selectionScreen.addChild(homingText);
var homingDesc = new Text2('3 Hasar, Hedefi Takip Eder', {
size: 50,
fill: 0xCCCCCC
});
homingDesc.anchor.set(0.5, 0.5);
homingDesc.x = 1024;
homingDesc.y = 1130;
selectionScreen.addChild(homingDesc);
// Wide bullet button
wideBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
wideBulletButton.tint = 0x44FF44;
wideBulletButton.x = 1024;
wideBulletButton.y = 1400;
selectionScreen.addChild(wideBulletButton);
var wideText = new Text2('GENİŞ MERMİ', {
size: 80,
fill: 0xFFFFFF
});
wideText.anchor.set(0.5, 0.5);
wideText.x = 1024;
wideText.y = 1370;
selectionScreen.addChild(wideText);
var wideDesc = new Text2('10 Hasar, Çok Yavaş', {
size: 50,
fill: 0xCCCCCC
});
wideDesc.anchor.set(0.5, 0.5);
wideDesc.x = 1024;
wideDesc.y = 1430;
selectionScreen.addChild(wideDesc);
// Button event handlers
normalBulletButton.down = function (x, y, obj) {
selectedBulletType = 'normal';
startGame();
};
homingBulletButton.down = function (x, y, obj) {
selectedBulletType = 'homing';
startGame();
};
wideBulletButton.down = function (x, y, obj) {
selectedBulletType = 'wide';
startGame();
};
// Laser bullet button
laserBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
laserBulletButton.tint = 0xFF0080;
laserBulletButton.x = 1024;
laserBulletButton.y = 1700;
selectionScreen.addChild(laserBulletButton);
var laserText = new Text2('LAZER MERMİ', {
size: 80,
fill: 0xFFFFFF
});
laserText.anchor.set(0.5, 0.5);
laserText.x = 1024;
laserText.y = 1670;
selectionScreen.addChild(laserText);
var laserDesc = new Text2('1 hasar, saldırı için basılı tut', {
size: 50,
fill: 0xCCCCCC
});
laserDesc.anchor.set(0.5, 0.5);
laserDesc.x = 1024;
laserDesc.y = 1720;
selectionScreen.addChild(laserDesc);
var laserCooldownDesc = new Text2('ateş etmek için 1.5 saniye bekle', {
size: 40,
fill: 0xFFFFFF
});
laserCooldownDesc.anchor.set(0.5, 0.5);
laserCooldownDesc.x = 1024;
laserCooldownDesc.y = 1760;
selectionScreen.addChild(laserCooldownDesc);
laserBulletButton.down = function (x, y, obj) {
selectedBulletType = 'laser';
startGame();
};
// Spread bullet button
spreadBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
spreadBulletButton.tint = 0xFFAA00;
spreadBulletButton.x = 1024;
spreadBulletButton.y = 2000;
selectionScreen.addChild(spreadBulletButton);
var spreadText = new Text2('BÖLÜNEN MERMİ', {
size: 80,
fill: 0xFFFFFF
});
spreadText.anchor.set(0.5, 0.5);
spreadText.x = 1024;
spreadText.y = 1970;
selectionScreen.addChild(spreadText);
var spreadDesc = new Text2('5 mermi atar, her biri 3 hasar', {
size: 50,
fill: 0xCCCCCC
});
spreadDesc.anchor.set(0.5, 0.5);
spreadDesc.x = 1024;
spreadDesc.y = 2030;
selectionScreen.addChild(spreadDesc);
spreadBulletButton.down = function (x, y, obj) {
selectedBulletType = 'spread';
startGame();
};
// Ice bullet button
var iceBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
iceBulletButton.tint = 0x191970;
iceBulletButton.x = 1024;
iceBulletButton.y = 2300;
selectionScreen.addChild(iceBulletButton);
var iceText = new Text2('BUZ MERMİ', {
size: 80,
fill: 0xFFFFFF
});
iceText.anchor.set(0.5, 0.5);
iceText.x = 1024;
iceText.y = 2270;
selectionScreen.addChild(iceText);
var iceDesc = new Text2('4 hasar, 5 isabet sonrası bossu dondurur', {
size: 50,
fill: 0xCCCCCC
});
iceDesc.anchor.set(0.5, 0.5);
iceDesc.x = 1024;
iceDesc.y = 2330;
selectionScreen.addChild(iceDesc);
iceBulletButton.down = function (x, y, obj) {
selectedBulletType = 'ice';
startGame();
};
// Miscellaneous bullet button
var miscBulletButton = LK.getAsset('shape', {
width: 600,
height: 200,
anchorX: 0.5,
anchorY: 0.5
});
miscBulletButton.tint = 0x9932CC;
miscBulletButton.x = 1024;
miscBulletButton.y = 2600;
selectionScreen.addChild(miscBulletButton);
var miscText = new Text2('ÇEŞİTLİ MERMİ', {
size: 70,
fill: 0xFFFFFF
});
miscText.anchor.set(0.5, 0.5);
miscText.x = 1024;
miscText.y = 2570;
selectionScreen.addChild(miscText);
var miscDesc = new Text2('Tüm mermi türlerini döngüsel kullanır', {
size: 50,
fill: 0xCCCCCC
});
miscDesc.anchor.set(0.5, 0.5);
miscDesc.x = 1024;
miscDesc.y = 2630;
selectionScreen.addChild(miscDesc);
miscBulletButton.down = function (x, y, obj) {
selectedBulletType = 'miscellaneous';
startGame();
};
}
function startGame() {
gameStarted = true;
gameState = 'playing';
if (selectionScreen) {
selectionScreen.destroy();
selectionScreen = null;
}
// Create initial clouds
for (var c = 0; c < 8; c++) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = Math.random() * 1000 + 200;
clouds.push(cloud);
game.addChild(cloud);
}
// Initialize game objects
banana = game.addChild(new Banana());
banana.x = 200;
banana.y = 1366;
if (selectedBoss === 'watermelon') {
watermelonBoss = game.addChild(new WatermelonBoss());
watermelonBoss.x = 1600;
watermelonBoss.y = 1366;
// Play "Aa" music for Monster Watermelon boss fight
LK.playMusic('Aa');
} else if (selectedBoss === 'pineapple') {
pineappleBoss = game.addChild(new PineappleHorseBoss());
pineappleBoss.x = 1600;
pineappleBoss.y = 1366;
// Play "Aa" music for Pineapple Horse boss fight
LK.playMusic('Aa');
} else if (selectedBoss === 'both') {
watermelonBoss = game.addChild(new WatermelonBoss());
watermelonBoss.x = 1400;
watermelonBoss.y = 1000;
pineappleBoss = game.addChild(new PineappleHorseBoss());
pineappleBoss.x = 1700;
pineappleBoss.y = 1700;
// Play "Aa" music for both bosses fight
LK.playMusic('Aa');
}
}
// Show main menu screen
createMainMenu();
// UI Elements
var healthBar = new Text2('Can: 100', {
size: 80,
fill: 0xFFFFFF
});
healthBar.anchor.set(0.5, 0);
healthBar.y = 0;
LK.gui.top.addChild(healthBar);
var bossHealthBar = new Text2('Boss Canı: 500', {
size: 80,
fill: 0xFF0000
});
bossHealthBar.anchor.set(0.5, 0);
bossHealthBar.y = 90;
LK.gui.top.addChild(bossHealthBar);
var secondBossHealthBar = new Text2('', {
size: 80,
fill: 0xFFD700
});
secondBossHealthBar.anchor.set(0.5, 0);
secondBossHealthBar.y = 180;
LK.gui.top.addChild(secondBossHealthBar);
// Event handlers
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// No movement restrictions - banana can move freely anywhere
}
}
game.move = function (x, y, obj) {
if (gameState !== 'playing') return;
handleMove(x, y, obj);
};
game.down = function (x, y, obj) {
if (gameState !== 'playing') return;
mousePressed = true;
dragNode = banana;
handleMove(x, y, obj);
holdTimer = 0; // Reset hold timer when mouse is pressed
// Laser activation will be handled in update loop after 1 second hold requirement
// Handle miscellaneous bullet type - determine current bullet type
var actualBulletType = selectedBulletType;
if (selectedBulletType === 'miscellaneous') {
actualBulletType = miscBulletTypes[currentMiscBulletIndex];
// Cycle to next bullet type for next shot
currentMiscBulletIndex = (currentMiscBulletIndex + 1) % miscBulletTypes.length;
}
// Only shoot non-laser bullets on down event
if (actualBulletType !== 'laser') {
// Shoot projectile
var canShoot = false;
if (actualBulletType === 'wide') {
canShoot = wideBulletCooldown <= 0;
} else if (actualBulletType === 'spread') {
canShoot = spreadBulletCooldown <= 0;
} else {
canShoot = banana.shootCooldown <= 0;
}
if (canShoot) {
if (actualBulletType === 'spread') {
// Fire 5 spread bullets
for (var spreadIndex = 0; spreadIndex < 5; spreadIndex++) {
var spreadProjectile = new SpreadProjectile();
spreadProjectile.x = banana.x + 70;
spreadProjectile.y = banana.y;
// Calculate spread angles: -30, -15, 0, 15, 30 degrees
var spreadAngle = (spreadIndex - 2) * (Math.PI / 6); // 30 degrees in radians
spreadProjectile.angle = spreadAngle;
// Check if potion effect is active
if (banana.potionEffectActive) {
spreadProjectile.enhanced = true;
spreadProjectile.damage = spreadProjectile.damage * 3; // Enhanced damage
spreadProjectile.scaleX = 1.5; // Make projectile bigger
spreadProjectile.scaleY = 1.5;
spreadProjectile.tint = 0xFF88FF; // Purple tint for enhanced projectiles
}
bananaProjectiles.push(spreadProjectile);
game.addChild(spreadProjectile);
}
spreadBulletCooldown = 45; // 0.75 seconds cooldown for spread bullets
} else {
var projectile;
if (actualBulletType === 'homing') {
projectile = new HomingProjectile();
if (selectedBoss === 'watermelon') {
projectile.target = watermelonBoss;
} else if (selectedBoss === 'pineapple') {
projectile.target = pineappleBoss;
} else if (selectedBoss === 'both') {
// Target the boss with higher health, or watermelon if equal
if (watermelonBoss.health >= pineappleBoss.health) {
projectile.target = watermelonBoss;
} else {
projectile.target = pineappleBoss;
}
}
} else if (actualBulletType === 'wide') {
projectile = new WideProjectile();
} else if (actualBulletType === 'ice') {
projectile = new IceProjectile();
} else {
projectile = new BananaProjectile();
}
projectile.x = banana.x + 70;
projectile.y = banana.y;
// Check if potion effect is active
if (banana.potionEffectActive) {
projectile.enhanced = true;
projectile.damage = projectile.damage * 3; // Enhanced damage
projectile.scaleX = 1.5; // Make projectile bigger
projectile.scaleY = 1.5;
projectile.tint = 0xFF88FF; // Purple tint for enhanced projectiles
}
bananaProjectiles.push(projectile);
game.addChild(projectile);
if (actualBulletType === 'wide') {
wideBulletCooldown = 60; // 1 second for wide bullets
} else {
banana.shootCooldown = 15; // 0.25 seconds for other bullets
}
}
LK.getSound('shoot').play();
}
}
};
game.up = function (x, y, obj) {
if (gameState !== 'playing') return;
mousePressed = false;
dragNode = null;
laserPressUsed = false; // Reset laser press flag when mouse is released
holdTimer = 0; // Reset hold timer when mouse is released
};
// Main game loop
game.update = function () {
if (gameState !== 'playing') return;
// Update wide bullet cooldown
if (wideBulletCooldown > 0) {
wideBulletCooldown--;
}
// Update laser bullet cooldown
if (laserBulletCooldown > 0) {
laserBulletCooldown--;
}
// Update spread bullet cooldown
if (spreadBulletCooldown > 0) {
spreadBulletCooldown--;
}
// Update laser usage timers
if (laserUsageTimer > 0) {
laserUsageTimer--;
if (laserUsageTimer <= 0) {
laserCanUse = true; // Reset ability to use laser after 1.5 seconds
laserPressUsed = false; // Reset press flag to allow firing again while holding
}
}
if (laserUsageDuration > 0) {
laserUsageDuration--;
if (laserUsageDuration <= 0) {
laserCanUse = false; // Stop laser usage after 0.2 seconds
laserUsageTimer = 90; // Start 1.5 second cooldown (90 ticks at 60fps)
}
}
// Update hold timer when mouse is pressed
if (mousePressed) {
holdTimer++;
// Start laser usage duration when hold timer reaches 1 second (60 ticks) or when laser becomes available again
var shouldActivateLaser = false;
if (selectedBulletType === 'laser') {
shouldActivateLaser = true;
} else if (selectedBulletType === 'miscellaneous' && miscBulletTypes[currentMiscBulletIndex] === 'laser') {
shouldActivateLaser = true;
}
if (shouldActivateLaser && holdTimer >= 60 && laserCanUse && !laserPressUsed) {
laserUsageDuration = 12; // 0.2 seconds at 60fps
laserPressUsed = true; // Mark this press as used
}
}
// Handle laser shooting while mouse is pressed and within usage window (requires 1 second hold)
var shouldFireLaser = false;
if (selectedBulletType === 'laser') {
shouldFireLaser = true;
} else if (selectedBulletType === 'miscellaneous' && miscBulletTypes[currentMiscBulletIndex] === 'laser') {
shouldFireLaser = true;
}
if (shouldFireLaser && mousePressed && holdTimer >= 60 && laserBulletCooldown <= 0 && laserCanUse && laserUsageDuration > 0) {
var projectile = new LaserProjectile();
projectile.x = banana.x + 70;
projectile.y = banana.y;
// Check if potion effect is active
if (banana.potionEffectActive) {
projectile.enhanced = true;
projectile.damage = projectile.damage * 3; // Enhanced damage
projectile.scaleX = 1.5; // Make projectile bigger
projectile.scaleY = 1.5;
projectile.tint = 0xFF88FF; // Purple tint for enhanced projectiles
}
bananaProjectiles.push(projectile);
game.addChild(projectile);
laserBulletCooldown = 1; // 50 bullets per second (60 FPS / 1 tick = 60 bullets per second, close to 50)
LK.getSound('shoot').play();
}
// Update UI
if (banana.horseshoeInvincible) {
healthBar.setText('Can: Ölümsüz');
} else {
healthBar.setText('Can: ' + banana.health);
}
if (selectedBoss === 'watermelon') {
var phaseText = watermelonBoss.phase === 4 ? ' (Faz 2)' : '';
bossHealthBar.setText('Boss Canı: ' + watermelonBoss.health + phaseText);
secondBossHealthBar.setText('');
} else if (selectedBoss === 'pineapple') {
var phaseText = pineappleBoss.phase === 2 ? ' (Faz 2)' : '';
bossHealthBar.setText('Boss Canı: ' + pineappleBoss.health + phaseText);
secondBossHealthBar.setText('');
} else if (selectedBoss === 'both') {
var watermelonPhaseText = watermelonBoss.phase === 4 ? ' (Faz 2)' : '';
var pineapplePhaseText = pineappleBoss.phase === 2 ? ' (Faz 2)' : '';
bossHealthBar.setText('Karpuz: ' + watermelonBoss.health + watermelonPhaseText);
secondBossHealthBar.setText('Ananas: ' + pineappleBoss.health + pineapplePhaseText);
}
// Handle banana projectiles
for (var i = bananaProjectiles.length - 1; i >= 0; i--) {
var projectile = bananaProjectiles[i];
// Remove if off screen
if (projectile.x > 2098) {
projectile.destroy();
bananaProjectiles.splice(i, 1);
continue;
}
// Check collision with bosses
var hitBoss = false;
if (selectedBoss === 'watermelon' && projectile.intersects(watermelonBoss)) {
var isIce = projectile instanceof IceProjectile;
watermelonBoss.takeDamage(projectile.damage, isIce);
projectile.destroy();
bananaProjectiles.splice(i, 1);
hitBoss = true;
} else if (selectedBoss === 'pineapple' && projectile.intersects(pineappleBoss)) {
var isIce = projectile instanceof IceProjectile;
pineappleBoss.takeDamage(projectile.damage, isIce);
projectile.destroy();
bananaProjectiles.splice(i, 1);
hitBoss = true;
} else if (selectedBoss === 'both') {
if (projectile.intersects(watermelonBoss)) {
var isIce = projectile instanceof IceProjectile;
watermelonBoss.takeDamage(projectile.damage, isIce);
projectile.destroy();
bananaProjectiles.splice(i, 1);
hitBoss = true;
} else if (projectile.intersects(pineappleBoss)) {
var isIce = projectile instanceof IceProjectile;
pineappleBoss.takeDamage(projectile.damage, isIce);
projectile.destroy();
bananaProjectiles.splice(i, 1);
hitBoss = true;
}
}
if (hitBoss) continue;
// Check collision with thrown pineapples (only for pineapple boss)
if (selectedBoss === 'pineapple') {
var hitPineapple = false;
for (var tp = thrownPineapples.length - 1; tp >= 0; tp--) {
var thrownPineapple = thrownPineapples[tp];
if (projectile.intersects(thrownPineapple)) {
thrownPineapple.takeDamage(projectile.damage);
projectile.destroy();
bananaProjectiles.splice(i, 1);
hitPineapple = true;
break;
}
}
if (hitPineapple) continue;
}
}
// Handle watermelon seeds
for (var j = watermelonSeeds.length - 1; j >= 0; j--) {
var seed = watermelonSeeds[j];
// Remove if off screen
if (seed.x < -50 || seed.x > 2098 || seed.y < -50 || seed.y > 2782) {
seed.destroy();
watermelonSeeds.splice(j, 1);
continue;
}
// Check collision with banana
if (seed.intersects(banana)) {
banana.takeDamage(seed.damage);
// Calculate knockback direction from seed to banana
var knockbackX = banana.x - seed.x;
var knockbackY = banana.y - seed.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = 1;
knockbackY = 0;
}
// Calculate knockback destination (100 pixels away from seed)
var knockbackDistance = 100;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 200,
easing: tween.easeOut
});
seed.destroy();
watermelonSeeds.splice(j, 1);
continue;
}
}
// Handle watermelon slices
for (var s = watermelonSlices.length - 1; s >= 0; s--) {
var slice = watermelonSlices[s];
// Remove if off screen
if (slice.x < -100 || slice.x > 2148 || slice.y < -100 || slice.y > 2832) {
slice.destroy();
watermelonSlices.splice(s, 1);
continue;
}
// Check collision with banana
if (slice.intersects(banana)) {
banana.takeDamage(slice.damage);
// Calculate knockback direction from slice to banana
var knockbackX = banana.x - slice.x;
var knockbackY = banana.y - slice.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = 1;
knockbackY = 0;
}
// Calculate knockback destination (150 pixels away from slice)
var knockbackDistance = 150;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 250,
easing: tween.easeOut
});
slice.destroy();
watermelonSlices.splice(s, 1);
continue;
}
}
// Handle watermelon potions
for (var p = watermelonPotions.length - 1; p >= 0; p--) {
var potion = watermelonPotions[p];
// Remove if off screen
if (potion.x < -50 || potion.x > 2098 || potion.y < -50 || potion.y > 2782) {
potion.destroy();
watermelonPotions.splice(p, 1);
continue;
}
// Check collision with banana
if (potion.intersects(banana)) {
banana.activatePotionEffect();
potion.destroy();
watermelonPotions.splice(p, 1);
continue;
}
}
// Handle pineapple spears
for (var sp = pineappleSpears.length - 1; sp >= 0; sp--) {
var spear = pineappleSpears[sp];
// Remove if off screen
if (spear.x < -100 || spear.x > 2148 || spear.y < -100 || spear.y > 2832) {
spear.destroy();
pineappleSpears.splice(sp, 1);
continue;
}
// Check collision with banana
if (spear.intersects(banana)) {
banana.takeDamage(spear.damage);
// Calculate knockback direction from spear to banana
var knockbackX = banana.x - spear.x;
var knockbackY = banana.y - spear.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = 1;
knockbackY = 0;
}
// Calculate knockback destination (120 pixels away from spear)
var knockbackDistance = 120;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 220,
easing: tween.easeOut
});
spear.destroy();
pineappleSpears.splice(sp, 1);
continue;
}
}
// Handle thrown pineapples
for (var tp = thrownPineapples.length - 1; tp >= 0; tp--) {
var thrownPineapple = thrownPineapples[tp];
// Remove if off screen
if (thrownPineapple.x < -100 || thrownPineapple.x > 2148 || thrownPineapple.y < -100 || thrownPineapple.y > 2832) {
thrownPineapple.destroy();
thrownPineapples.splice(tp, 1);
continue;
}
// Check collision with banana (if pineapple hits banana directly)
if (thrownPineapple.intersects(banana)) {
banana.takeDamage(25); // Direct pineapple hit damage
// Calculate knockback direction from thrown pineapple to banana
var knockbackX = banana.x - thrownPineapple.x;
var knockbackY = banana.y - thrownPineapple.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = 1;
knockbackY = 0;
}
// Calculate knockback destination (180 pixels away from pineapple)
var knockbackDistance = 180;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 280,
easing: tween.easeOut
});
thrownPineapple.explode(); // Still explode into slices
continue;
}
}
// Handle pineapple slices
for (var ps = pineappleSlices.length - 1; ps >= 0; ps--) {
var slice = pineappleSlices[ps];
// Remove if off screen
if (slice.x < -100 || slice.x > 2148 || slice.y < -100 || slice.y > 2832) {
slice.destroy();
pineappleSlices.splice(ps, 1);
continue;
}
// Check collision with banana
if (slice.intersects(banana)) {
banana.takeDamage(slice.damage);
// Calculate knockback direction from slice to banana
var knockbackX = banana.x - slice.x;
var knockbackY = banana.y - slice.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = 1;
knockbackY = 0;
}
// Calculate knockback destination (130 pixels away from slice)
var knockbackDistance = 130;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 240,
easing: tween.easeOut
});
slice.destroy();
pineappleSlices.splice(ps, 1);
continue;
}
}
// Handle horseshoes
for (var hs = horseshoes.length - 1; hs >= 0; hs--) {
var horseshoe = horseshoes[hs];
// Remove if off screen
if (horseshoe.x < -100 || horseshoe.x > 2148 || horseshoe.y < -100 || horseshoe.y > 2832) {
horseshoe.destroy();
horseshoes.splice(hs, 1);
continue;
}
// Check collision with banana
if (horseshoe.intersects(banana)) {
banana.activateHorseshoeInvincibility();
// Add sparkle effect with tween animation
tween(horseshoe, {
scaleX: 3.0,
scaleY: 3.0,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
horseshoe.destroy();
}
});
horseshoes.splice(hs, 1);
continue;
}
}
// Check collision between banana and bosses
if (selectedBoss === 'watermelon' && banana.intersects(watermelonBoss)) {
banana.takeDamage(30);
// Calculate knockback direction from boss to banana
var knockbackX = banana.x - watermelonBoss.x;
var knockbackY = banana.y - watermelonBoss.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = -1; // Push away from boss (towards left)
knockbackY = 0;
}
// Calculate knockback destination (200 pixels away from boss)
var knockbackDistance = 200;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
} else if (selectedBoss === 'pineapple' && banana.intersects(pineappleBoss)) {
banana.takeDamage(35);
// Calculate knockback direction from boss to banana
var knockbackX = banana.x - pineappleBoss.x;
var knockbackY = banana.y - pineappleBoss.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = -1; // Push away from boss (towards left)
knockbackY = 0;
}
// Calculate knockback destination (200 pixels away from boss)
var knockbackDistance = 200;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
} else if (selectedBoss === 'both') {
if (banana.intersects(watermelonBoss)) {
banana.takeDamage(30);
// Calculate knockback direction from watermelon boss to banana
var knockbackX = banana.x - watermelonBoss.x;
var knockbackY = banana.y - watermelonBoss.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = -1; // Push away from boss (towards left)
knockbackY = 0;
}
// Calculate knockback destination (200 pixels away from boss)
var knockbackDistance = 200;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
} else if (banana.intersects(pineappleBoss)) {
banana.takeDamage(35);
// Calculate knockback direction from pineapple boss to banana
var knockbackX = banana.x - pineappleBoss.x;
var knockbackY = banana.y - pineappleBoss.y;
var distance = Math.sqrt(knockbackX * knockbackX + knockbackY * knockbackY);
// Normalize the knockback vector
if (distance > 0) {
knockbackX = knockbackX / distance;
knockbackY = knockbackY / distance;
} else {
// Default direction if objects are at exact same position
knockbackX = -1; // Push away from boss (towards left)
knockbackY = 0;
}
// Calculate knockback destination (200 pixels away from boss)
var knockbackDistance = 200;
var targetX = banana.x + knockbackX * knockbackDistance;
var targetY = banana.y + knockbackY * knockbackDistance;
// Clamp target position within screen bounds
targetX = Math.max(50, Math.min(1998, targetX));
targetY = Math.max(50, Math.min(2682, targetY));
// Apply knockback animation using tween
tween(banana, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
}
}
// Spawn new clouds occasionally
if (LK.ticks % 600 === 0) {
// Every 10 seconds
var newCloud = new Cloud();
newCloud.x = 2248;
newCloud.y = Math.random() * 1000 + 200;
clouds.push(newCloud);
game.addChild(newCloud);
}
// Clean up clouds that are too far off screen
for (var k = clouds.length - 1; k >= 0; k--) {
var cloud = clouds[k];
if (cloud.x < -300) {
cloud.destroy();
clouds.splice(k, 1);
}
}
};
// Start battle music
LK.playMusic('battle'); ===================================================================
--- original.js
+++ change.js
@@ -1559,8 +1559,27 @@
skinsText.anchor.set(0.5, 0.5);
skinsText.x = 1024;
skinsText.y = 1400;
mainMenu.addChild(skinsText);
+ // Language Button
+ var languageButton = LK.getAsset('shape', {
+ width: 400,
+ height: 120,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ languageButton.tint = 0x0088CC;
+ languageButton.x = 1024;
+ languageButton.y = 1600;
+ mainMenu.addChild(languageButton);
+ var languageText = new Text2('English', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ languageText.anchor.set(0.5, 0.5);
+ languageText.x = 1024;
+ languageText.y = 1600;
+ mainMenu.addChild(languageText);
// Play button event handler
playButton.down = function (x, y, obj) {
gameState = 'bossSelection';
mainMenu.destroy();
@@ -1571,8 +1590,29 @@
skinsButton.down = function (x, y, obj) {
// Show coming soon screen for skins
createSkinsComingSoonScreen();
};
+ // Language button event handler
+ languageButton.down = function (x, y, obj) {
+ // Toggle between Turkish and English
+ if (languageText.text === 'English') {
+ // Switch to English
+ gameTitle.setText('BANANJOHN');
+ subtitle.setText('DEFEAT THE MONSTER WATERMELON!');
+ playText.setText('PLAY');
+ instructions.setText('Drag Bananjohn to move!\nChoose your weapon wisely!');
+ skinsText.setText('SKINS');
+ languageText.setText('Türkçe');
+ } else {
+ // Switch back to Turkish
+ gameTitle.setText('BANANJOHN');
+ subtitle.setText('CANAVAR KARPUZU YEN!');
+ playText.setText('OYNA');
+ instructions.setText('Bananjohn\'u hareket ettirmek için sürükleyin!\nSilahınızı akıllıca seçin!');
+ skinsText.setText('GÖRÜNÜMLER');
+ languageText.setText('English');
+ }
+ };
}
// Create boss selection screen
function createBossSelectionScreen() {
bossSelectionScreen = new Container();