JavaFX and JBox2D
JAVAFX AND JBOX2D (GAME ENGINE)
Recently i was searching for the best 2d game engine API for java and i came across this blog talking about jbox2d ,I downloaded the api jbox2d .To work around pixel conversion between jbox2d and javafx i decided to use the utility class from this project.Utility Class Tweaking
This my utility class.
public class Utils {
//Create a JBox2D world.
public static final World world = new World(new Vec2(0.0f, -10.0f));
//Screen width and height
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
//Convert a JBox2D x coordinate to a JavaFX pixel x coordinate
public static float toPixelPosX(float posX) {
float x = WIDTH*posX / 100.0f;
return x;
}
//Convert a JavaFX pixel x coordinate to a JBox2D x coordinate
public static float toPosX(float posX) {
float x = (posX*100.0f*1.0f)/WIDTH;
return x;
}
//Convert a JBox2D y coordinate to a JavaFX pixel y coordinate
public static float toPixelPosY(float posY) {
float y = HEIGHT - (1.0f*HEIGHT) * posY / 100.0f;
return y;
}
//Convert a JavaFX pixel y coordinate to a JBox2D y coordinate
public static float toPosY(float posY) {
float y = 100.0f - ((posY * 100*1.0f) /HEIGHT) ;
return y;
}
//Convert a JBox2D width to pixel width
public static float toPixelWidth(float width) {
return WIDTH*width / 100.0f;
}
//Convert a JBox2D height to pixel height
public static float toPixelHeight(float height) {
return HEIGHT*height/100.0f;
}
}
The walls
public ImageView walls(int x,int y,int width,int height){
ImageView wall=new ImageView("file:wall.png");
wall.setFitWidth(Utils.toPixelWidth(width));
wall.setFitHeight(Utils.toPixelHeight(height));
wall.setLayoutX(Utils.toPixelPosX(x));
wall.setLayoutY(Utils.toPixelPosY(y));
BodyDef bd = new BodyDef();
bd.position.set(x,y);
PolygonShape ps = new PolygonShape();
ps.setAsBox(width,height);
FixtureDef fd = new FixtureDef();
fd.shape = ps;
Body body = Utils.world.createBody(bd);
body.createFixture(fd);
wall.setUserData(body);
return wall;
}
The Tennispublic ImageView ball(int x,int y){
ImageView ball=new ImageView("file:tennis.png");
ball.setSmooth(true);
ball.setCache(true);
ball.setLayoutX(Utils.toPixelPosX(x));
ball.setLayoutY(Utils.toPixelPosY(y));
BodyDef bd = new BodyDef();
bd.type = BodyType.DYNAMIC;
bd.position.set(x,y);
CircleShape cs = new CircleShape();
cs.m_radius = 20*0.1f;
FixtureDef fd = new FixtureDef();
fd.shape = cs;
fd.density = 0.9f;
fd.friction = 0.3f;
fd.restitution = 0.6f;
Body body = Utils.world.createBody(bd);
body.createFixture(fd);
ball.setUserData(body);
return ball;
}
Bounce Sound
public void onContact(){
AudioClip audio=new AudioClip("file:tennis_bounce.mp3");
Utils.world.setContactListener(new ContactListener(){
@Override
public void beginContact(Contact cntct) {
//produce sound if in contact with the walls
if(cntct.m_fixtureA.m_shape.m_type==ShapeType.POLYGON){
audio.play();
}
}
@Override
public void endContact(Contact cntct) {
}
@Override
public void preSolve(Contact cntct, Manifold mnfld) {
}
@Override
public void postSolve(Contact cntct, ContactImpulse ci) {
}
});
}
Timeline
ImageView c []=new ImageView[BALL_COUNT];
for(int i=0;i<BALL_COUNT;i++){
c[i]=ball(r.nextInt(90)+5,r.nextInt(400)+100);
}
Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
Duration duration = Duration.seconds(1.0/60.0);
EventHandler<ActionEvent> ae = new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
Utils.world.step(1.0f/60.0f, 3, 8);
for(int i=0;i<BALL_COUNT;i++) {
Body body = (Body)c[i].getUserData();
float xpos = Utils.toPixelPosX(body.getPosition().x);
float ypos = Utils.toPixelPosY(body.getPosition().y);
c[i].setLayoutX(xpos);
c[i].setLayoutY(ypos);
onContact();
}
}
};
KeyFrame frame = new KeyFrame(duration, ae, null,null);
timeline.getKeyFrames().add(frame);
timeline.playFromStart();
ScreenShot
Video Demo
The balls don't bounce that well off the floor or the right hand wall. For the floor they sink in a little and for the right hand wall they clearly bounce before making contact. Have you found a way to fix that? They do seem to bounce realistically of the left hand side wall though. I've noticed this from watching the video.
ReplyDelete