Use the physical engine jbox2d in javafx

Source: Internet
Author: User
Tags gety

On the weekend, I suddenly thought that a physical engine is needed in the game engine. So I studied jbox2d (why jbox2d is better because I think jbox2d is more portable, whether other physical engines are used ).

As I developed the javafx game engine wjfxgame, the example of the physical engine in it is not easy to learn. So I wrote another one.

In fact, it is very simple. The Physical Operations of jbox2d are separated from the graphic rendering. We only need to process the graphic rendering part.

Example address: Click

Here we use the latest version of jbox2d downloaded from the official website, as shown in:


First, we create a wbody class that combines the rigid body in jbox2d with the graphics in javafx.

import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Paint;import org.jbox2d.dynamics.Body;public abstract class WBody{    protected Body mBody;    protected Paint mColor;    protected final static int RATE = 30;    protected double x,y,width,height;public Body getBody() {return mBody;}public void setBody(Body mBody) {this.mBody = mBody;}public Paint getColor() {return mColor;}public void setColor(Paint mColor) {this.mColor = mColor;}public abstract void draw(GraphicsContext gc);public abstract void update();public double getX() {return x;}public void setX(double x) {this.x = x;}public double getY() {return y;}public void setY(double y) {this.y = y;}public void setLocation(double x,double y){setX(x);setY(y);}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}}

This class contains a rigid body and a set of attributes such as position and size. For the sake of simplicity, common attributes are used here, and binding attributes are not used (in wjfxgame, all attributes that can be bound to javafx are used ).

Rate is the ratio of the screen to the world. Generally, the larger the ratio is, because the gravity speed is the same, the screen will see faster motion.

Then we create a circle wbody called wcirclebody.

import org.jbox2d.dynamics.Body;import javafx.beans.property.DoubleProperty;import javafx.beans.property.SimpleDoubleProperty;import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Paint;public class WCircleBody extends WBody {protected DoubleProperty radius;public WCircleBody(Body body, double radius, Paint color){this.mBody = body;this.radius = new SimpleDoubleProperty(radius);this.mColor = color;}@Overridepublic void draw(GraphicsContext gc) {gc.save();gc.setFill(mColor);gc.fillOval(getX(), getY(),  getRaidus() * 2, getRaidus() * 2);gc.restore();}@Overridepublic void update() {setX(mBody.getPosition().x * RATE - getRaidus());setY(mBody.getPosition().y * RATE - getRaidus());}public double getWidth(){return 2 * getRaidus();}public double getHeight(){return 2 * getRaidus();}public DoubleProperty radiusProperty(){return radius;}public double getRaidus(){return radius.get();}public void setRadius(double radius){this.radius.set(radius);}}

This is inherited from wbody. In the draw method, circles are drawn based on X, Y, and radius. In the update method, set the image position of the circle to the position of the body rigid body. Since the position in the rigid body is center-centered, We need to calculate the position in the upper left corner by ourselves.

Then create a rectangle wbody called wboxbody.

import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Paint;import org.jbox2d.dynamics.Body;public class WBoxBody extends WBody {public WBoxBody(double width,double height, Body body, Paint paint) {this.mBody = body;this.mColor = paint;this.width = width;this.height = height;}@Overridepublic void draw(GraphicsContext gc) {gc.save();gc.setFill(mColor);gc.fillRect(getX(), getY(), getWidth(),getHeight());gc.restore();}@Overridepublic void update() {        setX(mBody.getPosition().x * RATE - getWidth() / 2);        setY(mBody.getPosition().y * RATE - getHeight() / 2);}}

Similarly, wboxbody is similar to wcirclebody. I will not explain it too much.

Next, we will create a new class that inherits the canvas and is responsible for all the painting and update operations.

