In the previous article, "Chrome comes with dinosaur games," The Source study (vi), studied the jumping process of dinosaurs, the study of the collision between dinosaurs and obstacles detection.
Collision Box
The game uses a rectangular (non-rotating rectangle) collision. The advantage of this kind of collision is that the calculation is relatively simple, the disadvantage is that the detection of irregular objects is not accurate. If you do not do more granular processing, the results will look like:
, two boxes have overlapping parts, but the reality is that there is no collision between dinosaurs and cacti. To solve this problem, multiple collision boxes need to be built:
However, there are still problems, the observation of images, dinosaurs and cacti have four collision boxes, if each game loop in the collision detection of these boxes, then the result is every time the need to 4x4=16 calculation, if the object or box a lot, it will lead to greatly increased computational capacity, resulting in serious performance problems. To improve this, only need to detect the collision between two large boxes, if not, then omit the inside of the small box collision detection. Conversely, the inside of the small box to do collision detection. The game uses the Collisionbox constructor to create a collision box:
/* * * Collision Box * @param x {Number} box x coordinate * @param y {number} box y-coordinate * @param w {number} box width * @param h {number} box height */ function collisionbox (x, Y, W, h) { this. x = x; this. y = y; this. width = w; this. height = h;}
Use the Boxcompare method to detect if two boxes collide:
1 /**2 * Collision Detection3 * @param trexbox {Object} tyrannosaurus Rex Collision box4 * @param collision box for Obstaclebox {Object} barrier5 */6 functionBoxcompare (Trexbox, Obstaclebox) {7 varTrexboxx =trexbox.x,8Trexboxy =trexbox.y,9Obstacleboxx =obstaclebox.x,TenObstacleboxy =obstaclebox.y; One A returnTrexboxx < Obstacleboxx + obstaclebox.width && Trexboxx + trexbox.width > Obstacleboxx && trexboxy & Lt Obstacleboxy + obstaclebox.height && trexbox.height + trexboxy >Obstacleboxy; -}
Create a collision box
The next step is to create a collision box for dinosaurs and obstacles. The game created 6 collision boxes for the dinosaurs, distributed over the head, torso and feet, and it also had Dodge status:
Trex.collisionboxes ={ducking:[NewCollisionbox (1,18,55,25)], RUNNING: [NewCollisionbox (22, 0, 17, 16), NewCollisionbox (1, 18, 30, 9), NewCollisionbox (10, 35, 14, 8), NewCollisionbox (1, 24, 29, 5), NewCollisionbox (5, 30, 21, 4), NewCollisionbox (9, 34, 15, 4) ] };
The collision box of the obstacle is defined in the Obstacle.types:
1Obstacle.types = [{2Type: ' Cactus_small ',3Width:17,4Height:35,5ypos:105,6Multiplespeed:4,7mingap:120,8minspeed:0,9Collisionboxes: [NewCollisionbox (0, 7, 5, 27),NewCollisionbox (4, 0, 6, 34),NewCollisionbox (10, 4, 7, 14)]Ten }, One { AType: ' Cactus_large ', -Width:25, -Height:50, theYpos:90, -Multiplespeed:7, -mingap:120, -minspeed:0, +Collisionboxes: [NewCollisionbox (0, 12, 7, 38),NewCollisionbox (8, 0, 7, 49),NewCollisionbox (13, 10, 10, 38)] - }, + { AType: ' Pterodactyl ', atwidth:46, -Height:40, -YPos: [100, 75, 50], - //Variable height Mobile. -multiplespeed:999, -minspeed:8.5, inmingap:150, -Collisionboxes: [NewCollisionbox (15, 15, 16, 5),NewCollisionbox (18, 21, 24, 6),NewCollisionbox (2, 14, 4, 3),NewCollisionbox (6, 10, 4, 7),NewCollisionbox (10, 8, 6, 9)], toNumframes:2, +Framerate:1000/6, -Speedoffset:. 8 the}];View Code
However, this only defines the case where the number of obstacles is 1, and complex obstacles need to be fixed when creating the collision box:
1 if (this. Size > 1) {// only for cactus 2 This This This this. collisionboxes[2].width; 3 This This this. collisionboxes[2].width; 4 }
The boxes are singular and plural respectively.
Finally, the collision detection is performed:
1 functioncheckforcollision (Obstacle, Trex) {2 //Create the outermost large box3 varTrexbox =NewCollisionbox (Trex.xpos + 1, Trex.ypos + 1, trex.config.width-2, trex.config.height-2);4 varObstaclebox =NewCollisionbox (Obstacle.xpos + 1, Obstacle.ypos + 1, obstacle.typeConfig.width * obstacle.size-2, Obstacle.typeConfig.hei Ght-2);5 6 }7 if(Boxcompare (Trexbox, Obstaclebox)) {8 varCollisionboxes =obstacle.collisionboxes;9 varTrexcollisionboxes = trex.ducking?Trex.collisionBoxes.DUCKING:Trex.collisionBoxes.RUNNING;Ten One for(vart = 0; T < Trexcollisionboxes.length; t++) { A for(vari = 0; i < collisionboxes.length; i++) { - //Fix Box - varAdjtrexbox =Createadjustedcollisionbox (trexcollisionboxes[t], trexbox); the varAdjobstaclebox =Createadjustedcollisionbox (Collisionboxes[i], obstaclebox); - varcrashed =Boxcompare (Adjtrexbox, adjobstaclebox); - - if(crashed) { + return[Adjtrexbox, Adjobstaclebox]; - } + } A } at } - return false; -}View Code
// fix box to shift relative coordinates to canvas coordinates function createadjustedcollisionbox (box, adjustment) { returnnew collisionbox (box.x + Adjustment.x, box.y + adjustment.y, box.width, box.height);}
View Code
Here is the final run effect, opening the console to see the collision output:
Postscript
Collision detection through the creation of collision boxes in the application of the very extensive, the famous arcade game "Street Fighter" and "Boxing King" is the use of this way:
You can see that the game has built multiple collision boxes for the characters, red for the attack area, blue for the area to be attacked, and no overlap between the green areas to push the opponent.
Chrome's own dinosaur Games source code study (vii)