学习jbox2d遇到问题

lbgongfu 发布于 2013/08/04 14:20
阅读 587
收藏 0
最近一直学习jbox2d,也试着做了一个练习,但是遇到了一个让我很头疼的问题。是这样的,屏幕上绘制了一个框框,框框里面绘制了一个球,球会自由落体,但是当球碰到下边框的时候并没有弹起,直接穿过去了。查了很多资料,就是找不到答案,请问是怎么回事?
加载中
0
小耶果
小耶果
框框是否加到了物理引擎中?(静态body)
lbgongfu
lbgongfu
当然加到world里了,也是静态的。我的代码在家里,晚上我贴出来,帮我看看。我用的是最新的2.2,与之前版本的用法好像不一样。书上的例子都是基于之前版本。也没个参考。
0
lbgongfu
lbgongfu
以下是有问题的代码。
不知道在哪里编辑原帖子,所以就在此列出。
//GameView.java 视图类

package com.example.jbox2ddemo;

import java.util.ArrayList;
import java.util.List;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;

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

public class GameView extends SurfaceView implements Callback {
	private DrawThread drawThread;
	private List<CustomBody> bodyList = new ArrayList<CustomBody>();
	private World world;

	public GameView(Context context) {
		super(context);
		getHolder().addCallback(this);
		world = new World(new Vec2(0f, 10f));
		world.setAllowSleep(true);
		world.setContinuousPhysics(true);
		world.setSubStepping(true);
		world.setWarmStarting(true);
		drawThread = new DrawThread(this, getHolder());
		drawThread.start();
	}
	
	public void addBodys(CustomBody... bodys) {
		for (CustomBody body : bodys) {
			bodyList.add(body);
		}
	}

	public void doDraw(Canvas canvas, Paint paint) {
		canvas.drawColor(Color.BLACK);
		for (CustomBody body : bodyList) {
			body.drawSelf(canvas, paint);
		}
	}
	
	public World getWorld() {
		return world;
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if (!drawThread.isAlive()) {
			drawThread.start();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		drawThread.setFlag(false);
		drawThread = null;
	}
	
}
//=========
//DrawThread.java 刷频线程

package com.example.jbox2ddemo;

import org.jbox2d.dynamics.World;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;

public class DrawThread extends Thread {
	private boolean flag = false;
	private long timeSleep = 20;
	private GameView gameView;
	private SurfaceHolder holder;

	public DrawThread(GameView view, SurfaceHolder holder) {
		flag = true;
		this.gameView = view;
		this.holder = holder;
	}
	
