/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // BackgroundContainer class var BackgroundContainer = Container.expand(function () { var self = Container.call(this); }); //<Assets used in the game will automatically appear here> //<Write imports for supported plugins here> // Enemy class to handle enemy logic var Enemy = Container.expand(function (assetType) { var self = Container.call(this); if (!assetType) { console.error("Asset type is undefined"); return; } self.assetType = assetType; // Store assetType as a property of the enemy instance self.enemyGraphics = LK.getAsset(assetType, { anchorX: 0.5, anchorY: 0.5 }); // Fetch unique graphics self.enemyGraphics.anchor.set(0.5, 0.5); // Set anchor to center self.addChild(self.enemyGraphics); // Attach the cached asset to the enemy self.init = function (initialHP) { //{8.5} self.interactive = true; // Make the enemy interactive self.on('down', function (x, y, obj) { if (self.hp > 0) { // Check if the enemy is not dead rollDice(x, y, obj); // Call rollDice when enemy is clicked } }); self.x = 2048 / 2; self.y = 2732 / 2 - 500; // Initialize the enemy's HP self.hp = initialHP; //{8.5} self.lastWasDead = false; // Initialize lastWasDead to track death state // Add a text to display the enemy's HP self.hpText = new Text2("", { size: 150, fill: 0x000000 }); self.hpText.anchor.set(0.5, 0.5); self.hpText.y = -700; // Move the text higher self.addChild(self.hpText); // Update the enemy's HP text if (self.hpText) { self.hpText.setText("HP: " + self.hp); } }; // self.init(); // Ensure init is called during construction }); // ForegroundContainer class var ForegroundContainer = Container.expand(function () { var self = Container.call(this); }); // MidgroundContainer class var MidgroundContainer = Container.expand(function () { var self = Container.call(this); }); // Peon class to represent the player character var Peon = Container.expand(function () { var self = Container.call(this); // Attach the 'peon' asset to the Peon var peonGraphics = self.attachAsset('peon', { anchorX: 0.5, anchorY: 0.5 }); // Initialize the Peon's position on the wheel self.init = function (wheel) { self.x = wheel.x; self.y = wheel.y + 10; self.currentPosition = Math.floor(Math.random() * 8); // Peon's current position on the wheel self.playerHP = new PlayerHP(); self.x += self.currentPosition * 250; // Position Peon on the random cell }; // Spin the Peon around the wheel self.spin = function (wheel, steps) { self.steps = steps; // Use the passed steps parameter instead of random assignment self.movementTracker = new PeonMovementTracker(); // Initialize the movement tracker var passedGo = false; var totalHeal = upgradeState.global.peonPriestIncrement || 0; var _spinStep = function spinStep() { self.currentPosition = (self.currentPosition + 1) % 8; self.movementTracker.incrementTilesMoved(); // Increment tiles moved self.x = wheel.x + self.currentPosition * 250; totalHeal++; if (self.currentPosition == 0) { passedGo = true; self.x = wheel.x; totalHeal += upgradeState.global.passGoHealIncrement; } self.steps--; if (self.steps <= 0) { var cell = wheel.cells[self.currentPosition]; // Display Pass_GO asset in the center of the screen if (passedGo) { var passGoAsset = LK.getAsset('Pass_GO', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 880, y: 2732 / 2 + 950, alpha: 0 }); midgroundContainer.addChild(passGoAsset); tween(passGoAsset, { alpha: 1 }, { duration: 300, onFinish: function onFinish() { LK.setTimeout(function () { tween(passGoAsset, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { passGoAsset.destroy(); } }); }, 500); } }); } var cell = wheel.cells[self.currentPosition]; if (cell.actionType === 'heal') { LK.getSound('Heal').play(); // Play the 'Heal' sound totalHeal += cell.baseValue; totalHeal += upgradeState.global.healBoost; totalHeal += upgradeState.individual[self.currentPosition] || 0; } else { totalHeal += upgradeState.global.vampiricAbility; var projectile = projectilePool.getProjectile(); projectile.init(self.x, self.y, enemy.x, enemy.y, 10, self.currentPosition); if (!projectile.parent) { game.addChild(projectile); } } // Heal application and animation if (totalHeal > 0) { self.playerHP.updateHP(totalHeal); var peonHealText = new Text2('+' + totalHeal, { size: 150, fill: 0x00FF00 // Green color for heal }); peonHealText.anchor.set(0.5, 0.5); peonHealText.x = self.playerHP.hpText.x + 250; peonHealText.y = self.playerHP.hpText.y; LK.gui.top.addChild(peonHealText); tween(peonHealText, { alpha: 0, y: peonHealText.y - 50 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { peonHealText.destroy(); } }); } self.movementTracker.resetTilesMoved(); // Reset tiles moved after restoring HP wheel.isSpinning = false; inputHandler.disableInput(); // Disable input immediately after peon lands LK.setTimeout(function () { inputHandler.reset(); // Re-enable input after 500ms }, 500); } else { LK.setTimeout(_spinStep, currentInterval * 10); // Increase interval to slow down peon speed } }; _spinStep(); }; }); // PlayerHP class to manage player's health and display var PlayerHP = Container.expand(function () { var self = Container.call(this); self.hp = 100; self.maxHP = 100; self.hpText = new Text2('Player HP: ' + self.hp + '/' + self.maxHP, { size: 100, fill: 0x000000 }); self.hpText.anchor.set(0.5, 0); self.hpText.y += 1500; LK.gui.top.addChild(self.hpText); self.updateHP = function (amount) { var currentHP = self.hp; var targetHP = self.hp + amount; if (targetHP > self.maxHP) { targetHP = self.maxHP; } else if (targetHP < 0) { targetHP = 0; } var increment = (targetHP - currentHP) / 20; // Divide the difference into 20 steps var step = 0; var _updateHPCounter = function updateHPCounter() { if (step < 20) { currentHP += increment; self.hp = Math.round(currentHP); self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); step++; LK.setTimeout(_updateHPCounter, 10); // Update every 10ms } else { self.hp = targetHP; // Ensure it ends at the exact targetHP self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); } }; _updateHPCounter(); if (self.hp <= 0) { self.hp = 0; // Ensure HP does not go below 0 LK.showGameOver(); } }; self.setMaxHP = function (newMaxHP) { var currentMaxHP = self.maxHP; var increment = (newMaxHP - currentMaxHP) / 20; // Divide the difference into 20 steps var step = 0; var _updateMaxHPCounter = function updateMaxHPCounter() { if (step < 20) { currentMaxHP += increment; self.maxHP = Math.round(currentMaxHP); self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); step++; LK.setTimeout(_updateMaxHPCounter, 10); // Update every 10ms } else { self.maxHP = newMaxHP; // Ensure it ends at the exact newMaxHP self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); } }; _updateMaxHPCounter(); if (self.hp > self.maxHP) { self.hp = self.maxHP; } self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); }; self.getCurrentHP = function () { return self.hp; }; self.getMaxHP = function () { return self.maxHP; }; self.resetHP = function () { self.hp = self.maxHP; self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP); }; }); // Projectile class to represent the projectiles shot by the cells var Projectile = Container.expand(function () { var self = Container.call(this); // Attach the 'projectile' asset to the Projectile var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5, alpha: 0 // Set the projectile to be invisible }); // Initialize the Projectile's position and target self.init = function (startX, startY, targetX, targetY, speed, cellIndex) { self.x = startX; self.y = startY; self.targetX = targetX; self.targetY = targetY; self.speed = speed * 10; // Further increase the bullet speed var damage = 0; var cell = wheel.cells[cellIndex]; if (cell) { damage += cell.baseValue; damage += upgradeState.global.totalDamageBoost; damage += upgradeState.individual[cellIndex] || 0; switch (cell.type) { case 'minor': damage += upgradeState.global.minorDamageBoost; break; case 'major': damage += upgradeState.global.majorDamageBoost; break; case 'critical': damage += upgradeState.global.criticalDamageBoost; break; } } self.damage = damage; self.active = true; // Mark projectile as active }; // Move the Projectile towards its target self.update = function () { if (!self.active) { return; } // Skip update if not active var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = calculateDistance(self.x, self.y, self.targetX, self.targetY); if (dist < self.speed) { self.x = self.targetX; self.y = self.targetY; self.deactivate(); // Deactivate when reaching target } else { self.x += dx * self.speed / dist; self.y += dy * self.speed / dist; // Check if the projectile has intersected with the enemy if (self.intersects(enemy)) { // Deal damage to the enemy var currentHP = enemy.hp; var targetHP = enemy.hp - self.damage; var increment = (targetHP - currentHP) / 20; // Divide the difference into 20 steps var step = 0; var _updateEnemyHPCounter = function updateEnemyHPCounter() { if (step < 20) { currentHP += increment; enemy.hp = Math.round(currentHP); if (enemy.hpText) { enemy.hpText.setText("HP: " + Math.max(0, enemy.hp)); } step++; LK.setTimeout(_updateEnemyHPCounter, 10); // Update every 10ms } else { enemy.hp = Math.max(0, targetHP); // Ensure it ends at the exact targetHP and never goes below 0 if (enemy.hpText) { enemy.hpText.setText("HP: " + enemy.hp); } } }; _updateEnemyHPCounter(); // Delay the damage application to the player's health LK.setTimeout(function () { if (enemy.hp <= 0 && !enemy.lastWasDead) { enemy.lastWasDead = true; // Mark enemy as dead to prevent multiple sound plays console.log("Enemy Type:", enemy.assetType); if (enemy.assetType === 'enemy') { LK.getSound('Enemy_1_Die').play(); // Play the 'Enemy_1_Die' sound//{3d.5} } else if (enemy.assetType === 'enemy_2') { LK.getSound('Enemy_2_Die').play(); // Play the 'Enemy_2_Die' sound//{3d.7} } else if (enemy.assetType === 'enemy_3') { LK.getSound('Enemy_3_Die').play(); // Play the 'Enemy_3_Die' sound//{3d.9} } enemy.destroy(); upgradeManager.refreshCellDamage(); // Refresh cell damage before entering upgrade mode gameState = "upgradeMode"; pauseGame(); upgradeManager.enterUpgradeMode(); } else { var damage = enemyDamage.calculateDamage(); peon.playerHP.updateHP(-damage); // Log the correct damage value after it's calculated console.log("Player received damage: " + damage); } }, 500); // Delay of 500ms // Display damage text on enemy var damagePanel = LK.getAsset('Damage_Panel', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, scaleX: 1, // Ensure the panel is at its original size scaleY: 1 // Ensure the panel is at its original size }); var damageText = new Text2(self.damage.toString(), { size: 150, fill: 0xFF0000 }); damageText.stroke = 0x000000; damageText.strokeThickness = 10; damageText.anchor.set(0.5, 0.5); damageText.x = 2048 / 2; // Center horizontally damageText.y = 2732 / 2 - 1000; // Move 600 pixels higher damagePanel.x = damageText.x; damagePanel.y = damageText.y + 50; foregroundContainer.addChild(damageText); midgroundContainer.addChild(damagePanel); // Attach the panel to the midground container // Tween animation for appearance and fade out tween(damageText, { // Apply tween to the damage text alpha: 0, y: damageText.y - 100 // Move slightly up during fade out }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { damageText.destroy(); // Destroy the text after animation damagePanel.destroy(); // Destroy the panel after animation } }); tween(damagePanel, { // Apply tween to the panel alpha: 0, y: damagePanel.y - 100 // Move slightly up during fade out }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { // No need to destroy here as it's handled in damageText's onFinish } }); // Update the enemy's HP text if (enemy) { if (enemy.hpText) { if (enemy.hpText) { enemy.hpText.setText("HP: " + enemy.hp); // Update the enemy's HP text } } } self.deactivate(); // Deactivate the projectile // Add shake animation to the enemy var shake = 20; var shakeSpeed = 15; var originalEnemyX = enemy.x; // Save the original position of the enemy var shakeInterval = LK.setInterval(function () { shake *= -1; enemy.x += shake; shakeSpeed--; if (shakeSpeed <= 0) { LK.clearInterval(shakeInterval); enemy.x = originalEnemyX; // Reset the enemy's position after the shake animation ends } }, shakeSpeed); // If enemy's HP reaches 0, destroy the enemy and play explosion animation if (enemy.hp <= 0) { enemy.destroy(); upgradeManager.refreshCellDamage(); // Refresh cell damage before entering upgrade mode gameState = "upgradeMode"; pauseGame(); upgradeManager.enterUpgradeMode(); // Create a custom explosion animation if (enemy.assetType) { var explosion = self.attachAsset(enemy.assetType, { anchorX: 0.5, anchorY: 0.5 }); explosion.x = enemy.x; explosion.y = enemy.y; explosion.scaleX = 2; explosion.scaleY = 2; explosion.alpha = 0.5; game.addChild(explosion); var _fadeOut = function fadeOut() { explosion.alpha -= 0.05; if (explosion.alpha <= 0) { explosion.destroy(); } else { LK.setTimeout(_fadeOut, 50); } }; _fadeOut(); } // Enemy creation moved to after upgrade selection } } } }; // Deactivate the projectile and return it to the pool self.deactivate = function () { self.active = false; self.x = -1000; // Move off-screen self.y = -1000; // Move off-screen }; }); // SpinningWheel class to handle spinning mechanics var SpinningWheel = Container.expand(function () { var self = Container.call(this); self.cells = []; self.isSpinning = false; // Initialize the wheel with cells self.init = function () { self.cells = []; var cellTypes = [{ type: 'critical', baseValue: 100, actionType: 'damage' }, { type: 'minor', baseValue: 15, actionType: 'damage' }, { type: 'major', baseValue: 25, actionType: 'damage' }, { type: 'heal', baseValue: 10, actionType: 'heal' }, { type: 'minor', baseValue: 15, actionType: 'damage' }, { type: 'major', baseValue: 25, actionType: 'damage' }, { type: 'minor', baseValue: 15, actionType: 'damage' }, { type: 'heal', baseValue: 10, actionType: 'heal' }]; for (var i = 0; i < cellTypes.length; i++) { var cell = self.addChild(new Tile(cellTypes[i].type, cellTypes[i].baseValue, cellTypes[i].actionType, i)); cell.x = i * 250; cell.y = 100; self.cells.push(cell); } }; // Spin the Player around the wheel self.spin = function (player) { if (!self.isSpinning) { self.isSpinning = true; player.spin(self); } }; }); var Tile = Container.expand(function (type, baseValue, actionType, id) { var self = Container.call(this); self.type = type; self.baseValue = baseValue; self.actionType = actionType; self.id = id; // Add unique ID to each cell self.display = self.addChild(LK.getAsset('tile_' + type, { anchorX: 0.5, anchorY: 0.5 })); // Create and add damageText to the tile display var damageTextValue = self.baseValue; var damageText = self.addChild(new Text2(self.baseValue, { size: 100, fill: 0x000000 })); damageText.anchor.set(0.5, 0.5); // Method to update the tile's damage value self.updateDamageText = function (newDamage) { if (newDamage !== damageTextValue) { var currentDamage = damageTextValue; // Start from the current damage value var increment = (newDamage - currentDamage) / 20; // Divide the difference into 20 steps var step = 0; var _updateCounter = function updateCounter() { if (step < 20) { currentDamage += increment; damageText.setText(Math.round(currentDamage)); step++; LK.setTimeout(_updateCounter, 10); // Update every 50ms } else { damageText.setText(newDamage); // Ensure it ends at the exact newDamage } }; _updateCounter(); // TODO: Add animation to tile / text var flash = LK.getAsset('Flash', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.addChild(flash); tween(flash, { alpha: 1 }, { duration: 10, easing: tween.easeIn, onFinish: function onFinish() { tween(flash, { alpha: 0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { flash.destroy(); } }); } }); // Enlarge and shrink the cell's asset during the flash animation tween(self.display.scale, { x: 1.2, y: 1.2 }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.display.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeInOut }); } }); damageTextValue = newDamage; // Update the damageTextValue to prevent re-triggering } }; }); // Initialize UpgradeManager var UpgradeManager = Container.expand(function (wheel) { var self = Container.call(this); self.wheel = wheel; // Store the wheel instance self.applyUpgrade = function (selectedUpgrade) { switch (selectedUpgrade.type) { case 'increaseAllTiles': upgradeState.global.healBoost += selectedUpgrade.value; upgradeState.global.totalDamageBoost += selectedUpgrade.value; break; case 'increaseAllDamage': upgradeState.global.totalDamageBoost += selectedUpgrade.value; break; case 'increaseMinorDamage': upgradeState.global.minorDamageBoost += selectedUpgrade.value; break; case 'increaseMajorDamage': upgradeState.global.majorDamageBoost += selectedUpgrade.value; break; case 'increaseCriticalDamage': upgradeState.global.criticalDamageBoost += selectedUpgrade.value; break; case 'increaseRandomDamage': var damageCells = self.wheel.cells.filter(function (cell) { return cell.actionType === 'damage'; }); if (damageCells.length > 0) { var randomIndex = Math.floor(Math.random() * damageCells.length); var randomCell = damageCells[randomIndex]; var cellIndex = randomCell.id; // Use the unique ID of the cell if (!randomCell.upgraded) { if (!upgradeState.individual[cellIndex]) { upgradeState.individual[cellIndex] = 0; } upgradeState.individual[cellIndex] += selectedUpgrade.value; // Add to specific cell boost randomCell.upgraded = true; // Mark as upgraded to prevent duplicate upgrades } } break; case 'heal': var restoredHP = peon.playerHP.getMaxHP() - peon.playerHP.getCurrentHP(); peon.playerHP.updateHP(restoredHP); if (restoredHP > 0) { var peonHealText = new Text2('+' + restoredHP, { size: 150, fill: 0x00FF00 // Green color for heal }); peonHealText.anchor.set(0.5, 0.5); peonHealText.x = peon.playerHP.hpText.x + 250; peonHealText.y = peon.playerHP.hpText.y; LK.gui.top.addChild(peonHealText); tween(peonHealText, { alpha: 0, y: peonHealText.y - 50 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { peonHealText.destroy(); } }); } break; case 'healBoost': // Increase the damage value of heal cells upgradeState.global.healBoost += selectedUpgrade.value; // Increment healBoost console.log("Total heal boost is now", upgradeState.global.healBoost); // Log total heal boost break; case 'increaseHP': peon.playerHP.setMaxHP(peon.playerHP.getMaxHP() + selectedUpgrade.value); peon.playerHP.updateHP(selectedUpgrade.value); break; case 'increaseVampiric': // Increase the vampiric ability of projectiles upgradeState.global.vampiricAbility += selectedUpgrade.value; console.log("Vampiric Ability increased to:", upgradeState.global.vampiricAbility); break; case 'passGoHeal': upgradeState.global.passGoHealIncrement += selectedUpgrade.value; // Increment the pass GO heal increment console.log("Pass GO Heal Increment is now", upgradeState.global.passGoHealIncrement); break; case 'increasePeonPriest': upgradeState.global.peonPriestIncrement += selectedUpgrade.value; break; case 'increaseHealIncrement': upgradeState.global.passGoHealIncrement += selectedUpgrade.value; break; // case 'doubleCellValue': // var randomIndex = Math.floor(Math.random() * self.wheel.cells.length); // var randomCell = self.wheel.cells[randomIndex]; // if (randomCell.actionType === 'damage' || randomCell.actionType === 'heal') { // randomCell.damage += randomCell.damage; // Double the cell's damage value // console.log("Doubled value of cell index:", randomIndex); // } // break; default: console.error('Unknown upgrade type'); } self.refreshCellDamage(); // Refresh cell damage after applying upgrade }; self.refreshCellDamage = function () { for (var i = 0; i < self.wheel.cells.length; i++) { var cell = self.wheel.cells[i]; var effectiveDamage = cell.baseValue; var specificBoost = upgradeState.individual[i] || 0; var globalBoost = upgradeState.global.totalDamageBoost; switch (cell.type) { case 'minor': effectiveDamage += upgradeState.global.minorDamageBoost; break; case 'major': effectiveDamage += upgradeState.global.majorDamageBoost; break; case 'critical': effectiveDamage += upgradeState.global.criticalDamageBoost; break; } if (cell.actionType === 'heal') { effectiveDamage += upgradeState.global.healBoost; } else { effectiveDamage += globalBoost; } effectiveDamage += specificBoost; if (cell.lastLoggedDamage !== effectiveDamage) { console.log('Cell '.concat(i, ' (').concat(cell.type, ') new damage: ').concat(effectiveDamage)); cell.lastLoggedDamage = effectiveDamage; } cell.updateDamageText(effectiveDamage); } }; self.enterUpgradeMode = function () { if (self.upgradeScreenOpen) { return; } // Check if upgrade screen is already open self.upgradeScreenOpen = true; // Set flag to indicate upgrade screen is open var options = getRandomUpgrades(); // Directly call getRandomUpgrades to ensure fresh selection var upgradeUI = new UpgradeUI(); upgradeUI.init(options); game.addChild(upgradeUI); }; }); // UpgradeUI class to handle upgrade selection interface var UpgradeUI = Container.expand(function () { var self = Container.call(this); self.upgradeOptions = []; // Initialize the UI with two upgrade options self.init = function (options) { self.upgradeOptions = options; self.displayOptions(); }; // Display the upgrade options self.displayOptions = function () { for (var i = 0; i < 2; i++) { var optionContainer = new Container(); // Create a container for each option optionContainer.x = i === 0 ? -1024 : 3072; // Start off-screen, left for first, right for second optionContainer.y = 1700 + i * 250; // Move options 800 pixels lower var backgroundAsset = 'rectangle'; if (self.upgradeOptions[i].rarity === 'rare') { backgroundAsset = 'rectangle_rare'; } else if (self.upgradeOptions[i].rarity === 'epic') { backgroundAsset = 'rectangle_epic'; } var optionBackground = LK.getAsset(backgroundAsset, { width: 2048, height: 200, color: 0xFFFFFF, anchorX: 0.5, anchorY: 0.5 }); optionContainer.addChild(optionBackground); // Add rectangle to the container var optionText = new Text2(self.upgradeOptions[i].description, { size: 150, fill: 0x800080 }); optionText.anchor.set(0.5, 0.5); optionContainer.addChild(optionText); // Add text to the container optionContainer.interactive = true; // Make the container interactive optionContainer.on('down', function (selectedUpgrade, optionContainer) { // Use closure to capture the correct upgrade return function () { console.log('Upgrade option clicked:', selectedUpgrade.description); // Log the click event // Add tween animation to simulate pressing effect tween(optionContainer.scale, { x: 0.9, y: 0.9 }, { duration: 75, easing: tween.easeInOut, onFinish: function onFinish() { tween(optionContainer.scale, { x: 1, y: 1 }, { duration: 75, easing: tween.easeInOut, onFinish: function onFinish() { self.selectUpgrade(selectedUpgrade); } }); } }); }; }(self.upgradeOptions[i], optionContainer)); // Pass the correct upgrade option and container self.addChild(optionContainer); // Add the container to the UI // Animate the option to slide into position tween(optionContainer, { x: 1024 }, { duration: 500, easing: tween.easeOut }); } }; // Handle upgrade selection self.selectUpgrade = function (selectedUpgrade) { console.log("Selected upgrade:", selectedUpgrade.description); // Log the selected upgrade upgradeManager.applyUpgrade(selectedUpgrade); if (selectedUpgrade.type === 'heal') { LK.getSound('Heal').play(); // Play the 'Heal' sound when the upgrade is selected } else { LK.getSound('Upgrade').play(); // Play the 'Upgrade' sound } upgradeManager.refreshCellDamage(); // Ensure cell damage is updated after applying upgrade self.destroy(); // Close the UI gameState = "playing"; // Resume the game resumeGame(); // Restore game interactivity enemy = createNewEnemy(); // Create a new enemy after upgrade selection game.addChild(enemy); upgradeManager.upgradeScreenOpen = false; // Reset flag after upgrade selection }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xFFFFFF, //Init game with black background interaction: true // Enable interaction manager }); /**** * Game Code ****/ // PeonMovementTracker class to track Peon's tile movements and restore HP var PeonMovementTracker = function PeonMovementTracker() { this.tilesMoved = 0; // Initialize the number of tiles moved to 0 }; // Method to increment the number of tiles moved PeonMovementTracker.prototype.incrementTilesMoved = function () { this.tilesMoved++; }; // Method to reset the number of tiles moved PeonMovementTracker.prototype.resetTilesMoved = function () { this.tilesMoved = 0; }; // Method to get the number of tiles moved PeonMovementTracker.prototype.getTilesMoved = function () { return this.tilesMoved; }; var EnemyDamage = function EnemyDamage() { this.minDamage = 5; this.maxDamage = 7; this.round = 1; this.minDamageIncrement = 1; // Separate increment for min damage this.maxDamageIncrement = 2; // Increase max damage increment by 2 per round this.calculateDamage = function () { return Math.floor(Math.random() * (this.maxDamage - this.minDamage)) + this.minDamage; }; this.increaseDamage = function () { this.minDamage += this.minDamageIncrement; this.maxDamage += this.maxDamageIncrement; this.round += 1; }; }; var InputHandler = function InputHandler() { this.holdTimer = null; this.isInputDisabled = false; // Method to start the hold timer this.startHoldTimer = function () { var self = this; this.holdTimer = LK.setTimeout(function () { self.disableInput(); }, 1500); // Disable input after 1.5 seconds }; // Method to disable player input this.disableInput = function () { this.isInputDisabled = true; game.interaction = false; // Disable interaction console.log("Input disabled due to prolonged hold"); // Simulate finger release to release the peon if (chargeTimer) { LK.clearInterval(chargeTimer); chargeTimer = null; if (chargeCount >= 1) { LK.getSound('Roll').play(); // Play the 'Roll' sound peon.spin(wheel, chargeCount); } chargeCount = 0; currentInterval = startingInterval; multiplier = 0.5; tween.stop(peon, { x: true }); // inputHandler.reset(); // Reset the input handler LK.getSound('Charge').stop(); // Stop the 'Charge' sound LK.getSound('Tap_Release').play(); // Play the 'Tap_Release' sound } }; // Method to reset the input handler this.reset = function () { if (this.holdTimer) { LK.clearTimeout(this.holdTimer); this.holdTimer = null; } this.isInputDisabled = false; game.interaction = true; // Re-enable interaction }; }; var inputHandler = new InputHandler(); // PlayerHP class to manage player's health and display LK.on('damageReceived', function (damageAmount) { peon.playerHP.updateHP(-damageAmount); }); LK.on('healingReceived', function (healAmount) { peon.playerHP.updateHP(healAmount); }); function startPeonShake() { tween(peon, { x: peon.x + 5 }, { duration: 50, easing: tween.easeInOut, onFinish: function onFinish() { tween(peon, { x: peon.x - 5 }, { duration: 50, easing: tween.easeInOut, onFinish: function onFinish() { if (chargeTimer) { startPeonShake(); // Continue shaking } } }); } }); } var midgroundContainer = new MidgroundContainer(); game.addChild(midgroundContainer); var platform = LK.getAsset('Platform', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 150 }); midgroundContainer.addChild(platform); // Centralized state for tracking upgrades var enemySpawnCount = 0; var upgradeState = { global: { totalDamageBoost: 0, passGoHealIncrement: 10, peonPriestIncrement: 0, vampiricAbility: 0, minorDamageBoost: 0, majorDamageBoost: 0, criticalDamageBoost: 0, healBoost: 0 }, multipliers: {}, individual: { specificCellBoosts: {} } }; // Initialize gameState to manage game states // UpgradeManager class to handle upgrades var gameState = "playing"; // Possible states: playing, paused, upgradeMode // Centralized data structure for upgrade options var upgradeOptions = [{ type: 'increaseHP', value: 50, description: '+50 to Max HP', rarity: 'rare' }, { type: 'increaseAllTiles', value: 3, description: '+3 to all tiles', rarity: 'common' }, { type: 'increaseAllDamage', value: 5, description: '+5 to all Damage tiles', rarity: 'common' }, { type: 'increaseRandomDamage', value: 50, description: '+50 to random Damage tile', rarity: 'rare' }, { type: 'increaseMinorDamage', value: 15, description: '+15 to Minor damage', rarity: 'rare' }, { type: 'increaseMajorDamage', value: 25, description: '+25 to Major damage', rarity: 'rare' }, { type: 'heal', value: 100, description: 'Restore full HP', rarity: 'common' }, { type: 'healBoost', value: 10, description: '+10 to Heal tiles', rarity: 'common' }, { type: 'increaseVampiric', value: 5, description: '+5 HP Lifesteal', rarity: 'epic' }, { // type: 'doubleCellValue', // description: 'X2 to a random tile' }, { type: 'increaseHealIncrement', value: 10, description: '+10 HP when you pass GO', rarity: 'common' }, { type: 'increasePeonPriest', value: 2, description: '+2 to Healing Steps', rarity: 'common' }, { type: 'increaseCriticalDamage', value: 100, description: '+100 to Critical Damage', rarity: 'epic' }]; var rarityWeights = { common: 50, rare: 40, epic: 30 }; var upgradeBucket = []; var remainingItems = 0; function initializeUpgradeBucket() { upgradeBucket = []; upgradeOptions.forEach(function (upgrade) { for (var i = 0; i < rarityWeights[upgrade.rarity]; i++) { upgradeBucket.push(upgrade); } }); remainingItems = upgradeBucket.length; } function getRandomUpgrades() { if (remainingItems <= 3) { initializeUpgradeBucket(); } var selectedUpgrades = []; var firstUpgradeIndex = Math.floor(Math.random() * remainingItems); selectedUpgrades.push(upgradeBucket[firstUpgradeIndex]); upgradeBucket.splice(firstUpgradeIndex, 1); remainingItems--; var secondUpgradeIndex; do { secondUpgradeIndex = Math.floor(Math.random() * remainingItems); } while (upgradeBucket[secondUpgradeIndex].type === selectedUpgrades[0].type); selectedUpgrades.push(upgradeBucket[secondUpgradeIndex]); upgradeBucket.splice(secondUpgradeIndex, 1); remainingItems--; return selectedUpgrades; } initializeUpgradeBucket(); function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var _ref = [array[j], array[i]]; array[i] = _ref[0]; array[j] = _ref[1]; } } // Function to pause the game function pauseGame() { // Logic to pause animations, input, and timers console.log("Game paused"); } // Function to trigger the upgrade system UI function triggerUpgradeUI(options) { // Logic to display upgrade options to the player console.log("Upgrade UI triggered with options:", options); // Display options in a UI for the player to select // This is a placeholder for the actual UI implementation } // Function to resume the game function resumeGame() { // Logic to resume animations, input, and timers console.log("Game resumed"); } // Example usage: Generate upgrade options and apply one to the Peon // ProjectilePool class to manage projectile instances // Helper function to calculate distance between two points // Cache enemy assets for reuse // ProjectilePool class to manage projectile instances function calculateDistance(x1, y1, x2, y2) { return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); } var cachedEnemyAssets = { enemy: LK.getAsset('enemy', {}), enemy_2: LK.getAsset('enemy_2', {}), enemy_3: LK.getAsset('enemy_3', {}) }; var ProjectilePool = function ProjectilePool() { this.pool = []; this.getProjectile = function () { for (var i = 0; i < this.pool.length; i++) { if (!this.pool[i].active) { return this.pool[i]; } } if (this.pool.length < this.maxPoolSize) { var newProjectile = new Projectile(); this.pool.push(newProjectile); return newProjectile; } return null; // Return null if pool is full }; this.releaseProjectile = function (projectile) { projectile.deactivate(); }; }; var projectilePool = new ProjectilePool(); projectilePool.maxPoolSize = 10; // Set maximum pool size // ProjectilePool class to manage projectile instances // Global timing variables var startingInterval = 2; // Starting interval for the spin var multiplier = 0.5; // Multiplier for the interval increase var currentInterval = startingInterval; var startingMovingTiles = 11; // Starting moving tiles var maxTiles = 17; // Maximum number of tiles var enemyStartingHP = 50; // Starting HP for enemies var enemyHPIncrement = 25; // HP increment per round var enemyDamage = new EnemyDamage(); var backgroundContainer = new BackgroundContainer(); game.addChild(backgroundContainer); var midgroundContainer = new MidgroundContainer(); game.addChild(midgroundContainer); var foregroundContainer = new ForegroundContainer(); game.addChild(foregroundContainer); var wheel = new SpinningWheel(); var upgradeManager = game.addChild(new UpgradeManager(wheel)); wheel.init(); wheel.x = 150; // Initial x position wheel.y = 2500; // Space cells horizontally upgradeManager.wheel = wheel; // Assign wheel reference to UpgradeManager upgradeManager.enterUpgradeMode = upgradeManager.enterUpgradeMode.bind(upgradeManager); midgroundContainer.addChild(wheel); // Initialize the Peon and add it to the game var peon = new Peon(); peon.init(wheel); game.addChild(peon); // Function to create a new enemy function createNewEnemy() { // Define available enemy types var enemyTypes = [{ asset: 'enemy' }, { asset: 'enemy_2' }, { asset: 'enemy_3' }]; // Select a random enemy type var randomIndex = Math.floor(Math.random() * enemyTypes.length); var selectedEnemy = enemyTypes[randomIndex]; // Increment the spawn count enemySpawnCount += 1; enemyDamage.increaseDamage(); // Calculate HP using global variables var enemyHP = enemyStartingHP + enemyHPIncrement * (enemySpawnCount - 1); // Instantiate the enemy with required parameters var newEnemy = new Enemy(selectedEnemy.asset); newEnemy.init(enemyHP); backgroundContainer.addChild(newEnemy); //{6e.5} newEnemy.lastWasDead = false; // Reset lastWasDead state for new enemy updateLevelText(); enemies.push(newEnemy); // Add the new enemy to the array return newEnemy; } // Initialize level text var levelText = new Text2('Level: 1', { size: 50, fill: 0x000000 }); levelText.anchor.set(0.5, 0); levelText.y = 10; // Position it at the top of the screen LK.gui.top.addChild(levelText); // Initialize the first enemy var enemies = []; // Array to store multiple enemies var enemy = createNewEnemy(); enemies.push(enemy); // Add the new enemy to the array // Function to update level text function updateLevelText() { levelText.setText('Level: ' + enemySpawnCount); } // Add a text to display the player's HP var playerHPState = { currentHP: peon.playerHP.getCurrentHP(), maxHP: peon.playerHP.getMaxHP() }; // Restore player HP state when game resumes function restorePlayerHPState() { peon.playerHP.hp = playerHPState.currentHP; peon.playerHP.maxHP = playerHPState.maxHP; peon.playerHP.hpText.setText('Player: ' + peon.playerHP.hp); } // Add a down event to the game to spin the Peon when the screen is tapped var chargeCount = 0; var chargeTimer = null; function rollDice(x, y, obj) { if (gameState !== "upgradeMode" && !wheel.isSpinning && !chargeTimer && !inputHandler.isInputDisabled) { chargeCount = Math.floor(Math.random() * 2) + 1; // Randomly set chargeCount between 1 and 2 chargeTimer = LK.setInterval(function () { chargeCount++; }, 150); // Start peon shake effect startPeonShake(); inputHandler.startHoldTimer(); // Start the hold timer LK.getSound('Charge').play(); // Play the 'Charge' sound } } game.up = function (x, y, obj) { if (chargeTimer) { game.interaction = false; // Disable interaction LK.setTimeout(function () { game.interaction = true; // Re-enable interaction after 200ms }, 400); LK.clearInterval(chargeTimer); chargeTimer = null; if (chargeCount >= 1) { LK.getSound('Roll').play(); // Play the 'Roll' sound peon.spin(wheel, chargeCount); } chargeCount = 0; // Reset chargeCount after spin currentInterval = startingInterval; // Reset the interval to the starting interval multiplier = 0.5; // Reset the multiplier to its initial value // Stop peon shake effect tween.stop(peon, { x: true }); // inputHandler.reset(); // Reset the input handler } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BackgroundContainer class
var BackgroundContainer = Container.expand(function () {
var self = Container.call(this);
});
//<Assets used in the game will automatically appear here>
//<Write imports for supported plugins here>
// Enemy class to handle enemy logic
var Enemy = Container.expand(function (assetType) {
var self = Container.call(this);
if (!assetType) {
console.error("Asset type is undefined");
return;
}
self.assetType = assetType; // Store assetType as a property of the enemy instance
self.enemyGraphics = LK.getAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
}); // Fetch unique graphics
self.enemyGraphics.anchor.set(0.5, 0.5); // Set anchor to center
self.addChild(self.enemyGraphics); // Attach the cached asset to the enemy
self.init = function (initialHP) {
//{8.5}
self.interactive = true; // Make the enemy interactive
self.on('down', function (x, y, obj) {
if (self.hp > 0) {
// Check if the enemy is not dead
rollDice(x, y, obj); // Call rollDice when enemy is clicked
}
});
self.x = 2048 / 2;
self.y = 2732 / 2 - 500;
// Initialize the enemy's HP
self.hp = initialHP; //{8.5}
self.lastWasDead = false; // Initialize lastWasDead to track death state
// Add a text to display the enemy's HP
self.hpText = new Text2("", {
size: 150,
fill: 0x000000
});
self.hpText.anchor.set(0.5, 0.5);
self.hpText.y = -700; // Move the text higher
self.addChild(self.hpText);
// Update the enemy's HP text
if (self.hpText) {
self.hpText.setText("HP: " + self.hp);
}
};
// self.init(); // Ensure init is called during construction
});
// ForegroundContainer class
var ForegroundContainer = Container.expand(function () {
var self = Container.call(this);
});
// MidgroundContainer class
var MidgroundContainer = Container.expand(function () {
var self = Container.call(this);
});
// Peon class to represent the player character
var Peon = Container.expand(function () {
var self = Container.call(this);
// Attach the 'peon' asset to the Peon
var peonGraphics = self.attachAsset('peon', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize the Peon's position on the wheel
self.init = function (wheel) {
self.x = wheel.x;
self.y = wheel.y + 10;
self.currentPosition = Math.floor(Math.random() * 8); // Peon's current position on the wheel
self.playerHP = new PlayerHP();
self.x += self.currentPosition * 250; // Position Peon on the random cell
};
// Spin the Peon around the wheel
self.spin = function (wheel, steps) {
self.steps = steps; // Use the passed steps parameter instead of random assignment
self.movementTracker = new PeonMovementTracker(); // Initialize the movement tracker
var passedGo = false;
var totalHeal = upgradeState.global.peonPriestIncrement || 0;
var _spinStep = function spinStep() {
self.currentPosition = (self.currentPosition + 1) % 8;
self.movementTracker.incrementTilesMoved(); // Increment tiles moved
self.x = wheel.x + self.currentPosition * 250;
totalHeal++;
if (self.currentPosition == 0) {
passedGo = true;
self.x = wheel.x;
totalHeal += upgradeState.global.passGoHealIncrement;
}
self.steps--;
if (self.steps <= 0) {
var cell = wheel.cells[self.currentPosition];
// Display Pass_GO asset in the center of the screen
if (passedGo) {
var passGoAsset = LK.getAsset('Pass_GO', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 880,
y: 2732 / 2 + 950,
alpha: 0
});
midgroundContainer.addChild(passGoAsset);
tween(passGoAsset, {
alpha: 1
}, {
duration: 300,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(passGoAsset, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
passGoAsset.destroy();
}
});
}, 500);
}
});
}
var cell = wheel.cells[self.currentPosition];
if (cell.actionType === 'heal') {
LK.getSound('Heal').play(); // Play the 'Heal' sound
totalHeal += cell.baseValue;
totalHeal += upgradeState.global.healBoost;
totalHeal += upgradeState.individual[self.currentPosition] || 0;
} else {
totalHeal += upgradeState.global.vampiricAbility;
var projectile = projectilePool.getProjectile();
projectile.init(self.x, self.y, enemy.x, enemy.y, 10, self.currentPosition);
if (!projectile.parent) {
game.addChild(projectile);
}
}
// Heal application and animation
if (totalHeal > 0) {
self.playerHP.updateHP(totalHeal);
var peonHealText = new Text2('+' + totalHeal, {
size: 150,
fill: 0x00FF00 // Green color for heal
});
peonHealText.anchor.set(0.5, 0.5);
peonHealText.x = self.playerHP.hpText.x + 250;
peonHealText.y = self.playerHP.hpText.y;
LK.gui.top.addChild(peonHealText);
tween(peonHealText, {
alpha: 0,
y: peonHealText.y - 50
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
peonHealText.destroy();
}
});
}
self.movementTracker.resetTilesMoved(); // Reset tiles moved after restoring HP
wheel.isSpinning = false;
inputHandler.disableInput(); // Disable input immediately after peon lands
LK.setTimeout(function () {
inputHandler.reset(); // Re-enable input after 500ms
}, 500);
} else {
LK.setTimeout(_spinStep, currentInterval * 10); // Increase interval to slow down peon speed
}
};
_spinStep();
};
});
// PlayerHP class to manage player's health and display
var PlayerHP = Container.expand(function () {
var self = Container.call(this);
self.hp = 100;
self.maxHP = 100;
self.hpText = new Text2('Player HP: ' + self.hp + '/' + self.maxHP, {
size: 100,
fill: 0x000000
});
self.hpText.anchor.set(0.5, 0);
self.hpText.y += 1500;
LK.gui.top.addChild(self.hpText);
self.updateHP = function (amount) {
var currentHP = self.hp;
var targetHP = self.hp + amount;
if (targetHP > self.maxHP) {
targetHP = self.maxHP;
} else if (targetHP < 0) {
targetHP = 0;
}
var increment = (targetHP - currentHP) / 20; // Divide the difference into 20 steps
var step = 0;
var _updateHPCounter = function updateHPCounter() {
if (step < 20) {
currentHP += increment;
self.hp = Math.round(currentHP);
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
step++;
LK.setTimeout(_updateHPCounter, 10); // Update every 10ms
} else {
self.hp = targetHP; // Ensure it ends at the exact targetHP
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
}
};
_updateHPCounter();
if (self.hp <= 0) {
self.hp = 0; // Ensure HP does not go below 0
LK.showGameOver();
}
};
self.setMaxHP = function (newMaxHP) {
var currentMaxHP = self.maxHP;
var increment = (newMaxHP - currentMaxHP) / 20; // Divide the difference into 20 steps
var step = 0;
var _updateMaxHPCounter = function updateMaxHPCounter() {
if (step < 20) {
currentMaxHP += increment;
self.maxHP = Math.round(currentMaxHP);
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
step++;
LK.setTimeout(_updateMaxHPCounter, 10); // Update every 10ms
} else {
self.maxHP = newMaxHP; // Ensure it ends at the exact newMaxHP
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
}
};
_updateMaxHPCounter();
if (self.hp > self.maxHP) {
self.hp = self.maxHP;
}
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
};
self.getCurrentHP = function () {
return self.hp;
};
self.getMaxHP = function () {
return self.maxHP;
};
self.resetHP = function () {
self.hp = self.maxHP;
self.hpText.setText('Player: ' + self.hp + ' / ' + self.maxHP);
};
});
// Projectile class to represent the projectiles shot by the cells
var Projectile = Container.expand(function () {
var self = Container.call(this);
// Attach the 'projectile' asset to the Projectile
var projectileGraphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0 // Set the projectile to be invisible
});
// Initialize the Projectile's position and target
self.init = function (startX, startY, targetX, targetY, speed, cellIndex) {
self.x = startX;
self.y = startY;
self.targetX = targetX;
self.targetY = targetY;
self.speed = speed * 10; // Further increase the bullet speed
var damage = 0;
var cell = wheel.cells[cellIndex];
if (cell) {
damage += cell.baseValue;
damage += upgradeState.global.totalDamageBoost;
damage += upgradeState.individual[cellIndex] || 0;
switch (cell.type) {
case 'minor':
damage += upgradeState.global.minorDamageBoost;
break;
case 'major':
damage += upgradeState.global.majorDamageBoost;
break;
case 'critical':
damage += upgradeState.global.criticalDamageBoost;
break;
}
}
self.damage = damage;
self.active = true; // Mark projectile as active
};
// Move the Projectile towards its target
self.update = function () {
if (!self.active) {
return;
} // Skip update if not active
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = calculateDistance(self.x, self.y, self.targetX, self.targetY);
if (dist < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.deactivate(); // Deactivate when reaching target
} else {
self.x += dx * self.speed / dist;
self.y += dy * self.speed / dist;
// Check if the projectile has intersected with the enemy
if (self.intersects(enemy)) {
// Deal damage to the enemy
var currentHP = enemy.hp;
var targetHP = enemy.hp - self.damage;
var increment = (targetHP - currentHP) / 20; // Divide the difference into 20 steps
var step = 0;
var _updateEnemyHPCounter = function updateEnemyHPCounter() {
if (step < 20) {
currentHP += increment;
enemy.hp = Math.round(currentHP);
if (enemy.hpText) {
enemy.hpText.setText("HP: " + Math.max(0, enemy.hp));
}
step++;
LK.setTimeout(_updateEnemyHPCounter, 10); // Update every 10ms
} else {
enemy.hp = Math.max(0, targetHP); // Ensure it ends at the exact targetHP and never goes below 0
if (enemy.hpText) {
enemy.hpText.setText("HP: " + enemy.hp);
}
}
};
_updateEnemyHPCounter();
// Delay the damage application to the player's health
LK.setTimeout(function () {
if (enemy.hp <= 0 && !enemy.lastWasDead) {
enemy.lastWasDead = true; // Mark enemy as dead to prevent multiple sound plays
console.log("Enemy Type:", enemy.assetType);
if (enemy.assetType === 'enemy') {
LK.getSound('Enemy_1_Die').play(); // Play the 'Enemy_1_Die' sound//{3d.5}
} else if (enemy.assetType === 'enemy_2') {
LK.getSound('Enemy_2_Die').play(); // Play the 'Enemy_2_Die' sound//{3d.7}
} else if (enemy.assetType === 'enemy_3') {
LK.getSound('Enemy_3_Die').play(); // Play the 'Enemy_3_Die' sound//{3d.9}
}
enemy.destroy();
upgradeManager.refreshCellDamage(); // Refresh cell damage before entering upgrade mode
gameState = "upgradeMode";
pauseGame();
upgradeManager.enterUpgradeMode();
} else {
var damage = enemyDamage.calculateDamage();
peon.playerHP.updateHP(-damage);
// Log the correct damage value after it's calculated
console.log("Player received damage: " + damage);
}
}, 500); // Delay of 500ms
// Display damage text on enemy
var damagePanel = LK.getAsset('Damage_Panel', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
scaleX: 1,
// Ensure the panel is at its original size
scaleY: 1 // Ensure the panel is at its original size
});
var damageText = new Text2(self.damage.toString(), {
size: 150,
fill: 0xFF0000
});
damageText.stroke = 0x000000;
damageText.strokeThickness = 10;
damageText.anchor.set(0.5, 0.5);
damageText.x = 2048 / 2; // Center horizontally
damageText.y = 2732 / 2 - 1000; // Move 600 pixels higher
damagePanel.x = damageText.x;
damagePanel.y = damageText.y + 50;
foregroundContainer.addChild(damageText);
midgroundContainer.addChild(damagePanel); // Attach the panel to the midground container
// Tween animation for appearance and fade out
tween(damageText, {
// Apply tween to the damage text
alpha: 0,
y: damageText.y - 100 // Move slightly up during fade out
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
damageText.destroy(); // Destroy the text after animation
damagePanel.destroy(); // Destroy the panel after animation
}
});
tween(damagePanel, {
// Apply tween to the panel
alpha: 0,
y: damagePanel.y - 100 // Move slightly up during fade out
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
// No need to destroy here as it's handled in damageText's onFinish
}
});
// Update the enemy's HP text
if (enemy) {
if (enemy.hpText) {
if (enemy.hpText) {
enemy.hpText.setText("HP: " + enemy.hp); // Update the enemy's HP text
}
}
}
self.deactivate(); // Deactivate the projectile
// Add shake animation to the enemy
var shake = 20;
var shakeSpeed = 15;
var originalEnemyX = enemy.x; // Save the original position of the enemy
var shakeInterval = LK.setInterval(function () {
shake *= -1;
enemy.x += shake;
shakeSpeed--;
if (shakeSpeed <= 0) {
LK.clearInterval(shakeInterval);
enemy.x = originalEnemyX; // Reset the enemy's position after the shake animation ends
}
}, shakeSpeed);
// If enemy's HP reaches 0, destroy the enemy and play explosion animation
if (enemy.hp <= 0) {
enemy.destroy();
upgradeManager.refreshCellDamage(); // Refresh cell damage before entering upgrade mode
gameState = "upgradeMode";
pauseGame();
upgradeManager.enterUpgradeMode();
// Create a custom explosion animation
if (enemy.assetType) {
var explosion = self.attachAsset(enemy.assetType, {
anchorX: 0.5,
anchorY: 0.5
});
explosion.x = enemy.x;
explosion.y = enemy.y;
explosion.scaleX = 2;
explosion.scaleY = 2;
explosion.alpha = 0.5;
game.addChild(explosion);
var _fadeOut = function fadeOut() {
explosion.alpha -= 0.05;
if (explosion.alpha <= 0) {
explosion.destroy();
} else {
LK.setTimeout(_fadeOut, 50);
}
};
_fadeOut();
}
// Enemy creation moved to after upgrade selection
}
}
}
};
// Deactivate the projectile and return it to the pool
self.deactivate = function () {
self.active = false;
self.x = -1000; // Move off-screen
self.y = -1000; // Move off-screen
};
});
// SpinningWheel class to handle spinning mechanics
var SpinningWheel = Container.expand(function () {
var self = Container.call(this);
self.cells = [];
self.isSpinning = false;
// Initialize the wheel with cells
self.init = function () {
self.cells = [];
var cellTypes = [{
type: 'critical',
baseValue: 100,
actionType: 'damage'
}, {
type: 'minor',
baseValue: 15,
actionType: 'damage'
}, {
type: 'major',
baseValue: 25,
actionType: 'damage'
}, {
type: 'heal',
baseValue: 10,
actionType: 'heal'
}, {
type: 'minor',
baseValue: 15,
actionType: 'damage'
}, {
type: 'major',
baseValue: 25,
actionType: 'damage'
}, {
type: 'minor',
baseValue: 15,
actionType: 'damage'
}, {
type: 'heal',
baseValue: 10,
actionType: 'heal'
}];
for (var i = 0; i < cellTypes.length; i++) {
var cell = self.addChild(new Tile(cellTypes[i].type, cellTypes[i].baseValue, cellTypes[i].actionType, i));
cell.x = i * 250;
cell.y = 100;
self.cells.push(cell);
}
};
// Spin the Player around the wheel
self.spin = function (player) {
if (!self.isSpinning) {
self.isSpinning = true;
player.spin(self);
}
};
});
var Tile = Container.expand(function (type, baseValue, actionType, id) {
var self = Container.call(this);
self.type = type;
self.baseValue = baseValue;
self.actionType = actionType;
self.id = id; // Add unique ID to each cell
self.display = self.addChild(LK.getAsset('tile_' + type, {
anchorX: 0.5,
anchorY: 0.5
}));
// Create and add damageText to the tile display
var damageTextValue = self.baseValue;
var damageText = self.addChild(new Text2(self.baseValue, {
size: 100,
fill: 0x000000
}));
damageText.anchor.set(0.5, 0.5);
// Method to update the tile's damage value
self.updateDamageText = function (newDamage) {
if (newDamage !== damageTextValue) {
var currentDamage = damageTextValue; // Start from the current damage value
var increment = (newDamage - currentDamage) / 20; // Divide the difference into 20 steps
var step = 0;
var _updateCounter = function updateCounter() {
if (step < 20) {
currentDamage += increment;
damageText.setText(Math.round(currentDamage));
step++;
LK.setTimeout(_updateCounter, 10); // Update every 50ms
} else {
damageText.setText(newDamage); // Ensure it ends at the exact newDamage
}
};
_updateCounter();
// TODO: Add animation to tile / text
var flash = LK.getAsset('Flash', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.addChild(flash);
tween(flash, {
alpha: 1
}, {
duration: 10,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(flash, {
alpha: 0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
flash.destroy();
}
});
}
});
// Enlarge and shrink the cell's asset during the flash animation
tween(self.display.scale, {
x: 1.2,
y: 1.2
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.display.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
damageTextValue = newDamage; // Update the damageTextValue to prevent re-triggering
}
};
});
// Initialize UpgradeManager
var UpgradeManager = Container.expand(function (wheel) {
var self = Container.call(this);
self.wheel = wheel; // Store the wheel instance
self.applyUpgrade = function (selectedUpgrade) {
switch (selectedUpgrade.type) {
case 'increaseAllTiles':
upgradeState.global.healBoost += selectedUpgrade.value;
upgradeState.global.totalDamageBoost += selectedUpgrade.value;
break;
case 'increaseAllDamage':
upgradeState.global.totalDamageBoost += selectedUpgrade.value;
break;
case 'increaseMinorDamage':
upgradeState.global.minorDamageBoost += selectedUpgrade.value;
break;
case 'increaseMajorDamage':
upgradeState.global.majorDamageBoost += selectedUpgrade.value;
break;
case 'increaseCriticalDamage':
upgradeState.global.criticalDamageBoost += selectedUpgrade.value;
break;
case 'increaseRandomDamage':
var damageCells = self.wheel.cells.filter(function (cell) {
return cell.actionType === 'damage';
});
if (damageCells.length > 0) {
var randomIndex = Math.floor(Math.random() * damageCells.length);
var randomCell = damageCells[randomIndex];
var cellIndex = randomCell.id; // Use the unique ID of the cell
if (!randomCell.upgraded) {
if (!upgradeState.individual[cellIndex]) {
upgradeState.individual[cellIndex] = 0;
}
upgradeState.individual[cellIndex] += selectedUpgrade.value; // Add to specific cell boost
randomCell.upgraded = true; // Mark as upgraded to prevent duplicate upgrades
}
}
break;
case 'heal':
var restoredHP = peon.playerHP.getMaxHP() - peon.playerHP.getCurrentHP();
peon.playerHP.updateHP(restoredHP);
if (restoredHP > 0) {
var peonHealText = new Text2('+' + restoredHP, {
size: 150,
fill: 0x00FF00 // Green color for heal
});
peonHealText.anchor.set(0.5, 0.5);
peonHealText.x = peon.playerHP.hpText.x + 250;
peonHealText.y = peon.playerHP.hpText.y;
LK.gui.top.addChild(peonHealText);
tween(peonHealText, {
alpha: 0,
y: peonHealText.y - 50
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
peonHealText.destroy();
}
});
}
break;
case 'healBoost':
// Increase the damage value of heal cells
upgradeState.global.healBoost += selectedUpgrade.value; // Increment healBoost
console.log("Total heal boost is now", upgradeState.global.healBoost); // Log total heal boost
break;
case 'increaseHP':
peon.playerHP.setMaxHP(peon.playerHP.getMaxHP() + selectedUpgrade.value);
peon.playerHP.updateHP(selectedUpgrade.value);
break;
case 'increaseVampiric':
// Increase the vampiric ability of projectiles
upgradeState.global.vampiricAbility += selectedUpgrade.value;
console.log("Vampiric Ability increased to:", upgradeState.global.vampiricAbility);
break;
case 'passGoHeal':
upgradeState.global.passGoHealIncrement += selectedUpgrade.value; // Increment the pass GO heal increment
console.log("Pass GO Heal Increment is now", upgradeState.global.passGoHealIncrement);
break;
case 'increasePeonPriest':
upgradeState.global.peonPriestIncrement += selectedUpgrade.value;
break;
case 'increaseHealIncrement':
upgradeState.global.passGoHealIncrement += selectedUpgrade.value;
break;
// case 'doubleCellValue':
// var randomIndex = Math.floor(Math.random() * self.wheel.cells.length);
// var randomCell = self.wheel.cells[randomIndex];
// if (randomCell.actionType === 'damage' || randomCell.actionType === 'heal') {
// randomCell.damage += randomCell.damage; // Double the cell's damage value
// console.log("Doubled value of cell index:", randomIndex);
// }
// break;
default:
console.error('Unknown upgrade type');
}
self.refreshCellDamage(); // Refresh cell damage after applying upgrade
};
self.refreshCellDamage = function () {
for (var i = 0; i < self.wheel.cells.length; i++) {
var cell = self.wheel.cells[i];
var effectiveDamage = cell.baseValue;
var specificBoost = upgradeState.individual[i] || 0;
var globalBoost = upgradeState.global.totalDamageBoost;
switch (cell.type) {
case 'minor':
effectiveDamage += upgradeState.global.minorDamageBoost;
break;
case 'major':
effectiveDamage += upgradeState.global.majorDamageBoost;
break;
case 'critical':
effectiveDamage += upgradeState.global.criticalDamageBoost;
break;
}
if (cell.actionType === 'heal') {
effectiveDamage += upgradeState.global.healBoost;
} else {
effectiveDamage += globalBoost;
}
effectiveDamage += specificBoost;
if (cell.lastLoggedDamage !== effectiveDamage) {
console.log('Cell '.concat(i, ' (').concat(cell.type, ') new damage: ').concat(effectiveDamage));
cell.lastLoggedDamage = effectiveDamage;
}
cell.updateDamageText(effectiveDamage);
}
};
self.enterUpgradeMode = function () {
if (self.upgradeScreenOpen) {
return;
} // Check if upgrade screen is already open
self.upgradeScreenOpen = true; // Set flag to indicate upgrade screen is open
var options = getRandomUpgrades(); // Directly call getRandomUpgrades to ensure fresh selection
var upgradeUI = new UpgradeUI();
upgradeUI.init(options);
game.addChild(upgradeUI);
};
});
// UpgradeUI class to handle upgrade selection interface
var UpgradeUI = Container.expand(function () {
var self = Container.call(this);
self.upgradeOptions = [];
// Initialize the UI with two upgrade options
self.init = function (options) {
self.upgradeOptions = options;
self.displayOptions();
};
// Display the upgrade options
self.displayOptions = function () {
for (var i = 0; i < 2; i++) {
var optionContainer = new Container(); // Create a container for each option
optionContainer.x = i === 0 ? -1024 : 3072; // Start off-screen, left for first, right for second
optionContainer.y = 1700 + i * 250; // Move options 800 pixels lower
var backgroundAsset = 'rectangle';
if (self.upgradeOptions[i].rarity === 'rare') {
backgroundAsset = 'rectangle_rare';
} else if (self.upgradeOptions[i].rarity === 'epic') {
backgroundAsset = 'rectangle_epic';
}
var optionBackground = LK.getAsset(backgroundAsset, {
width: 2048,
height: 200,
color: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0.5
});
optionContainer.addChild(optionBackground); // Add rectangle to the container
var optionText = new Text2(self.upgradeOptions[i].description, {
size: 150,
fill: 0x800080
});
optionText.anchor.set(0.5, 0.5);
optionContainer.addChild(optionText); // Add text to the container
optionContainer.interactive = true; // Make the container interactive
optionContainer.on('down', function (selectedUpgrade, optionContainer) {
// Use closure to capture the correct upgrade
return function () {
console.log('Upgrade option clicked:', selectedUpgrade.description); // Log the click event
// Add tween animation to simulate pressing effect
tween(optionContainer.scale, {
x: 0.9,
y: 0.9
}, {
duration: 75,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(optionContainer.scale, {
x: 1,
y: 1
}, {
duration: 75,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.selectUpgrade(selectedUpgrade);
}
});
}
});
};
}(self.upgradeOptions[i], optionContainer)); // Pass the correct upgrade option and container
self.addChild(optionContainer); // Add the container to the UI
// Animate the option to slide into position
tween(optionContainer, {
x: 1024
}, {
duration: 500,
easing: tween.easeOut
});
}
};
// Handle upgrade selection
self.selectUpgrade = function (selectedUpgrade) {
console.log("Selected upgrade:", selectedUpgrade.description); // Log the selected upgrade
upgradeManager.applyUpgrade(selectedUpgrade);
if (selectedUpgrade.type === 'heal') {
LK.getSound('Heal').play(); // Play the 'Heal' sound when the upgrade is selected
} else {
LK.getSound('Upgrade').play(); // Play the 'Upgrade' sound
}
upgradeManager.refreshCellDamage(); // Ensure cell damage is updated after applying upgrade
self.destroy(); // Close the UI
gameState = "playing"; // Resume the game
resumeGame(); // Restore game interactivity
enemy = createNewEnemy(); // Create a new enemy after upgrade selection
game.addChild(enemy);
upgradeManager.upgradeScreenOpen = false; // Reset flag after upgrade selection
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFFFFF,
//Init game with black background
interaction: true // Enable interaction manager
});
/****
* Game Code
****/
// PeonMovementTracker class to track Peon's tile movements and restore HP
var PeonMovementTracker = function PeonMovementTracker() {
this.tilesMoved = 0; // Initialize the number of tiles moved to 0
};
// Method to increment the number of tiles moved
PeonMovementTracker.prototype.incrementTilesMoved = function () {
this.tilesMoved++;
};
// Method to reset the number of tiles moved
PeonMovementTracker.prototype.resetTilesMoved = function () {
this.tilesMoved = 0;
};
// Method to get the number of tiles moved
PeonMovementTracker.prototype.getTilesMoved = function () {
return this.tilesMoved;
};
var EnemyDamage = function EnemyDamage() {
this.minDamage = 5;
this.maxDamage = 7;
this.round = 1;
this.minDamageIncrement = 1; // Separate increment for min damage
this.maxDamageIncrement = 2; // Increase max damage increment by 2 per round
this.calculateDamage = function () {
return Math.floor(Math.random() * (this.maxDamage - this.minDamage)) + this.minDamage;
};
this.increaseDamage = function () {
this.minDamage += this.minDamageIncrement;
this.maxDamage += this.maxDamageIncrement;
this.round += 1;
};
};
var InputHandler = function InputHandler() {
this.holdTimer = null;
this.isInputDisabled = false;
// Method to start the hold timer
this.startHoldTimer = function () {
var self = this;
this.holdTimer = LK.setTimeout(function () {
self.disableInput();
}, 1500); // Disable input after 1.5 seconds
};
// Method to disable player input
this.disableInput = function () {
this.isInputDisabled = true;
game.interaction = false; // Disable interaction
console.log("Input disabled due to prolonged hold");
// Simulate finger release to release the peon
if (chargeTimer) {
LK.clearInterval(chargeTimer);
chargeTimer = null;
if (chargeCount >= 1) {
LK.getSound('Roll').play(); // Play the 'Roll' sound
peon.spin(wheel, chargeCount);
}
chargeCount = 0;
currentInterval = startingInterval;
multiplier = 0.5;
tween.stop(peon, {
x: true
});
// inputHandler.reset(); // Reset the input handler
LK.getSound('Charge').stop(); // Stop the 'Charge' sound
LK.getSound('Tap_Release').play(); // Play the 'Tap_Release' sound
}
};
// Method to reset the input handler
this.reset = function () {
if (this.holdTimer) {
LK.clearTimeout(this.holdTimer);
this.holdTimer = null;
}
this.isInputDisabled = false;
game.interaction = true; // Re-enable interaction
};
};
var inputHandler = new InputHandler();
// PlayerHP class to manage player's health and display
LK.on('damageReceived', function (damageAmount) {
peon.playerHP.updateHP(-damageAmount);
});
LK.on('healingReceived', function (healAmount) {
peon.playerHP.updateHP(healAmount);
});
function startPeonShake() {
tween(peon, {
x: peon.x + 5
}, {
duration: 50,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(peon, {
x: peon.x - 5
}, {
duration: 50,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (chargeTimer) {
startPeonShake(); // Continue shaking
}
}
});
}
});
}
var midgroundContainer = new MidgroundContainer();
game.addChild(midgroundContainer);
var platform = LK.getAsset('Platform', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 150
});
midgroundContainer.addChild(platform);
// Centralized state for tracking upgrades
var enemySpawnCount = 0;
var upgradeState = {
global: {
totalDamageBoost: 0,
passGoHealIncrement: 10,
peonPriestIncrement: 0,
vampiricAbility: 0,
minorDamageBoost: 0,
majorDamageBoost: 0,
criticalDamageBoost: 0,
healBoost: 0
},
multipliers: {},
individual: {
specificCellBoosts: {}
}
};
// Initialize gameState to manage game states
// UpgradeManager class to handle upgrades
var gameState = "playing"; // Possible states: playing, paused, upgradeMode
// Centralized data structure for upgrade options
var upgradeOptions = [{
type: 'increaseHP',
value: 50,
description: '+50 to Max HP',
rarity: 'rare'
}, {
type: 'increaseAllTiles',
value: 3,
description: '+3 to all tiles',
rarity: 'common'
}, {
type: 'increaseAllDamage',
value: 5,
description: '+5 to all Damage tiles',
rarity: 'common'
}, {
type: 'increaseRandomDamage',
value: 50,
description: '+50 to random Damage tile',
rarity: 'rare'
}, {
type: 'increaseMinorDamage',
value: 15,
description: '+15 to Minor damage',
rarity: 'rare'
}, {
type: 'increaseMajorDamage',
value: 25,
description: '+25 to Major damage',
rarity: 'rare'
}, {
type: 'heal',
value: 100,
description: 'Restore full HP',
rarity: 'common'
}, {
type: 'healBoost',
value: 10,
description: '+10 to Heal tiles',
rarity: 'common'
}, {
type: 'increaseVampiric',
value: 5,
description: '+5 HP Lifesteal',
rarity: 'epic'
}, {
// type: 'doubleCellValue',
// description: 'X2 to a random tile'
}, {
type: 'increaseHealIncrement',
value: 10,
description: '+10 HP when you pass GO',
rarity: 'common'
}, {
type: 'increasePeonPriest',
value: 2,
description: '+2 to Healing Steps',
rarity: 'common'
}, {
type: 'increaseCriticalDamage',
value: 100,
description: '+100 to Critical Damage',
rarity: 'epic'
}];
var rarityWeights = {
common: 50,
rare: 40,
epic: 30
};
var upgradeBucket = [];
var remainingItems = 0;
function initializeUpgradeBucket() {
upgradeBucket = [];
upgradeOptions.forEach(function (upgrade) {
for (var i = 0; i < rarityWeights[upgrade.rarity]; i++) {
upgradeBucket.push(upgrade);
}
});
remainingItems = upgradeBucket.length;
}
function getRandomUpgrades() {
if (remainingItems <= 3) {
initializeUpgradeBucket();
}
var selectedUpgrades = [];
var firstUpgradeIndex = Math.floor(Math.random() * remainingItems);
selectedUpgrades.push(upgradeBucket[firstUpgradeIndex]);
upgradeBucket.splice(firstUpgradeIndex, 1);
remainingItems--;
var secondUpgradeIndex;
do {
secondUpgradeIndex = Math.floor(Math.random() * remainingItems);
} while (upgradeBucket[secondUpgradeIndex].type === selectedUpgrades[0].type);
selectedUpgrades.push(upgradeBucket[secondUpgradeIndex]);
upgradeBucket.splice(secondUpgradeIndex, 1);
remainingItems--;
return selectedUpgrades;
}
initializeUpgradeBucket();
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var _ref = [array[j], array[i]];
array[i] = _ref[0];
array[j] = _ref[1];
}
}
// Function to pause the game
function pauseGame() {
// Logic to pause animations, input, and timers
console.log("Game paused");
}
// Function to trigger the upgrade system UI
function triggerUpgradeUI(options) {
// Logic to display upgrade options to the player
console.log("Upgrade UI triggered with options:", options);
// Display options in a UI for the player to select
// This is a placeholder for the actual UI implementation
}
// Function to resume the game
function resumeGame() {
// Logic to resume animations, input, and timers
console.log("Game resumed");
}
// Example usage: Generate upgrade options and apply one to the Peon
// ProjectilePool class to manage projectile instances
// Helper function to calculate distance between two points
// Cache enemy assets for reuse
// ProjectilePool class to manage projectile instances
function calculateDistance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
var cachedEnemyAssets = {
enemy: LK.getAsset('enemy', {}),
enemy_2: LK.getAsset('enemy_2', {}),
enemy_3: LK.getAsset('enemy_3', {})
};
var ProjectilePool = function ProjectilePool() {
this.pool = [];
this.getProjectile = function () {
for (var i = 0; i < this.pool.length; i++) {
if (!this.pool[i].active) {
return this.pool[i];
}
}
if (this.pool.length < this.maxPoolSize) {
var newProjectile = new Projectile();
this.pool.push(newProjectile);
return newProjectile;
}
return null; // Return null if pool is full
};
this.releaseProjectile = function (projectile) {
projectile.deactivate();
};
};
var projectilePool = new ProjectilePool();
projectilePool.maxPoolSize = 10; // Set maximum pool size
// ProjectilePool class to manage projectile instances
// Global timing variables
var startingInterval = 2; // Starting interval for the spin
var multiplier = 0.5; // Multiplier for the interval increase
var currentInterval = startingInterval;
var startingMovingTiles = 11; // Starting moving tiles
var maxTiles = 17; // Maximum number of tiles
var enemyStartingHP = 50; // Starting HP for enemies
var enemyHPIncrement = 25; // HP increment per round
var enemyDamage = new EnemyDamage();
var backgroundContainer = new BackgroundContainer();
game.addChild(backgroundContainer);
var midgroundContainer = new MidgroundContainer();
game.addChild(midgroundContainer);
var foregroundContainer = new ForegroundContainer();
game.addChild(foregroundContainer);
var wheel = new SpinningWheel();
var upgradeManager = game.addChild(new UpgradeManager(wheel));
wheel.init();
wheel.x = 150; // Initial x position
wheel.y = 2500; // Space cells horizontally
upgradeManager.wheel = wheel; // Assign wheel reference to UpgradeManager
upgradeManager.enterUpgradeMode = upgradeManager.enterUpgradeMode.bind(upgradeManager);
midgroundContainer.addChild(wheel);
// Initialize the Peon and add it to the game
var peon = new Peon();
peon.init(wheel);
game.addChild(peon);
// Function to create a new enemy
function createNewEnemy() {
// Define available enemy types
var enemyTypes = [{
asset: 'enemy'
}, {
asset: 'enemy_2'
}, {
asset: 'enemy_3'
}];
// Select a random enemy type
var randomIndex = Math.floor(Math.random() * enemyTypes.length);
var selectedEnemy = enemyTypes[randomIndex];
// Increment the spawn count
enemySpawnCount += 1;
enemyDamage.increaseDamage();
// Calculate HP using global variables
var enemyHP = enemyStartingHP + enemyHPIncrement * (enemySpawnCount - 1);
// Instantiate the enemy with required parameters
var newEnemy = new Enemy(selectedEnemy.asset);
newEnemy.init(enemyHP);
backgroundContainer.addChild(newEnemy); //{6e.5}
newEnemy.lastWasDead = false; // Reset lastWasDead state for new enemy
updateLevelText();
enemies.push(newEnemy); // Add the new enemy to the array
return newEnemy;
}
// Initialize level text
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0x000000
});
levelText.anchor.set(0.5, 0);
levelText.y = 10; // Position it at the top of the screen
LK.gui.top.addChild(levelText);
// Initialize the first enemy
var enemies = []; // Array to store multiple enemies
var enemy = createNewEnemy();
enemies.push(enemy); // Add the new enemy to the array
// Function to update level text
function updateLevelText() {
levelText.setText('Level: ' + enemySpawnCount);
}
// Add a text to display the player's HP
var playerHPState = {
currentHP: peon.playerHP.getCurrentHP(),
maxHP: peon.playerHP.getMaxHP()
};
// Restore player HP state when game resumes
function restorePlayerHPState() {
peon.playerHP.hp = playerHPState.currentHP;
peon.playerHP.maxHP = playerHPState.maxHP;
peon.playerHP.hpText.setText('Player: ' + peon.playerHP.hp);
}
// Add a down event to the game to spin the Peon when the screen is tapped
var chargeCount = 0;
var chargeTimer = null;
function rollDice(x, y, obj) {
if (gameState !== "upgradeMode" && !wheel.isSpinning && !chargeTimer && !inputHandler.isInputDisabled) {
chargeCount = Math.floor(Math.random() * 2) + 1; // Randomly set chargeCount between 1 and 2
chargeTimer = LK.setInterval(function () {
chargeCount++;
}, 150);
// Start peon shake effect
startPeonShake();
inputHandler.startHoldTimer(); // Start the hold timer
LK.getSound('Charge').play(); // Play the 'Charge' sound
}
}
game.up = function (x, y, obj) {
if (chargeTimer) {
game.interaction = false; // Disable interaction
LK.setTimeout(function () {
game.interaction = true; // Re-enable interaction after 200ms
}, 400);
LK.clearInterval(chargeTimer);
chargeTimer = null;
if (chargeCount >= 1) {
LK.getSound('Roll').play(); // Play the 'Roll' sound
peon.spin(wheel, chargeCount);
}
chargeCount = 0; // Reset chargeCount after spin
currentInterval = startingInterval; // Reset the interval to the starting interval
multiplier = 0.5; // Reset the multiplier to its initial value
// Stop peon shake effect
tween.stop(peon, {
x: true
});
// inputHandler.reset(); // Reset the input handler
}
};
8-bit pixelated triangle pick. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Design a panel for a hyper-casual 2D video game, styled as a clean, white speech bubble. The panel has softly rounded corners and a slight cloud-like shape, with a small, rounded tail pointing downward or to the side. The design is pure and minimal, with no shadows or unnecessary details, ensuring a crisp, modern look. The edges are outlined with a subtle, light-gray stroke to enhance contrast while maintaining a soft and approachable aesthetic. Perfect for displaying text or damage stats in a playful yet functional manner.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Design a 2D UI element for a cute and lively text graphic that says 'GO.' The text should be bold and bubbly, with a soft, rounded font in a bright, cheerful green to indicate life and healing. The background features a large, semi-transparent green plus sign, subtly glowing and radiating a gentle, rejuvenating energy. The 'GO' text is prominently centered, with a slight 3D effect and playful highlights to make it pop, exuding a sense of positivity and vitality. The overall design is clean, minimal, and adorable, perfect for a hyper-casual mobile game.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
video game cute banana Pokémon with Matrix-like black glasses and a trench coat, oversized head occupying most of its body, standing on two tiny chubby feet at the bottom, tiny adorable creature with a cute angry expression, looking straight ahead, facing the camera directly. 2D flat vector illustration. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
video game cute divine grape bunch Pokémon with an angelic halo above its head and a harp beside it, oversized head occupying most of its body, standing on two tiny chubby feet at the bottom, tiny adorable creature with a cute angry expression, looking straight ahead, facing the camera directly. 2D flat vector illustration. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.