User prompt
Please fix the bug: 'window.addEventListener is not a function' in or related to this line: 'window.addEventListener('keydown', function (e) {' Line Number: 444
User prompt
Player shall move with "W/A/S/D" or arrow keys.
Code edit (1 edits merged)
Please save this source code
User prompt
Tank Battle
Initial prompt
Make a game for me. First, this game shall be 2D. The name is Tank Battle. Player has 100 HP (this means the health). There is a health bar in the left down corner. This game is pixel art. This game has levels. The player is a tank. The player shoots normal shells. The player has infinite shells. Every one of shells hit the skin color tank 3 HP. Every one of shells hit the red tank 10 HP. Every one of shells hit the green tank 25 HP. There are the tank enemies: Skin Color Tank: This tank has 50 shells (After finished all the shells, doesn't shoot anymore and destroys itself with explode {It explodes in a circular area, the radius of the circle is 2 meters. {1 meter = 16 pixels, 1 block [ground] = Sixteen by sixteen pixels} Depending on the distance, if the player is directly next to the center of the circle, the player takes 95 HP damage. If the player is less than 1 meter and more than 0.5 meters from the center of the circle, the player takes 65 HP damage. If the player is less than 1.5 meters and more than 1 meter away, the player takes 40 HP damage. If the player is less than 2 meters and more than 1.5 meters away, they take 20 HP damage. }). This tank is skin color. This tank has 50 HP. And shoots armor-piercing and explosive shells. Every one of shells damage 5 HP when they touch the player. Red Tank: This tank has 75 dynamites (After finished all the dynamites, doesn't shoot anymore, gets faster, when catches the player, explodes itself {It damages 75 HP}). This tank is red. This tank has 80 HP. If this tank is so close to player, it exploses and damages the player 50 HP. Every one of dynamites damage 15 HP when they touch the player. Green Tank: This tank has 150 asid bombs (After finished all the asid bombs, doesn't shoot anymore, gets faster, when catches the player, explodes itself {It damages 75 HP}). When an asid bomb hit the player, it damages 45 HP and posions for 3 seconds. Every one second, it hits player 1 HP and stops after three seconds. In the levels, there is a portal. If player enters that portal, the level finishes and the player passes to the next level. There is a labyrinth created with walls. But there are random counted tank enemies random places. There can be spawned Skin Color Tanks between 5 and 20, there can be spawned Red Tanks between 10 and 30, there can be spawned Green Tanks between 20 and 25 in a level.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var AcidBomb = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('acidBomb', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.directionX = 0; self.directionY = 0; self.damage = 5; self.poisonDamage = 2; self.poisonDuration = 180; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var Dynamite = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('dynamite', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.directionX = 0; self.directionY = 0; self.damage = 25; self.explosionRadius = 80; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.directionX = 0; self.directionY = 0; self.damage = 10; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var GreenTank = Container.expand(function () { var self = Container.call(this); var tankGraphics = self.attachAsset('greenTank', { anchorX: 0.5, anchorY: 0.5 }); self.health = 40; self.speed = 0.8; self.shootCooldown = 0; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; var dx = playerTank.x - self.x; var dy = playerTank.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200 && self.shootCooldown <= 0) { var length = Math.sqrt(dx * dx + dy * dy); var dirX = dx / length; var dirY = dy / length; var acidBomb = new AcidBomb(); acidBomb.x = self.x; acidBomb.y = self.y; acidBomb.directionX = dirX; acidBomb.directionY = dirY; acidBombs.push(acidBomb); game.addChild(acidBomb); self.shootCooldown = 150; LK.getSound('shoot').play(); } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.directionX = 0; self.directionY = 0; self.damage = 10; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var PlayerTank = Container.expand(function () { var self = Container.call(this); var tankGraphics = self.attachAsset('playerTank', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = 100; self.speed = 3; self.shootCooldown = 0; self.poisonTimer = 0; self.poisonDamage = 0; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; if (self.poisonTimer > 0) { self.poisonTimer--; if (LK.ticks % 30 === 0) { self.health -= self.poisonDamage; if (self.health <= 0) { LK.showGameOver(); } } } }; return self; }); var Portal = Container.expand(function () { var self = Container.call(this); var portalGraphics = self.attachAsset('portal', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.rotation += 0.05; }; return self; }); var RedTank = Container.expand(function () { var self = Container.call(this); var tankGraphics = self.attachAsset('redTank', { anchorX: 0.5, anchorY: 0.5 }); self.health = 80; self.speed = 1; self.shootCooldown = 0; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; var dx = playerTank.x - self.x; var dy = playerTank.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 250 && self.shootCooldown <= 0) { var length = Math.sqrt(dx * dx + dy * dy); var dirX = dx / length; var dirY = dy / length; var dynamite = new Dynamite(); dynamite.x = self.x; dynamite.y = self.y; dynamite.directionX = dirX; dynamite.directionY = dirY; dynamites.push(dynamite); game.addChild(dynamite); self.shootCooldown = 120; LK.getSound('shoot').play(); } }; return self; }); var SkinTank = Container.expand(function () { var self = Container.call(this); var tankGraphics = self.attachAsset('skinTank', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.speed = 1.5; self.shootCooldown = 0; self.explosionRadius = 100; self.lastPlayerX = 0; self.lastPlayerY = 0; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; var dx = playerTank.x - self.x; var dy = playerTank.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { var moveX = dx > 0 ? self.speed : -self.speed; var moveY = dy > 0 ? self.speed : -self.speed; var newX = self.x + moveX; var newY = self.y + moveY; if (!checkWallCollision(newX, self.y)) { self.x = newX; } if (!checkWallCollision(self.x, newY)) { self.y = newY; } } if (distance < 300 && self.shootCooldown <= 0) { var length = Math.sqrt(dx * dx + dy * dy); var dirX = dx / length; var dirY = dy / length; var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y; bullet.directionX = dirX; bullet.directionY = dirY; bullet.damage = 3; enemyBullets.push(bullet); game.addChild(bullet); self.shootCooldown = 90; LK.getSound('shoot').play(); } }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F2F }); /**** * Game Code ****/ var gridWidth = 32; var gridHeight = 42; var cellSize = 64; var walls = []; var skinTanks = []; var redTanks = []; var greenTanks = []; var playerBullets = []; var enemyBullets = []; var dynamites = []; var acidBombs = []; var explosions = []; var playerTank; var portal; var currentLevel = 1; var gameStarted = false; var healthBar = new Text2('Health: 100/100', { size: 40, fill: 0xFFFFFF }); healthBar.anchor.set(0, 1); LK.gui.bottomLeft.addChild(healthBar); var levelText = new Text2('Level: 1', { size: 50, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); function generateMaze() { walls = []; for (var x = 0; x < gridWidth; x++) { for (var y = 0; y < gridHeight; y++) { if (x === 0 || x === gridWidth - 1 || y === 0 || y === gridHeight - 1) { var wall = new Wall(); wall.x = x * cellSize + cellSize / 2; wall.y = y * cellSize + cellSize / 2; walls.push(wall); game.addChild(wall); } else if (Math.random() < 0.3) { var wall = new Wall(); wall.x = x * cellSize + cellSize / 2; wall.y = y * cellSize + cellSize / 2; walls.push(wall); game.addChild(wall); } } } } function spawnEnemies() { var skinCount = Math.floor(Math.random() * 16) + 5; var redCount = Math.floor(Math.random() * 21) + 10; var greenCount = Math.floor(Math.random() * 6) + 20; for (var i = 0; i < skinCount; i++) { var tank = new SkinTank(); do { tank.x = Math.random() * (2048 - 200) + 100; tank.y = Math.random() * (2732 - 200) + 100; } while (checkWallCollision(tank.x, tank.y) || getDistanceToPlayer(tank.x, tank.y) < 200); skinTanks.push(tank); game.addChild(tank); } for (var i = 0; i < redCount; i++) { var tank = new RedTank(); do { tank.x = Math.random() * (2048 - 200) + 100; tank.y = Math.random() * (2732 - 200) + 100; } while (checkWallCollision(tank.x, tank.y) || getDistanceToPlayer(tank.x, tank.y) < 200); redTanks.push(tank); game.addChild(tank); } for (var i = 0; i < greenCount; i++) { var tank = new GreenTank(); do { tank.x = Math.random() * (2048 - 200) + 100; tank.y = Math.random() * (2732 - 200) + 100; } while (checkWallCollision(tank.x, tank.y) || getDistanceToPlayer(tank.x, tank.y) < 200); greenTanks.push(tank); game.addChild(tank); } } function checkWallCollision(x, y) { for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var dx = Math.abs(x - wall.x); var dy = Math.abs(y - wall.y); if (dx < 32 && dy < 32) { return true; } } return false; } function getDistanceToPlayer(x, y) { if (!playerTank) return 1000; var dx = x - playerTank.x; var dy = y - playerTank.y; return Math.sqrt(dx * dx + dy * dy); } function createExplosion(x, y, radius, damage) { var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: x, y: y, scaleX: radius / 60, scaleY: radius / 60, alpha: 0.8 }); game.addChild(explosion); explosions.push(explosion); tween(explosion, { alpha: 0, scaleX: explosion.scaleX * 1.5, scaleY: explosion.scaleY * 1.5 }, { duration: 500, onFinish: function onFinish() { explosion.destroy(); var index = explosions.indexOf(explosion); if (index > -1) explosions.splice(index, 1); } }); var dx = playerTank.x - x; var dy = playerTank.y - y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < radius) { playerTank.health -= damage; LK.getSound('hit').play(); if (playerTank.health <= 0) { LK.showGameOver(); } } LK.getSound('explosion').play(); } function startLevel() { for (var i = walls.length - 1; i >= 0; i--) { walls[i].destroy(); } walls = []; for (var i = skinTanks.length - 1; i >= 0; i--) { skinTanks[i].destroy(); } skinTanks = []; for (var i = redTanks.length - 1; i >= 0; i--) { redTanks[i].destroy(); } redTanks = []; for (var i = greenTanks.length - 1; i >= 0; i--) { greenTanks[i].destroy(); } greenTanks = []; generateMaze(); spawnEnemies(); playerTank = new PlayerTank(); playerTank.x = 1024; playerTank.y = 1366; playerTank.health = 100; game.addChild(playerTank); portal = new Portal(); do { portal.x = Math.random() * (2048 - 200) + 100; portal.y = Math.random() * (2732 - 200) + 100; } while (checkWallCollision(portal.x, portal.y) || getDistanceToPlayer(portal.x, portal.y) < 300); game.addChild(portal); levelText.setText('Level: ' + currentLevel); gameStarted = true; } var dragStartX = 0; var dragStartY = 0; var isDragging = false; var keys = {}; game.down = function (x, y, obj) { dragStartX = x; dragStartY = y; isDragging = true; }; game.move = function (x, y, obj) { if (!gameStarted || !playerTank || !isDragging) return; var dx = x - dragStartX; var dy = y - dragStartY; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 20) { var moveX = dx > 0 ? playerTank.speed : -playerTank.speed; var moveY = dy > 0 ? playerTank.speed : -playerTank.speed; var newX = playerTank.x + moveX; var newY = playerTank.y + moveY; if (!checkWallCollision(newX, playerTank.y)) { playerTank.x = newX; } if (!checkWallCollision(playerTank.x, newY)) { playerTank.y = newY; } dragStartX = x; dragStartY = y; } }; game.up = function (x, y, obj) { if (!gameStarted || !playerTank) return; isDragging = false; if (playerTank.shootCooldown <= 0) { var dx = x - playerTank.x; var dy = y - playerTank.y; var length = Math.sqrt(dx * dx + dy * dy); if (length > 0) { var dirX = dx / length; var dirY = dy / length; var bullet = new PlayerBullet(); bullet.x = playerTank.x; bullet.y = playerTank.y; bullet.directionX = dirX; bullet.directionY = dirY; playerBullets.push(bullet); game.addChild(bullet); playerTank.shootCooldown = 15; LK.getSound('shoot').play(); } } }; game.update = function () { if (!gameStarted) { startLevel(); return; } // Movement is now handled via touch/drag in game.move method for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) { bullet.destroy(); playerBullets.splice(i, 1); continue; } if (checkWallCollision(bullet.x, bullet.y)) { bullet.destroy(); playerBullets.splice(i, 1); continue; } for (var j = skinTanks.length - 1; j >= 0; j--) { if (bullet.intersects(skinTanks[j])) { skinTanks[j].health -= 3; bullet.destroy(); playerBullets.splice(i, 1); if (skinTanks[j].health <= 0) { createExplosion(skinTanks[j].x, skinTanks[j].y, 100, 15); skinTanks[j].destroy(); skinTanks.splice(j, 1); LK.setScore(LK.getScore() + 10); } break; } } for (var j = redTanks.length - 1; j >= 0; j--) { if (bullet.intersects(redTanks[j])) { redTanks[j].health -= 10; bullet.destroy(); playerBullets.splice(i, 1); if (redTanks[j].health <= 0) { redTanks[j].destroy(); redTanks.splice(j, 1); LK.setScore(LK.getScore() + 20); } break; } } for (var j = greenTanks.length - 1; j >= 0; j--) { if (bullet.intersects(greenTanks[j])) { greenTanks[j].health -= 25; bullet.destroy(); playerBullets.splice(i, 1); if (greenTanks[j].health <= 0) { greenTanks[j].destroy(); greenTanks.splice(j, 1); LK.setScore(LK.getScore() + 30); } break; } } } for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } if (checkWallCollision(bullet.x, bullet.y)) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } if (bullet.intersects(playerTank)) { playerTank.health -= bullet.damage; bullet.destroy(); enemyBullets.splice(i, 1); LK.getSound('hit').play(); if (playerTank.health <= 0) { LK.showGameOver(); } continue; } } for (var i = dynamites.length - 1; i >= 0; i--) { var dynamite = dynamites[i]; if (dynamite.x < 0 || dynamite.x > 2048 || dynamite.y < 0 || dynamite.y > 2732) { createExplosion(dynamite.x, dynamite.y, dynamite.explosionRadius, dynamite.damage); dynamite.destroy(); dynamites.splice(i, 1); continue; } if (checkWallCollision(dynamite.x, dynamite.y)) { createExplosion(dynamite.x, dynamite.y, dynamite.explosionRadius, dynamite.damage); dynamite.destroy(); dynamites.splice(i, 1); continue; } if (dynamite.intersects(playerTank)) { createExplosion(dynamite.x, dynamite.y, dynamite.explosionRadius, dynamite.damage); dynamite.destroy(); dynamites.splice(i, 1); continue; } } for (var i = acidBombs.length - 1; i >= 0; i--) { var acidBomb = acidBombs[i]; if (acidBomb.x < 0 || acidBomb.x > 2048 || acidBomb.y < 0 || acidBomb.y > 2732) { acidBomb.destroy(); acidBombs.splice(i, 1); continue; } if (checkWallCollision(acidBomb.x, acidBomb.y)) { acidBomb.destroy(); acidBombs.splice(i, 1); continue; } if (acidBomb.intersects(playerTank)) { playerTank.health -= acidBomb.damage; playerTank.poisonTimer = acidBomb.poisonDuration; playerTank.poisonDamage = acidBomb.poisonDamage; acidBomb.destroy(); acidBombs.splice(i, 1); LK.getSound('hit').play(); if (playerTank.health <= 0) { LK.showGameOver(); } continue; } } for (var i = skinTanks.length - 1; i >= 0; i--) { if (skinTanks[i].intersects(playerTank)) { createExplosion(skinTanks[i].x, skinTanks[i].y, skinTanks[i].explosionRadius, 20); skinTanks[i].destroy(); skinTanks.splice(i, 1); } } for (var i = redTanks.length - 1; i >= 0; i--) { if (redTanks[i].intersects(playerTank)) { playerTank.health -= 15; LK.getSound('hit').play(); if (playerTank.health <= 0) { LK.showGameOver(); } } } if (playerTank.intersects(portal) && skinTanks.length === 0 && redTanks.length === 0 && greenTanks.length === 0) { currentLevel++; gameStarted = false; portal.destroy(); playerTank.destroy(); } healthBar.setText('Health: ' + Math.max(0, playerTank.health) + '/100'); };
===================================================================
--- original.js
+++ change.js
@@ -407,19 +407,8 @@
var dragStartX = 0;
var dragStartY = 0;
var isDragging = false;
var keys = {};
-// Add keyboard event listeners
-if (typeof window !== 'undefined') {
- window.addEventListener('keydown', function (e) {
- keys[e.key.toLowerCase()] = true;
- keys[e.code.toLowerCase()] = true;
- });
- window.addEventListener('keyup', function (e) {
- keys[e.key.toLowerCase()] = false;
- keys[e.code.toLowerCase()] = false;
- });
-}
game.down = function (x, y, obj) {
dragStartX = x;
dragStartY = y;
isDragging = true;
@@ -470,39 +459,9 @@
if (!gameStarted) {
startLevel();
return;
}
- // Handle keyboard movement
- if (gameStarted && playerTank) {
- var moveX = 0;
- var moveY = 0;
- // Check WASD keys
- if (keys['w'] || keys['arrowup']) {
- moveY = -playerTank.speed;
- }
- if (keys['s'] || keys['arrowdown']) {
- moveY = playerTank.speed;
- }
- if (keys['a'] || keys['arrowleft']) {
- moveX = -playerTank.speed;
- }
- if (keys['d'] || keys['arrowright']) {
- moveX = playerTank.speed;
- }
- // Apply movement with collision detection
- if (moveX !== 0) {
- var newX = playerTank.x + moveX;
- if (!checkWallCollision(newX, playerTank.y)) {
- playerTank.x = newX;
- }
- }
- if (moveY !== 0) {
- var newY = playerTank.y + moveY;
- if (!checkWallCollision(playerTank.x, newY)) {
- playerTank.y = newY;
- }
- }
- }
+ // Movement is now handled via touch/drag in game.move method
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
pixel art dynamite. In-Game asset. 2d. High contrast. No shadows
skin color tank pixel art top down. In-Game asset. 2d. High contrast. No shadows
green tank pixel art top down. In-Game asset. 2d. High contrast. No shadows
red tank pixel art top down. In-Game asset. 2d. High contrast. No shadows
blue tank pixel art top down. In-Game asset. 2d. High contrast. No shadows
pixel art bullet. In-Game asset. 2d. High contrast. No shadows
a green bomb (pixel art) writes "Acid" on it. In-Game asset. 2d. High contrast. No shadows
medkit pixel art. In-Game asset. 2d. High contrast. No shadows
dark green square 16*16 pixels pixel art. In-Game asset. 2d. High contrast. No shadows
orange circle pixel art. In-Game asset. 2d. High contrast. No shadows
A portal, outline is purple, and inside is magenta. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat pixel art
dark gray square 16*16 pixels pixel art.. In-Game asset. 2d. High contrast. No shadows
pixel art blackhole. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat