从零开始box2d(2) 物体的运动

一步步来 从简单到困难 就像王健林说的 先定一个小目标 一步步来 哈哈.

上一篇说了世界的创建 下面 模拟物体的运动

首先需要介绍新的东西

上一片介绍了AABB 包围盒 Vec2 二维向量 和world 世界.

在物理世界里面 还需要有物体 那么就是 Body .
body (刚体 )创建的时候不能通过直接从构造器创建,必须通过World类对象的.createBody(BodyDef bd) 方法创建. 然后调用其createShape(ShapeDef sd)方法创建刚体的 几何图形

BodyDef , 其对象用于存储刚体的一些描述信息,主要是在创建刚体的时候调用的.
例如: public boolean isSleeping 表示刚体当前是否处于休眠

ShapeDef (形状描述) , 其对象主要用来存储形状的描述信息 该类有两个子类
CircleDef,(圆形描述) ,PolygonDef(多边形描述) . 形状参数有 密度,摩擦系数,弹性系数.

**

下面实例 效果

这里写图片描述

下面是代码

package com.cp;

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

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class MySurfaceView extends SurfaceView implements Callback, Runnable {
    private Thread th;
    private SurfaceHolder sfh;
    private Canvas canvas;
    private Paint paint;
    private boolean flag;
    // ---添加物理世界----->>
    final float RATE = 30;
    World world;
    AABB aabb;
    Vec2 gravity;
    float timeStep = 1f / 60f;
    final int iterations = 10;
    // ----在物理世界中添加一个多边形--->>
    Body body;// 声明物体对象
    float polygonX = 40;// 声明矩形X坐标
    float polygonY = 10;// 声明矩形Y坐标
    float polygonWidth = 50;// 声明矩形宽度
    float polygonHeight = 50;// 声明矩形高度
    // ----在物理世界中添加一个多边形--->>
    Body body2;// 声明物体对象
    float polygonX2 = 5;// 声明矩形X坐标
    float polygonY2 = 400;// 声明矩形Y坐标
    float polygonWidth2 = 50;// 声明矩形宽度
    float polygonHeight2 = 50;// 声明矩形高度
    // ----在物理世界中添加一个多边形--->>
    Body body3;// 声明物体对象
    float polygonX3 = 5;// 声明矩形X坐标
    float polygonY3 = 700;// 声明矩形Y坐标
    float polygonWidth3 = 800;// 声明矩形宽度
    float polygonHeight3 = 2;// 声明矩形高度

    public MySurfaceView(Context context) {
        super(context);
        this.setKeepScreenOn(true);
        sfh = this.getHolder();
        sfh.addCallback(this);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Style.STROKE);
        setFocusable(true);
        // ---添加物理世界-->>
        aabb = new AABB();
        gravity = new Vec2(0f, 10f);
        aabb.lowerBound.set(-100f, -100f);// 世界左上角
        aabb.upperBound.set(400f, 400f);// 世界右下角
        world = new World(aabb, gravity, true);

        // ----在物理世界中添加一个多边形--->> 动态的
        body = createPolygon(polygonX, polygonY, polygonWidth, polygonHeight,
                false);// 创建一个多边形
        // ----在物理世界中添加一个多边形--->>  静态的
        body2 = createPolygon(polygonX2, polygonY2, polygonWidth2,
                polygonHeight2, true);// 创建一个多边形
        // ----在物理世界中添加一个多边形--->> 这个是地平线
        body3 = createPolygon(polygonX3, polygonY3, polygonWidth3,
                polygonHeight3, true);// 创建一个多边形
    }

    public void surfaceCreated(SurfaceHolder holder) {
        flag = true;
        th = new Thread(this);
        th.start();
    }

    public Body createPolygon(float x, float y, float width, float height,
            boolean isStatic) {
        // ---创建多边形皮肤 多边形描述
        PolygonDef pd = new PolygonDef(); // 实例一个多边形的皮肤
        if (isStatic) {
            pd.density = 0; // 设置多边形为静态
        } else {
            pd.density = 1; // 设置多边形的质量
        }
        pd.friction = 0.8f; // 设置多边形的摩擦力
        pd.restitution = 0.3f; // 设置多边形的恢复力
        // 设置多边形快捷成盒子(矩形)
        // 两个参数为多边形宽高的一半
        pd.setAsBox(width / 2 / RATE, height / 2 / RATE);
        // ---创建刚体
        BodyDef bd = new BodyDef(); // 实例一个刚体对象
        bd.position.set((x + width / 2) / RATE, (y + height / 2) / RATE);// 设置刚体的坐标
        // ---创建Body(物体)
        Body body = world.createBody(bd); // 物理世界创建物体
        body.createShape(pd); // 为Body添加皮肤
        body.setMassFromShapes(); // 将整个物体计算打包
        return body;
    }

    public void myDraw() {
        try {
            canvas = sfh.lockCanvas();
            if (canvas != null) {
                canvas.drawColor(Color.WHITE);
                canvas.drawRect(polygonX, polygonY, polygonX + polygonWidth,
                        polygonY + polygonHeight, paint);// 绘画矩形
                canvas.drawRect(polygonX2, polygonY2,
                        polygonX2 + polygonWidth2, polygonY2 + polygonHeight2,
                        paint);// 绘画矩形
                canvas.drawRect(polygonX3, polygonY3,
                        polygonX3 + polygonWidth3, polygonY3 + polygonHeight3,
                        paint);// 绘画矩形
            }
        } catch (Exception e) {
            Log.e("tag", "myDraw is Error!");
        } finally {
            if (canvas != null)
                sfh.unlockCanvasAndPost(canvas);
        }
    }

    public void Logic() {
        // ----物理世界进行模拟
        world.step(timeStep, iterations);
        Vec2 position = body.getPosition();
        polygonX = position.x * RATE - polygonWidth / 2;
        polygonY = position.y * RATE - polygonHeight / 2;
        Vec2 position2 = body2.getPosition();
        polygonX2 = position2.x * RATE - polygonWidth2 / 2;
        polygonY2 = position2.y * RATE - polygonHeight2 / 2;
        Vec2 position3 = body3.getPosition();
        polygonX3 = position3.x * RATE - polygonWidth3 / 2;
        polygonY3 = position3.y * RATE - polygonHeight3 / 2;
    }

    public void run() {
        while (flag) {
            myDraw();
            Logic();
            try {
                Thread.sleep((long) timeStep * 1000);
            } catch (Exception ex) {
                Log.e("tag", "Thread is Error!");
            }
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = false;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值