We now have an important function, yes, the creation of enemy tanks and the collision detection function when bullets hit enemy tanks.
5. Create an enemy tank to complete the Shell collision detection
5.1 Creating enemy Tank objects
Enemy tanks, like the players ' tanks, inherit from our tank objects as well. So we write the following code in Tank.js:
1 //Enemy Tank Object2Enimytank =function () {3 This. Direction =Enumdirection.down;4 This. Bombnum = 1;5 This. UI = Utilityclass.createe ("div", "", "Etank", document.getElementById ("Divmap"));6 This. UI.style.backgroundPosition = "0-" + This. Direction * + "px";7 8 }9 TenEnimytank.prototype =NewTank;
View Code
Then create the enemy tank when initializing the game in our game loading object.
1 var New Enimytank (); 2 enimyt1.xposition = 0; 3 enimyt1.yposition = 0; 4 Enimyt1.updateui (this. _battlefield); 5 this. _enimytanks.push (enimyT1);
View Code
5.2 Enemy tanks move and launch shells
Tank created, how do we get him to move? It is simply a matter of adding an enemy tank to our game load object to move and launch the method, and call it in the run main loop.
Code:
1 for(vari = 0; I < This. _enimytanks.length; i++) {2 3 if( This. _enimytanks[i]instanceofMover) {4 This. _enimytanks[i]. Move ( This. _battlefield);5 if(Math.random () * < 5) { This. _enimytanks[i]. Shot ( This. _battlefield)};/*5% probability of firing shells*/6 }7}
View Code
OK, now our tanks can move and fire the shells normally. But we find that the direction of the tank movement does not change, so we need a little bit of processing to add the following code to our mover object's Move method, and the enemy tank will be able to change direction randomly.
1 // enemy tanks have a 30% chance of changing direction . 2 if (Thisinstanceof enimytank) && math.random () * >) {3 this. Direction = parseint (Math.random () * 4); 4 }
5.3 Projectile Collision detection
Before the collision detection of our shells only wrote the detection of the obstacles, so we also need to add shells collision to the tank case. The idea is simple, when our bullets go through the open space or the grass (the two types of terrain the tank can stay in), we check that the map's possession is not a tank. On the code:
Bomb.js:
1 //If the next one is grass or open space2 Else if(Nextobj.objinstanceofEmptyb | | Nextobj.objinstanceofTodb) {3 //player shells hit enemy tank4 if(Nextobj.occupierinstanceofEnimytank && This. OwnerinstanceofSelftank) {5Utilityclass.removee (NextObj.occupier.UI, document.getElementById ("Divmap"));6NextObj.occupier.UI =NULL;7 Gameloader.prototype._enimytanks.pop ();8Nextobj.occupier =NULL;9}//enemy shells hit player tankTen Else if(Nextobj.occupierinstanceofSelftank && This. OwnerinstanceofEnimytank) { One //Utilityclass.removee (NextObj.occupier.UI, document.getElementById ("Divmap")); A //nextobj.occupier = null; - } -}
View Code
At this point, we will find that when the player's shells hit the enemy, the enemy tank will randomly occupy one of his 4 directions of a cell. What is the cause of this? We can imagine that when our shells hit the enemy, he might be moving. We removed him at this time, but his move's stepping method will continue to execute, don't forget, we are using the setinterval, so he is unconsciously step into the next cell. When the tank object is removed, but the occupation is still there, there will be a problem.
The solution is simple, and we've set the tank's UI to NULL when we remove the tank, so we'll stop stepping when we figure out that the value of his UI is null when we step forward. The code is simple:
1 if instanceof Enimytank) {2 // If the enemy tank is destroyed, stop stepping 3 ifnull) { 4 clearinterval (submove); 5 }6 }
Solutions for more than 5.4 enemy tanks
We also found a serious problem: our enemy tanks are an array of objects stored in the game, and when we destroy the enemy tanks, we don't know exactly which tank to remove from.
In fact, the solution to this problem is quite simple: when initializing an enemy tank, give him a property to save his index in the array, and when the tank object needs to be eliminated, we can simply remove it from the index.
1. Initialize the storage index
this. _enimytanks.length;
2. Extend the prototype method to array to remove the array at the specified location.
1Array.prototype.removeAt =function(index) {2 vararr = [], j = 0;3 //iterates through an array, filtering the elements at a specified position4 for(vari = 0; I < This. length; i++) {5 if(I! =index) {6Arr[j++] = This[i];7 }8 }9 returnarr;Ten}
3. Modify the shell to hit the enemy code.
1 //player shells hit enemy tank2 if(Nextobj.occupierinstanceofEnimytank && This. OwnerinstanceofSelftank) {3Utilityclass.removee (NextObj.occupier.UI, document.getElementById ("Divmap"));4NextObj.occupier.UI =NULL;5 vararr =gameloader.prototype._enimytanks.removeat (nextObj.occupier.index);6 //Reset Tank Index7 for(vari = 0; i < arr.length; i++) {8Arr[i].index =i;9 }TenGameloader.prototype._enimytanks =arr; OneNextobj.occupier =NULL; A}
Here's a code to reset the index, and you might not understand why. When we removed a tank, the number of elements in the array changed, so the original array index could be invalidated. So we just have to reset it, OK.
The general function has come out, there must be some bugs and places to be perfected. Columns such as tank movement and the firing of shells are incompatible, player bullets and enemy bullets should be eliminated when colliding ... There are also some features that are not implemented: Player tanks are hit disappear, game props, enemy tank spawn, scoring, levels, players draw their own maps. There is no mistake, I intend to give you these problems. The main purpose of writing this blog has been achieved: Learning JS Object-oriented. Hope you have time to continue to improve the game, in the process of completion can learn a lot of things. Thank you for listening to my nagging.
Last of this version:
Http://pan.baidu.com/s/1pJ3DWKV
Object-oriented production of Tank wars with JavaScript (iv)