100 lines of JS code implementation ❤ Tank war JS game source code HTML5 tank war game code (HTML+CSS+JavaScript)

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!

Added by nemethpeter on Tue, 04 Jan 2022 18:15:38 +0200