User prompt
and i want to say you that each bullet shot must be removed untill reloading
User prompt
change 5/5 bullet count to asset for making pic
User prompt
take level word to left corner
User prompt
add this text like a asset for changing it
User prompt
add player a bullet 5 bullet and if they used he must reload about 2 seconds and it must show on screen `Reloading...` ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enemy moves slower
User prompt
make game 5 lane and enemy cant touch player if he was another lane
User prompt
I can't see buttons on play
User prompt
I meant arrows and fire buttons bring front and increase their transparency
User prompt
bring buttons front and make them bright
User prompt
let's decrease speed of enemy for level 1. and give them randomly between enemy_1 and enemy_2
User prompt
change place of lives no need wording just put heart
User prompt
let's add life and decrease fire rate for normal hero without powerups
User prompt
no need lane divider just add asset for near of road
User prompt
add asset as a name of side lanes as side of assets_road
User prompt
Let's fit it left to right
User prompt
let's adjust the gameplay area fit to screen
User prompt
add the controller arrows and fire button into assets
User prompt
Let's agree on 5 lanes. Let's make controller side-by-side with arrow on left side and add button for fire
User prompt
Let's adjust lane for hero and enemy in the gameplay
User prompt
Enemy assets should be hidden when they pass controller lane
User prompt
The asset of the road should be ended at the controller line
User prompt
Let's create place for gaming and controllling down for cintrollong and above gameplay. adjust size for buttons
User prompt
remove or take road place back from controller lane. no any relations with gameplay area.
User prompt
Change the format of controller side background and distinguish the place. It should be different color can be army green
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); var enemySprite = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.width = enemySprite.width; self.height = enemySprite.height; self.speed = 12; // Downwards, can be increased by game speed self.alive = true; self.update = function () { self.y += self.speed * gameSpeed; }; 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) 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); } } if (fireRateActive) { self.shootCooldown = 4; // much faster } else { self.shootCooldown = 12; // normal } 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 }); self.width = bulletSprite.width; self.height = bulletSprite.height; self.speed = -36; // Upwards self.update = function () { self.y += self.speed; }; 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111111 }); /**** * Game Code ****/ // jungle green // tank: green box // soldier: gray box // Music // Sound effects // Road (background) // Speed boost drop // Enemy // Hero bullet // Hero (player) // --- Global variables --- 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. 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; // --- 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 (fit to gameplay area only) --- var road = LK.getAsset('road', { anchorX: 0.5, anchorY: 0 }); road.x = 2048 / 2; road.y = GAMEPLAY_AREA_TOP; game.addChild(road); // --- Hero --- hero = new Hero(); hero.x = 2048 / 2; hero.y = GAMEPLAY_AREA_BOTTOM - 150; game.addChild(hero); // --- GUI: Lives --- var livesTxt = new Text2('♥♥♥', { size: 90, fill: 0xFF4D4D }); livesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(livesTxt); // --- GUI: Level/Target --- var levelTxt = new Text2('Level 1', { size: 90, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.topRight.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); // --- Music --- LK.playMusic('bgmusic'); // --- Helper: Update GUI --- function updateLivesDisplay() { var s = ''; for (var i = 0; i < lives; i++) s += '♥'; livesTxt.setText(s); } function updateTimerDisplay() { // Timer GUI removed, nothing to update } function updateScoreDisplay() { scoreTxt.setText(score); } // --- Touch controls: Move hero, shoot --- var dragHero = false; var leftBtn, rightBtn; var leftBtnPressed = false; var rightBtnPressed = false; var controllerBtnSize = 220; // Clamp hero inside road function clampHero(x, y) { var minX = road.x - road.width / 2 + hero.width / 2 + 20; var maxX = road.x + road.width / 2 - hero.width / 2 - 20; var minY = 200 + hero.height / 2; var maxY = GAMEPLAY_AREA_BOTTOM - hero.height / 2 - 40; hero.x = Math.max(minX, Math.min(maxX, x)); hero.y = Math.max(minY, Math.min(maxY, y)); } // Controller buttons (left/right) leftBtn = LK.getAsset('hero', { anchorX: 0.5, anchorY: 0.5, width: controllerBtnSize, height: controllerBtnSize, color: 0x444444 }); rightBtn = LK.getAsset('hero', { anchorX: 0.5, anchorY: 0.5, width: controllerBtnSize, height: controllerBtnSize, color: 0x444444 }); leftBtn.alpha = 0.35; rightBtn.alpha = 0.35; // Place buttons in the control area at the bottom, centered vertically in control area leftBtn.x = 220; leftBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; rightBtn.x = 2048 - 220; rightBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2; // Make sure controllerBg is below buttons (already added above) // Add controller buttons game.addChild(leftBtn); game.addChild(rightBtn); // 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; } game.down = function (x, y, obj) { // If touch is on left/right controller, set pressed if (isInsideBtn(leftBtn, x, y)) { leftBtnPressed = true; leftBtn.alpha = 0.7; return; } if (isInsideBtn(rightBtn, x, y)) { rightBtnPressed = true; rightBtn.alpha = 0.7; return; } // Only shoot on tap (no drag/mouse control) hero.shoot(); }; game.move = function (x, y, obj) { // Drag control disabled // If finger moves off controller, release if (!isInsideBtn(leftBtn, x, y)) { leftBtnPressed = false; leftBtn.alpha = 0.35; } if (!isInsideBtn(rightBtn, x, y)) { rightBtnPressed = false; rightBtn.alpha = 0.35; } }; game.up = function (x, y, obj) { leftBtnPressed = false; rightBtnPressed = false; leftBtn.alpha = 0.35; rightBtn.alpha = 0.35; }; // --- Enemy spawn logic --- function spawnEnemy() { // Enemies spawn randomly within road var enemy = new Enemy(); var minX = road.x - road.width / 2 + enemy.width / 2 + 20; var maxX = road.x + road.width / 2 - enemy.width / 2 - 20; enemy.x = minX + Math.random() * (maxX - minX); enemy.y = GAMEPLAY_AREA_TOP - enemy.height / 2 - 10; // Randomize speed a bit enemy.speed = 10 + Math.random() * 6; 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) return; // --- Controller movement --- if (leftBtnPressed) { clampHero(hero.x - 32, hero.y); } if (rightBtnPressed) { clampHero(hero.x + 32, hero.y); } // --- 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 > GAMEPLAY_AREA_BOTTOM + e.height) { e.destroy(); enemies.splice(i, 1); continue; } // Check collision with hero if (e.alive && 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++; updateScoreDisplay(); LK.getSound('enemyDown').play(); // Win if enough enemies killed for this level if (score >= killTarget) { finished = true; LK.showYouWin(); // Prepare for next level level++; updateKillTarget(); updateLevelDisplay(); return; } // 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 > GAMEPLAY_AREA_BOTTOM + 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();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemySprite.width;
self.height = enemySprite.height;
self.speed = 12; // Downwards, can be increased by game speed
self.alive = true;
self.update = function () {
self.y += self.speed * gameSpeed;
};
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) 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);
}
}
if (fireRateActive) {
self.shootCooldown = 4; // much faster
} else {
self.shootCooldown = 12; // normal
}
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
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = -36; // Upwards
self.update = function () {
self.y += self.speed;
};
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x111111
});
/****
* Game Code
****/
// jungle green
// tank: green box
// soldier: gray box
// Music
// Sound effects
// Road (background)
// Speed boost drop
// Enemy
// Hero bullet
// Hero (player)
// --- Global variables ---
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.
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;
// --- 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 (fit to gameplay area only) ---
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0
});
road.x = 2048 / 2;
road.y = GAMEPLAY_AREA_TOP;
game.addChild(road);
// --- Hero ---
hero = new Hero();
hero.x = 2048 / 2;
hero.y = GAMEPLAY_AREA_BOTTOM - 150;
game.addChild(hero);
// --- GUI: Lives ---
var livesTxt = new Text2('♥♥♥', {
size: 90,
fill: 0xFF4D4D
});
livesTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(livesTxt);
// --- GUI: Level/Target ---
var levelTxt = new Text2('Level 1', {
size: 90,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.topRight.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);
// --- Music ---
LK.playMusic('bgmusic');
// --- Helper: Update GUI ---
function updateLivesDisplay() {
var s = '';
for (var i = 0; i < lives; i++) s += '♥';
livesTxt.setText(s);
}
function updateTimerDisplay() {
// Timer GUI removed, nothing to update
}
function updateScoreDisplay() {
scoreTxt.setText(score);
}
// --- Touch controls: Move hero, shoot ---
var dragHero = false;
var leftBtn, rightBtn;
var leftBtnPressed = false;
var rightBtnPressed = false;
var controllerBtnSize = 220;
// Clamp hero inside road
function clampHero(x, y) {
var minX = road.x - road.width / 2 + hero.width / 2 + 20;
var maxX = road.x + road.width / 2 - hero.width / 2 - 20;
var minY = 200 + hero.height / 2;
var maxY = GAMEPLAY_AREA_BOTTOM - hero.height / 2 - 40;
hero.x = Math.max(minX, Math.min(maxX, x));
hero.y = Math.max(minY, Math.min(maxY, y));
}
// Controller buttons (left/right)
leftBtn = LK.getAsset('hero', {
anchorX: 0.5,
anchorY: 0.5,
width: controllerBtnSize,
height: controllerBtnSize,
color: 0x444444
});
rightBtn = LK.getAsset('hero', {
anchorX: 0.5,
anchorY: 0.5,
width: controllerBtnSize,
height: controllerBtnSize,
color: 0x444444
});
leftBtn.alpha = 0.35;
rightBtn.alpha = 0.35;
// Place buttons in the control area at the bottom, centered vertically in control area
leftBtn.x = 220;
leftBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2;
rightBtn.x = 2048 - 220;
rightBtn.y = 2732 - CONTROL_AREA_HEIGHT / 2;
// Make sure controllerBg is below buttons (already added above)
// Add controller buttons
game.addChild(leftBtn);
game.addChild(rightBtn);
// 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;
}
game.down = function (x, y, obj) {
// If touch is on left/right controller, set pressed
if (isInsideBtn(leftBtn, x, y)) {
leftBtnPressed = true;
leftBtn.alpha = 0.7;
return;
}
if (isInsideBtn(rightBtn, x, y)) {
rightBtnPressed = true;
rightBtn.alpha = 0.7;
return;
}
// Only shoot on tap (no drag/mouse control)
hero.shoot();
};
game.move = function (x, y, obj) {
// Drag control disabled
// If finger moves off controller, release
if (!isInsideBtn(leftBtn, x, y)) {
leftBtnPressed = false;
leftBtn.alpha = 0.35;
}
if (!isInsideBtn(rightBtn, x, y)) {
rightBtnPressed = false;
rightBtn.alpha = 0.35;
}
};
game.up = function (x, y, obj) {
leftBtnPressed = false;
rightBtnPressed = false;
leftBtn.alpha = 0.35;
rightBtn.alpha = 0.35;
};
// --- Enemy spawn logic ---
function spawnEnemy() {
// Enemies spawn randomly within road
var enemy = new Enemy();
var minX = road.x - road.width / 2 + enemy.width / 2 + 20;
var maxX = road.x + road.width / 2 - enemy.width / 2 - 20;
enemy.x = minX + Math.random() * (maxX - minX);
enemy.y = GAMEPLAY_AREA_TOP - enemy.height / 2 - 10;
// Randomize speed a bit
enemy.speed = 10 + Math.random() * 6;
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) return;
// --- Controller movement ---
if (leftBtnPressed) {
clampHero(hero.x - 32, hero.y);
}
if (rightBtnPressed) {
clampHero(hero.x + 32, hero.y);
}
// --- 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 > GAMEPLAY_AREA_BOTTOM + e.height) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Check collision with hero
if (e.alive && 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++;
updateScoreDisplay();
LK.getSound('enemyDown').play();
// Win if enough enemies killed for this level
if (score >= killTarget) {
finished = true;
LK.showYouWin();
// Prepare for next level
level++;
updateKillTarget();
updateLevelDisplay();
return;
}
// 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 > GAMEPLAY_AREA_BOTTOM + 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();
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