Box2D physical engine simulates bomb explosion effect, box2d physical engine bomb

Source: Internet
Author: User

Box2D physical engine simulates bomb explosion effect, box2d physical engine bomb

Let's simulate the bomb effect today. So the question comes: "Why do we need to imitate the effect of such violence? In a few days, has Yorhom become a tough character ?"

In fact, everyone who has played Angry Birds should have been familiar with this effect, because according to unofficial reports, the second amazing bird-the black bird stunt is self-defeating. Question 2: "Which is the first bird ?" According to Yorhom, I personally tested that the big red bird should be the most amazing, but does not seem to have any special effects? A superficial game like Angry Birds, Y, I am the best at it. I will write a special introduction to this game in the future. The two birds are as follows:


If I had asked question 2, question 3 came: "How can we achieve this ?" This problem is not perfunctory, so I will introduce how to use Box2D to achieve this effect in the next article.

Before learning this chapter, you need to understand Box2D, a very practical and famous physical engine. Based on my personal learning experience, I recommend uncle Bin Laden's blog. The Box2D topic Address of His blog is as follows:

Http://www.ladeng6666.com/blog/category/box2d/


I. Bomb effect principle

When achieving this effect, I came up with two solutions.

Solution 1:When a bomb's rigid body explodes, the bomb's rigid body is used as the starting point to spray a small rigid body around it. These Xiaogang experiences are sprayed to a nearby rigid body and they apply force to nearby rigid bodies, then, the force is the reason why the motion of the object changes (from high school physics to compulsory 1), and then the explosion effect can be completed. This method is relatively simple, but I think it is a bit dirty way. For example, if my earphones are labeled with R, they must be on the right and those marked with L must be on the left. How can this problem be met? Of course, interested friends can try this method on their own ~

Solution 2:First, we can find another rigid body around the bomb's rigid body, and then apply a force to them. We can achieve the explosive effect only by controlling the force. Hmm ~ Good. It seems that this method is more beautiful ~

The obvious difference between the two solutions is that solution 2 is a little less than solution 2. What does this mean? I think everyone should have done at least six years of math problems. According to my experience over the past 9.5 years, the less words a question will be, the more difficult it will be because it provides less information. Therefore, although solution 2 has a relatively better effect, it may be much more complicated to implement.

Solution 2 is hard to implement because we don't know how to find the surrounding rigid bodies. To this end, I have covered all the features in Box2D that I have learned and found that I have never used a feature that I have heard of before-ray projection may be useful. However, Xin has a lot of related information on the Internet, so I learned the b2RayCastInput and b2RayCastOutput classes.

The above two classes are very important, so you must first understand these two classes. The tutorial is http://ohcoder.com/blog/2012/12/10/ray-casting/. the tutorial uses box2d C ++, the usage is the same.

What are the functions of b2RayCastInput and b2RayCastOutput classes? From the tutorial provided above, we can see that the instances of these two classes are generally passed into the b2Fixture RayCast function as parameters. This function is used to check whether a ray is at the intersection of a rigid body. So we only use the bomb's rigid position as the starting point, and then inject rays to the surrounding area. Then, the rigid body in the circular world will be used to determine whether the circular rigid body is intersecting with the rays. If yes, a force will be applied to the current rigid body. In this way, the principle of bomb effect is basically eliminated.


2. Build a physical world

First, create the most basic world. Therefore, add the following code to index.html:

<!DOCTYPE html>Html code is not the focus, but Main. js:

window.addEventListener("load", main, false);var b2Vec2 = Box2D.Common.Math.b2Vec2, b2AABB = Box2D.Collision.b2AABB, b2BodyDef = Box2D.Dynamics.b2BodyDef, b2Body = Box2D.Dynamics.b2Body, b2FixtureDef = Box2D.Dynamics.b2FixtureDef, b2Fixture = Box2D.Dynamics.b2Fixture, b2World = Box2D.Dynamics.b2World, b2MassData = Box2D.Collision.Shapes.b2MassData, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, b2DebugDraw = Box2D.Dynamics.b2DebugDraw, b2MouseJointDef =  Box2D.Dynamics.Joints.b2MouseJointDef, b2RayCastInput = Box2D.Collision.b2RayCastInput, b2RayCastOutput = Box2D.Collision.b2RayCastOutput;var world, fixDef, bodyDef;var bomb = null;var timer = 0;function main () {world = new b2World(new b2Vec2(0, 9.8), true);fixDef = new b2FixtureDef();fixDef.density = 1.0;fixDef.friction = 0.5;fixDef.restitution = 0.2;bodyDef = new b2BodyDef();createGround();createBlocks();createBomb();createDebugDraw();setInterval(update, 1000 / 60);}function createGround () {fixDef.shape = new b2PolygonShape();fixDef.shape.SetAsBox(20, 1);bodyDef.type = b2Body.b2_staticBody;bodyDef.position.Set(10, 13);world.CreateBody(bodyDef).CreateFixture(fixDef);}function createBlocks () {var list = [{width : 120, height : 30, x : 140, y : 330},{width : 20, height : 100, x : 50, y : 200},{width : 20, height : 100, x : 230, y : 200},{width : 120, height : 20, x : 140, y : 80},{width : 120, height : 30, x : 440, y : 330},{width : 20, height : 100, x : 350, y : 200},{width : 20, height : 100, x : 530, y : 200},{width : 120, height : 20, x : 440, y : 80}];for (var i = 0; i < list.length; i++) {var data = list[i];fixDef.shape = new b2PolygonShape();fixDef.shape.SetAsBox(data.width / 30, data.height / 30);bodyDef.type = b2Body.b2_dynamicBody;bodyDef.position.Set(data.x / 30, data.y / 30);world.CreateBody(bodyDef).CreateFixture(fixDef);}}function createBomb () {fixDef.shape = new b2CircleShape(0.5);bodyDef.type = b2Body.b2_dynamicBody;bodyDef.position.Set(9.7, 1);bomb = world.CreateBody(bodyDef);bomb.userData = "iambomb";bomb.CreateFixture(fixDef);}function createDebugDraw () {var debugDraw = new b2DebugDraw();debugDraw.SetSprite(document.getElementById("mycanvas").getContext("2d"));debugDraw.SetDrawScale(30.0);debugDraw.SetFillAlpha(0.5);debugDraw.SetLineThickness(1.0);debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit | b2DebugDraw.e_controllerBit | b2DebugDraw.e_pairBit);world.SetDebugDraw(debugDraw);}function update () {world.Step(1 / 60, 10, 10);world.DrawDebugData();world.ClearForces();if (timer++ == 100) {detonated();}}
It is worth noting that the timer variable is used to timing the explosion. In the update function, we call the dentonated function. I will not publish the code of this function for the moment. This function is used to detonate the bomb.
Run the code to get the physical world:

The ball in the figure is actually a bomb.


3. detonate a bomb

The dentonated function is mentioned above. Here, we will learn the code, which is also the core part of this development.

function detonated () {var position = bomb.GetWorldCenter();var range = 3;for (var i = 0; i <= 100; i++) {var angle = 360 / 100 * i;var input = new b2RayCastInput();input.p1 = position;input.p2.Set(position.x + range * Math.cos(angle), position.y + range * Math.sin(angle));input.maxFraction = 1;var output = new b2RayCastOutput();for (var currentBody = world.GetBodyList(); currentBody; currentBody = currentBody.GetNext()) {if (currentBody.userData == bomb.userData) {continue;}var fix = currentBody.GetFixtureList();if (!fix) {continue;}var isHit = fix.RayCast(output, input);if (isHit) {var p1 = input.p1.Copy();var p2 = input.p2.Copy();p2.Subtract(p1);p2.Multiply(output.fraction);p1.Add(p2);var hitPoint = p1.Copy();hitPoint.Subtract(position);currentBody.ApplyForce(new b2Vec2(hitPoint.x * (1 - output.fraction) * 300, hitPoint.y * (1 - output.fraction) * 300), hitPoint);}}}world.DestroyBody(bomb);}
In this function, I first use GetWorldCenter to get the location of the bomb's rigid body, and then set an explosion range variable range. Then, the cycle starts to create rays for the surrounding area. Here I set a total of 100 rays to be sprayed, so the angle between each Ray is 3.6 degrees. After knowing the angle, we can calculate the end point of each ray vector and pass the end point and start point into b2RayCastInput.

After preparing a series of rays, we will begin to cycle the rigid bodies in the world. Then, obtain the circular rigid body (a b2Fixture object), and call the rigid RayCast to determine whether the created Ray is in conflict with the rigid body.

if (isHit) {var p1 = input.p1.Copy();var p2 = input.p2.Copy();p2.Subtract(p1);p2.Multiply(output.fraction);p1.Add(p2);var hitPoint = p1.Copy();hitPoint.Subtract(position);currentBody.ApplyForce(new b2Vec2(hitPoint.x * (1 - output.fraction) * 300, hitPoint.y * (1 - output.fraction) * 300), hitPoint);}
The preceding code is used to calculate the vector corresponding to the position where the ray and the rigid body intersect, and apply a force to the position. How can we calculate the vector corresponding to the intersection of rays and rigid bodies? Let's take a look at the figure:

Now, let's mobilize the knowledge of the vector in the four compulsory high school mathematics. So the mathematical problem arises: known vectorsOp1,Op2Coordinates, and p1, p2, and p3 are all in line,P1p3= NP1p2, PleaseOp3.

To solve this problem, you can use the knowledge such as the ratio and point, add or subtract a vector, and the number multiplication operation can also solve the problem. Here are my answers:


Deploy p1 (x1, y1), p2 (x2, y2)

Op3=Op1+P1p3= NP1p2+Op1= N (x2-x1, y2-y1) + (x1, y1) = (nx2-nx1 + x1, ny2-ny1 + y1)


This is a mathematical method, and it is changed to the program code:

var p1 = input.p1.Copy();var p2 = input.p2.Copy();p2.Subtract(p1);p2.Multiply(output.fraction);p1.Add(p2);var hitPoint = p1.Copy();
The output. fraction here is equivalent to the n given in the above question. Copy, Substact, Add, and Multiply are used to Copy the current vector, vector subtraction, vector addition, and vector multiplication.

After calculating the collision position, we apply a force to the rigid body using ApplyForce, and then the rigid body is like the impact of the airflow produced by an explosion ~

If a bomb has exploded, it must not exist. Therefore, after applying the force to the surrounding rigid body, use DestroyBody to destroy the bomb's rigid body ~


Run the code and get:

Online Test address:Http://wyh.wjjsoft.com/demo/box2d_bomb/

Source code:Http://wyh.wjjsoft.com/downloads/box2d_bomb.zip


This chapter is over. You are welcome to leave a message ~

----------------------------------------------------------------

You are welcome to repost my article.

Reprinted Please note:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.