User prompt
leveli gösteren yazıları büyük yap ve yazı fontunu kalınlaştır
User prompt
üstteki Leveli gösteren yazıları büyült ve kalınlaştır
User prompt
oyuncunun miss atack vurma şansını biraz daha düşür
User prompt
level 9 ve 10 daki düşmanların hasarlarını ve canlarını biraz daha artır
User prompt
oyuncu her hasar aldığında +5 enerji fazladan yeniler , oyuncu düşmana her hasar verdiğinde oyuncu +4 can kazanır
User prompt
oyuncu her hasar aldığında +5 enerji fazladan yeniler ve rakibe her hasar verdiğinde +4 can kazanır
User prompt
oyuncu her hasar aldığında 7 can yeniler
User prompt
miss oluncaki 15 olsun
User prompt
+19 olan düşmana enerji eklemesini 14e düşür
User prompt
eğer oyuncu düşmana 30 hasar ve daha fazlasını vurursa düşmana ek ilave olarak 5 enerji ekle
User prompt
oyuncu vuruşu ıskalayıp hasar vuramasa bile düşmana belirlenen enerji ilavesini ver
User prompt
her hasar almadan sonra oyuncunun +10 enerji kazanmasını kaldır
User prompt
her hasar almadan sonra rakip düşman +19 enerji kazanır, her hasar almadan sonra oyuncu +10 enerji kazanır
User prompt
oyuncu yüzde 10luk bir şans ile bazı vuruşlarını kaçırır ve düşmana hiç hasar veremez ve bu olduğunda ekranda "Missed!" yazar
User prompt
oyuncunun canının %20 ve altına düşmesi durumunda ona yetecenklerin bulunduğu yerde çıkan yeni bir özel ulti vuruşu butonu aktif et, bu ulti şu şekilde çalışsın: oyuncu ekrana her tıkladığında 1 damage biriksin, 4 saniyelik geri sayım içinde ne kadar tıklanılırsa o kadar hasar versin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyuncunun canının %20 ve altına düşmesi durumunda ona yetecenklerin bulunduğu yerde çıkan yeni bir özel ulti vuruşu butonu aktif et, bu ulti şu şekilde çalışsın: oyuncu ekrana her tıkladığında 1 damage biriksin, 4 saniyelik geri sayım içinde ne kadar tıklanılırsa o kadar hasar versin
User prompt
rakip düşmanlar her hasar aldığında 15 enerji yenilerler
User prompt
rakip düşmanlar her hasar aldığında 5 enerji yenilesinler
User prompt
eğer düşman karakter oyuncuya onun canını tamamen bitirip öldürebilecek bir vuruş gerçekleştirir ise oyunu durdurup küçük bir popup ekranında bir minigame açılır. minigame şu şekildedir: ekranda rastgele yerlerde ve 8 ila 5 arasında bir sayıda hedefler çıkar ve oyuncu bu hedeflerin hepsine geri sayım bitmeden tıklamak zorundadır. hedeflere 2.6 saniyelik süre içerisinde tıklaması gereklidir. minigame penceresi ve hedefler için iki ayrı resim asseti oluştur ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
minigame şu şekilde değiştir: ekranda rastgele yerlerde ve 10 ila 5 arasında bir sayıda hedefler çıkar ve oyuncu bu hedeflerin hepsine geri sayım bitmeden tıklamak zorundadır. hedeflere 1.8 saniyelik süre içerisinde tıklaması gereklidir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
eğer düşman karakter oyuncuya onun canını tamamen bitirip öldürebilecek bir vuruş gerçekleştirir ise oyunu durdurup küçük bir popup ekranında bir minigame açılır
User prompt
oyuncunun onu öldürecek ölümcül bir hasar alması durumunda ekranda belirecek bir kutucuğun içinde minigame hazırla, oyuncunun 1.8 saniyelik bir geri sayım içerisinde ekranda belirecek olan rastgele hedeflerin hepsine tıklaması gerekli, eğer belirtilen süre içerisinde bu hedeflere başarıyla tıklayabilirse oyuncu ölmez ve 40 can ile hayatta kalır ve ikinci bir şans elde eder, eğer başarısız olursa karakter ölür ve oyun sona erer. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
bu animasyonun ölçeğini biraz daha küçült ve hafiflet ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
"Giris" assetine giriş ekranı boyunca devam eden, genişleyip daralıp uzayan ve yavaşca tekrar eski haline dönen , döngü halindeki bir nefes alma animasyonu ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
"Giris" assetinin konumunu ekranın biraz daha soluna taşı
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AttackButton = Container.expand(function (attackData) { var self = Container.call(this); self.attackData = attackData; // Button background // Calculate scale so button width is about 1/5 of 2048px (screen width) var desiredButtonWidth = 2048 / 5; var attackButtonAsset = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5 }); var scaleX = desiredButtonWidth / attackButtonAsset.width; var scaleY = 1.5; // Make it taller for easier touch, adjust as needed self.bg = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: scaleX, scaleY: scaleY }); // Attack name self.nameText = new Text2(attackData.name, { size: 36, fill: 0xFFFFFF }); self.nameText.anchor.set(0.5, 0); self.nameText.y = -30; self.addChild(self.nameText); // Attack stats self.statsText = new Text2("DMG: " + attackData.damage + " | EN: " + attackData.energy, { size: 26, fill: 0xFFFFFF }); self.statsText.anchor.set(0.5, 1); self.statsText.y = 30; self.addChild(self.statsText); // Interactive self.bg.interactive = true; // Event handlers self.down = function (x, y, obj) { self.bg.alpha = 0.7; }; self.up = function (x, y, obj) { self.bg.alpha = 1; if (self.onAttack) { self.onAttack(self.attackData); } }; self.disable = function () { self.bg.alpha = 0.5; self.bg.interactive = false; }; self.enable = function () { self.bg.alpha = 1; self.bg.interactive = true; }; return self; }); var BloodSplatter = Container.expand(function () { var self = Container.call(this); self.particles = []; var numParticles = 10 + Math.floor(Math.random() * 10); // 10 to 19 particles var baseLife = 30 + Math.random() * 30; // Approx 0.5 to 1 second life at 60FPS self.update = function () { for (var i = self.particles.length - 1; i >= 0; i--) { var p = self.particles[i]; p.life--; if (p.life <= 0) { self.removeChild(p.sprite); p.sprite.destroy(); // Destroy the individual particle sprite self.particles.splice(i, 1); // Remove from the array } else { p.sprite.x += p.vx; p.sprite.y += p.vy; p.sprite.rotation += p.rotationSpeed; p.sprite.alpha = Math.max(0, p.life / p.initialLife); // Fade out // Apply some friction/drag to slow down particles p.vx *= 0.97; p.vy *= 0.97; // Optional: apply gravity // p.vy += 0.1; } } if (self.particles.length === 0) { // All particles are gone, remove the container itself if (self.parent) { self.parent.removeChild(self); } self.destroy(); // Destroy the BloodSplatter container } }; for (var i = 0; i < numParticles; i++) { // Use LK.getAsset as we are creating multiple instances dynamically var particleSprite = LK.getAsset('bloodSplatterEffect', { anchorX: 0.5, anchorY: 0.5 }); // Randomize scale for each particle to be smaller than original effect var scale = 0.05 + Math.random() * 0.2; // e.g., 0.05 to 0.25 particleSprite.scale.set(scale); particleSprite.rotation = Math.random() * Math.PI * 2; // Random initial rotation var angle = Math.random() * Math.PI * 2; // Random direction var speed = 3 + Math.random() * 7; // Random speed (3 to 10 pixels/frame) var particle = { sprite: particleSprite, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, rotationSpeed: (Math.random() - 0.5) * 0.3, // Random rotation speed (radians/frame) life: baseLife * (0.7 + Math.random() * 0.6), // Vary lifetime slightly per particle initialLife: 0 // Will be set after life is determined }; particle.initialLife = particle.life; // Store initial life for alpha calculation self.addChild(particleSprite); self.particles.push(particle); } return self; }); var Fighter = Container.expand(function (isPlayer, maxHealth, maxEnergy) { var self = Container.call(this); self.isPlayer = isPlayer || false; self.maxHealth = maxHealth || 100; self.maxEnergy = maxEnergy || 100; self.health = self.maxHealth; self.energy = self.maxEnergy; self.name = isPlayer ? "Player" : "Enemy"; // Sprite and visual elements self.sprite = self.attachAsset(isPlayer ? 'player' : 'enemy' + (currentLevel || 1), { anchorX: 0.5, anchorY: 0.5 }); // Health bar container self.healthBarContainer = new Container(); self.addChild(self.healthBarContainer); // Health bar background self.healthBarBg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, alpha: 0.3 }); self.healthBarContainer.addChild(self.healthBarBg); // Health bar foreground self.healthBarFg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5 }); self.healthBarContainer.addChild(self.healthBarFg); // Energy bar container self.energyBarContainer = new Container(); self.addChild(self.energyBarContainer); // Energy bar background self.energyBarBg = LK.getAsset('energyBar', { anchorX: 0, anchorY: 0.5, alpha: 0.3 }); self.energyBarContainer.addChild(self.energyBarBg); // Energy bar foreground self.energyBarFg = LK.getAsset('energyBar', { anchorX: 0, anchorY: 0.5 }); self.energyBarContainer.addChild(self.energyBarFg); // Name label self.nameLabel = new Text2(self.name, { size: 36, fill: 0xFFFFFF }); self.nameLabel.anchor.set(0.5, 0.5); self.addChild(self.nameLabel); // Position elements if (isPlayer) { // Position at top-left self.healthBarContainer.x = -self.healthBarBg.width / 2; self.healthBarContainer.y = -self.sprite.height / 2 - 600; self.energyBarContainer.x = -self.energyBarBg.width / 2; self.energyBarContainer.y = -self.sprite.height / 2 - 550; self.nameLabel.x = 0; self.nameLabel.y = -self.sprite.height / 2 - 640; } else { // Position at top-right self.healthBarContainer.x = -self.healthBarBg.width / 2; self.healthBarContainer.y = -self.sprite.height / 2 - 600; self.energyBarContainer.x = -self.energyBarBg.width / 2; self.energyBarContainer.y = -self.sprite.height / 2 - 550; self.nameLabel.x = 0; self.nameLabel.y = -self.sprite.height / 2 - 640; } // Methods self.updateBars = function () { var healthRatio = Math.max(0, Math.min(1, self.health / self.maxHealth)); var energyRatio = Math.max(0, Math.min(1, self.energy / self.maxEnergy)); // Animate health bar changes tween(self.healthBarFg.scale, { x: healthRatio }, { duration: 300 }); // Animate energy bar changes tween(self.energyBarFg.scale, { x: energyRatio }, { duration: 300 }); }; self.takeDamage = function (amount) { self.health = Math.max(0, self.health - amount); self.updateBars(); // --- Auto-heal and block chance boost if health drops below 30% --- if (!self._boosted && self.health / self.maxHealth < 0.3) { // Only boost once per drop below 30% self._boosted = true; self.replenishEnergy(70); self._blockChanceBoost = 0.6; // 60% extra block chance // Optional: show a status message if this is the player if (self.isPlayer && typeof statusMessage !== "undefined") { statusMessage.show("Emergency boost! +70 energy, block chance up!", 1200); } } else if (self.health / self.maxHealth >= 0.3) { // Reset boost if healed above 30% self._boosted = false; self._blockChanceBoost = 0; } // Visual feedback // Animate a quick scale "squash" for damage feedback, then restore if (self.sprite && self.sprite.scale) { // Squash vertically (y) and stretch horizontally (x) for a quick hit effect tween(self.sprite.scale, { x: 1.08, y: 0.92 }, { duration: 100, onFinish: function onFinish() { tween(self.sprite.scale, { x: 1, y: 1 }, { duration: 100, onFinish: function onFinish() { // Ensure breathing animation continues after the feedback if (self.sprite && self.sprite.parent) { self.startBreathingAnimation(); } } }); } }); } return self.health <= 0; }; self.useEnergy = function (amount) { var canUse = self.energy >= amount; if (canUse) { self.energy -= amount; self.updateBars(); } return canUse; }; self.replenishEnergy = function (amount) { self.energy = Math.min(self.maxEnergy, self.energy + amount); self.updateBars(); }; self.reset = function (newHealth, newEnergy) { self.health = newHealth || self.maxHealth; self.energy = newEnergy || self.maxEnergy; self.updateBars(); }; self.setName = function (newName) { self.name = newName; self.nameLabel.setText(newName); }; self.startBreathingAnimation = function () { // If a previous breathing tween exists for this fighter, stop it. // This assumes the tween library returns a controllable object with a 'kill' method. if (self.breathingTween && typeof self.breathingTween.kill === 'function') { self.breathingTween.kill(); } // Ensure the sprite and its scale property are available. if (self.sprite && self.sprite.scale) { // Reset sprite scale to a base of (1,1) before starting the animation. // This ensures the animation is consistent even if called multiple times. self.sprite.scale.set(1, 1); // Create the tween for the y-scale. self.breathingTween = tween(self.sprite.scale, { y: 1.03 }, // Target y-scale (3% taller) { duration: 1500, // Duration of one half of the animation (e.g., inhale) in milliseconds. yoyo: true, // Makes the animation reverse automatically (e.g., exhale). repeat: Infinity // Loop the animation indefinitely. }); } }; // Initialize bars self.updateBars(); // Start the breathing animation when the fighter is initialized. self.startBreathingAnimation(); // Death animation: fade out, scale up, then destroy sprite (optionally show blood splatter) self.playDeathAnimation = function (_onFinish) { // Stop breathing animation if any if (self.breathingTween && typeof self.breathingTween.kill === 'function') { self.breathingTween.kill(); } // Animate: scale up and fade out tween(self.sprite.scale, { x: 1.3, y: 1.3 }, { duration: 700 }); tween(self.sprite, { alpha: 0 }, { duration: 700, onFinish: function onFinish() { // Optionally, keep the sprite invisible but don't destroy the whole fighter container self.sprite.visible = false; if (typeof _onFinish === "function") _onFinish(); } }); }; return self; }); var StatusMessage = Container.expand(function () { var self = Container.call(this); self.text = new Text2("", { size: 60, fill: 0xFFFFFF }); self.text.anchor.set(0.5, 0.5); self.addChild(self.text); self.show = function (message, duration) { self.text.setText(message); self.visible = true; if (self.hideTimeout) { LK.clearTimeout(self.hideTimeout); } self.hideTimeout = LK.setTimeout(function () { self.visible = false; self.hideTimeout = null; }, duration || 1500); }; self.visible = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Placeholder ID, engine handles actual resource // Music assets for each level // Game state // Assuming a generic ID for now var currentLevel = 0; // Start at level 0 (menu) var totalLevels = 10; var playerTurn = true; var gameActive = false; var enemyAttackDelay = 1000; // --- Level 0 (Intro/Menu) UI Elements --- var introContainer; var startButton; // Characters var player; var enemy; var enemies = [{ name: "Qeko", health: 70, energy: 80, damage: 1.0 }, { name: "Oramakoma Buramako", health: 90, energy: 90, damage: 1.1 }, { name: "Dust2person", health: 100, energy: 100, damage: 1.2 }, { name: "Rockey", health: 120, energy: 100, damage: 1.3 }, { name: "Zikko", health: 130, energy: 110, damage: 1.4 }, { name: "Sweetie", health: 150, energy: 120, damage: 1.5 }, { name: "Master Baitor", health: 170, energy: 130, damage: 1.6 }, { name: "Grandmaster", health: 200, energy: 140, damage: 1.7 }, { name: "The God", health: 220, energy: 150, damage: 1.8 }, { name: "Woody CHADMAN", health: 250, energy: 150, damage: 2.0 }]; // Attack options var attacks = [{ name: "Quick Strike", damage: 10, energy: 20, description: "A fast, low damage attack" }, { name: "Heavy Blow", damage: 25, energy: 40, description: "A powerful but energy-draining strike" }, { name: "Risky Slash", damage: 40, energy: 60, description: "High damage but very energy intensive" }, { name: "Desperate Attack", damage: 60, energy: 90, description: "All-in attack with massive energy cost" }]; // UI Elements var attackButtons = []; var statusMessage; var levelDisplay; var nextLevelButton; // Initialize the game elements function initGame() { if (currentLevel === 0) { // --- Show Intro/Menu --- introContainer = new Container(); // Background var introBg = LK.getAsset('background1', { anchorX: 0, anchorY: 0 }); introBg.isBackground = true; introContainer.addChild(introBg); // Game Title var titleText = new Text2("CHAD HARDWOOD vs. Everything", { size: 160, fill: 0xFFFFFF, font: "Impact, 'Arial Black', Tahoma, 'GillSans-Bold', sans-serif", stroke: 0xFFD700, strokeThickness: 12, dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 8, dropShadowAngle: Math.PI / 4, dropShadowBlur: 12 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 600; introContainer.addChild(titleText); // Subtitle var subtitle = new Text2("Turn-based Arena Combat", { size: 60, fill: 0xdddddd }); subtitle.anchor.set(0.5, 0.5); subtitle.x = 2048 / 2; subtitle.y = 800; introContainer.addChild(subtitle); // Start Button startButton = new AttackButton({ name: "START GAME", damage: 0, energy: 0 }); startButton.x = 2048 / 2; startButton.y = 1200; startButton.onAttack = function () { // Remove intro, set level 1, and start game if (introContainer && introContainer.parent) { introContainer.parent.removeChild(introContainer); } currentLevel = 1; initGame(); }; introContainer.addChild(startButton); // Add big image asset at center bottom for intro (level 0) only var introBigImage = LK.getAsset('Giris', { anchorX: 0.5, anchorY: 1, scaleX: 1.2, scaleY: 1.2, // Move image further to the left by subtracting 250px from center x: 2048 / 2 - 250, y: 2732 - 80 // 80px margin from bottom }); introContainer.addChild(introBigImage); // Credits var credits = new Text2("by zibby_d", { size: 40, fill: 0xaaaaaa }); credits.anchor.set(0.5, 0.5); credits.x = 2048 / 2; credits.y = 1500; introContainer.addChild(credits); game.addChild(introContainer); return; } // Add background for current level var background = LK.getAsset('background1', { anchorX: 0, anchorY: 0 }); background.isBackground = true; // Mark as background for easy identification game.addChild(background); // Create player and enemy player = new Fighter(true, 150, 100); player.setName("Chad Hardwood"); player.x = 2048 / 4; player.y = 2732 / 2 + 100; // Move down to make room for health bars at top game.addChild(player); enemy = new Fighter(false, enemies[0].health, enemies[0].energy); enemy.x = 2048 / 4 * 3; enemy.y = 2732 / 2 + 100; // Move down to make room for health bars at top enemy.setName(enemies[0].name); // Make sure we're using the enemy1 asset for the first level enemy.sprite.destroy(); enemy.sprite = enemy.attachAsset('enemy1', { anchorX: 0.5, anchorY: 0.5 }); enemy.startBreathingAnimation(); // Restart animation for the new sprite game.addChild(enemy); // Create attack buttons var buttonContainer = new Container(); game.addChild(buttonContainer); buttonContainer.x = 2048 / 2; buttonContainer.y = 2732 - 200; for (var i = 0; i < attacks.length; i++) { var button = new AttackButton(attacks[i]); // Increase horizontal spacing and separation between buttons // Spread them more: use a larger multiplier and a small offset for extra separation button.x = (i - 1.5) * 420 + (i - 1.5) * 40; button.onAttack = handlePlayerAttack; attackButtons.push(button); buttonContainer.addChild(button); } // Create status message statusMessage = new StatusMessage(); statusMessage.x = 2048 / 2; statusMessage.y = 2732 / 3; game.addChild(statusMessage); // Create level display levelDisplay = new Text2("Level " + currentLevel + "/" + totalLevels, { size: 40, fill: 0xFFFFFF }); levelDisplay.anchor.set(0.5, 0.5); levelDisplay.x = 2048 / 2; levelDisplay.y = 80; game.addChild(levelDisplay); // Create next level button (hidden initially) nextLevelButton = new AttackButton({ name: "NEXT LEVEL", damage: 0, energy: 0 }); nextLevelButton.x = 2048 / 2; nextLevelButton.y = 2732 / 2 + 200; nextLevelButton.onAttack = startNextLevel; nextLevelButton.visible = false; game.addChild(nextLevelButton); // Start game startGame(); } function startGame() { LK.playMusic('level' + currentLevel + 'Music'); gameActive = true; playerTurn = true; updateUI(); statusMessage.show("Battle Start! Your Turn", 1500); } function updateUI() { // Update level display levelDisplay.setText("Level " + currentLevel + "/" + totalLevels); // Enable/disable attack buttons based on player's energy for (var i = 0; i < attackButtons.length; i++) { if (playerTurn && gameActive && player.energy >= attacks[i].energy) { attackButtons[i].enable(); } else { attackButtons[i].disable(); } } // Show/hide next level button // Button is visible if game is not active (round ended), it's not the last level, AND player is still alive nextLevelButton.visible = !gameActive && currentLevel < totalLevels && player && player.health > 0; } function handlePlayerAttack(attackData) { if (!playerTurn || !gameActive) return; // Use energy for attack if (!player.useEnergy(attackData.energy)) { statusMessage.show("Not enough energy!", 1000); return; } // Apply damage to enemy var damage = attackData.damage; // Random chance for critical hit (20% chance) var isCritical = Math.random() < 0.2; if (isCritical) { damage = Math.floor(damage * 1.5); LK.getSound('critical').play(); statusMessage.show("Critical Hit! " + damage + " damage", 1000); // Level 9 & 10: 7% chance to fully heal enemy after critical hit if ((currentLevel === 9 || currentLevel === 10) && Math.random() < 0.07) { enemy.health = enemy.maxHealth; enemy.updateBars(); statusMessage.show("The enemy miraculously healed to full health!", 1200); } } else { LK.getSound('hit').play(); statusMessage.show(attackData.name + "! " + damage + " damage", 1000); } // Visual feedback // --- Fast approach-and-return animation for player attacking enemy --- var originalPlayerX = player.x; var originalEnemyX = enemy.x; var approachDistance = Math.abs(enemy.x - player.x) * 0.4; // Move 40% of the distance var approachDuration = 120; var returnDuration = 180; // Swap to attack asset for player var oldPlayerSprite = player.sprite; oldPlayerSprite.visible = false; var attackSprite = player.attachAsset('playerAttack', { anchorX: 0.5, anchorY: 0.5 }); attackSprite.x = 0; attackSprite.y = 0; player.addChild(attackSprite); player.sprite = attackSprite; // Move player towards enemy tween(player, { x: player.x + approachDistance }, { duration: approachDuration, easing: tween.cubicOut, onFinish: function onFinish() { // Move player back to original position tween(player, { x: originalPlayerX }, { duration: returnDuration, easing: tween.cubicIn, onFinish: function onFinish() { // Remove attack sprite and restore original player.removeChild(attackSprite); attackSprite.destroy(); oldPlayerSprite.visible = true; player.sprite = oldPlayerSprite; player.startBreathingAnimation(); } }); } }); // Move enemy slightly towards player (for impact effect) tween(enemy, { x: enemy.x - approachDistance * 0.15 }, { duration: approachDuration, easing: tween.cubicOut, onFinish: function onFinish() { tween(enemy, { x: originalEnemyX }, { duration: returnDuration, easing: tween.cubicIn }); } }); LK.effects.flashObject(enemy.sprite, 0xff0000, 300); // Play specific sound for level 2 enemy damage if (currentLevel === 2) { LK.getSound('level2EnemyDamage').play(); } // Enemy block chance: 10% base, +60% if health < 30% var enemyBlockChance = 0.1 + (enemy._blockChanceBoost || 0); var enemyBlocked = Math.random() < enemyBlockChance; if (enemyBlocked) { damage = Math.floor(damage * 0.5); LK.getSound('block').play(); statusMessage.show("Enemy Blocked! " + damage + " damage", 1000); } // Apply damage var defeated = enemy.takeDamage(damage); // Create and show blood splatter effect on enemy var splatter = new BloodSplatter(); // Position splatter slightly above the center of the enemy, with some randomness splatter.x = enemy.x + (Math.random() - 0.5) * enemy.sprite.width * 0.25; // Random x-offset within 25% of sprite width splatter.y = enemy.y - enemy.sprite.height * 0.2 + (Math.random() - 0.5) * (enemy.sprite.height * 0.25); // Positioned towards upper part game.addChild(splatter); if (defeated) { // {2J} handleEnemyDefeated(); } else { // End player turn if no energy left if (player.energy < 20) { endPlayerTurn(); } } updateUI(); } function handleEnemyDefeated() { gameActive = false; // Play enemy death animation, then continue with defeat logic enemy.playDeathAnimation(function () { // Play special death sound for level 2 enemy if (currentLevel === 2) { LK.getSound('level2EnemyDeath').play(); } // Play special death sound for level 3 enemy if (currentLevel === 3) { LK.getSound('level3EnemyDeath').play(); } LK.getSound('victory').play(); if (currentLevel >= totalLevels) { // Game completed LK.setScore(LK.getScore() + 69); // Add 69 points for level completion statusMessage.show("Congratulations! You are the Arena Champion!", 3000); LK.setTimeout(function () { LK.showYouWin(); }, 3000); } else { // Level completed LK.setScore(LK.getScore() + 69); // Add 69 points for level completion statusMessage.show("Enemy Defeated! Get ready for the next challenge", 2000); LK.setTimeout(function () { nextLevelButton.visible = true; updateUI(); }, 2000); } }); } function endPlayerTurn() { playerTurn = false; statusMessage.show("Out of energy! Enemy's turn", 1000); // Schedule enemy attack LK.setTimeout(enemyAttack, enemyAttackDelay); updateUI(); } function enemyAttack() { if (gameActive) { // Choose a random attack based on available energy var availableAttacks = []; for (var i = 0; i < attacks.length; i++) { if (enemy.energy >= attacks[i].energy) { availableAttacks.push(attacks[i]); } } if (availableAttacks.length === 0) { // Enemy has no energy for attacks startPlayerTurn(); return; } var attack = availableAttacks[Math.floor(Math.random() * availableAttacks.length)]; // Use energy enemy.useEnergy(attack.energy); // Calculate damage (apply enemy damage multiplier) var enemyDamageMultiplier = enemies[currentLevel - 1].damage; var damage = Math.floor(attack.damage * enemyDamageMultiplier); // 2% instant kill chance for enemy attacks at level 6 and below var instantKill = false; if (currentLevel <= 6 && Math.random() < 0.02) { damage = player.health; // Set damage to current health for instant kill instantKill = true; } // Random chance for player to block (10% base chance, +60% if player health < 30%) var blockChance = 0.1 + (player._blockChanceBoost || 0); var isBlocked = Math.random() < blockChance; if (isBlocked) { damage = Math.floor(damage * 0.5); LK.getSound('block').play(); statusMessage.show("Attack Blocked! " + damage + " damage", 1000); } else if (instantKill) { LK.getSound('critical').play(); statusMessage.show("Fatal Strike! Instant defeat!", 1200); } else { LK.getSound('hit').play(); statusMessage.show("Enemy used " + attack.name + "! " + damage + " damage", 1000); } // Visual feedback // --- Fast approach-and-return animation for enemy attacking player --- var originalEnemyX = enemy.x; var originalPlayerX = player.x; var approachDistance = Math.abs(enemy.x - player.x) * 0.4; // Move 40% of the distance var approachDuration = 120; var returnDuration = 180; // Swap to attack asset for enemy var oldEnemySprite = enemy.sprite; oldEnemySprite.visible = false; var attackAssetName = 'enemy' + currentLevel + 'Attack'; var attackSprite = enemy.attachAsset(attackAssetName, { anchorX: 0.5, anchorY: 0.5 }); attackSprite.x = 0; attackSprite.y = 0; enemy.addChild(attackSprite); enemy.sprite = attackSprite; // Move enemy towards player tween(enemy, { x: enemy.x - approachDistance }, { duration: approachDuration, easing: tween.cubicOut, onFinish: function onFinish() { // Move enemy back to original position tween(enemy, { x: originalEnemyX }, { duration: returnDuration, easing: tween.cubicIn, onFinish: function onFinish() { // Remove attack sprite and restore original enemy.removeChild(attackSprite); attackSprite.destroy(); oldEnemySprite.visible = true; enemy.sprite = oldEnemySprite; enemy.startBreathingAnimation(); } }); } }); // Move player slightly towards enemy (for impact effect) tween(player, { x: player.x + approachDistance * 0.15 }, { duration: approachDuration, easing: tween.cubicOut, onFinish: function onFinish() { tween(player, { x: originalPlayerX }, { duration: returnDuration, easing: tween.cubicIn }); } }); LK.effects.flashObject(player.sprite, 0xff0000, 300); // Apply damage var defeated = player.takeDamage(damage); // Create and show blood splatter effect on player var splatter = new BloodSplatter(); // Position splatter slightly above the center of the player, with some randomness splatter.x = player.x + (Math.random() - 0.5) * player.sprite.width * 0.25; // Random x-offset within 25% of sprite width splatter.y = player.y - player.sprite.height * 0.2 + (Math.random() - 0.5) * (player.sprite.height * 0.25); // Positioned towards upper part game.addChild(splatter); if (defeated) { // {3a} handlePlayerDefeated(); } else { // Continue enemy attacks if it has energy if (enemy.energy >= 20) { LK.setTimeout(enemyAttack, enemyAttackDelay); } else { LK.setTimeout(startPlayerTurn, enemyAttackDelay); } } } updateUI(); } function handlePlayerDefeated() { gameActive = false; // Play player death animation, then continue with defeat/game over player.playDeathAnimation(function () { LK.getSound('defeat').play(); LK.getSound('gameOverDefeat').play(); statusMessage.show("You have been defeated!", 2000); LK.setTimeout(function () { LK.showGameOver(); }, 2000); }); } function startPlayerTurn() { playerTurn = true; // Replenish some energy for player player.replenishEnergy(30); statusMessage.show("Your Turn", 1000); updateUI(); } function startNextLevel() { currentLevel++; // Update enemy based on current level var enemyData = enemies[currentLevel - 1]; // Update background for new level // Remove previous background and add new one for (var i = 0; i < game.children.length; i++) { if (game.children[i].isBackground) { game.removeChild(game.children[i]); break; } } var background = LK.getAsset('background' + currentLevel, { anchorX: 0, anchorY: 0 }); background.isBackground = true; // Mark as background for easy identification game.addChildAt(background, 0); // Add to the bottom layer // Remove old enemy sprite and create new one with current level's asset enemy.sprite.destroy(); enemy.sprite = enemy.attachAsset('enemy' + currentLevel, { anchorX: 0.5, anchorY: 0.5 }); enemy.startBreathingAnimation(); // Restart animation for the new sprite enemy.setName(enemyData.name); enemy.reset(enemyData.health, enemyData.energy); // Replenish player health and energy if (currentLevel > 7) { // Give extra 20 health for player after level 7 player.maxHealth += 20; } player.reset(player.maxHealth, player.maxEnergy); // Reset to full health and energy at start of each level // Reset game state LK.playMusic('level' + currentLevel + 'Music'); gameActive = true; playerTurn = true; nextLevelButton.visible = false; // Show level message statusMessage.show("Level " + currentLevel + ": " + enemyData.name, 1500); updateUI(); } // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AttackButton = Container.expand(function (attackData) {
var self = Container.call(this);
self.attackData = attackData;
// Button background
// Calculate scale so button width is about 1/5 of 2048px (screen width)
var desiredButtonWidth = 2048 / 5;
var attackButtonAsset = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5
});
var scaleX = desiredButtonWidth / attackButtonAsset.width;
var scaleY = 1.5; // Make it taller for easier touch, adjust as needed
self.bg = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scaleX,
scaleY: scaleY
});
// Attack name
self.nameText = new Text2(attackData.name, {
size: 36,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0);
self.nameText.y = -30;
self.addChild(self.nameText);
// Attack stats
self.statsText = new Text2("DMG: " + attackData.damage + " | EN: " + attackData.energy, {
size: 26,
fill: 0xFFFFFF
});
self.statsText.anchor.set(0.5, 1);
self.statsText.y = 30;
self.addChild(self.statsText);
// Interactive
self.bg.interactive = true;
// Event handlers
self.down = function (x, y, obj) {
self.bg.alpha = 0.7;
};
self.up = function (x, y, obj) {
self.bg.alpha = 1;
if (self.onAttack) {
self.onAttack(self.attackData);
}
};
self.disable = function () {
self.bg.alpha = 0.5;
self.bg.interactive = false;
};
self.enable = function () {
self.bg.alpha = 1;
self.bg.interactive = true;
};
return self;
});
var BloodSplatter = Container.expand(function () {
var self = Container.call(this);
self.particles = [];
var numParticles = 10 + Math.floor(Math.random() * 10); // 10 to 19 particles
var baseLife = 30 + Math.random() * 30; // Approx 0.5 to 1 second life at 60FPS
self.update = function () {
for (var i = self.particles.length - 1; i >= 0; i--) {
var p = self.particles[i];
p.life--;
if (p.life <= 0) {
self.removeChild(p.sprite);
p.sprite.destroy(); // Destroy the individual particle sprite
self.particles.splice(i, 1); // Remove from the array
} else {
p.sprite.x += p.vx;
p.sprite.y += p.vy;
p.sprite.rotation += p.rotationSpeed;
p.sprite.alpha = Math.max(0, p.life / p.initialLife); // Fade out
// Apply some friction/drag to slow down particles
p.vx *= 0.97;
p.vy *= 0.97;
// Optional: apply gravity
// p.vy += 0.1;
}
}
if (self.particles.length === 0) {
// All particles are gone, remove the container itself
if (self.parent) {
self.parent.removeChild(self);
}
self.destroy(); // Destroy the BloodSplatter container
}
};
for (var i = 0; i < numParticles; i++) {
// Use LK.getAsset as we are creating multiple instances dynamically
var particleSprite = LK.getAsset('bloodSplatterEffect', {
anchorX: 0.5,
anchorY: 0.5
});
// Randomize scale for each particle to be smaller than original effect
var scale = 0.05 + Math.random() * 0.2; // e.g., 0.05 to 0.25
particleSprite.scale.set(scale);
particleSprite.rotation = Math.random() * Math.PI * 2; // Random initial rotation
var angle = Math.random() * Math.PI * 2; // Random direction
var speed = 3 + Math.random() * 7; // Random speed (3 to 10 pixels/frame)
var particle = {
sprite: particleSprite,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
rotationSpeed: (Math.random() - 0.5) * 0.3,
// Random rotation speed (radians/frame)
life: baseLife * (0.7 + Math.random() * 0.6),
// Vary lifetime slightly per particle
initialLife: 0 // Will be set after life is determined
};
particle.initialLife = particle.life; // Store initial life for alpha calculation
self.addChild(particleSprite);
self.particles.push(particle);
}
return self;
});
var Fighter = Container.expand(function (isPlayer, maxHealth, maxEnergy) {
var self = Container.call(this);
self.isPlayer = isPlayer || false;
self.maxHealth = maxHealth || 100;
self.maxEnergy = maxEnergy || 100;
self.health = self.maxHealth;
self.energy = self.maxEnergy;
self.name = isPlayer ? "Player" : "Enemy";
// Sprite and visual elements
self.sprite = self.attachAsset(isPlayer ? 'player' : 'enemy' + (currentLevel || 1), {
anchorX: 0.5,
anchorY: 0.5
});
// Health bar container
self.healthBarContainer = new Container();
self.addChild(self.healthBarContainer);
// Health bar background
self.healthBarBg = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
alpha: 0.3
});
self.healthBarContainer.addChild(self.healthBarBg);
// Health bar foreground
self.healthBarFg = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5
});
self.healthBarContainer.addChild(self.healthBarFg);
// Energy bar container
self.energyBarContainer = new Container();
self.addChild(self.energyBarContainer);
// Energy bar background
self.energyBarBg = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
alpha: 0.3
});
self.energyBarContainer.addChild(self.energyBarBg);
// Energy bar foreground
self.energyBarFg = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0.5
});
self.energyBarContainer.addChild(self.energyBarFg);
// Name label
self.nameLabel = new Text2(self.name, {
size: 36,
fill: 0xFFFFFF
});
self.nameLabel.anchor.set(0.5, 0.5);
self.addChild(self.nameLabel);
// Position elements
if (isPlayer) {
// Position at top-left
self.healthBarContainer.x = -self.healthBarBg.width / 2;
self.healthBarContainer.y = -self.sprite.height / 2 - 600;
self.energyBarContainer.x = -self.energyBarBg.width / 2;
self.energyBarContainer.y = -self.sprite.height / 2 - 550;
self.nameLabel.x = 0;
self.nameLabel.y = -self.sprite.height / 2 - 640;
} else {
// Position at top-right
self.healthBarContainer.x = -self.healthBarBg.width / 2;
self.healthBarContainer.y = -self.sprite.height / 2 - 600;
self.energyBarContainer.x = -self.energyBarBg.width / 2;
self.energyBarContainer.y = -self.sprite.height / 2 - 550;
self.nameLabel.x = 0;
self.nameLabel.y = -self.sprite.height / 2 - 640;
}
// Methods
self.updateBars = function () {
var healthRatio = Math.max(0, Math.min(1, self.health / self.maxHealth));
var energyRatio = Math.max(0, Math.min(1, self.energy / self.maxEnergy));
// Animate health bar changes
tween(self.healthBarFg.scale, {
x: healthRatio
}, {
duration: 300
});
// Animate energy bar changes
tween(self.energyBarFg.scale, {
x: energyRatio
}, {
duration: 300
});
};
self.takeDamage = function (amount) {
self.health = Math.max(0, self.health - amount);
self.updateBars();
// --- Auto-heal and block chance boost if health drops below 30% ---
if (!self._boosted && self.health / self.maxHealth < 0.3) {
// Only boost once per drop below 30%
self._boosted = true;
self.replenishEnergy(70);
self._blockChanceBoost = 0.6; // 60% extra block chance
// Optional: show a status message if this is the player
if (self.isPlayer && typeof statusMessage !== "undefined") {
statusMessage.show("Emergency boost! +70 energy, block chance up!", 1200);
}
} else if (self.health / self.maxHealth >= 0.3) {
// Reset boost if healed above 30%
self._boosted = false;
self._blockChanceBoost = 0;
}
// Visual feedback
// Animate a quick scale "squash" for damage feedback, then restore
if (self.sprite && self.sprite.scale) {
// Squash vertically (y) and stretch horizontally (x) for a quick hit effect
tween(self.sprite.scale, {
x: 1.08,
y: 0.92
}, {
duration: 100,
onFinish: function onFinish() {
tween(self.sprite.scale, {
x: 1,
y: 1
}, {
duration: 100,
onFinish: function onFinish() {
// Ensure breathing animation continues after the feedback
if (self.sprite && self.sprite.parent) {
self.startBreathingAnimation();
}
}
});
}
});
}
return self.health <= 0;
};
self.useEnergy = function (amount) {
var canUse = self.energy >= amount;
if (canUse) {
self.energy -= amount;
self.updateBars();
}
return canUse;
};
self.replenishEnergy = function (amount) {
self.energy = Math.min(self.maxEnergy, self.energy + amount);
self.updateBars();
};
self.reset = function (newHealth, newEnergy) {
self.health = newHealth || self.maxHealth;
self.energy = newEnergy || self.maxEnergy;
self.updateBars();
};
self.setName = function (newName) {
self.name = newName;
self.nameLabel.setText(newName);
};
self.startBreathingAnimation = function () {
// If a previous breathing tween exists for this fighter, stop it.
// This assumes the tween library returns a controllable object with a 'kill' method.
if (self.breathingTween && typeof self.breathingTween.kill === 'function') {
self.breathingTween.kill();
}
// Ensure the sprite and its scale property are available.
if (self.sprite && self.sprite.scale) {
// Reset sprite scale to a base of (1,1) before starting the animation.
// This ensures the animation is consistent even if called multiple times.
self.sprite.scale.set(1, 1);
// Create the tween for the y-scale.
self.breathingTween = tween(self.sprite.scale, {
y: 1.03
},
// Target y-scale (3% taller)
{
duration: 1500,
// Duration of one half of the animation (e.g., inhale) in milliseconds.
yoyo: true,
// Makes the animation reverse automatically (e.g., exhale).
repeat: Infinity // Loop the animation indefinitely.
});
}
};
// Initialize bars
self.updateBars();
// Start the breathing animation when the fighter is initialized.
self.startBreathingAnimation();
// Death animation: fade out, scale up, then destroy sprite (optionally show blood splatter)
self.playDeathAnimation = function (_onFinish) {
// Stop breathing animation if any
if (self.breathingTween && typeof self.breathingTween.kill === 'function') {
self.breathingTween.kill();
}
// Animate: scale up and fade out
tween(self.sprite.scale, {
x: 1.3,
y: 1.3
}, {
duration: 700
});
tween(self.sprite, {
alpha: 0
}, {
duration: 700,
onFinish: function onFinish() {
// Optionally, keep the sprite invisible but don't destroy the whole fighter container
self.sprite.visible = false;
if (typeof _onFinish === "function") _onFinish();
}
});
};
return self;
});
var StatusMessage = Container.expand(function () {
var self = Container.call(this);
self.text = new Text2("", {
size: 60,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.show = function (message, duration) {
self.text.setText(message);
self.visible = true;
if (self.hideTimeout) {
LK.clearTimeout(self.hideTimeout);
}
self.hideTimeout = LK.setTimeout(function () {
self.visible = false;
self.hideTimeout = null;
}, duration || 1500);
};
self.visible = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Placeholder ID, engine handles actual resource
// Music assets for each level
// Game state
// Assuming a generic ID for now
var currentLevel = 0; // Start at level 0 (menu)
var totalLevels = 10;
var playerTurn = true;
var gameActive = false;
var enemyAttackDelay = 1000;
// --- Level 0 (Intro/Menu) UI Elements ---
var introContainer;
var startButton;
// Characters
var player;
var enemy;
var enemies = [{
name: "Qeko",
health: 70,
energy: 80,
damage: 1.0
}, {
name: "Oramakoma Buramako",
health: 90,
energy: 90,
damage: 1.1
}, {
name: "Dust2person",
health: 100,
energy: 100,
damage: 1.2
}, {
name: "Rockey",
health: 120,
energy: 100,
damage: 1.3
}, {
name: "Zikko",
health: 130,
energy: 110,
damage: 1.4
}, {
name: "Sweetie",
health: 150,
energy: 120,
damage: 1.5
}, {
name: "Master Baitor",
health: 170,
energy: 130,
damage: 1.6
}, {
name: "Grandmaster",
health: 200,
energy: 140,
damage: 1.7
}, {
name: "The God",
health: 220,
energy: 150,
damage: 1.8
}, {
name: "Woody CHADMAN",
health: 250,
energy: 150,
damage: 2.0
}];
// Attack options
var attacks = [{
name: "Quick Strike",
damage: 10,
energy: 20,
description: "A fast, low damage attack"
}, {
name: "Heavy Blow",
damage: 25,
energy: 40,
description: "A powerful but energy-draining strike"
}, {
name: "Risky Slash",
damage: 40,
energy: 60,
description: "High damage but very energy intensive"
}, {
name: "Desperate Attack",
damage: 60,
energy: 90,
description: "All-in attack with massive energy cost"
}];
// UI Elements
var attackButtons = [];
var statusMessage;
var levelDisplay;
var nextLevelButton;
// Initialize the game elements
function initGame() {
if (currentLevel === 0) {
// --- Show Intro/Menu ---
introContainer = new Container();
// Background
var introBg = LK.getAsset('background1', {
anchorX: 0,
anchorY: 0
});
introBg.isBackground = true;
introContainer.addChild(introBg);
// Game Title
var titleText = new Text2("CHAD HARDWOOD vs. Everything", {
size: 160,
fill: 0xFFFFFF,
font: "Impact, 'Arial Black', Tahoma, 'GillSans-Bold', sans-serif",
stroke: 0xFFD700,
strokeThickness: 12,
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 8,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 12
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
introContainer.addChild(titleText);
// Subtitle
var subtitle = new Text2("Turn-based Arena Combat", {
size: 60,
fill: 0xdddddd
});
subtitle.anchor.set(0.5, 0.5);
subtitle.x = 2048 / 2;
subtitle.y = 800;
introContainer.addChild(subtitle);
// Start Button
startButton = new AttackButton({
name: "START GAME",
damage: 0,
energy: 0
});
startButton.x = 2048 / 2;
startButton.y = 1200;
startButton.onAttack = function () {
// Remove intro, set level 1, and start game
if (introContainer && introContainer.parent) {
introContainer.parent.removeChild(introContainer);
}
currentLevel = 1;
initGame();
};
introContainer.addChild(startButton);
// Add big image asset at center bottom for intro (level 0) only
var introBigImage = LK.getAsset('Giris', {
anchorX: 0.5,
anchorY: 1,
scaleX: 1.2,
scaleY: 1.2,
// Move image further to the left by subtracting 250px from center
x: 2048 / 2 - 250,
y: 2732 - 80 // 80px margin from bottom
});
introContainer.addChild(introBigImage);
// Credits
var credits = new Text2("by zibby_d", {
size: 40,
fill: 0xaaaaaa
});
credits.anchor.set(0.5, 0.5);
credits.x = 2048 / 2;
credits.y = 1500;
introContainer.addChild(credits);
game.addChild(introContainer);
return;
}
// Add background for current level
var background = LK.getAsset('background1', {
anchorX: 0,
anchorY: 0
});
background.isBackground = true; // Mark as background for easy identification
game.addChild(background);
// Create player and enemy
player = new Fighter(true, 150, 100);
player.setName("Chad Hardwood");
player.x = 2048 / 4;
player.y = 2732 / 2 + 100; // Move down to make room for health bars at top
game.addChild(player);
enemy = new Fighter(false, enemies[0].health, enemies[0].energy);
enemy.x = 2048 / 4 * 3;
enemy.y = 2732 / 2 + 100; // Move down to make room for health bars at top
enemy.setName(enemies[0].name);
// Make sure we're using the enemy1 asset for the first level
enemy.sprite.destroy();
enemy.sprite = enemy.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5
});
enemy.startBreathingAnimation(); // Restart animation for the new sprite
game.addChild(enemy);
// Create attack buttons
var buttonContainer = new Container();
game.addChild(buttonContainer);
buttonContainer.x = 2048 / 2;
buttonContainer.y = 2732 - 200;
for (var i = 0; i < attacks.length; i++) {
var button = new AttackButton(attacks[i]);
// Increase horizontal spacing and separation between buttons
// Spread them more: use a larger multiplier and a small offset for extra separation
button.x = (i - 1.5) * 420 + (i - 1.5) * 40;
button.onAttack = handlePlayerAttack;
attackButtons.push(button);
buttonContainer.addChild(button);
}
// Create status message
statusMessage = new StatusMessage();
statusMessage.x = 2048 / 2;
statusMessage.y = 2732 / 3;
game.addChild(statusMessage);
// Create level display
levelDisplay = new Text2("Level " + currentLevel + "/" + totalLevels, {
size: 40,
fill: 0xFFFFFF
});
levelDisplay.anchor.set(0.5, 0.5);
levelDisplay.x = 2048 / 2;
levelDisplay.y = 80;
game.addChild(levelDisplay);
// Create next level button (hidden initially)
nextLevelButton = new AttackButton({
name: "NEXT LEVEL",
damage: 0,
energy: 0
});
nextLevelButton.x = 2048 / 2;
nextLevelButton.y = 2732 / 2 + 200;
nextLevelButton.onAttack = startNextLevel;
nextLevelButton.visible = false;
game.addChild(nextLevelButton);
// Start game
startGame();
}
function startGame() {
LK.playMusic('level' + currentLevel + 'Music');
gameActive = true;
playerTurn = true;
updateUI();
statusMessage.show("Battle Start! Your Turn", 1500);
}
function updateUI() {
// Update level display
levelDisplay.setText("Level " + currentLevel + "/" + totalLevels);
// Enable/disable attack buttons based on player's energy
for (var i = 0; i < attackButtons.length; i++) {
if (playerTurn && gameActive && player.energy >= attacks[i].energy) {
attackButtons[i].enable();
} else {
attackButtons[i].disable();
}
}
// Show/hide next level button
// Button is visible if game is not active (round ended), it's not the last level, AND player is still alive
nextLevelButton.visible = !gameActive && currentLevel < totalLevels && player && player.health > 0;
}
function handlePlayerAttack(attackData) {
if (!playerTurn || !gameActive) return;
// Use energy for attack
if (!player.useEnergy(attackData.energy)) {
statusMessage.show("Not enough energy!", 1000);
return;
}
// Apply damage to enemy
var damage = attackData.damage;
// Random chance for critical hit (20% chance)
var isCritical = Math.random() < 0.2;
if (isCritical) {
damage = Math.floor(damage * 1.5);
LK.getSound('critical').play();
statusMessage.show("Critical Hit! " + damage + " damage", 1000);
// Level 9 & 10: 7% chance to fully heal enemy after critical hit
if ((currentLevel === 9 || currentLevel === 10) && Math.random() < 0.07) {
enemy.health = enemy.maxHealth;
enemy.updateBars();
statusMessage.show("The enemy miraculously healed to full health!", 1200);
}
} else {
LK.getSound('hit').play();
statusMessage.show(attackData.name + "! " + damage + " damage", 1000);
}
// Visual feedback
// --- Fast approach-and-return animation for player attacking enemy ---
var originalPlayerX = player.x;
var originalEnemyX = enemy.x;
var approachDistance = Math.abs(enemy.x - player.x) * 0.4; // Move 40% of the distance
var approachDuration = 120;
var returnDuration = 180;
// Swap to attack asset for player
var oldPlayerSprite = player.sprite;
oldPlayerSprite.visible = false;
var attackSprite = player.attachAsset('playerAttack', {
anchorX: 0.5,
anchorY: 0.5
});
attackSprite.x = 0;
attackSprite.y = 0;
player.addChild(attackSprite);
player.sprite = attackSprite;
// Move player towards enemy
tween(player, {
x: player.x + approachDistance
}, {
duration: approachDuration,
easing: tween.cubicOut,
onFinish: function onFinish() {
// Move player back to original position
tween(player, {
x: originalPlayerX
}, {
duration: returnDuration,
easing: tween.cubicIn,
onFinish: function onFinish() {
// Remove attack sprite and restore original
player.removeChild(attackSprite);
attackSprite.destroy();
oldPlayerSprite.visible = true;
player.sprite = oldPlayerSprite;
player.startBreathingAnimation();
}
});
}
});
// Move enemy slightly towards player (for impact effect)
tween(enemy, {
x: enemy.x - approachDistance * 0.15
}, {
duration: approachDuration,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(enemy, {
x: originalEnemyX
}, {
duration: returnDuration,
easing: tween.cubicIn
});
}
});
LK.effects.flashObject(enemy.sprite, 0xff0000, 300);
// Play specific sound for level 2 enemy damage
if (currentLevel === 2) {
LK.getSound('level2EnemyDamage').play();
}
// Enemy block chance: 10% base, +60% if health < 30%
var enemyBlockChance = 0.1 + (enemy._blockChanceBoost || 0);
var enemyBlocked = Math.random() < enemyBlockChance;
if (enemyBlocked) {
damage = Math.floor(damage * 0.5);
LK.getSound('block').play();
statusMessage.show("Enemy Blocked! " + damage + " damage", 1000);
}
// Apply damage
var defeated = enemy.takeDamage(damage);
// Create and show blood splatter effect on enemy
var splatter = new BloodSplatter();
// Position splatter slightly above the center of the enemy, with some randomness
splatter.x = enemy.x + (Math.random() - 0.5) * enemy.sprite.width * 0.25; // Random x-offset within 25% of sprite width
splatter.y = enemy.y - enemy.sprite.height * 0.2 + (Math.random() - 0.5) * (enemy.sprite.height * 0.25); // Positioned towards upper part
game.addChild(splatter);
if (defeated) {
// {2J}
handleEnemyDefeated();
} else {
// End player turn if no energy left
if (player.energy < 20) {
endPlayerTurn();
}
}
updateUI();
}
function handleEnemyDefeated() {
gameActive = false;
// Play enemy death animation, then continue with defeat logic
enemy.playDeathAnimation(function () {
// Play special death sound for level 2 enemy
if (currentLevel === 2) {
LK.getSound('level2EnemyDeath').play();
}
// Play special death sound for level 3 enemy
if (currentLevel === 3) {
LK.getSound('level3EnemyDeath').play();
}
LK.getSound('victory').play();
if (currentLevel >= totalLevels) {
// Game completed
LK.setScore(LK.getScore() + 69); // Add 69 points for level completion
statusMessage.show("Congratulations! You are the Arena Champion!", 3000);
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
} else {
// Level completed
LK.setScore(LK.getScore() + 69); // Add 69 points for level completion
statusMessage.show("Enemy Defeated! Get ready for the next challenge", 2000);
LK.setTimeout(function () {
nextLevelButton.visible = true;
updateUI();
}, 2000);
}
});
}
function endPlayerTurn() {
playerTurn = false;
statusMessage.show("Out of energy! Enemy's turn", 1000);
// Schedule enemy attack
LK.setTimeout(enemyAttack, enemyAttackDelay);
updateUI();
}
function enemyAttack() {
if (gameActive) {
// Choose a random attack based on available energy
var availableAttacks = [];
for (var i = 0; i < attacks.length; i++) {
if (enemy.energy >= attacks[i].energy) {
availableAttacks.push(attacks[i]);
}
}
if (availableAttacks.length === 0) {
// Enemy has no energy for attacks
startPlayerTurn();
return;
}
var attack = availableAttacks[Math.floor(Math.random() * availableAttacks.length)];
// Use energy
enemy.useEnergy(attack.energy);
// Calculate damage (apply enemy damage multiplier)
var enemyDamageMultiplier = enemies[currentLevel - 1].damage;
var damage = Math.floor(attack.damage * enemyDamageMultiplier);
// 2% instant kill chance for enemy attacks at level 6 and below
var instantKill = false;
if (currentLevel <= 6 && Math.random() < 0.02) {
damage = player.health; // Set damage to current health for instant kill
instantKill = true;
}
// Random chance for player to block (10% base chance, +60% if player health < 30%)
var blockChance = 0.1 + (player._blockChanceBoost || 0);
var isBlocked = Math.random() < blockChance;
if (isBlocked) {
damage = Math.floor(damage * 0.5);
LK.getSound('block').play();
statusMessage.show("Attack Blocked! " + damage + " damage", 1000);
} else if (instantKill) {
LK.getSound('critical').play();
statusMessage.show("Fatal Strike! Instant defeat!", 1200);
} else {
LK.getSound('hit').play();
statusMessage.show("Enemy used " + attack.name + "! " + damage + " damage", 1000);
}
// Visual feedback
// --- Fast approach-and-return animation for enemy attacking player ---
var originalEnemyX = enemy.x;
var originalPlayerX = player.x;
var approachDistance = Math.abs(enemy.x - player.x) * 0.4; // Move 40% of the distance
var approachDuration = 120;
var returnDuration = 180;
// Swap to attack asset for enemy
var oldEnemySprite = enemy.sprite;
oldEnemySprite.visible = false;
var attackAssetName = 'enemy' + currentLevel + 'Attack';
var attackSprite = enemy.attachAsset(attackAssetName, {
anchorX: 0.5,
anchorY: 0.5
});
attackSprite.x = 0;
attackSprite.y = 0;
enemy.addChild(attackSprite);
enemy.sprite = attackSprite;
// Move enemy towards player
tween(enemy, {
x: enemy.x - approachDistance
}, {
duration: approachDuration,
easing: tween.cubicOut,
onFinish: function onFinish() {
// Move enemy back to original position
tween(enemy, {
x: originalEnemyX
}, {
duration: returnDuration,
easing: tween.cubicIn,
onFinish: function onFinish() {
// Remove attack sprite and restore original
enemy.removeChild(attackSprite);
attackSprite.destroy();
oldEnemySprite.visible = true;
enemy.sprite = oldEnemySprite;
enemy.startBreathingAnimation();
}
});
}
});
// Move player slightly towards enemy (for impact effect)
tween(player, {
x: player.x + approachDistance * 0.15
}, {
duration: approachDuration,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(player, {
x: originalPlayerX
}, {
duration: returnDuration,
easing: tween.cubicIn
});
}
});
LK.effects.flashObject(player.sprite, 0xff0000, 300);
// Apply damage
var defeated = player.takeDamage(damage);
// Create and show blood splatter effect on player
var splatter = new BloodSplatter();
// Position splatter slightly above the center of the player, with some randomness
splatter.x = player.x + (Math.random() - 0.5) * player.sprite.width * 0.25; // Random x-offset within 25% of sprite width
splatter.y = player.y - player.sprite.height * 0.2 + (Math.random() - 0.5) * (player.sprite.height * 0.25); // Positioned towards upper part
game.addChild(splatter);
if (defeated) {
// {3a}
handlePlayerDefeated();
} else {
// Continue enemy attacks if it has energy
if (enemy.energy >= 20) {
LK.setTimeout(enemyAttack, enemyAttackDelay);
} else {
LK.setTimeout(startPlayerTurn, enemyAttackDelay);
}
}
}
updateUI();
}
function handlePlayerDefeated() {
gameActive = false;
// Play player death animation, then continue with defeat/game over
player.playDeathAnimation(function () {
LK.getSound('defeat').play();
LK.getSound('gameOverDefeat').play();
statusMessage.show("You have been defeated!", 2000);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
});
}
function startPlayerTurn() {
playerTurn = true;
// Replenish some energy for player
player.replenishEnergy(30);
statusMessage.show("Your Turn", 1000);
updateUI();
}
function startNextLevel() {
currentLevel++;
// Update enemy based on current level
var enemyData = enemies[currentLevel - 1];
// Update background for new level
// Remove previous background and add new one
for (var i = 0; i < game.children.length; i++) {
if (game.children[i].isBackground) {
game.removeChild(game.children[i]);
break;
}
}
var background = LK.getAsset('background' + currentLevel, {
anchorX: 0,
anchorY: 0
});
background.isBackground = true; // Mark as background for easy identification
game.addChildAt(background, 0); // Add to the bottom layer
// Remove old enemy sprite and create new one with current level's asset
enemy.sprite.destroy();
enemy.sprite = enemy.attachAsset('enemy' + currentLevel, {
anchorX: 0.5,
anchorY: 0.5
});
enemy.startBreathingAnimation(); // Restart animation for the new sprite
enemy.setName(enemyData.name);
enemy.reset(enemyData.health, enemyData.energy);
// Replenish player health and energy
if (currentLevel > 7) {
// Give extra 20 health for player after level 7
player.maxHealth += 20;
}
player.reset(player.maxHealth, player.maxEnergy); // Reset to full health and energy at start of each level
// Reset game state
LK.playMusic('level' + currentLevel + 'Music');
gameActive = true;
playerTurn = true;
nextLevelButton.visible = false;
// Show level message
statusMessage.show("Level " + currentLevel + ": " + enemyData.name, 1500);
updateUI();
}
// Initialize the game
initGame();
daha uzaktan çekilmiş bir halini yarat. karakterin kafasının üstü ve saçları, ayakları gözüküyor olsun
tüm vücudunun ayaklarına kadar gözükebileceği açıdan daha uzaktan çekilmiş kafasının üstünün ve saçlarının belli olduğu halini yarat, ayrıca "the silhouette of the very big gun that the man hides in his pants creates a big bump towards to ground with the tension of the pants" belli olsun
detailed pixelart, fighter style while keeping the original: details, color, and lighting. "Tamer Market" text can be seen
remove the girl on right
arabic street, islam, dust. background image. Bomb explotion in the background. pixelated. 2d. In-Game asset. flat
make pixelated, add homeless with tents
pixel streetfighter style blonde american fighter, looked like donald trump, with american flag short, and boxing gloves
red button square. In-Game asset. 2d. High contrast. No shadows
red blood texture, square bar. In-Game asset. 2d. High contrast. No shadows
glow much much more, powerfull green
pixelated style very sexy horror space monkey fighter character. Her sexy body looks lizard. In-game asset. Full picture of character. In-Game asset. 2d
dark themed horror pixelated fight game style background scene. In-game asset. space.
saturated themed psychedelic horror pixelated game style background scene. In-game asset. Surrealistic. dreamy. In-Game asset
pixelated style terrifing uncanny very hot psychedelic horror space monster creep character. theirs body looks very disgusting and super sexy. In-game asset. Full picture of character. In-Game asset. 2d
horror uncanny scary pixelated
pixel
detailed pixel game
pixel styled. No background. Transparent background. Blank background.
surreal, araf
white surreal space with nothing in it looks scary
alpha male's room ,very masculine king's room, awesomeness, badass, cool place
the silhouette of the very large big cucumber that the man hides in his pants creates a big bump towards to right with the tension of the pants
blood splatter effect. In-game assets. No background. Transparent background.. High contrast. No shadows
ileri doğru yumtuk atarken kolunu gergin bir şekilde çiz, resmin geri kalanı birebir aynı kalsın
attacking with gun
pençeleriyle saldırı anı
high kick attack
elindeki bıçakla karşısındakine saldırıp bıçaklama hareketi
uppercut attack
hard punch
mouth opens bigger fot eat attacking
make his head backwards looking to camera and smiles uncanny horror
he is hiding very large secret cucumber in his pants so it creates big bump in his pants
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Chad Hardwood Turn-Based Fighter" and with the description "A turn-based fighting game where players battle through 10 increasingly challenging opponents. Choose from 4 attack options with different damage and energy costs. Manage your energy wisely - when it's depleted, your turn ends. Defeat each opponent to advance and become the ultimate Fighter.". Chad Hardwood is muscular long haired bearded sunglasses man, and his opponent is japanese sexy looking body fighter girl wearing sexy purple fight dress. No text on banner!
level6Music
Music
level7Music
Music
level8Music
Music
level5Music
Music
level3Music
Music
level1Music
Music
level2EnemyDamage
Sound effect
level2Music
Music
level4Music
Music
level4EnemyAttackSound
Sound effect
hit
Sound effect
level2EnemyDeath
Sound effect
level3EnemyDeath
Sound effect
gameOverDefeat
Sound effect
critical
Sound effect
block
Sound effect
defeat
Sound effect