JBox2D Android рисования динамических тел - PullRequest
2 голосов
/ 26 сентября 2010

Я начал с урока здесь и добавил код для рисования для вида (охватывающий весь экран).Сцена выглядит статичной и не динамичной, хотя я вызываю world.step (,).Как сделать сцену динамичной, и я рисую правильную реализацию, или есть лучший способ (с использованием функций jBox2d)?

Ответы [ 3 ]

2 голосов
/ 17 декабря 2010

Есть ряд проблем с вашим кодом .... но этот ответ, вероятно, слишком поздно, чтобы быть полезным в любом случае.

Во-первых, world.createBody () устарела.Теперь вам нужно явно вызвать world.createDynamicBody () в последней версии Jar Android Box2D, которая у меня есть.

В любом случае ... моя версия выглядит примерно так ... не идеально, но по крайней мере динамично.

package com.box2D;

import java.util.ArrayList;

import org.jbox2d.collision.AABB;
import org.jbox2d.collision.CircleDef;
import org.jbox2d.collision.PolygonDef;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.World;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;

public class PhysicsWorld 
{
    public float timeStep = 1;
    public int iterations = 1;

    private ArrayList<Body> bodies;
    private int count = 0;

    private AABB worldAABB;
    private World world;
    private BodyDef groundBodyDef;
    private PolygonDef boxShapeDef;

    //a paint
    private Paint paint;

    public void create() 
    {
        //create the paint
        paint           = new Paint();
        paint.setColor(0xFFFFFF);

        // Step 1: Create Physics World Boundaries
        worldAABB       = new AABB();
        worldAABB.lowerBound.set(new Vec2((float) -100.0, (float) -100.0));
        worldAABB.upperBound.set(new Vec2((float) 100.0, (float) 300.0));

        // Step 2: Create Physics World with Gravity
        Vec2 gravity    = new Vec2((float) 0.0, (float)10.0);
        boolean doSleep = true;
        world           = new World(worldAABB, gravity, doSleep);
        bodies          = new ArrayList<Body>();

        // Step 3: Create Ground Box
        groundBodyDef   = new BodyDef();
        groundBodyDef.position.set(new Vec2((float) 0.0, (float) 300.0));
        Body groundBody = world.createDynamicBody(groundBodyDef);
        boxShapeDef  = new PolygonDef();
        boxShapeDef.setAsBox((float) 50.0, (float) 10.0);
        groundBody.createShape(boxShapeDef);
    }

    public void addBall() 
    {
        // Create Dynamic Body
        BodyDef bodyDef  = new BodyDef();
        bodyDef.position.set((float)16.0+(count * 10), (float)24.0);        
        Body newBody     = world.createDynamicBody(bodyDef);        

        // Create Shape with Properties
        CircleDef circle = new CircleDef();
        circle.radius    = (float)5;
        circle.density   = (float)1.0;

        // Assign shape to Body
        newBody.createShape(circle);
        newBody.setMassFromShapes();  
        newBody.m_userData = "Circle";
        bodies.add(newBody);

        // Increase Counter
        count += 1;
    }    

    public void addBox() 
    {
        // Create Dynamic Body
        BodyDef bodyDef  = new BodyDef();
        bodyDef.position.set((float)36.0+(count * 10), (float)24.0);
        Body newBody     = world.createDynamicBody(bodyDef);        

        // Create Shape with Properties
        boxShapeDef  = new PolygonDef();
        boxShapeDef.setAsBox((float) 50.0, (float) 10.0);

        // Assign shape to Body
        newBody.createShape(boxShapeDef);
        newBody.setMassFromShapes();  
        newBody.m_userData = "Box";
        bodies.add(newBody);

        // Increase Counter
        count += 1;
    }

    /*
     * 
     * 
     * Physics Update
     */

    private Vec2 position;
    private float angle;

