The previous flight has achieved the flying Effect of arrows, but the arrows bounce back directly when they hit the wall, like a steel rod rather than an arrow. In Box2d, you can use the Joint (Joint) to connect the arrow and the target to form a whole to achieve the shooting effect. To use a joint, you must add a new variable at the beginning of the file for later use: [javascript] var b2Joints = Box2D. dynamics. joints; var b2Contacts = Box2D. dynamics. contacts; var b2Listener = Box2D. dynamics. b2ContactListener; the starting position of the arrow and the target is different. to check whether the arrow hits the target, the system must perform Collision Detection in real time. Fortunately, Box2d can automatically perform this operation, however, you need to define how to deal with the detected collision. Therefore, the following statement declares a b2Listener. When two objects collide, the method specified by Listener is called. [Javascript] var arrowContactListener = new b2Listener; arrowContactListener. preSolve = arrowPreSolve; world. setContactListener (arrowContactListener); arrowPreSolve is the method to be executed when a collision is detected. The specific implementation is as follows: [javascript] function arrowPreSolve (contact, oldManifold) {var contactPoint = new b2Vec2; var weldJointDef = new b2Joints. b2WeldJointDef; if (contact. isTouching () {var bodyA = contact. getFixtureA (). getBody (); var body B = contact. getFixtureB (). getBody (); var objA = bodyA. getUserData (); var objB = bodyB. getUserData (); if (objA. name = "arrow" & objB. name = "arrow") {for (var j = bodyA. getJointList (); j = j. next) {bodyA. getWorld (). destroyJoint (j. joint);} for (j = bodyB. getJointList (); j = j. next) {bodyB. getWorld (). destroyJoint (j. joint) ;}} if (objA. name = "arrow" & objB. name = "target") {if (objA. isflying) {wel DJointDef = newb2Joints. b2WeldJointDef; weldJointDef. initialize (bodyB, bodyA, bodyA. getWorldCenter (); bodyB. getWorld (). createJoint (weldJointDef);} console. log ("Hit Target! ");} If (objB. name = "wall" & objA. name = "arrow") {if (objA. isflying) {weldJointDef = newb2Joints. b2WeldJointDef; weldJointDef. initialize (bodyA, bodyB, bodyB. getWorldCenter (); bodyA. getWorld (). createJoint (weldJointDef) ;}} if (objB. name = "arrow") {objB. isflying = false;} if (objA. name = "arrow") {objA. isflying = false ;}} several condition statements are used to handle three conditions: Arrow and arrow collision, arrow and target collision, and arrow and wall collision. Finally, the flying status of the arrow is updated. The main purpose of setting the arrow flight status is to ensure that there is only one arrow in the current world. Some games usually have an energy slot to indicate the intensity when archery or shells occur. Next, add an energy slot to the game. The longer the mouse is, the more powerful Archery is. First, add the following div to the arrow.html file to indicate the energy slot and dynamically update its length in the subsequent JS Code. [Html] <dividdivid = "power_bar"> </div> then modify the mouse message response method in the js file, functiononMouseDown (e) {if (arrowGame. state = arrowGame. STATE_PLAY) {if (allowCreateArrow () {arrowGame. chargeTaskID = setInterval (calculateStrength, 25) ;}} functiononMouseUp (e) {if (arrowGame. state = arrowGame. STATE_PLAY) {// Only one arrow in gaming. if (allowCreateArrow () {createArrow (e. clientX-canvasPosition.x, e. clientY-canvasPositi On. y, arrowGame. power); clearInterval (arrowGame. chargeTaskID); arrowGame. power = 0 ;}}functioncalculatestrength () {arrowGame. power ++; arrowGame. powerBar. style. width = arrowGame. power * 10 + "px"; if (arrowGame. powerBar. style. width = "300px") {clearInterval (arrowGame. chargeTaskID) ;}} when you press the mouse, turn on the timer to increase the length of the Energy slot. When the mouse is up, create an arrow based on the current mouse position and the length of the Energy slot. The effect is as follows: