User prompt
if player kill enemy while holding in same lane untill 3 seconds reset timer to 0 and start count again ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
if player kill enemy while holding in same lane untill 3 seconds reset timer ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when level ends make full health player
User prompt
if player touch market and doing nothing about 5 seconds then close market and resume game ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
larger market picture and for upgrading from market make upgrades touchable
User prompt
make back button usable large area for touching
User prompt
back button is not usable fix it
User prompt
when touch market button stop game and add back button to continue game , when market button used then open window which includes to increas bullet size, enemy speed slower ,
User prompt
Change warning asset image to use `laneholding` instead of `Enemy_2` for danger visual
User prompt
change picture to danger image for damaging from lane holding
User prompt
if player stops in same lane about 3 seconds and damage it then stop counting his lane holding about 5 seconds and again start count ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
if player stopped about 3seconds and damaged from it then stop counting his lane holding about seconds and again start to count ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add warning asset when player stops 2sec in same lane ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make asset about them for chaning their looks
User prompt
if player stops in same lane about 3 seconds then show make an asset which holds on him about 2 seconds and disappear and make an asset which made on player takes his one health ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
change number color black and take this conbination a little left
User prompt
make coin image larger and locate smaller number on it
User prompt
change color of number to silver
User prompt
locate this image belower
User prompt
add coin image instead of coins word like 21+coin image not word
User prompt
when player score count it like coin and add market button ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
when level 1 ends dont stop game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // Randomly choose between enemy_1 and enemy_2 var enemyAsset = Math.random() < 0.5 ? 'enemy' : 'Enemy_2'; var enemySprite = self.attachAsset(enemyAsset, { anchorX: 0.5, anchorY: 0.5 }); self.width = enemySprite.width; self.height = enemySprite.height; self.speed = 5; // Decreased speed for level 1 self.alive = true; self.lane = 0; // Track which lane this enemy is in (0-4) self.update = function () { var effectiveSpeed = self.speed; if (enemySpeedUpgrade) { effectiveSpeed *= 0.7; // 30% slower } self.y += effectiveSpeed * gameSpeed; if (self.y > GAMEPLAY_AREA_BOTTOM) { self.alpha = 0; } else { self.alpha = 1; } }; return self; }); // FireRateBoost drop var FireRateBoost = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('speedBoost', { anchorX: 0.5, anchorY: 0.5, color: 0x00bfff // blue }); self.width = sprite.width; self.height = sprite.height; self.speed = 10; self.type = 'firerate'; self.update = function () { self.y += self.speed * gameSpeed; }; return self; }); // FireStyleBoost drop var FireStyleBoost = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('speedBoost', { anchorX: 0.5, anchorY: 0.5, color: 0xff8800 // orange }); self.width = sprite.width; self.height = sprite.height; self.speed = 10; self.type = 'firestyle'; self.update = function () { self.y += self.speed * gameSpeed; }; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); var heroSprite = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.width = heroSprite.width; self.height = heroSprite.height; self.shootCooldown = 0; // frames until next allowed shot // Shoot method self.shoot = function () { if (self.shootCooldown > 0 || isReloading || bulletCount <= 0) return; // Calculate bullets to fire based on fire style var bulletsToFire = fireStyle; if (bulletCount < bulletsToFire) { startReload(); return; } // Fire style: 1=single, 2=double, 3=triple if (fireStyle === 1) { var bullet = new HeroBullet(); bullet.x = self.x; bullet.y = self.y - self.height / 2 - bullet.height / 2; heroBullets.push(bullet); game.addChild(bullet); } else if (fireStyle === 2) { for (var i = -1; i <= 1; i += 2) { var bullet = new HeroBullet(); bullet.x = self.x + i * 40; bullet.y = self.y - self.height / 2 - bullet.height / 2; heroBullets.push(bullet); game.addChild(bullet); } } else if (fireStyle === 3) { for (var i = -1; i <= 1; i++) { var bullet = new HeroBullet(); bullet.x = self.x + i * 40; bullet.y = self.y - self.height / 2 - bullet.height / 2; heroBullets.push(bullet); game.addChild(bullet); } } // Consume bullets bulletCount -= bulletsToFire; updateBulletDisplay(); // Remove bullet display elements based on bullets fired for (var k = 0; k < bulletsToFire; k++) { if (bulletTxt.children.length > 0) { var bulletElement = bulletTxt.children[bulletTxt.children.length - 1]; bulletTxt.removeChild(bulletElement); } } // Check if we need to reload if (bulletCount <= 0) { startReload(); } if (fireRateActive) { self.shootCooldown = 4; // much faster } else { self.shootCooldown = 20; // slower normal fire rate } LK.getSound('shoot').play(); }; // Called every tick self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; }; return self; }); // Hero bullet class var HeroBullet = Container.expand(function () { var self = Container.call(this); var bulletSprite = self.attachAsset('heroBullet', { anchorX: 0.5, anchorY: 0.5 }); // Apply bullet size upgrade if (bulletSizeUpgrade) { bulletSprite.scaleX = 1.5; bulletSprite.scaleY = 1.5; } self.width = bulletSprite.width; self.height = bulletSprite.height; self.speed = -36; // Upwards self.update = function () { self.y += self.speed; }; return self; }); // Market window class var MarketWindow = Container.expand(function () { var self = Container.call(this); // Semi-transparent background var bg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1200, color: 0x000000 }); bg.alpha = 0.8; self.addChild(bg); // Market title var title = new Text2('MARKET', { size: 80, fill: 0xffffff }); title.anchor.set(0.5, 0.5); title.x = 0; title.y = -400; self.addChild(title); // Bullet size upgrade button var bulletUpgradeBtn = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, color: 0x00ff00 }); bulletUpgradeBtn.x = 0; bulletUpgradeBtn.y = -200; self.addChild(bulletUpgradeBtn); var bulletUpgradeText = new Text2('BIGGER BULLETS\n50 Coins', { size: 40, fill: 0xffffff }); bulletUpgradeText.anchor.set(0.5, 0.5); bulletUpgradeText.x = 0; bulletUpgradeText.y = -200; self.addChild(bulletUpgradeText); // Enemy speed slower upgrade button var speedUpgradeBtn = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, color: 0xff6600 }); speedUpgradeBtn.x = 0; speedUpgradeBtn.y = 0; self.addChild(speedUpgradeBtn); var speedUpgradeText = new Text2('SLOWER ENEMIES\n75 Coins', { size: 40, fill: 0xffffff }); speedUpgradeText.anchor.set(0.5, 0.5); speedUpgradeText.x = 0; speedUpgradeText.y = 0; self.addChild(speedUpgradeText); // Back button var backBtn = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, color: 0xff0000 }); backBtn.x = 0; backBtn.y = 300; self.addChild(backBtn); var backText = new Text2('BACK', { size: 50, fill: 0xffffff }); backText.anchor.set(0.5, 0.5); backText.x = 0; backText.y = 300; self.addChild(backText); // Store button references for hit detection self.bulletUpgradeBtn = bulletUpgradeBtn; self.speedUpgradeBtn = speedUpgradeBtn; self.backBtn = backBtn; return self; }); // ShieldBoost drop var ShieldBoost = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('speedBoost', { anchorX: 0.5, anchorY: 0.5, color: 0x00ffea // cyan }); self.width = sprite.width; self.height = sprite.height; self.speed = 10; self.type = 'shield'; self.update = function () { self.y += self.speed * gameSpeed; }; return self; }); // Speed boost drop class var SpeedBoost = Container.expand(function () { var self = Container.call(this); var boostSprite = self.attachAsset('speedBoost', { anchorX: 0.5, anchorY: 0.5 }); self.width = boostSprite.width; self.height = boostSprite.height; self.speed = 10; self.type = 'speed'; // default type self.update = function () { self.y += self.speed * gameSpeed; }; return self; }); // Warning asset that appears on idle player var WarningAsset = Container.expand(function () { var self = Container.call(this); var warningSprite = self.attachAsset('laneholding', { anchorX: 0.5, anchorY: 0.5 }); self.width = warningSprite.width; self.height = warningSprite.height; self.lifeTimer = 2000; // 2 seconds self.update = function () { self.lifeTimer -= 1000 / 60; // Decrease by frame time if (self.lifeTimer <= 0) { // Check if damage cooldown is active if (damageCooldown <= 0) { // Damage player lives--; updateLivesDisplay(); LK.getSound('hit').play(); LK.effects.flashObject(hero, 0xff0000, 400); // Start damage cooldown damageCooldown = damageCooldownDuration; // Check game over if (lives <= 0) { finished = true; LK.showGameOver(); return; } } // Remove warning asset regardless of whether damage was dealt if (warningAsset) { warningAsset.destroy(); warningAsset = null; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111111 }); /**** * Game Code ****/ // --- Global variables --- // Hero (player) // Hero bullet // Enemy // Speed boost drop // Road (background) // Sound effects // Music // soldier: gray box // tank: green box // jungle green var hero; var heroBullets = []; var enemies = []; var boosts = []; var lives = 3; var gameTime = 0; // ms var gameDuration = 20000; // 20 seconds var gameSpeed = 1; // Multiplier, affected by boosts var boostActive = false; var boostTimer = 0; // Power-up states var fireRateActive = false; var fireRateTimer = 0; var fireStyle = 1; // 1: single, 2: double, 3: triple var fireStyleTimer = 0; var shieldActive = false; var shieldTimer = 0; var lastEnemySpawnTick = 0; var enemySpawnInterval = 48; // frames (0.8s at 60fps) var score = 0; var finished = false; var level = 1; var killTarget = 10; // Level 1: 10, Level 2: 15, Level 3: 20, etc. // Lane idle detection var lastLane = 2; // Track last lane position var laneIdleTimer = 0; // Timer for staying in same lane var idleThreshold = 3000; // 3 seconds in milliseconds var warningAsset = null; // Asset that appears on player var damageCooldown = 0; // Cooldown timer after taking damage var damageCooldownDuration = 5000; // 5 seconds cooldown after damage // Coin system var coins = storage.coins || 0; // Market system var gamePaused = false; var marketWindowVisible = false; var marketWindow = null; // Upgrade states var bulletSizeUpgrade = false; var enemySpeedUpgrade = false; // Bullet system var bulletCount = 5; // Current bullets available var maxBullets = 5; // Maximum bullets in magazine var isReloading = false; var reloadTimer = 0; var reloadDuration = 2000; // 2 seconds in milliseconds function updateKillTarget() { if (level === 1) { killTarget = 10; } else if (level === 2) { killTarget = 15; } else { killTarget = 15 + (level - 2) * 5; } } updateKillTarget(); // --- Define gameplay and control areas --- var CONTROL_AREA_HEIGHT = 400; // px reserved for controller at bottom var GAMEPLAY_AREA_TOP = 0; var GAMEPLAY_AREA_BOTTOM = 2732 - CONTROL_AREA_HEIGHT; // --- Define 5 lanes --- var LANE_COUNT = 5; var ROAD_WIDTH = 900; var LANE_WIDTH = ROAD_WIDTH / LANE_COUNT; // 180px per lane var ROAD_LEFT = 2048 / 2 - ROAD_WIDTH / 2; var currentLane = 2; // Start hero in middle lane (0-4) // Get lane center X position function getLaneX(laneIndex) { return ROAD_LEFT + (laneIndex + 0.5) * LANE_WIDTH; } // Get lane index from X position function getLaneFromX(x) { var relativeX = x - ROAD_LEFT; var laneIndex = Math.floor(relativeX / LANE_WIDTH); return Math.max(0, Math.min(LANE_COUNT - 1, laneIndex)); } // --- Controller area background (army green) --- var controllerBg = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0, width: 2048, height: CONTROL_AREA_HEIGHT, color: 0x4B5320, // army green x: 0, y: 2732 - CONTROL_AREA_HEIGHT }); game.addChild(controllerBg); // --- Road background (restricted to end at controller line) --- var road = LK.getAsset('road', { anchorX: 0.5, anchorY: 0, width: 900, height: 2732 - CONTROL_AREA_HEIGHT // End at controller line }); road.x = 2048 / 2; road.y = 0; game.addChild(road); // --- Hero --- hero = new Hero(); hero.x = getLaneX(currentLane); hero.y = GAMEPLAY_AREA_BOTTOM - 150; game.addChild(hero); // --- GUI: Lives (Heart Icons) --- var heartIcons = []; for (var i = 0; i < 3; i++) { var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); heart.x = 150 + i * 100; // Space hearts 100px apart heart.y = 60; heartIcons.push(heart); LK.gui.top.addChild(heart); } // --- GUI: Level/Target --- var levelTxt = new Text2('Level 1', { size: 90, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(levelTxt); var targetTxt = new Text2('Target: 10', { size: 90, fill: 0xFFFFFF }); targetTxt.anchor.set(0.5, 0); LK.gui.bottom.addChild(targetTxt); function updateLevelDisplay() { levelTxt.setText('Level ' + level); targetTxt.setText('Target: ' + killTarget); } // --- GUI: Score --- var scoreTxt = new Text2('0', { size: 90, fill: 0xFFE066 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- GUI: Coins --- var coinContainer = new Container(); var coinTxt = new Text2(coins, { size: 50, fill: 0x000000 }); coinTxt.anchor.set(0.5, 0.5); var coinIcon = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); coinIcon.x = 0; coinIcon.y = 0; coinTxt.x = 0; coinTxt.y = 0; coinContainer.addChild(coinIcon); coinContainer.addChild(coinTxt); coinContainer.x = -100; coinContainer.y = 120; LK.gui.topRight.addChild(coinContainer); // --- GUI: Bullet Count and Reloading --- var bulletTxt = LK.getAsset('bulletCount', { anchorX: 1.0, anchorY: 0 }); LK.gui.topRight.addChild(bulletTxt); var reloadingTxt = LK.getAsset('reloadingText', { anchorX: 0.5, anchorY: 0.5 }); reloadingTxt.alpha = 0; LK.gui.center.addChild(reloadingTxt); // --- Music --- LK.playMusic('bgmusic'); // --- Helper: Update GUI --- function updateLivesDisplay() { for (var i = 0; i < heartIcons.length; i++) { heartIcons[i].alpha = i < lives ? 1 : 0.2; // Show full hearts for remaining lives, dim for lost lives } } function updateTimerDisplay() { // Timer GUI removed, nothing to update } function updateScoreDisplay() { scoreTxt.setText(score); } function updateBulletDisplay() { // Clear existing bullet display elements while (bulletTxt.children.length > 0) { bulletTxt.removeChild(bulletTxt.children[0]); } // Add bullet elements based on current bullet count for (var i = 0; i < bulletCount; i++) { var bulletElement = LK.getAsset('heroBullet', { anchorX: 0.5, anchorY: 0.5 }); bulletElement.x = -30 - i * 25; // Position bullets horizontally bulletElement.y = 0; bulletTxt.addChild(bulletElement); } } function updateCoinDisplay() { coinTxt.setText(coins); storage.coins = coins; // Save to persistent storage } function startReload() { if (!isReloading && bulletCount < maxBullets) { isReloading = true; reloadTimer = reloadDuration; reloadingTxt.alpha = 1; tween(reloadingTxt, { alpha: 0 }, { duration: reloadDuration, onFinish: function onFinish() { bulletCount = maxBullets; isReloading = false; updateBulletDisplay(); } }); } } // --- Touch controls: Move hero, shoot --- var dragHero = false; var leftArrowBtn, rightArrowBtn, fireBtn; var leftBtnPressed = false; var rightBtnPressed = false; var fireBtnPressed = false; var controllerBtnSize = 200; // Size for arrow buttons var fireBtnSize = 250; // Size for fire button // Move hero to specific lane function moveHeroToLane(newLane) { currentLane = Math.max(0, Math.min(LANE_COUNT - 1, newLane)); hero.x = getLaneX(currentLane); } // Controller buttons (left arrow, right arrow, fire) leftArrowBtn = LK.getAsset('leftArrow', { anchorX: 0.5, anchorY: 0.5 }); rightArrowBtn = LK.getAsset('rightArrow', { anchorX: 0.5, anchorY: 0.5 }); fireBtn = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5 }); leftArrowBtn.alpha = 1.0; rightArrowBtn.alpha = 1.0; fireBtn.alpha = 1.0; // Place buttons side-by-side in the control area with better left-to-right spacing leftArrowBtn.x = 300; leftArrowBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; rightArrowBtn.x = 600; rightArrowBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; fireBtn.x = 1600; fireBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; // Make sure controllerBg is below buttons (already added above) // Add controller buttons to game layer to make them visible game.addChild(leftArrowBtn); game.addChild(rightArrowBtn); game.addChild(fireBtn); // Market button var marketBtn = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5 }); marketBtn.x = 1000; marketBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; marketBtn.alpha = 0.8; game.addChild(marketBtn); // Market text label var marketLabel = new Text2('MARKET', { size: 30, fill: 0xffffff }); marketLabel.anchor.set(0.5, 0.5); marketLabel.x = marketBtn.x; marketLabel.y = marketBtn.y; game.addChild(marketLabel); // Make buttons more visible with higher alpha leftArrowBtn.alpha = 0.8; rightArrowBtn.alpha = 0.8; fireBtn.alpha = 0.8; // Helper: check if point is inside button function isInsideBtn(btn, x, y) { return x >= btn.x - btn.width / 2 && x <= btn.x + btn.width / 2 && y >= btn.y - btn.height / 2 && y <= btn.y + btn.height / 2; } function showMarket() { if (!marketWindowVisible) { gamePaused = true; marketWindowVisible = true; // Create and show market window marketWindow = new MarketWindow(); marketWindow.x = 2048 / 2; marketWindow.y = 2732 / 2; game.addChild(marketWindow); } } function hideMarket() { if (marketWindowVisible) { gamePaused = false; marketWindowVisible = false; // Remove market window if (marketWindow) { marketWindow.destroy(); marketWindow = null; } } } game.down = function (x, y, obj) { // If touch is on left arrow, set pressed if (isInsideBtn(leftArrowBtn, x, y)) { leftBtnPressed = true; leftArrowBtn.alpha = 0.9; return; } // If touch is on right arrow, set pressed if (isInsideBtn(rightArrowBtn, x, y)) { rightBtnPressed = true; rightArrowBtn.alpha = 0.9; return; } // If touch is on fire button, set pressed and shoot if (isInsideBtn(fireBtn, x, y)) { fireBtnPressed = true; fireBtn.alpha = 0.9; hero.shoot(); return; } // If touch is on market button, show market if (isInsideBtn(marketBtn, x, y)) { marketBtn.alpha = 0.9; showMarket(); return; } // Handle market window interactions if (marketWindowVisible && marketWindow) { // Convert to market window local coordinates var localPos = marketWindow.toLocal({ x: x, y: y }); // Check bullet upgrade button - use global coordinates var bulletBtnGlobalPos = marketWindow.toGlobal(marketWindow.bulletUpgradeBtn.position); if (isInsideBtn({ x: bulletBtnGlobalPos.x, y: bulletBtnGlobalPos.y, width: marketWindow.bulletUpgradeBtn.width, height: marketWindow.bulletUpgradeBtn.height }, x, y)) { if (coins >= 50 && !bulletSizeUpgrade) { coins -= 50; bulletSizeUpgrade = true; updateCoinDisplay(); LK.effects.flashScreen(0x00ff00, 300); } return; } // Check enemy speed upgrade button - use global coordinates var speedBtnGlobalPos = marketWindow.toGlobal(marketWindow.speedUpgradeBtn.position); if (isInsideBtn({ x: speedBtnGlobalPos.x, y: speedBtnGlobalPos.y, width: marketWindow.speedUpgradeBtn.width, height: marketWindow.speedUpgradeBtn.height }, x, y)) { if (coins >= 75 && !enemySpeedUpgrade) { coins -= 75; enemySpeedUpgrade = true; updateCoinDisplay(); LK.effects.flashScreen(0x00ff00, 300); } return; } // Check back button - use global coordinates var backBtnGlobalPos = marketWindow.toGlobal(marketWindow.backBtn.position); if (isInsideBtn({ x: backBtnGlobalPos.x, y: backBtnGlobalPos.y, width: marketWindow.backBtn.width, height: marketWindow.backBtn.height }, x, y)) { hideMarket(); return; } } }; game.move = function (x, y, obj) { // Drag control disabled // If finger moves off controller, release if (!isInsideBtn(leftArrowBtn, x, y)) { leftBtnPressed = false; leftArrowBtn.alpha = 0.8; } if (!isInsideBtn(rightArrowBtn, x, y)) { rightBtnPressed = false; rightArrowBtn.alpha = 0.8; } if (!isInsideBtn(fireBtn, x, y)) { fireBtnPressed = false; fireBtn.alpha = 0.8; } if (!isInsideBtn(marketBtn, x, y)) { marketBtn.alpha = 0.8; } }; game.up = function (x, y, obj) { leftBtnPressed = false; rightBtnPressed = false; fireBtnPressed = false; leftArrowBtn.alpha = 0.8; rightArrowBtn.alpha = 0.8; fireBtn.alpha = 0.8; marketBtn.alpha = 0.8; }; // --- Enemy spawn logic --- function spawnEnemy() { // Enemies spawn randomly in one of the 5 lanes var enemy = new Enemy(); var enemyLane = Math.floor(Math.random() * LANE_COUNT); enemy.x = getLaneX(enemyLane); enemy.lane = enemyLane; // Set the enemy's lane // Spawn at the top of the gameplay area, not above the road enemy.y = GAMEPLAY_AREA_TOP - enemy.height / 2 - 10; // Randomize speed a bit enemy.speed = 6 + Math.random() * 3; enemies.push(enemy); game.addChild(enemy); } // --- Boost logic --- function spawnBoost(x, y) { // Randomly choose power-up type var r = Math.random(); var boost; if (r < 0.25) { boost = new SpeedBoost(); } else if (r < 0.5) { boost = new FireRateBoost(); } else if (r < 0.75) { boost = new FireStyleBoost(); } else { boost = new ShieldBoost(); } boost.x = x; boost.y = y; boosts.push(boost); game.addChild(boost); } // --- Game update --- game.update = function () { if (finished || gamePaused) return; // --- Controller movement --- if (leftBtnPressed) { moveHeroToLane(currentLane - 1); leftBtnPressed = false; // Single lane move per press leftArrowBtn.alpha = 0.8; } if (rightBtnPressed) { moveHeroToLane(currentLane + 1); rightBtnPressed = false; // Single lane move per press rightArrowBtn.alpha = 0.8; } // --- Update damage cooldown --- if (damageCooldown > 0) { damageCooldown -= 1000 / 60; // Decrease by frame time } // --- Lane idle detection --- if (currentLane === lastLane) { // Only increase idle timer if not in damage cooldown if (damageCooldown <= 0) { laneIdleTimer += 1000 / 60; // Increase by frame time (milliseconds) } // If player has been idle for 3 seconds and no warning exists and not in cooldown if (laneIdleTimer >= idleThreshold && !warningAsset && damageCooldown <= 0) { warningAsset = new WarningAsset(); warningAsset.x = hero.x; warningAsset.y = hero.y - 100; // Position above hero game.addChild(warningAsset); } } else { // Player moved to different lane, reset timer laneIdleTimer = 0; lastLane = currentLane; // Remove warning if it exists if (warningAsset) { warningAsset.destroy(); warningAsset = null; } } // --- Update warning asset --- if (warningAsset) { warningAsset.update(); // Keep warning positioned above hero warningAsset.x = hero.x; warningAsset.y = hero.y - 100; } // --- Timer --- // (Timer removed, no time-based win/lose condition) updateTimerDisplay(); // --- Win condition --- // (Handled by kill target below) // --- Boost logic --- if (boostActive) { boostTimer -= 1000 / 60; if (boostTimer <= 0) { boostActive = false; gameSpeed = 1; } } if (fireRateActive) { fireRateTimer -= 1000 / 60; if (fireRateTimer <= 0) { fireRateActive = false; } } if (fireStyle > 1) { fireStyleTimer -= 1000 / 60; if (fireStyleTimer <= 0) { fireStyle = 1; } } if (shieldActive) { shieldTimer -= 1000 / 60; if (shieldTimer <= 0) { shieldActive = false; } } // --- Enemy spawn --- if (LK.ticks - lastEnemySpawnTick >= enemySpawnInterval) { spawnEnemy(); lastEnemySpawnTick = LK.ticks; } // --- Update hero --- hero.update(); // --- Update hero bullets --- for (var i = heroBullets.length - 1; i >= 0; i--) { var b = heroBullets[i]; b.update(); // Remove if off screen if (b.y < -b.height) { b.destroy(); heroBullets.splice(i, 1); } } // --- Update enemies --- for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); // Remove if off screen if (e.y > 2732 + e.height) { e.destroy(); enemies.splice(i, 1); continue; } // Check collision with hero - only if enemy is in same lane if (e.alive && e.lane === currentLane && e.intersects(hero)) { if (shieldActive) { // Ignore hit, just destroy enemy LK.effects.flashObject(hero, 0x00ffea, 200); e.alive = false; e.destroy(); enemies.splice(i, 1); continue; } // Lose a life, destroy enemy lives--; updateLivesDisplay(); LK.getSound('hit').play(); LK.effects.flashObject(hero, 0xff0000, 400); e.alive = false; e.destroy(); enemies.splice(i, 1); // Game over? if (lives <= 0) { finished = true; LK.showGameOver(); return; } continue; } // Check collision with hero bullets for (var j = heroBullets.length - 1; j >= 0; j--) { var b = heroBullets[j]; if (e.alive && b.intersects(e)) { // Enemy down e.alive = false; e.destroy(); enemies.splice(i, 1); b.destroy(); heroBullets.splice(j, 1); score++; coins++; // Award 1 coin per enemy kill updateScoreDisplay(); updateCoinDisplay(); LK.getSound('enemyDown').play(); // Win if enough enemies killed for this level if (score >= killTarget) { // Prepare for next level level++; updateKillTarget(); updateLevelDisplay(); // Reset score for next level score = 0; updateScoreDisplay(); // Increase enemy spawn rate for higher difficulty enemySpawnInterval = Math.max(20, enemySpawnInterval - 3); // Flash screen to indicate level complete LK.effects.flashScreen(0x00ff00, 500); } // Chance to drop boost (30%) if (Math.random() < 0.3) { spawnBoost(e.x, e.y); } break; } } } // --- Update boosts --- for (var i = boosts.length - 1; i >= 0; i--) { var boost = boosts[i]; boost.update(); // Remove if off screen if (boost.y > 2732 + boost.height) { boost.destroy(); boosts.splice(i, 1); continue; } // Check collision with hero if (boost.intersects(hero)) { if (boost.type === 'speed') { boostActive = true; boostTimer = 2000; // 2 seconds gameSpeed = 2.2; LK.getSound('boost').play(); LK.effects.flashObject(hero, 0x44e07b, 400); } else if (boost.type === 'firerate') { fireRateActive = true; fireRateTimer = 4000; // 4 seconds LK.effects.flashObject(hero, 0x00bfff, 400); } else if (boost.type === 'firestyle') { fireStyle = Math.min(3, fireStyle + 1); // double, then triple fireStyleTimer = 4000; // 4 seconds LK.effects.flashObject(hero, 0xff8800, 400); } else if (boost.type === 'shield') { shieldActive = true; shieldTimer = 4000; // 4 seconds LK.effects.flashObject(hero, 0x00ffea, 400); } boost.destroy(); boosts.splice(i, 1); } } }; // --- Initial GUI update --- updateLivesDisplay(); updateScoreDisplay(); updateLevelDisplay(); updateBulletDisplay(); updateCoinDisplay();
===================================================================
--- original.js
+++ change.js
@@ -675,30 +675,48 @@
var localPos = marketWindow.toLocal({
x: x,
y: y
});
- // Check bullet upgrade button
- if (isInsideBtn(marketWindow.bulletUpgradeBtn, localPos.x, localPos.y)) {
+ // Check bullet upgrade button - use global coordinates
+ var bulletBtnGlobalPos = marketWindow.toGlobal(marketWindow.bulletUpgradeBtn.position);
+ if (isInsideBtn({
+ x: bulletBtnGlobalPos.x,
+ y: bulletBtnGlobalPos.y,
+ width: marketWindow.bulletUpgradeBtn.width,
+ height: marketWindow.bulletUpgradeBtn.height
+ }, x, y)) {
if (coins >= 50 && !bulletSizeUpgrade) {
coins -= 50;
bulletSizeUpgrade = true;
updateCoinDisplay();
LK.effects.flashScreen(0x00ff00, 300);
}
return;
}
- // Check enemy speed upgrade button
- if (isInsideBtn(marketWindow.speedUpgradeBtn, localPos.x, localPos.y)) {
+ // Check enemy speed upgrade button - use global coordinates
+ var speedBtnGlobalPos = marketWindow.toGlobal(marketWindow.speedUpgradeBtn.position);
+ if (isInsideBtn({
+ x: speedBtnGlobalPos.x,
+ y: speedBtnGlobalPos.y,
+ width: marketWindow.speedUpgradeBtn.width,
+ height: marketWindow.speedUpgradeBtn.height
+ }, x, y)) {
if (coins >= 75 && !enemySpeedUpgrade) {
coins -= 75;
enemySpeedUpgrade = true;
updateCoinDisplay();
LK.effects.flashScreen(0x00ff00, 300);
}
return;
}
- // Check back button
- if (isInsideBtn(marketWindow.backBtn, localPos.x, localPos.y)) {
+ // Check back button - use global coordinates
+ var backBtnGlobalPos = marketWindow.toGlobal(marketWindow.backBtn.position);
+ if (isInsideBtn({
+ x: backBtnGlobalPos.x,
+ y: backBtnGlobalPos.y,
+ width: marketWindow.backBtn.width,
+ height: marketWindow.backBtn.height
+ }, x, y)) {
hideMarket();
return;
}
}
Let's remove background and resize it bigger
Make it view from sky and change color of rifle to black and brown
Change towards to right
change it mecha-style heart for hero lives. In-Game asset. 2d. High contrast. No shadows. mechaart
fire button for tank game controller. Fire button in mecha style. In-Game asset. 2d. High contrast. No shadows
green line with army style. In-Game asset. 2d. High contrast. No shadows
make shorter horizontal wing
make it vertical
remove dollar emblem from it
exclamantation. In-Game asset. 2d. High contrast. No shadows
black market which sells weapon. In-Game asset. 2d. High contrast. No shadows
blur brown