User prompt
game over after tank passed paddle zone
User prompt
erase red color
User prompt
tank destroy after 5 times hit
User prompt
fix tank dificulty
User prompt
tank dificult to destroy
User prompt
fast ball run ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
smooth paddle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
delete tank turret asset
User prompt
add background
User prompt
play get victory when finish hit all tank at first wave
User prompt
game over when tank pass paddle zone
User prompt
game end when player hit all tanks
User prompt
fix game wave
User prompt
another logic game over after tank pass player zone
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'Quadratic')' in or related to this line: 'tween(self, {' Line Number: 128 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make paddle smooth control
User prompt
tank stoped move on midle screen. but still shoot
User prompt
slugish tank
User prompt
tank dead one hit
User prompt
erase defense line rule and logic
User prompt
change game logic game over when bullet tanks hit paddle
User prompt
slow tanks move
Code edit (1 edits merged)
Please save this source code
User prompt
Tank Pong Battle
Initial prompt
1. paddle pong gameplay 2. pong ball hit battle tank 3. pong vs battle tanks
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = ballGraphics.width / 2;
self.velocityX = 0;
self.velocityY = 0;
self.active = false;
self.damage = 1;
self.launch = function (startX, startY, velX, velY) {
self.x = startX;
self.y = startY;
self.velocityX = velX;
self.velocityY = velY;
self.active = true;
};
self.update = function () {
if (!self.active) {
return;
}
// Move the ball
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off walls
if (self.x - self.radius < 0 || self.x + self.radius > 2048) {
self.velocityX = -self.velocityX;
LK.getSound('bounce').play();
// Fix position if out of bounds
if (self.x - self.radius < 0) {
self.x = self.radius;
} else if (self.x + self.radius > 2048) {
self.x = 2048 - self.radius;
}
}
// Bounce off top
if (self.y - self.radius < 0) {
self.velocityY = -self.velocityY;
LK.getSound('bounce').play();
self.y = self.radius;
}
// Check if ball is off-screen at bottom
if (self.y - self.radius > 2732) {
self.active = false;
}
};
return self;
});
var EnemyProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('enemyProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.active = true;
self.update = function () {
self.y += self.speed;
if (self.y > 2732) {
self.active = false;
}
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.lifetime = 30; // frames
self.age = 0;
self.update = function () {
self.age++;
// Scale up and fade out
var progress = self.age / self.lifetime;
self.scale.set(1 + progress);
explosionGraphics.alpha = 0.8 * (1 - progress);
return self.age >= self.lifetime;
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = paddleGraphics.width;
self.height = paddleGraphics.height;
self.speed = 15;
self.targetX = null;
self.move = function (x, y) {
self.targetX = x;
};
self.update = function () {
if (self.targetX !== null) {
var dx = self.targetX - self.x;
if (Math.abs(dx) < self.speed) {
self.x = self.targetX;
} else {
self.x += Math.sign(dx) * self.speed;
}
// Constrain to screen bounds
if (self.x < self.width / 2) {
self.x = self.width / 2;
} else if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
}
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'none';
self.speed = 3;
self.active = true;
self.setType = function (type) {
self.type = type;
switch (type) {
case 'multiball':
powerUpGraphics.tint = 0xFFFF00;
break;
case 'widepaddle':
powerUpGraphics.tint = 0x00FFFF;
break;
case 'slowmotion':
powerUpGraphics.tint = 0xFF00FF;
break;
}
return self;
};
self.update = function () {
self.y += self.speed;
if (self.y > 2732) {
self.active = false;
}
// Bob up and down animation
self.y += Math.sin(LK.ticks / 10) * 0.5;
};
return self;
});
var Tank = Container.expand(function () {
var self = Container.call(this);
var tankBody = self.attachAsset('tank', {
anchorX: 0.5,
anchorY: 0.5
});
var tankTurret = self.attachAsset('tankTurret', {
anchorX: 0.5,
anchorY: 0.8,
y: -20
});
self.width = tankBody.width;
self.height = tankBody.height;
self.health = 3;
self.maxHealth = 3;
self.speed = 1;
self.fireRate = 3000;
self.lastFire = 0;
self.value = 100;
self.type = 'basic';
self.update = function () {
self.y += self.speed;
// Fire logic
if (LK.ticks - self.lastFire > self.fireRate / (1000 / 60)) {
self.lastFire = LK.ticks;
return true; // Signal to the game that we should fire
}
return false;
};
self.hit = function (damage) {
self.health -= damage;
// Visual feedback
tween(tankBody, {
alpha: 0.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(tankBody, {
alpha: 1
}, {
duration: 100
});
}
});
LK.getSound('tankHit').play();
return self.health <= 0;
};
self.setType = function (type, wave) {
self.type = type;
switch (type) {
case 'basic':
tankBody.tint = 0xAA0000;
self.health = self.maxHealth = 3;
self.speed = 1 + wave * 0.1;
self.fireRate = 3000;
self.value = 100;
break;
case 'fast':
tankBody.tint = 0x00AA00;
self.health = self.maxHealth = 2;
self.speed = 2 + wave * 0.15;
self.fireRate = 4000;
self.value = 150;
break;
case 'heavy':
tankBody.tint = 0x0000AA;
self.health = self.maxHealth = 5 + Math.floor(wave / 2);
self.speed = 0.5 + wave * 0.05;
self.fireRate = 5000;
self.value = 200;
break;
}
return self;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Game settings and variables
var screenWidth = 2048;
var screenHeight = 2732;
var gameActive = false;
var score = 0;
var lives = 3;
var wave = 1;
var waveSize = 5;
var defenseLine = null;
var paddle = null;
var balls = [];
var tanks = [];
var projectiles = [];
var explosions = [];
var powerUps = [];
var nextBallId = 0;
var powerUpTimer = 0;
var slowMotionActive = false;
var slowMotionTimer = 0;
var dragTarget = null;
// UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -250;
scoreTxt.y = 20;
var livesTxt = new Text2('LIVES: ' + lives, {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(0, 0);
LK.gui.top.addChild(livesTxt);
livesTxt.x = -80;
livesTxt.y = 20;
var waveTxt = new Text2('WAVE: ' + wave, {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(waveTxt);
waveTxt.x = 120; // Keep away from top-left corner (menu area)
waveTxt.y = 20;
// Initialize game elements
function initGame() {
score = 0;
lives = 3;
wave = 1;
gameActive = true;
balls = [];
tanks = [];
projectiles = [];
explosions = [];
powerUps = [];
powerUpTimer = 0;
slowMotionActive = false;
slowMotionTimer = 0;
// Update UI
updateUI();
// Create defense line
defenseLine = game.addChild(LK.getAsset('defenseLine', {
anchorX: 0.5,
anchorY: 0.5,
y: screenHeight - 200
}));
// Create paddle
paddle = game.addChild(new Paddle());
paddle.x = screenWidth / 2;
paddle.y = screenHeight - 120;
// Create initial ball
createBall();
// Create initial wave
createWave();
// Start music
LK.playMusic('battleMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
}
function createBall() {
var ball = new Ball();
ball.id = nextBallId++;
balls.push(ball);
game.addChild(ball);
// Start the ball from the paddle position
ball.launch(paddle.x, paddle.y - paddle.height / 2 - ball.radius, Math.random() * 10 - 5, -8);
return ball;
}
function createWave() {
var currentWaveSize = waveSize + Math.floor(wave / 2);
for (var i = 0; i < currentWaveSize; i++) {
var tankType = 'basic';
var rand = Math.random();
// More advanced tanks in higher waves
if (wave > 2) {
if (rand < 0.2) {
tankType = 'heavy';
} else if (rand < 0.5) {
tankType = 'fast';
}
} else if (wave > 1) {
if (rand < 0.3) {
tankType = 'fast';
}
}
var tank = new Tank().setType(tankType, wave);
tank.x = 200 + (screenWidth - 400) * (i / (currentWaveSize - 1));
tank.y = 150 + Math.random() * 100;
tanks.push(tank);
game.addChild(tank);
}
// Update wave text
waveTxt.setText('WAVE: ' + wave);
}
function createExplosion(x, y) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
explosions.push(explosion);
game.addChild(explosion);
LK.getSound('tankDestroy').play();
}
function createPowerUp(x, y) {
if (Math.random() > 0.3) {
return;
} // 30% chance to drop
var powerUp = new PowerUp();
// Choose power-up type
var rand = Math.random();
var type = 'multiball';
if (rand < 0.33) {
type = 'multiball';
} else if (rand < 0.66) {
type = 'widepaddle';
} else {
type = 'slowmotion';
}
powerUp.setType(type);
powerUp.x = x;
powerUp.y = y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function tankFire(tank) {
var projectile = new EnemyProjectile();
projectile.x = tank.x;
projectile.y = tank.y + tank.height / 2;
projectiles.push(projectile);
game.addChild(projectile);
}
function activatePowerUp(type) {
LK.getSound('powerUp').play();
switch (type) {
case 'multiball':
// Create 2 additional balls
for (var i = 0; i < 2; i++) {
var ball = createBall();
ball.velocityX = Math.random() * 10 - 5;
}
break;
case 'widepaddle':
// Make paddle wider temporarily
tween(paddle, {
scaleX: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
// Schedule return to normal size
LK.setTimeout(function () {
tween(paddle, {
scaleX: 1
}, {
duration: 500
});
}, 10000);
}
});
break;
case 'slowmotion':
// Slow down all enemy tanks and projectiles
slowMotionActive = true;
slowMotionTimer = 600; // 10 seconds at 60fps
break;
}
}
function checkCollisions() {
// Ball collision with paddle
for (var i = 0; i < balls.length; i++) {
var ball = balls[i];
if (!ball.active) {
continue;
}
// Check paddle collision
if (ball.velocityY > 0 && ball.y + ball.radius >= paddle.y - paddle.height / 2 && ball.y - ball.radius <= paddle.y + paddle.height / 2 && ball.x + ball.radius >= paddle.x - paddle.width / 2 * paddle.scaleX && ball.x - ball.radius <= paddle.x + paddle.width / 2 * paddle.scaleX) {
// Calculate reflection angle based on hit position
var hitPos = (ball.x - paddle.x) / (paddle.width / 2 * paddle.scaleX);
ball.velocityX = hitPos * 10; // More angle at edges
ball.velocityY = -Math.abs(ball.velocityY); // Always bounce upward
// Add some randomness
ball.velocityX += (Math.random() - 0.5) * 2;
ball.velocityY -= Math.random() * 2;
// Ensure velocity doesn't get too small
if (Math.abs(ball.velocityY) < 4) {
ball.velocityY = -4;
}
LK.getSound('bounce').play();
}
// Check tank collisions
for (var j = 0; j < tanks.length; j++) {
var tank = tanks[j];
if (ball.intersects(tank)) {
// Bounce off tank
if (ball.x < tank.x - tank.width / 4 || ball.x > tank.x + tank.width / 4) {
ball.velocityX = -ball.velocityX;
} else {
ball.velocityY = -ball.velocityY;
}
// Add some randomness to bounce
ball.velocityX += (Math.random() - 0.5) * 2;
ball.velocityY += (Math.random() - 0.5) * 2;
// Damage tank
var destroyed = tank.hit(ball.damage);
if (destroyed) {
// Create explosion
createExplosion(tank.x, tank.y);
// Maybe drop a power-up
createPowerUp(tank.x, tank.y);
// Update score
score += tank.value;
updateUI();
// Remove tank
tank.destroy();
tanks.splice(j, 1);
j--;
}
break;
}
}
}
// Projectile collision with paddle and defense line
for (var i = 0; i < projectiles.length; i++) {
var projectile = projectiles[i];
if (!projectile.active) {
continue;
}
// Check if projectile crosses defense line
if (projectile.y >= defenseLine.y && projectile.y <= defenseLine.y + 20) {
lives--;
LK.getSound('playerHit').play();
updateUI();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 300);
// Remove projectile
projectile.destroy();
projectiles.splice(i, 1);
i--;
if (lives <= 0) {
endGame();
}
continue;
}
// Check paddle collision
if (projectile.intersects(paddle)) {
// Remove projectile
projectile.destroy();
projectiles.splice(i, 1);
i--;
LK.getSound('bounce').play();
}
}
// Power-up collision with paddle
for (var i = 0; i < powerUps.length; i++) {
var powerUp = powerUps[i];
if (!powerUp.active) {
continue;
}
if (powerUp.intersects(paddle)) {
activatePowerUp(powerUp.type);
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
i--;
}
}
}
function updateUI() {
scoreTxt.setText('SCORE: ' + score);
livesTxt.setText('LIVES: ' + lives);
waveTxt.setText('WAVE: ' + wave);
}
function endGame() {
gameActive = false;
// Check for high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Stop music with fade out
LK.playMusic('battleMusic', {
fade: {
start: 0.7,
end: 0,
duration: 800
}
});
LK.setTimeout(function () {
LK.stopMusic();
}, 800);
// Show game over screen
LK.showGameOver();
}
// Event handlers
game.down = function (x, y, obj) {
if (!gameActive) {
return;
}
dragTarget = paddle;
paddle.move(x, y);
};
game.up = function (x, y, obj) {
dragTarget = null;
};
game.move = function (x, y, obj) {
if (dragTarget) {
dragTarget.move(x, y);
}
};
// Main update loop
game.update = function () {
if (!gameActive) {
initGame();
return;
}
// Update slow motion timer
if (slowMotionActive) {
slowMotionTimer--;
if (slowMotionTimer <= 0) {
slowMotionActive = false;
}
}
// Update all game elements
paddle.update();
// Update balls
for (var i = balls.length - 1; i >= 0; i--) {
balls[i].update();
if (!balls[i].active) {
balls[i].destroy();
balls.splice(i, 1);
}
}
// Check if all balls are gone
if (balls.length === 0) {
createBall(); // Create a new ball
}
// Update tanks
for (var i = 0; i < tanks.length; i++) {
var shouldFire = false;
// Apply slow motion effect
if (!slowMotionActive || LK.ticks % 3 === 0) {
shouldFire = tanks[i].update();
}
if (shouldFire) {
tankFire(tanks[i]);
}
// Check if tank reached defense line
if (tanks[i].y + tanks[i].height / 2 >= defenseLine.y) {
// Destroy defense line
lives = 0;
updateUI();
endGame();
return;
}
}
// Check if all tanks are destroyed
if (tanks.length === 0) {
wave++;
createWave();
}
// Update projectiles
for (var i = projectiles.length - 1; i >= 0; i--) {
// Apply slow motion effect
if (!slowMotionActive || LK.ticks % 3 === 0) {
projectiles[i].update();
}
if (!projectiles[i].active) {
projectiles[i].destroy();
projectiles.splice(i, 1);
}
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var done = explosions[i].update();
if (done) {
explosions[i].destroy();
explosions.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
powerUps[i].update();
if (!powerUps[i].active) {
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
// Check all collisions
checkCollisions();
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,659 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Ball = Container.expand(function () {
+ var self = Container.call(this);
+ var ballGraphics = self.attachAsset('ball', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = ballGraphics.width / 2;
+ self.velocityX = 0;
+ self.velocityY = 0;
+ self.active = false;
+ self.damage = 1;
+ self.launch = function (startX, startY, velX, velY) {
+ self.x = startX;
+ self.y = startY;
+ self.velocityX = velX;
+ self.velocityY = velY;
+ self.active = true;
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move the ball
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ // Bounce off walls
+ if (self.x - self.radius < 0 || self.x + self.radius > 2048) {
+ self.velocityX = -self.velocityX;
+ LK.getSound('bounce').play();
+ // Fix position if out of bounds
+ if (self.x - self.radius < 0) {
+ self.x = self.radius;
+ } else if (self.x + self.radius > 2048) {
+ self.x = 2048 - self.radius;
+ }
+ }
+ // Bounce off top
+ if (self.y - self.radius < 0) {
+ self.velocityY = -self.velocityY;
+ LK.getSound('bounce').play();
+ self.y = self.radius;
+ }
+ // Check if ball is off-screen at bottom
+ if (self.y - self.radius > 2732) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var EnemyProjectile = Container.expand(function () {
+ var self = Container.call(this);
+ var projectileGraphics = self.attachAsset('enemyProjectile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 5;
+ self.active = true;
+ self.update = function () {
+ self.y += self.speed;
+ if (self.y > 2732) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var Explosion = Container.expand(function () {
+ var self = Container.call(this);
+ var explosionGraphics = self.attachAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.8
+ });
+ self.lifetime = 30; // frames
+ self.age = 0;
+ self.update = function () {
+ self.age++;
+ // Scale up and fade out
+ var progress = self.age / self.lifetime;
+ self.scale.set(1 + progress);
+ explosionGraphics.alpha = 0.8 * (1 - progress);
+ return self.age >= self.lifetime;
+ };
+ return self;
+});
+var Paddle = Container.expand(function () {
+ var self = Container.call(this);
+ var paddleGraphics = self.attachAsset('paddle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = paddleGraphics.width;
+ self.height = paddleGraphics.height;
+ self.speed = 15;
+ self.targetX = null;
+ self.move = function (x, y) {
+ self.targetX = x;
+ };
+ self.update = function () {
+ if (self.targetX !== null) {
+ var dx = self.targetX - self.x;
+ if (Math.abs(dx) < self.speed) {
+ self.x = self.targetX;
+ } else {
+ self.x += Math.sign(dx) * self.speed;
+ }
+ // Constrain to screen bounds
+ if (self.x < self.width / 2) {
+ self.x = self.width / 2;
+ } else if (self.x > 2048 - self.width / 2) {
+ self.x = 2048 - self.width / 2;
+ }
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUpGraphics = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = 'none';
+ self.speed = 3;
+ self.active = true;
+ self.setType = function (type) {
+ self.type = type;
+ switch (type) {
+ case 'multiball':
+ powerUpGraphics.tint = 0xFFFF00;
+ break;
+ case 'widepaddle':
+ powerUpGraphics.tint = 0x00FFFF;
+ break;
+ case 'slowmotion':
+ powerUpGraphics.tint = 0xFF00FF;
+ break;
+ }
+ return self;
+ };
+ self.update = function () {
+ self.y += self.speed;
+ if (self.y > 2732) {
+ self.active = false;
+ }
+ // Bob up and down animation
+ self.y += Math.sin(LK.ticks / 10) * 0.5;
+ };
+ return self;
+});
+var Tank = Container.expand(function () {
+ var self = Container.call(this);
+ var tankBody = self.attachAsset('tank', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var tankTurret = self.attachAsset('tankTurret', {
+ anchorX: 0.5,
+ anchorY: 0.8,
+ y: -20
+ });
+ self.width = tankBody.width;
+ self.height = tankBody.height;
+ self.health = 3;
+ self.maxHealth = 3;
+ self.speed = 1;
+ self.fireRate = 3000;
+ self.lastFire = 0;
+ self.value = 100;
+ self.type = 'basic';
+ self.update = function () {
+ self.y += self.speed;
+ // Fire logic
+ if (LK.ticks - self.lastFire > self.fireRate / (1000 / 60)) {
+ self.lastFire = LK.ticks;
+ return true; // Signal to the game that we should fire
+ }
+ return false;
+ };
+ self.hit = function (damage) {
+ self.health -= damage;
+ // Visual feedback
+ tween(tankBody, {
+ alpha: 0.3
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ tween(tankBody, {
+ alpha: 1
+ }, {
+ duration: 100
+ });
+ }
+ });
+ LK.getSound('tankHit').play();
+ return self.health <= 0;
+ };
+ self.setType = function (type, wave) {
+ self.type = type;
+ switch (type) {
+ case 'basic':
+ tankBody.tint = 0xAA0000;
+ self.health = self.maxHealth = 3;
+ self.speed = 1 + wave * 0.1;
+ self.fireRate = 3000;
+ self.value = 100;
+ break;
+ case 'fast':
+ tankBody.tint = 0x00AA00;
+ self.health = self.maxHealth = 2;
+ self.speed = 2 + wave * 0.15;
+ self.fireRate = 4000;
+ self.value = 150;
+ break;
+ case 'heavy':
+ tankBody.tint = 0x0000AA;
+ self.health = self.maxHealth = 5 + Math.floor(wave / 2);
+ self.speed = 0.5 + wave * 0.05;
+ self.fireRate = 5000;
+ self.value = 200;
+ break;
+ }
+ return self;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000033
+});
+
+/****
+* Game Code
+****/
+// Game settings and variables
+var screenWidth = 2048;
+var screenHeight = 2732;
+var gameActive = false;
+var score = 0;
+var lives = 3;
+var wave = 1;
+var waveSize = 5;
+var defenseLine = null;
+var paddle = null;
+var balls = [];
+var tanks = [];
+var projectiles = [];
+var explosions = [];
+var powerUps = [];
+var nextBallId = 0;
+var powerUpTimer = 0;
+var slowMotionActive = false;
+var slowMotionTimer = 0;
+var dragTarget = null;
+// UI elements
+var scoreTxt = new Text2('SCORE: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0, 0);
+LK.gui.topRight.addChild(scoreTxt);
+scoreTxt.x = -250;
+scoreTxt.y = 20;
+var livesTxt = new Text2('LIVES: ' + lives, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+livesTxt.anchor.set(0, 0);
+LK.gui.top.addChild(livesTxt);
+livesTxt.x = -80;
+livesTxt.y = 20;
+var waveTxt = new Text2('WAVE: ' + wave, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+waveTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(waveTxt);
+waveTxt.x = 120; // Keep away from top-left corner (menu area)
+waveTxt.y = 20;
+// Initialize game elements
+function initGame() {
+ score = 0;
+ lives = 3;
+ wave = 1;
+ gameActive = true;
+ balls = [];
+ tanks = [];
+ projectiles = [];
+ explosions = [];
+ powerUps = [];
+ powerUpTimer = 0;
+ slowMotionActive = false;
+ slowMotionTimer = 0;
+ // Update UI
+ updateUI();
+ // Create defense line
+ defenseLine = game.addChild(LK.getAsset('defenseLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: screenHeight - 200
+ }));
+ // Create paddle
+ paddle = game.addChild(new Paddle());
+ paddle.x = screenWidth / 2;
+ paddle.y = screenHeight - 120;
+ // Create initial ball
+ createBall();
+ // Create initial wave
+ createWave();
+ // Start music
+ LK.playMusic('battleMusic', {
+ fade: {
+ start: 0,
+ end: 0.7,
+ duration: 1000
+ }
+ });
+}
+function createBall() {
+ var ball = new Ball();
+ ball.id = nextBallId++;
+ balls.push(ball);
+ game.addChild(ball);
+ // Start the ball from the paddle position
+ ball.launch(paddle.x, paddle.y - paddle.height / 2 - ball.radius, Math.random() * 10 - 5, -8);
+ return ball;
+}
+function createWave() {
+ var currentWaveSize = waveSize + Math.floor(wave / 2);
+ for (var i = 0; i < currentWaveSize; i++) {
+ var tankType = 'basic';
+ var rand = Math.random();
+ // More advanced tanks in higher waves
+ if (wave > 2) {
+ if (rand < 0.2) {
+ tankType = 'heavy';
+ } else if (rand < 0.5) {
+ tankType = 'fast';
+ }
+ } else if (wave > 1) {
+ if (rand < 0.3) {
+ tankType = 'fast';
+ }
+ }
+ var tank = new Tank().setType(tankType, wave);
+ tank.x = 200 + (screenWidth - 400) * (i / (currentWaveSize - 1));
+ tank.y = 150 + Math.random() * 100;
+ tanks.push(tank);
+ game.addChild(tank);
+ }
+ // Update wave text
+ waveTxt.setText('WAVE: ' + wave);
+}
+function createExplosion(x, y) {
+ var explosion = new Explosion();
+ explosion.x = x;
+ explosion.y = y;
+ explosions.push(explosion);
+ game.addChild(explosion);
+ LK.getSound('tankDestroy').play();
+}
+function createPowerUp(x, y) {
+ if (Math.random() > 0.3) {
+ return;
+ } // 30% chance to drop
+ var powerUp = new PowerUp();
+ // Choose power-up type
+ var rand = Math.random();
+ var type = 'multiball';
+ if (rand < 0.33) {
+ type = 'multiball';
+ } else if (rand < 0.66) {
+ type = 'widepaddle';
+ } else {
+ type = 'slowmotion';
+ }
+ powerUp.setType(type);
+ powerUp.x = x;
+ powerUp.y = y;
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+}
+function tankFire(tank) {
+ var projectile = new EnemyProjectile();
+ projectile.x = tank.x;
+ projectile.y = tank.y + tank.height / 2;
+ projectiles.push(projectile);
+ game.addChild(projectile);
+}
+function activatePowerUp(type) {
+ LK.getSound('powerUp').play();
+ switch (type) {
+ case 'multiball':
+ // Create 2 additional balls
+ for (var i = 0; i < 2; i++) {
+ var ball = createBall();
+ ball.velocityX = Math.random() * 10 - 5;
+ }
+ break;
+ case 'widepaddle':
+ // Make paddle wider temporarily
+ tween(paddle, {
+ scaleX: 1.5
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ // Schedule return to normal size
+ LK.setTimeout(function () {
+ tween(paddle, {
+ scaleX: 1
+ }, {
+ duration: 500
+ });
+ }, 10000);
+ }
+ });
+ break;
+ case 'slowmotion':
+ // Slow down all enemy tanks and projectiles
+ slowMotionActive = true;
+ slowMotionTimer = 600; // 10 seconds at 60fps
+ break;
+ }
+}
+function checkCollisions() {
+ // Ball collision with paddle
+ for (var i = 0; i < balls.length; i++) {
+ var ball = balls[i];
+ if (!ball.active) {
+ continue;
+ }
+ // Check paddle collision
+ if (ball.velocityY > 0 && ball.y + ball.radius >= paddle.y - paddle.height / 2 && ball.y - ball.radius <= paddle.y + paddle.height / 2 && ball.x + ball.radius >= paddle.x - paddle.width / 2 * paddle.scaleX && ball.x - ball.radius <= paddle.x + paddle.width / 2 * paddle.scaleX) {
+ // Calculate reflection angle based on hit position
+ var hitPos = (ball.x - paddle.x) / (paddle.width / 2 * paddle.scaleX);
+ ball.velocityX = hitPos * 10; // More angle at edges
+ ball.velocityY = -Math.abs(ball.velocityY); // Always bounce upward
+ // Add some randomness
+ ball.velocityX += (Math.random() - 0.5) * 2;
+ ball.velocityY -= Math.random() * 2;
+ // Ensure velocity doesn't get too small
+ if (Math.abs(ball.velocityY) < 4) {
+ ball.velocityY = -4;
+ }
+ LK.getSound('bounce').play();
+ }
+ // Check tank collisions
+ for (var j = 0; j < tanks.length; j++) {
+ var tank = tanks[j];
+ if (ball.intersects(tank)) {
+ // Bounce off tank
+ if (ball.x < tank.x - tank.width / 4 || ball.x > tank.x + tank.width / 4) {
+ ball.velocityX = -ball.velocityX;
+ } else {
+ ball.velocityY = -ball.velocityY;
+ }
+ // Add some randomness to bounce
+ ball.velocityX += (Math.random() - 0.5) * 2;
+ ball.velocityY += (Math.random() - 0.5) * 2;
+ // Damage tank
+ var destroyed = tank.hit(ball.damage);
+ if (destroyed) {
+ // Create explosion
+ createExplosion(tank.x, tank.y);
+ // Maybe drop a power-up
+ createPowerUp(tank.x, tank.y);
+ // Update score
+ score += tank.value;
+ updateUI();
+ // Remove tank
+ tank.destroy();
+ tanks.splice(j, 1);
+ j--;
+ }
+ break;
+ }
+ }
+ }
+ // Projectile collision with paddle and defense line
+ for (var i = 0; i < projectiles.length; i++) {
+ var projectile = projectiles[i];
+ if (!projectile.active) {
+ continue;
+ }
+ // Check if projectile crosses defense line
+ if (projectile.y >= defenseLine.y && projectile.y <= defenseLine.y + 20) {
+ lives--;
+ LK.getSound('playerHit').play();
+ updateUI();
+ // Flash screen red
+ LK.effects.flashScreen(0xFF0000, 300);
+ // Remove projectile
+ projectile.destroy();
+ projectiles.splice(i, 1);
+ i--;
+ if (lives <= 0) {
+ endGame();
+ }
+ continue;
+ }
+ // Check paddle collision
+ if (projectile.intersects(paddle)) {
+ // Remove projectile
+ projectile.destroy();
+ projectiles.splice(i, 1);
+ i--;
+ LK.getSound('bounce').play();
+ }
+ }
+ // Power-up collision with paddle
+ for (var i = 0; i < powerUps.length; i++) {
+ var powerUp = powerUps[i];
+ if (!powerUp.active) {
+ continue;
+ }
+ if (powerUp.intersects(paddle)) {
+ activatePowerUp(powerUp.type);
+ // Remove power-up
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ i--;
+ }
+ }
+}
+function updateUI() {
+ scoreTxt.setText('SCORE: ' + score);
+ livesTxt.setText('LIVES: ' + lives);
+ waveTxt.setText('WAVE: ' + wave);
+}
+function endGame() {
+ gameActive = false;
+ // Check for high score
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+ // Stop music with fade out
+ LK.playMusic('battleMusic', {
+ fade: {
+ start: 0.7,
+ end: 0,
+ duration: 800
+ }
+ });
+ LK.setTimeout(function () {
+ LK.stopMusic();
+ }, 800);
+ // Show game over screen
+ LK.showGameOver();
+}
+// Event handlers
+game.down = function (x, y, obj) {
+ if (!gameActive) {
+ return;
+ }
+ dragTarget = paddle;
+ paddle.move(x, y);
+};
+game.up = function (x, y, obj) {
+ dragTarget = null;
+};
+game.move = function (x, y, obj) {
+ if (dragTarget) {
+ dragTarget.move(x, y);
+ }
+};
+// Main update loop
+game.update = function () {
+ if (!gameActive) {
+ initGame();
+ return;
+ }
+ // Update slow motion timer
+ if (slowMotionActive) {
+ slowMotionTimer--;
+ if (slowMotionTimer <= 0) {
+ slowMotionActive = false;
+ }
+ }
+ // Update all game elements
+ paddle.update();
+ // Update balls
+ for (var i = balls.length - 1; i >= 0; i--) {
+ balls[i].update();
+ if (!balls[i].active) {
+ balls[i].destroy();
+ balls.splice(i, 1);
+ }
+ }
+ // Check if all balls are gone
+ if (balls.length === 0) {
+ createBall(); // Create a new ball
+ }
+ // Update tanks
+ for (var i = 0; i < tanks.length; i++) {
+ var shouldFire = false;
+ // Apply slow motion effect
+ if (!slowMotionActive || LK.ticks % 3 === 0) {
+ shouldFire = tanks[i].update();
+ }
+ if (shouldFire) {
+ tankFire(tanks[i]);
+ }
+ // Check if tank reached defense line
+ if (tanks[i].y + tanks[i].height / 2 >= defenseLine.y) {
+ // Destroy defense line
+ lives = 0;
+ updateUI();
+ endGame();
+ return;
+ }
+ }
+ // Check if all tanks are destroyed
+ if (tanks.length === 0) {
+ wave++;
+ createWave();
+ }
+ // Update projectiles
+ for (var i = projectiles.length - 1; i >= 0; i--) {
+ // Apply slow motion effect
+ if (!slowMotionActive || LK.ticks % 3 === 0) {
+ projectiles[i].update();
+ }
+ if (!projectiles[i].active) {
+ projectiles[i].destroy();
+ projectiles.splice(i, 1);
+ }
+ }
+ // Update explosions
+ for (var i = explosions.length - 1; i >= 0; i--) {
+ var done = explosions[i].update();
+ if (done) {
+ explosions[i].destroy();
+ explosions.splice(i, 1);
+ }
+ }
+ // Update power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ powerUps[i].update();
+ if (!powerUps[i].active) {
+ powerUps[i].destroy();
+ powerUps.splice(i, 1);
+ }
+ }
+ // Check all collisions
+ checkCollisions();
+};
\ No newline at end of file
2d anime top down view style brown plains landscape image game photo.
captain america shield. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
vertical 2d anime image style. german nazi ww2 battle tank. top down image. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
vertical tank bullet. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
orange yellow float explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
american flag. Single Game Texture. In-Game asset.