Tank war js game source code HTML5 tank war game code (HTML+CSS+JavaScript)
HTML5 tank war web game perfectly restores the effect of xiaooverlord learning machine. It takes tank battle and defending base as the theme. It is a strategic game.
Game introduction
Operating instructions: Player 1: wasd up, left, down, right, space shooting; Player 2: direction key, enter shooting. n next level, p last level.
Game design ideas
1. There should be a combat area. There is a canvas that can help us solve it.
2. We should have tanks, including our own and the enemy's.
3. We should have bullets, including our own and the enemy's.
4. There must be a bomb.
5. My tank should be able to fire bullets by pressing the button, and the enemy's tank should be able to fire bullets continuously and automatically.
6. When my bullet hits the enemy, the bullet will disappear. At the same time, the enemy will explode and disappear. No more bullets can be fired.
The above is the simple idea of game design. This is the preliminary design. Next, analyze the detailed design process with code:
1, Game demo
2, Code directory
3, Code implementation
<!-- * @Author: your name * @Date: 2021-08-09 13:54:49 * @LastEditTime: 2021-08-09 13:55:38 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \04a1814eae5f272fc467de30f227ca6d\index.html --> <!DOCTYPE html> <html lang="zh" class="no-js demo-1"> <head> <title>Tank Battle js Small game source code HTML5 Tank war game code </title> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="js/jquery.min.js"></script> <script src="js/Helper.js"></script> <script src="js/keyboard.js"></script> <script src="js/const.js"></script> <script src="js/level.js"></script> <script src="js/crackAnimation.js"></script> <script src="js/prop.js"></script> <script src="js/bullet.js"></script> <script src="js/tank.js"></script> <script src="js/num.js"></script> <script src="js/menu.js"></script> <script src="js/map.js"></script> <script src="js/Collision.js"></script> <script src="js/stage.js"></script> <script src="js/main.js"></script> <style type="text/css"> #canvasDiv canvas { position: absolute; } #canvasDiv { position: absolute; left: 30%; } </style> </head> <body> <div class="container"> <center> <head> <h3>Operating instructions: Player 1: wasd Top left, bottom right, space Shooting; Player 2: direction keys, enter Shooting. n Next level, p Go up.</h3> </head> </center> <div class="main clearfix"> <div id="canvasDiv"> <canvas id="wallCanvas"></canvas> <canvas id="tankCanvas"></canvas> <canvas id="grassCanvas"></canvas> <canvas id="overCanvas"></canvas> <canvas id="stageCanvas"></canvas> </div> </div> </div> </body> </html>
1. Draw bullets
1. Collision detection,
2. Criticality detection,
3. Determine whether the bullet collided with other bullets
4. Did you hit the tank
var Bullet = function(context, owner, type, dir) { this.ctx = context; this.x = 0; this.y = 0; this.owner = owner; //The owner of the bullet this.type = type; //1. Player 2, enemy /** * collision detection */ this.isHit = function() { if (this.isDestroyed) { return; } //Critical detection if (this.x < map.offsetX) { this.x = map.offsetX; this.hit = true; } else if (this.x > map.offsetX + map.mapWidth - this.size) { this.x = map.offsetX + map.mapWidth - this.size; this.hit = true; } if (this.y < map.offsetY) { this.y = map.offsetY; this.hit = true; } else if (this.y > map.offsetY + map.mapHeight - this.size) { this.y = map.offsetY + map.mapHeight - this.size; this.hit = true; } //Did the bullet hit other bullets if (!this.hit) { if (bulletArray != null && bulletArray.length > 0) { for (var i = 0; i < bulletArray.length; i++) { if (bulletArray[i] != this && this.owner.isAI != bulletArray[i].owner.isAI && bulletArray[i].hit == false && CheckIntersect(bulletArray[i], this, 0)) { this.hit = true; bulletArray[i].hit = true; break; } } } } if (!this.hit) { //Map detection if (bulletMapCollision(this, map)) { this.hit = true; } //Did you hit the tank if (this.type == BULLET_TYPE_PLAYER) { if (enemyArray != null || enemyArray.length > 0) { for (var i = 0; i < enemyArray.length; i++) { var enemyObj = enemyArray[i]; if (!enemyObj.isDestroyed && CheckIntersect(this, enemyObj, 0)) { CheckIntersect(this, enemyObj, 0); if (enemyObj.lives > 1) { enemyObj.lives--; } else { enemyObj.distroy(); } this.hit = true; break; } } } }
2. Collision detection
1. Check whether two objects collide
2. The tank collided with the map block
3. Collision between bullet and map block
/** * Detect whether two objects collide * @param object1 Object 1 * @param object2 Object 2 * @param overlap Allowable overlap size * @returns {Boolean} If collision occurs, return true */ function CheckIntersect(object1, object2, overlap) { // x-axis x-axis // A1------>B1 C1 A2------>B2 C2 // +--------+ ^ +--------+ ^ // |Object1 | Y-axis | object2 | y-axis // | | | | | | // +--------+ D1 +--------+ D2 // //overlap is an overlapping area value A1 = object1.x + overlap; B1 = object1.x + object1.size - overlap; C1 = object1.y + overlap; D1 = object1.y + object1.size - overlap; A2 = object2.x + overlap; B2 = object2.x + object2.size - overlap; C2 = object2.y + overlap; D2 = object2.y + object2.size - overlap; //If they overlap on the x-axis if (A1 >= A2 && A1 <= B2 || B1 >= A2 && B1 <= B2) { //Judge y-axis overlap if (C1 >= C2 && C1 <= D2 || D1 >= C2 && D1 <= D2) { return true; } } return false; } /** * Tank collides with map block * @param tank Tank object * @param mapobj Map object * @returns {Boolean} Returns true if there is a collision */ function tankMapCollision(tank, mapobj) { //Movement detection, record the last movement direction, and judge + - overlap according to the direction, var tileNum = 0; //Number of tile s to be detected var rowIndex = 0; //Row index in map var colIndex = 0; //Column index in map var overlap = 3; //Allowable overlap size //Calculate the row and col in the map according to the x and y of tank if (tank.dir == UP) { rowIndex = parseInt((tank.tempY + overlap - mapobj.offsetY) / mapobj.tileSize); colIndex = parseInt((tank.tempX + overlap - mapobj.offsetX) / mapobj.tileSize); } else if (tank.dir == DOWN) { //Downward, that is, when dir==1, the calculation of row index needs + tank Height rowIndex = parseInt((tank.tempY - overlap - mapobj.offsetY + tank.size) / mapobj.tileSize); colIndex = parseInt((tank.tempX + overlap - mapobj.offsetX) / mapobj.tileSize); } else if (tank.dir == LEFT) { rowIndex = parseInt((tank.tempY + overlap - mapobj.offsetY) / mapobj.tileSize); colIndex = parseInt((tank.tempX + overlap - mapobj.offsetX) / mapobj.tileSize); } else if (tank.dir == RIGHT) { rowIndex = parseInt((tank.tempY + overlap - mapobj.offsetY) / mapobj.tileSize); //To the right, that is, when dir==3, the calculation of column index needs + tank Height colIndex = parseInt((tank.tempX - overlap - mapobj.offsetX + tank.size) / mapobj.tileSize); } if (rowIndex >= mapobj.HTileCount || rowIndex < 0 || colIndex >= mapobj.wTileCount || colIndex < 0) { return true; } if (tank.dir == UP || tank.dir == DOWN) { var tempWidth = parseInt(tank.tempX - map.offsetX - (colIndex) * mapobj.tileSize + tank.size - overlap); //Remove overlap if (tempWidth % mapobj.tileSize == 0) { tileNum = parseInt(tempWidth / mapobj.tileSize); } else { tileNum = parseInt(tempWidth / mapobj.tileSize) + 1; } for (var i = 0; i < tileNum && colIndex + i < mapobj.wTileCount; i++) { var mapContent = mapobj.mapLevel[rowIndex][colIndex + i]; if (mapContent == WALL || mapContent == GRID || mapContent == WATER || mapContent == HOME || mapContent == ANOTHREHOME) { if (tank.dir == UP) { tank.y = mapobj.offsetY + rowIndex * mapobj.tileSize + mapobj.tileSize - overlap; } else if (tank.dir == DOWN) { tank.y = mapobj.offsetY + rowIndex * mapobj.tileSize - tank.size + overlap; } return true; } } } /** * Bullet collision with map block * @param bullet Bullet object * @param mapobj Map object */ function bulletMapCollision(bullet, mapobj) { var tileNum = 0; //Number of tile s to be detected var rowIndex = 0; //Row index in map var colIndex = 0; //Column index in map var mapChangeIndex = []; //Index array to be updated in map var result = false; //Collision //Calculate the row and col in the map according to the bullet's x and y if (bullet.dir == UP) { rowIndex = parseInt((bullet.y - mapobj.offsetY) / mapobj.tileSize); colIndex = parseInt((bullet.x - mapobj.offsetX) / mapobj.tileSize); } else if (bullet.dir == DOWN) { //Downward, that is, when dir==1, the calculation of row index needs + bullet Height rowIndex = parseInt((bullet.y - mapobj.offsetY + bullet.size) / mapobj.tileSize); colIndex = parseInt((bullet.x - mapobj.offsetX) / mapobj.tileSize); } else if (bullet.dir == LEFT) { rowIndex = parseInt((bullet.y - mapobj.offsetY) / mapobj.tileSize); colIndex = parseInt((bullet.x - mapobj.offsetX) / mapobj.tileSize); } else if (bullet.dir == RIGHT) { rowIndex = parseInt((bullet.y - mapobj.offsetY) / mapobj.tileSize); //To the right, that is, when dir==3, the calculation of column index needs + bullet Height colIndex = parseInt((bullet.x - mapobj.offsetX + bullet.size) / mapobj.tileSize); } if (rowIndex >= mapobj.HTileCount || rowIndex < 0 || colIndex >= mapobj.wTileCount || colIndex < 0) { return true; } if (bullet.dir == UP || bullet.dir == DOWN) { var tempWidth = parseInt(bullet.x - map.offsetX - (colIndex) * mapobj.tileSize + bullet.size); if (tempWidth % mapobj.tileSize == 0) { tileNum = parseInt(tempWidth / mapobj.tileSize); } else { tileNum = parseInt(tempWidth / mapobj.tileSize) + 1; } for (var i = 0; i < tileNum && colIndex + i < mapobj.wTileCount; i++) { var mapContent = mapobj.mapLevel[rowIndex][colIndex + i]; if (mapContent == WALL || mapContent == GRID || mapContent == HOME || mapContent == ANOTHREHOME) { //bullet.distroy(); result = true; if (mapContent == WALL) { //The wall was knocked down mapChangeIndex.push([rowIndex, colIndex + i]); } else if (mapContent == GRID) { } else { isGameOver = true; break; } } } } //Update map map.updateMap(mapChangeIndex, 0); return result; }
3. Draw menu
1. Draw menu
2. Select the tank
3. Painting background
4. Select the tank
/** * Game start menu **/ var Menu = function(context) { this.ctx = context; this.x = 0; this.y = SCREEN_HEIGHT; this.selectTank = new SelectTank(); this.playNum = 1; this.times = 0; /** * Draw menu */ this.draw = function() { this.times++; var temp = 0; if (parseInt(this.times / 6) % 2 == 0) { temp = 0; } else { temp = this.selectTank.size; } if (this.y <= 0) { this.y = 0; } else { this.y -= 5; } this.ctx.clearRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); this.ctx.save(); //Painting background this.ctx.drawImage(MENU_IMAGE, this.x, this.y); //Painting selection tank this.ctx.drawImage(RESOURCE_IMAGE, POS["selectTank"][0], POS["selectTank"][1] + temp, this.selectTank.size, this.selectTank.size, this.selectTank.x, this.y + this.selectTank.ys[this.playNum - 1], this.selectTank.size, this.selectTank.size); this.ctx.restore(); }; /** * Select the tank to move up and down */ this.next = function(n) { this.playNum += n; if (this.playNum > 2) { this.playNum = 1; } else if (this.playNum < 1) { this.playNum = 2; } }; };
4. Draw the tank
1. Tank base
2. Criticality detection
3. Collision detection
4. Map detection
/** * Tank base class * @returns */ var Tank = function() { this.x = 0; this.y = 0; this.size = 32; //Tank size this.dir = UP; //Direction 0: up 1: down 2: left 3: right this.speed = 1; //Tank speed this.frame = 0; //Control the time for enemy tanks to switch directions this.hit = false; //Did you touch a wall or a tank this.isAI = false; //Auto this.isShooting = false; //Is the bullet running this.bullet = null; //bullet this.shootRate = 0.6; //Shooting probability this.isDestroyed = false; this.tempX = 0; this.tempY = 0; /** * collision detection */ this.isHit = function() { //Critical detection if (this.dir == LEFT) { if (this.x <= map.offsetX) { this.x = map.offsetX; this.hit = true; } } else if (this.dir == RIGHT) { if (this.x >= map.offsetX + map.mapWidth - this.size) { this.x = map.offsetX + map.mapWidth - this.size; this.hit = true; } } else if (this.dir == UP) { if (this.y <= map.offsetY) { this.y = map.offsetY; this.hit = true; } } else if (this.dir == DOWN) { if (this.y >= map.offsetY + map.mapHeight - this.size) { this.y = map.offsetY + map.mapHeight - this.size; this.hit = true; } } if (!this.hit) { //Map detection if (tankMapCollision(this, map)) { this.hit = true; } } /** * Shooting */ this.shoot = function(type) { if (this.isAI && emenyStopTime > 0) { return; } if (this.isShooting) { return; } else { var tempX = this.x; var tempY = this.y; this.bullet = new Bullet(this.ctx, this, type, this.dir); if (this.dir == UP) { tempX = this.x + parseInt(this.size / 2) - parseInt(this.bullet.size / 2); tempY = this.y - this.bullet.size; } else if (this.dir == DOWN) { tempX = this.x + parseInt(this.size / 2) - parseInt(this.bullet.size / 2); tempY = this.y + this.size; } else if (this.dir == LEFT) { tempX = this.x - this.bullet.size; tempY = this.y + parseInt(this.size / 2) - parseInt(this.bullet.size / 2); } else if (this.dir == RIGHT) { tempX = this.x + this.size; tempY = this.y + parseInt(this.size / 2) - parseInt(this.bullet.size / 2); } }; /** * The tank was destroyed */ this.distroy = function() { this.isDestroyed = true; crackArray.push(new CrackAnimation(CRACK_TYPE_TANK, this.ctx, this)); TANK_DESTROY_AUDIO.play(); }; }; /** * Player tank * @param context Paint the canvas of the tank * @returns */ var PlayTank = function(context) { this.ctx = context; this.lives = 3; //Life value this.isProtected = true; //Is it protected this.protectedTime = 500; //Protection time this.offsetX = 0; //Distance between tank 2 and tank 1 this.speed = 2; //Tank speed this.draw = function() { this.hit = false; this.ctx.drawImage(RESOURCE_IMAGE, POS["player"][0] + this.offsetX + this.dir * this.size, POS["player"][1], this.size, this.size, this.x, this.y, this.size, this.size); if (this.isProtected) { var temp = parseInt((500 - this.protectedTime) / 5) % 2; this.ctx.drawImage(RESOURCE_IMAGE, POS["protected"][0], POS["protected"][1] + 32 * temp, 32, 32, this.x, this.y, 32, 32); this.protectedTime--; if (this.protectedTime == 0) { this.isProtected = false; } } }; }; EnemyOne.prototype = new Tank();
4, A complete set of web front-end introduction to advanced (Video + source code + materials + interview) (Tutorial)
A complete set of web front-end zero foundation - Introduction to advanced (Video + source code + development software + learning materials + interview questions) (Tutorial)
Suitable for entry-level to advanced children's shoes ~ send 1000 sets of HTML+CSS+JavaScript template websites
5, Source code acquisition
❉ ~ pay attention to me and praise the blog ~ bring you up knowledge every day!
❉1. See here, with the support of [praise + praise + collection] three companies, your "praise, praise and collection" is the driving force of my creation.
❉ 2. Pay attention to me ~ take you to learn every day: various front-end plug-ins, 3D cool effects, picture display, text effects, whole station templates, college students' Graduation HTML templates, final homework templates, etc! "There are many front-end developers here to discuss front-end Node knowledge and learn from each other"!
❉3. You can learn from each other about the above technical issues. You can pay attention to ↓ Gong Z to get more source code!
6, More HTML final assignments (finished product download)
>>>Poke me > > > Click to enter 200 final assignments
The source code of more than 200 HTML5 final assessment assignments includes individuals, food, companies, schools, tourism, e-commerce, pets, electrical appliances, tea, home, hotels, dance, animation, stars, clothing, sports, cosmetics, logistics, environmental protection, books, wedding dress, military, games, festivals, smoking cessation, movies, photography, culture, hometown, flowers Gifts, cars and others can meet the web design needs of College Students' Web homework. You can download what you like!