`

android 游戏学习(jbox2d)

阅读更多

导入jbox2d-2.0.1-library-only.jar

/**
* 矩形对象
*
* @time 上午11:17:09
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MyRect {
private float x, y, w, h, angle;


public MyRect(float x, float y, float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}


public void drawRect(Canvas canvas, Paint paint) {
canvas.save();
canvas.rotate(angle, x + w / 2, y + h / 2);
canvas.drawRect(x, y, x + w, y + h, paint);
canvas.restore();
}


public void setX(float x) {
this.x = x;
}


public void setY(float y) {
this.y = y;
}


public void setAngle(float angle) {
this.angle = angle;
}


public float getWidth() {
return w;
}


public float getHeight() {
return h;
}
}

 

 

/**
* 砖块
*
* @time 上午11:17:44
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MyTitle {


private float x, y,//
w, h,//
angle;//
private Bitmap bg;


public MyTitle(float x, float y, float w, float h, Bitmap bg) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.bg = bg;
}


public float getX() {
return x;
}


public void setX(float x) {
this.x = x;
}


public float getY() {
return y;
}


public void setY(float y) {
this.y = y;
}


public void setWidth(float w) {
this.w = w;
}


public void setHeight(float h) {
this.h = h;
}


public float getWidth() {
return w;
}


public float getHeight() {
return h;
}


public void setAngle(float angle) {
this.angle = angle;
}


/**
* 绘制砖块
*/
public void draw(Canvas canvas, Paint paint) {
canvas.save();
canvas.rotate(angle, x + w / 2, y + h / 2);
canvas.drawBitmap(bg, x, y, paint);


canvas.restore();
}


}

 

 

/**
* 游戏主界面
*
* @time 上午11:18:15
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
@SuppressWarnings("unused")
public class BuildHourseSurfaceView extends SurfaceView implements Callback, Runnable {
private Random random;// 随机图片
private static final float RATE = 30;
private Thread thread;
private Paint paint;
private SurfaceHolder sfh;
private int screenW, screenH;
private boolean flag;
private Canvas canvas;


// 图片
private Bitmap bmp_bg,// 背景图片
bmp_title1, bmp_title2, bmp_title3;// 砖块


// 创建物理世界
private float timeStep = 1f / 10f;
private AABB aabb;
private World world;
private Vec2 gravity;
private int iterations;


// 固定body
private Body bodyWall;
// 固定body的坐标与高宽
private int bodyWallX, bodyWallY,// 坐标
bodyWallW, bodyWallH;// 高宽
// 砖块
private Body bodyHouse;


// 临时body记录上一次绑定在距离关节上的body
private Body tempBody;
// 距离关节
private DistanceJoint dj;
// ---线条的颜色值
private int[] lineColor = { 0xFFDACDC5, 0xFF825B56, 0xFF3A3E59 };


private int temp;
private boolean isDeleteJoint;
private boolean isDown;
private int isDownCount;


/**
* 构造函数
*
* @param context
*/
public BuildHourseSurfaceView(Context context) {
super(context);


screenW = this.getWidth();
screenH = this.getHeight();


paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);


sfh = this.getHolder();
sfh.addCallback(this);


this.setFocusable(true);
this.setKeepScreenOn(true);
this.setFocusableInTouchMode(true);


// 创建物理世界
aabb = new AABB();// 设置物理世界的范围
aabb.lowerBound.set(-100, -100);// 设置左上角坐标
aabb.upperBound.set(100, 100);// 设置右下角坐标
gravity = new Vec2(0f, 10f);// 设置重力向量
world = new World(aabb, gravity, true);// 创建物理世界对象


// 设置背景图
bmp_bg = BitmapFactory.decodeResource(this.getResources(), R.drawable.background);
// 实例化砖块
bmp_title1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile1);
bmp_title2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile2);
bmp_title3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile3);


}


@Override
public void surfaceCreated(SurfaceHolder holder) {


bodyWallW = 40;
bodyWallH = 2; // 固定关节的大小
bodyWallX = getWidth() / 2 - bodyWallW / 2;
bodyWallY = 1; // 固定关节的起始坐标


// 实例化两个绑定距离关节的 body
bodyWall = createPolygon(bodyWallX, bodyWallY, bodyWallW, bodyWallH, 0, true);
bodyHouse = createMyTitle(bodyWallX / 2, bodyWallY + bodyWallH + 50, bmp_title1.getWidth(), bmp_title1.getHeight(), 0, false);


// 创建临时body
tempBody = bodyHouse;


// 添加一个静态的下边界
createPolygon(0, getHeight(), getWidth() - 10, 10, 0, true);


// 添加一个距离关节
dj = createDistanceJoint(bodyWall, bodyHouse);


//
flag = true;
thread = new Thread(this);
thread.start();
}


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


}


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


/**
* 创建距离关节
*
* @param body1
* @param body2
* @return
*/
public DistanceJoint createDistanceJoint(Body body1, Body body2) {
// 创建距离关节信息
DistanceJointDef def = new DistanceJointDef();
def.body1 = body1;
def.body2 = body2;
// 初始化距 离信息
def.initialize(body1, body2, body1.getWorldCenter(), body2.getWorldCenter());
DistanceJoint distanceJoint = (DistanceJoint) world.createJoint(def);
return distanceJoint;


}


/**
* 创建砖块
*
* @param x
* @param y
* @param w
* @param h
* @param angle
* @param isStation
* @return
*/
private Body createMyTitle(float x, float y, float w, float h, float angle, boolean isStation) {
// 创建一个皮肤
PolygonDef polygonDef = new PolygonDef();
if (isStation) {
polygonDef.density = 0;// 设置矩形为静态
} else {
polygonDef.density = 1;// 设置矩形的质量
}


polygonDef.friction = 0.8f;// 摩擦力
polygonDef.restitution = 0.3f;// 恢复力
// 快捷成盒子
polygonDef.setAsBox(w / 2 / RATE, h / 2 / RATE);
polygonDef.filter.groupIndex = 2;
// 创建一个刚体
BodyDef def = new BodyDef();
// 设置刚体的坐标
def.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);
// 设置角度
def.angle = (float) (angle * Math.PI / 180);
def.angle = (float) (angle * Math.PI / 180);
random = new Random();
temp = random.nextInt(3);//
// 随机取背景图片
switch (temp) {
case 0:
bmp_bg = bmp_title1;
break;
case 1:
bmp_bg = bmp_title2;
break;
case 2:
bmp_bg = bmp_title3;
break;


}
Body body = world.createBody(def);// 创建一个物体
body.m_userData = new MyTitle(x, y, w, h, bmp_bg);
// 设置皮肤
body.createShape(polygonDef);
// 整个物体计算打包
body.setMassFromShapes();
return body;


}


/**
* 创建固定body
*
* @param x
* @param y
* 坐标
* @param w
* @param h
* 高宽
* @param angle
* 角度
* @param isStation
* 是否为静态
* @return
*/
private Body createPolygon(float x, float y, float w, float h, float angle, boolean isStation) {
// 创建皮肤
PolygonDef polygonDef = new PolygonDef();
if (isStation) {
polygonDef.density = 0;// 设置矩形为静态
} else {
polygonDef.density = 1;// 设置矩形质量
}
// 设置摩擦力
polygonDef.friction = 0.8f;
// 设置恢复力
polygonDef.restitution = 0.3f;
// 快捷成盒子
polygonDef.setAsBox(w / 2 / RATE, h / 2 / RATE);
// 创建一个刚体
BodyDef def = new BodyDef();
def.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);// 设置刚体的坐标
def.angle = (float) (angle * 180 / Math.PI);// 设置角度
Body body = world.createBody(def);
body.m_userData = new MyRect(x, y, w, h);
body.createShape(polygonDef);// 设置皮肤
body.setMassFromShapes();// 整个物体打包
return body;


}


/**
* 绘制方法
*/
private void draw() {
try {
canvas = sfh.lockCanvas();
if (null != canvas) {
canvas.drawColor(Color.BLACK);
// 绘制游戏的背景图
canvas.drawBitmap(bmp_bg, 0, -Math.abs((float) (getHeight() - bmp_bg.getHeight())), paint);


// 遍历body
Body body = world.getBodyList();
for (int i = 1; i < world.getBodyCount(); i++) {
if ((body.m_userData) instanceof MyRect) {
MyRect myRect = (MyRect) (body.m_userData);
myRect.drawRect(canvas, paint);
} else if ((body.m_userData) instanceof MyTitle) {
MyTitle myTitle = (MyTitle) (body.m_userData);
myTitle.draw(canvas, paint);
}
body = body.m_next;
}
if (null != bodyWall && null != bodyHouse) {
if (null != dj) {
// 设置画笔颜色
paint.setColor(lineColor[temp]);
// 设置画笔粗细
paint.setStrokeWidth(3);
// 绘制关节
canvas.drawLine(bodyWall.getPosition().x * RATE, bodyWall.getPosition().y * RATE, tempBody.getPosition().x * RATE, tempBody.getPosition().y * RATE, paint);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != canvas) {
sfh.unlockCanvasAndPost(canvas);
}
}


}


/**
* 游戏逻辑
*/
private void logic() {
// 运行物理世界
world.step(timeStep, iterations);


// 遍历body
Body body = world.getBodyList();
for (int i = 1; i < world.getBodyCount(); i++) {
if ((body.m_userData) instanceof MyRect) {
MyRect myRect = (MyRect) (body.m_userData);
// 更新坐标和角度
myRect.setX(body.getPosition().x * RATE - myRect.getWidth() / 2);
myRect.setY(body.getPosition().y * RATE - myRect.getHeight() / 2);
myRect.setAngle((float) (body.getAngle() * 180 / Math.PI));


} else if ((body.m_userData) instanceof MyTitle) {
MyTitle myTitle = (MyTitle) (body.m_userData);
// 更新坐标和角度
myTitle.setX(body.getPosition().x * RATE - myTitle.getWidth() / 2);
myTitle.setY(body.getPosition().y * RATE - myTitle.getHeight() / 2);
myTitle.setAngle((float) (body.getAngle() * 180 / Math.PI));
}
body = body.m_next;
}
if (isDeleteJoint) {
world.destroyJoint(dj);// 销毁关节
dj = null;
isDeleteJoint = false;
}
// 动态Body是否下落
if (isDown == true) {
// 计时器计时
isDownCount++;
// 计时器时间
if (isDownCount % 120 == 0) {
// 创建新的动态Body-砖块,并且使用临时Body保存最新动态Body
tempBody = createMyTitle(bodyWallX / 2, bodyWallY + bodyWallH + 50, bmp_title1.getWidth(), bmp_title1.getHeight(), 0, false);
// 创建新的距离关节
dj = createDistanceJoint(bodyWall, tempBody);
// 计时器重置
isDownCount = 0;
// 下落标识重置
isDown = false;
}
}


}


@SuppressWarnings("static-access")
@Override
public void run() {
while (flag) {
draw();
logic();
try {
thread.sleep((long) timeStep * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}


}


/**
* 重写触屏方法
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isDown == false) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 删除关节
isDeleteJoint = true;
// 动态body下落
isDown = true;


}
}


return true;
}


}

 

/**
* 建房子主界面
*
* @time 上午11:18:56
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// setContentView(R.layout.main);
setContentView(new BuildHourseSurfaceView(this));
}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics