Краткое руководство по началу работы с 2D физики на Android.

2D физики может значительно обогатить игры, реалистичное поведение объектов, таких как полигоны (ящики, прямоугольники, полигоны) и круги в мире установку. Двигатель рассчитывает столкновений, углы, силы и импульсы на основе заданных пользователем параметров, таких как тяжесть, плотность, трение, упругость и т.д.

Движок

Есть пара хороших открытым исходным кодом 2D физики движков , в первую очередь Box2D и Chipmunk . Для этого проекта мы будем использовать Box2D из-за его более высокой производительности (см. рисунок, подробный сравнения и тесты скорости ). На следующем рисунке из критериев сделан на ноутбуке XO:

b_150_100_16777215_00_images_stories_java_articles_2dphys_box2d_graph.png

 

 

К счастью, есть порт Java из библиотеки Box2D называется JBox2D (выпущен под лицензией Zlib). JBox2D использует обработку библиотека для отображения вещи, которые мы не собираемся использовать на Android: D.

JBox2D

Библиотека поставляется 154kb файл jbox2d-2.0.1-библиотека-only.jar от их SVN. Этот файл включает в себя всю функциональность Box2D и очень легко реализовать в пользовательских проектах Java.

Руководство и Docs

Импорт в библиотеку

Давайте импортировать JAR-файла в наших текущих проектов в Eclipse.

  1. Скачать jbox2d-2.0.1-библиотека-only.jar и сохранить его в любом месте, jbox2d.jar
  2. В Eclipse
    1. Создайте папку / Библиотека /
    2. Щелкните правой кнопкой мыши на / Библиотека выберите Импорт
    3. Выберите Общие / File System
    4. Выберите каталог jbox2d.jar
    5. Импорт файла jbox2d.jar
    6. Щелкните правой кнопкой мыши на проекте и выберите "Свойства"
    7. Нажмите на кнопку "Путь Java Build" и выберите "Библиотеки" на вкладке
    8. Нажмите на кнопку "Add JAR-файлы ..." и выберите файл jbox2d.jar

b_150_100_16777215_00_images_stories_java_articles_2dphys_box2d_box2d_eclipse1.png Вот и все, мы можем использовать Box2D на сегодняшний день и имеет доступ к справочной библиотеки в Eclipse, как показано на рисунке справа.

Физические Hello World

Давайте напишем быстро привет App World, который в основном соответствует Руководство пользователя Box2D , выполнив следующие действия:

  • Инициализация нового мира
  • Добавить земле окне
  • Создание некоторых динамических органов (шары)
  • Моделирование мира

Этот код не обращая что-либо на экране, пока нет. Это только для расчета физического поведения и выводит сообщение журнала о последних добавленный элемент (положение и угол).

Следующий код представляет собой класс, который обрабатывает только физики. Он может быть реализован любой деятельности, а также обновление () функция должна вызываться периодически.

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.util.Log;

public class PhysicsWorld {
 public int targetFPS = 40;
 public int timeStep = (1000 / targetFPS);
 public int iterations = 5;

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

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

 public void create() {
 // 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) 100.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);

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

 public void addBall() {
 // Create Dynamic Body
 BodyDef bodyDef = new BodyDef();
 bodyDef.position.set((float) 6.0+count, (float) 24.0);
 bodies[count] = world.createBody(bodyDef);

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

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

 // Increase Counter
 count += 1;
 }

 public void update() {
 // Update Physics World
 world.step(timeStep, iterations);

 // Print info of latest body
 if (count > 0) {
 Vec2 position = bodies[count].getPosition();
 float angle = bodies[count].getAngle();
 Log.v("Physics Test", "Pos: (" + position.x + ", " + position.y + "), Angle: " + angle);
 }
 }
}

Используя его в активности

Он реализации PhysicsWorld класса в деятельности так просто, как следующий план код:

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

public class Physics extends Activity {
 PhysicsWorld mWorld;
 private Handler mHandler;

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 mWorld = new PhysicsWorld();
 mWorld.create()

 // Add 50 Balls
 for (int i=0; i<50; i++) {
 mWorld.addBall();
 }

 // Start Regular Update
 mHandler = new Handler();
 mHandler.post(update));
 }

 @Override
 protected void onPause() {
 super.onPause();
 mHandler.removeCallbacks(update);
 }

 private Runnable update = new Runnable() {
 public void run() {
 mWorld.update();
 mHandler.postDelayed(update, (long) (mWorld.timeStep*1000));
 }
 };
}

Вот и все, поздравляю, вы теперь готовы к использованию Box2D во всех отношениях вы хотите!

Рисование элементов на экране

Рисование элементов является деликатной задачи, как производительность кода имеет большое значение, и это может ускорить или замедлить их очень! Android документы на 2D Графика предложить android.graphics.drawable и android.view.animation пакеты, где вы найдете общие классы, используемые для рисования и анимации в двух измерениях.

Я напишу об этом с примерами кода для рисования элемента в другой раз, хотя она должна быть не очень трудно начать работу с вводимого коэффициента, так как есть много примеров с исходным кодом.

Важно учитывать две вещи в виду:

  • Ось ориентации: координаты (0, 0) с G1, как правило, в верхнем левом углу экрана, в то время как (0, 0) в Box2D является левом нижнем углу экрана.
  • Другое дело, являются размеры: Box2D работает с размерами от 0,1 до 10 раз типичные размеры Земли, таких как плотность, трение, гравитация, .... Внутри двигателя с использованием метров и нам нужно будет конвертировать их в пикселях. Если мы говорим, 1 метр должна быть 10 пикселей, что функция может выглядеть следующим образом:

public Vec2 toScreen(Vec2 pos) {
 pos.x = pos.x*10;
 pos.y = 480 - (pos.y*10);
 return pos;
}