	@Override
	public void run() {
		World world = gameView.getWorld();
		Canvas canvas;
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		while (flag) {
			world.step(Constant.TIME_STEP, Constant.VELOCITY_ITERATIONS, Constant.POSITION_ITERATIONS);
			canvas = holder.lockCanvas();
			if (canvas != null) {
				gameView.doDraw(canvas, paint);
				holder.unlockCanvasAndPost(canvas);
			}
			try {
				Thread.sleep(timeSleep);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
}
==========
MainActivity.java

package com.example.jbox2ddemo;

import org.jbox2d.dynamics.World;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {
	private GameView gameView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		Constant.SCREEN_WIDTH = dm.widthPixels;
		Constant.SCREEN_HEIGHT = dm.heightPixels;
		
		gameView = new GameView(this);
		World world = gameView.getWorld();
		int span = 20;
		CustomBody ground = Box2dUtil.createRectBody(world, 0, Constant.SCREEN_HEIGHT - span, Constant.SCREEN_WIDTH, span, Color.GREEN, 0f, 0.3f, 0.8f, true);
		CustomBody ball = Box2dUtil.createCircleBody(world, Constant.SCREEN_WIDTH / 2, 30, Color.WHITE, 30, 1f, 0.1f, 0.8f, false);
		gameView.addBodys(ground, ball);
		setContentView(gameView);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}
//==========
//CustomBody.java 自定义body超类

package com.example.jbox2ddemo;

import org.jbox2d.dynamics.Body;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public abstract class CustomBody {
	protected Body body;
	protected int color = Color.RED;
	
	public abstract void drawSelf(Canvas canvas, Paint paint);
}
//============
//CircleBody.java// 圆形body

package com.example.jbox2ddemo;

import org.jbox2d.dynamics.Body;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;

public class CircleBody extends CustomBody {
	private int radius;
	
	public CircleBody(Body body, int color, int radius) {
		this.body = body;
		this.color = color;
		this.radius = radius;
	}
	
	@Override
	public void drawSelf(Canvas canvas, Paint paint) {
		paint.setStyle(Style.STROKE);
		paint.setStrokeWidth(1);
		paint.setColor(color);
		int x = (int) (body.getPosition().x * Constant.SCALE_FACTOR);
		int y = (int) (body.getPosition().y * Constant.SCALE_FACTOR);
		canvas.drawCircle(x, y, radius, paint);
	}

}
=========
RectBody.java//矩形body

package com.example.jbox2ddemo;

import org.jbox2d.dynamics.Body;

import android.graphics.Canvas;
import android.graphics.Paint;

public class RectBody extends CustomBody {
	private int width;
	private int height;
	
	public RectBody(Body body, int color, int width, int height) {
		this.body = body;
		this.color = color;
		this.width = width;
		this.height = height;
	}
	
	@Override
	public void drawSelf(Canvas canvas, Paint paint) {
		paint.setColor(color);
		int x = (int) (body.getPosition().x * Constant.SCALE_FACTOR);
		int y = (int) (body.getPosition().y * Constant.SCALE_FACTOR);
		canvas.drawRect(x, y, x + width, y + height, paint);
	}

}
========
Box2dUtil.java//用于创建自定义body对象的

package com.example.jbox2ddemo;

import org.jbox2d.collision.shapes.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;

public class Box2dUtil {
	public static CircleBody createCircleBody(World world, int x, int y,
			int color, int radius, float density, float friction,
			float restitution, boolean isStatic) {
		BodyDef bodyDef = new BodyDef();
		bodyDef.position = new Vec2(x / Constant.SCALE_FACTOR, y
				/ Constant.SCALE_FACTOR);
		Body body = world.createBody(bodyDef);
		body.setType(isStatic ? BodyType.STATIC : BodyType.DYNAMIC);
		CircleShape shape = new CircleShape();
		shape.m_radius = radius;
		FixtureDef fixtureDef = new FixtureDef();
		fixtureDef.shape = shape;
		fixtureDef.density = density;
		fixtureDef.friction = friction;
		fixtureDef.restitution = restitution;
		body.createFixture(fixtureDef);
		return new CircleBody(body, color, radius);
	}
	
	public static RectBody createRectBody(World world, int x, int y, int width, int height,int color, float density, float friction, float restitution, boolean isStatic) {
		BodyDef bodyDef = new BodyDef();
		bodyDef.position = new Vec2(x / Constant.SCALE_FACTOR, y / Constant.SCALE_FACTOR);
		Body body = world.createBody(bodyDef);
		body.setType(isStatic ? BodyType.STATIC : BodyType.DYNAMIC);
		PolygonShape shape = new PolygonShape();
		shape.setAsBox(width / 2 / Constant.SCALE_FACTOR, height / 2 / Constant.SCALE_FACTOR);
		FixtureDef fixtureDef = new FixtureDef();
		fixtureDef.density = density;
		fixtureDef.friction = friction;
		fixtureDef.restitution = restitution;
		return new RectBody(body, color, width, height);
	}
}
//=========
//Constant.java 常量

package com.example.jbox2ddemo;

public class Constant {
	public static final int SCALE_FACTOR = 10;
	public static final float TIME_STEP = 1f / 60f;
	public static final int VELOCITY_ITERATIONS = 3;
	public static final int POSITION_ITERATIONS = 8;
	public static int SCREEN_WIDTH;
	public static int SCREEN_HEIGHT;
}
返回顶部
顶部