Import Java. util. list; import Java. util. concurrent. copyonwritearraylist; import javafx. animation. keyframe; import javafx. animation. timeline; import javafx. event. actionevent; import javafx. event. eventhandler; import javafx. scene. canvas. canvas; import javafx. scene. canvas. graphicscontext; import javafx. scene. paint. color; import javafx. util. duration; import Org. jbox2d. collision. AABB; import Org. jbox2d. collision. s Hapes. circleshape; import Org. jbox2d. collision. shapes. polygonshape; import Org. jbox2d. common. vec2; import Org. jbox2d. dynamics. body; import Org. jbox2d. dynamics. bodydef; import Org. jbox2d. dynamics. bodytype; import Org. jbox2d. dynamics. fixturedef; import Org. jbox2d. dynamics. world; import Org. wing. jfx. physics. test. body. wbody; import Org. wing. jfx. physics. test. body. wboxbody; import Org. wing. jfx. physics. test. body. W Circlebody; public class canvasscreen extends canvas {private graphicscontext GC; private timeline mtimeline; private double duration = 10; Private Static final int rate = 10; private world; private AABB; private bodydef BD; private list <wbody> bodys = new copyonwritearraylist <> (); Public canvasscreen (double width, double height) {super (width, height ); vec2 gravity = new vec2 (-1.0f, 10.0f); World = New World (gravity); vec2 MINV = new vec2 (-1000000f,-1000000f); vec2 maxv = new vec2 (1000000f, 1000000f); AABB = new AABB (); AABB. lowerbound. set (MINV); AABB. upperbound. set (maxv); World. queryaabb (null, AABB); BD = new bodydef (); GC = getgraphicscontext2d (); Init (); initobjects ();} public void Init () {mtimeline = new timeline (); mtimeline. setcyclecount (timeline. indefinite); keyframe frame = new keyframe (duration. mill Is (duration), new eventhandler <actionevent> () {@ overridepublic void handle (actionevent event) {draw (GC); Update () ;}}); mtimeline. getkeyframes (). add (FRAME); mtimeline. play ();} public void initobjects () {createpolygon (10,500, (INT) getwidth ()-10*2, 10, 0.3f, 0.6f, true); createpolygon (10, 10, 10,500, 0.3f, 0.6f, true); createpolygon (INT) getwidth ()-10*2, 10, 10,500, 0.3f, 0.6f, true); float rest Itution [] = new float [] {0.9f, 0.9f, 0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f, 0.4f, 0.9f, 0.9f, 0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f, 0.4f, 0.9f, 0.9f, 0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f, 0.4f, 0.9f, 0.9f, 0.9f ,}; for (INT I = 0; I <restitution. length; I ++) {createcircle (80 + I * 20, 5 * I, 15, 0.3f, restitution [I], false);} public void draw (graphicscontext GC) {GC. clearrect (0, 0, Ge Twidth (), getheight (); GC. setfill (color. black); GC. fillrect (0, 0, getwidth (), getheight (); For (wbody mbody: bodys) {mbody. draw (GC) ;}} public void Update () {for (wbody body: bodys) {body. update ();} world. STEP (1.0f/601_f, 8, 3);}/*** create a rectangle */Public void createpolygon (float X, float y, float W, float H, float friction, float restitution, Boolean isstatic) {// create a polygonshape shape with a polygon Skin = new polygonsh APE (); shape. setasbox (W/2/rate, H/2/rate); fixturedef FD = new fixturedef (); FD. shape = shape; FD. density = 1.0f; // set the density FD. friction = friction; // sets the friction FD. restitution = restitution; // set the restoration force of a polygon. // set the initial coordinate of the rigid body. BD. type = isstatic? Bodytype. static: bodytype. dynamic; BD. position. set (x + W/2)/rate, (Y + H/2)/rate); // create Object Body = World. createbody (BD); // create an object in the physical world // This method changes // body. createshape (PDEF); // Add the skin body to the body. createfixture (FD); wboxbody boxbody = new wboxbody (W, H, body, color. white); boxbody. setlocation (x, y); bodys. add (boxbody);}/*** create a circle */Public void createcircle (float X, float y, float R, float friction, Flo At restitution, Boolean isstatic) {circleshape shape = new circleshape (); shape. m_radius = r/rate; fixturedef FD = new fixturedef (); FD. shape = shape; FD. density = 1.0f; FD. friction = friction; FD. restitution = restitution; // create a rigid body BD. type = isstatic? Bodytype. static: bodytype. dynamic; BD. position. set (x + r)/rate, (Y + r)/rate); // create a bodybody body = World. createbody (BD); body. createfixture (FD); wcirclebody circlebody = new wcirclebody (body, R, color. red); circlebody. setlocation (x, y); bodys. add (circlebody );}}

In this canvasscreen, we mainly perform the following operations.

1. Created the jbox2d world

2. Create a timeline, add a keyframe, and simulate the game update operation through an infinite loop.

3. Use createpolygon and createcircle to create the body and initialize the wbody element. Note that the position of the body is the center position, and the object we draw is the position on the top left. You need to handle it yourself. There is also the proportional rate between the screen and the world, which is processed during position.

4. In keyframe, draw the wbody list and update the wbody list in update.

5. Update the world. In update, we update the physical changes in the world of the jbox. Without world. Step, all physical operations cannot be performed.


Next is our main class.

Import javafx. application. application; import javafx. scene. group; import javafx. scene. scene; import javafx. stage. stage; public class mainclass extends application {Private Static final int width = 800; Private Static final int Height = 600; @ overridepublic void start (stage primarystage) {canvasscreen mcanvas = new canvasscreen (width, height); group root = new group (); root. getchildren (). add (mcanvas); scene = new scene (root, width, height); primarystage. settitle ("using jbox2d in javafx"); primarystage. setscene (scene); primarystage. show () ;}public static void main (string [] ARGs) {launch (ARGs );}}

You can check the running effect.

Click

I am using JDK 7. You can see the tips for downloading.

:

Reprinted please indicate the source:
HTTP:. // blog.csdn.net/ml3947

In addition, my personal blog address:
Http://www.wjfxgame.com




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.