    public void Update(Canvas canvas) 
    {
        // Update Physics World
        world.step(timeStep/5, 1);

        // Print info of latest body
        for (Body i : bodies) 
        {
            position = i.getPosition();
            angle    = i.getAngle(); 

            if(i.m_userData == "Circle")
            canvas.drawCircle(position.x, position.y, 5,paint );

            if(i.m_userData == "Box")
            canvas.drawRect((float)(position.x -5), (float)(position.y - 5), (float)(position.x + 5), (float)(position.y + 5), paint );

            Log.v("Physics Test", "Pos: (" + position.x + ", " + position.y + "), Angle: " + angle);
        }
    }
}
0 голосов
/ 07 февраля 2012
public class PhysicsWorld extends View{


protected static final int GUIUPDATEIDENTIFIER = 0x231;

public int targetFPS = 40;
public float timeStep = 10.0f / targetFPS;
public int iterations = 5;

private Body[] bodies;
private int count = 0;

private AABB worldAABB;
public World world;
private PolygonDef groundShapeDef;

public int World_W,World_H;

private Paint paint;

private float radius=10;


public PhysicsWorld(Context context,int W,int H) {
    super(context);
    World_W=W;
    World_H=H;
    // Step 1: Create Physics World Boundaries
    worldAABB = new AABB();

    Vec2 min = new Vec2(-50, -50);
    Vec2 max = new Vec2(World_W + 50, World_H + 50);

    worldAABB.lowerBound.set(min);
    worldAABB.upperBound.set(max);

    // Step 2: Create Physics World with Gravity
    Vec2 gravity = new Vec2((float) 0.0, (float) -10.0);
    boolean doSleep = true;
    world = new World(worldAABB, gravity, doSleep);


    // Step 3: 
    //Create Ground Box :
    BodyDef bodyDef = new BodyDef();
    bodyDef.position.set(new Vec2((float) 0.0, (float) -10.0));
    Body groundBody = world.createBody(bodyDef);
    groundShapeDef = new PolygonDef();
    groundShapeDef.setAsBox((float) World_W, (float) 10);
    groundBody.createShape(groundShapeDef); 
    // up :
    bodyDef = new BodyDef();
    bodyDef.position.set(new Vec2((float) 0.0, (float) (World_H+10.0) ));
    groundBody = world.createBody(bodyDef);
    groundShapeDef = new PolygonDef();
    groundShapeDef.setAsBox((float) World_W, (float) 10);
    groundBody.createShape(groundShapeDef); 
    // left :
    bodyDef = new BodyDef();
    bodyDef.position.set(new Vec2((float) -10, (float) 0.0 ));
    groundBody = world.createBody(bodyDef);
    groundShapeDef = new PolygonDef();
    groundShapeDef.setAsBox((float)10, (float) World_H);
    groundBody.createShape(groundShapeDef); 
    // right :
    bodyDef = new BodyDef();
    bodyDef.position.set(new Vec2((float) World_W+10, (float) 0.0 ));
    groundBody = world.createBody(bodyDef);
    groundShapeDef = new PolygonDef();
    groundShapeDef.setAsBox((float)10, (float) World_H);
    groundBody.createShape(groundShapeDef); 
    //

    // step 4: initialize 
    bodies=new Body[50];

    // 
    paint=new Paint();
    paint.setStyle(Style.FILL_AND_STROKE);

    paint.setColor(Color.CYAN);
}

public void addBall() {

    // Create Dynamic Body
    BodyDef bodyDef = new BodyDef();
    Random rnd = new Random();
    bodyDef.position.set((float) radius*2+rnd.nextInt( (int)(World_W-radius*4) ), (float)2*radius+ rnd.nextInt( (int)(World_H-radius*4) ));
    bodies[count] = world.createBody(bodyDef);

    // Create Shape with Properties
    CircleDef circle = new CircleDef();
    circle.radius = (float) radius;
    circle.density = (float) 1.0;
    circle.friction = 0.1f; 
    circle.restitution=0.5f;

    // Assign shape to Body
    bodies[count].createShape(circle);
    bodies[count].setMassFromShapes();






    // Increase Counter
    count += 1;        
}
public void addBox() {
    BodyDef bodyDef  = new BodyDef();
    Random rnd = new Random();
    bodyDef.position.set((float)2*count+rnd.nextInt( (int)(World_W-4*count) ), (float)2*count+rnd.nextInt( (int)(World_H-count*4) ));
    bodies[count]     = world.createBody(bodyDef);        

    // Create Shape with Properties
    PolygonDef boxShapeDef  = new PolygonDef();
    boxShapeDef.setAsBox((float) 10.0, (float) 10.0);
    boxShapeDef.density = 1.0f;     // A density of 0 will create a fixed Body that doesn't move
    boxShapeDef.friction = 0.1f;    // How much friction
    boxShapeDef.restitution = 0.5f; // How bouncy is this Shape?

    // Assign shape to Body
    bodies[count].createShape(boxShapeDef);
    bodies[count].setMassFromShapes();  
    bodies[count].m_userData = "Box";

    count += 1;
}


public void update() {  
world.step(timeStep/5, 1);
    postInvalidate(); 
 }  
protected void onDraw(Canvas canvas) {
    for(int j = 0;j<count;j++)
    {
        canvas.drawRect((float)(bodies[j].getPosition().x -10), (float)(bodies[j].getPosition().y - 10), (float)(bodies[j].getPosition().x+ 10), (float)(bodies[j].getPosition().y + 10), paint );
        canvas.drawCircle(bodies[j].getPosition().x,World_H- bodies[j].getPosition().y, radius, paint);
    }
}
0 голосов
/ 25 декабря 2011

В ответ на эту часть вашего вопроса:

"мой рисунок - правильная реализация или есть лучший способ"

Это с веб-сайта Box2D:

  • Какие единицы измерения использует Box2D?

Box2D настроен на метры-килограммы-секунды (МКС).Ваши движущиеся объекты должны быть на расстоянии от 0,1 до 10 метров.Не используйте пиксели как единицы измерения!Вы получите джиттер-симуляцию.

  • Как преобразовать пиксели в метры?

Предположим, у вас есть спрайт для символа размером 100x100пиксели.Вы решаете использовать коэффициент масштабирования 0,01.Это сделает коробку физики персонажа 1м х 1м.Итак, сделайте коробку с физикой 1x1.Теперь предположим, что персонаж начинается с пиксельной координаты (345 679).Поэтому поместите блок физики в (3.45,6.79).Теперь смоделируйте физику мира.Предположим, что поле физики персонажей перемещается в (2.31,4.98), поэтому переместите спрайт персонажа в пиксельные координаты (231,498).Теперь единственной сложной задачей является выбор коэффициента масштабирования.Это действительно зависит от вашей игры.Вы должны стараться, чтобы ваши движущиеся объекты находились в диапазоне от 0,1 до 10 метров, причем 1 метр - это самое приятное место.

...

  • Какие самые большие ошибки были допущены новыми пользователями?

Использование пикселей для длины вместо метров,

...

Источник: http://code.google.com/p/box2d/wiki/FAQ

...