本片文章是android仿摩拜贴纸碰撞|气泡碰撞的补充。
好多同学私信问我,圆形边界如何创建,今天就写篇文章一起学习下。
在android仿摩拜贴纸碰撞|气泡碰撞中的评论中,给大家提供了一种思路,就是通过绘制正多边形的方式,近似看做圆形,实际上当边足够多时,就是一个圆。
现在需要做的就是确定正多边形的每一个顶点的坐标(x,y)以及正多边形边的长度和角度。
/**
* 根据半径获取多边形每个点的坐标位置
*
* @param n 多边形边数
* @param r 半径
* @return
*/
public ArrayList polygon2(int n, int r) {
float segmentlength = Double.valueOf(r * Math.sin(Math.PI / n)).floatValue(); // 计算边长
ArrayList doubles = new ArrayList<>();
double theta = 2 * Math.PI / n; // 角度
for (int i = 0; i < n + 1; i++) {
float x, y = 0f;
x = Double.valueOf(r * Math.cos(theta * i)).floatValue();
y = Double.valueOf(r * Math.sin(theta * i)).floatValue();
float[] xy = new float[4];
xy[0] = x + r;
xy[1] = y + r;
xy[2] = segmentlength;
xy[3] = Double.valueOf(theta * i).floatValue();
doubles.add(xy);
}
return doubles;
}
生成圆形边界,这里使用polygonShape.setAsBox(height, width, new Vec2(x,y), angle)绘制每一条边,具体看下面代码。(这里重点需要关注物理单位和像素单位的区别,创建物理模型需要使用物理单位,绘制到屏幕上时,需要使用像素单位)
/**
* 设置世界边界 圆形
*/
private void initCircleWorldBounds(Canvas canvas) {
// 绘制圆形边框
canvas.drawCircle(pWidth / 2, pHeight / 2, pHeight / 2, paint);
if (isInitWorld) {
return;
}
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.STATIC;//设置零重力,零速度
bodyDef.position.set(0, 0);
Body bodyTop = world.createBody(bodyDef);//世界中创建刚体
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.density = 1f;//物质密度
fixtureDef.friction = 0.3f;//摩擦系数
fixtureDef.restitution = 0.5f;//恢复系数
//设置圆形刚体边界
ArrayList positions = polygon2(36, Double.valueOf(pHeight / 2).intValue());
for (int i = 0; i < positions.size(); i++) {
float[] xy = (float[]) positions.get(i);
float x = xy[0];
float y = xy[1];
float segmentlength = xy[2];
float angle = xy[3];
PolygonShape polygonShape = new PolygonShape();
// 设置具有方向的shape
polygonShape.setAsBox(0, pixelsToMeters(segmentlength), new Vec2(pixelsToMeters(x), pixelsToMeters(y)), angle);
fixtureDef.shape = polygonShape;
bodyTop.createFixture(fixtureDef);//刚体添加夹具
}
isInitWorld = true;
}
项目地址