package com.bg;
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.ContactListener;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.ContactPoint;
import org.jbox2d.dynamics.contacts.ContactResult;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class MySurfaceView extends SurfaceView implements Callback, Runnable, ContactListener {
private Thread th;
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;
private boolean flag;
// ----添加一个物理世界---->>
private final float RATE = 30;// 屏幕到现实世界的比例 30px:1m;
private World world;// 声明一个物理世界对象
private AABB aabb;// 声明一个物理世界的范围对象
private Vec2 gravity;// 声明一个重力向量对象
private float timeStep = 1f / 60f;// 物理世界模拟的的频率
private int iterations = 10;// 迭代值,迭代越大模拟越精确,但性能越低
// 声明小球的Body,便于后续对小球进行操作
private Body bodyBall;
//声明胜利与失败的body,用于判定游戏的胜负
private Body lostBody1, lostBody2, winBody;
// 声明屏幕宽高
private int screenW, screenH;
// 声明游戏状态
private final int GAMESTATE_MENU = 0;
private final int GAMESTATE_HELP = 1;
private final int GAMESTATE_GAMEING = 2;
private int gameState = GAMESTATE_MENU;
// 为了游戏暂停时,失败,胜利能继续可能到游戏中的状态,所以并没有将其写成一个状态
private boolean gameIsPause, gameIsLost, gameIsWin;
// Body图片资源
private Bitmap bmpH, bmpS, bmpSh, bmpSs, bmpBall;
// 菜单、按钮、游戏背景图片资源
private Bitmap bmpMenu_help, bmpMenu_play, bmpMenu_exit, bmpMenu_resume, bmpMenu_replay, bmp_menubg, bmp_gamebg, bmpMenuBack, bmp_smallbg, bmpMenu_menu,
bmp_helpbg, bmpBody_lost, bmpBody_win, bmpWinbg, bmpLostbg;
// 创建按钮
private HButton hbHelp, hbPlay, hbExit, hbResume, hbReplay, hbBack, hbMenu;
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);
this.setFocusable(true);
this.setFocusableInTouchMode(true);
// --添加一个物理世界--->>
aabb = new AABB();
gravity = new Vec2(0, 10);
aabb.lowerBound.set(-100, -100);
aabb.upperBound.set(100, 100);
world = new World(aabb, gravity, true);
// ---实例化Body图片资源
bmpH = BitmapFactory.decodeResource(getResources(), R.drawable.h);
bmpS = BitmapFactory.decodeResource(getResources(), R.drawable.s);
bmpSh = BitmapFactory.decodeResource(getResources(), R.drawable.sh);
bmpSs = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
bmpBall = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
// 实例菜单、按钮、游戏背景图片资源
bmpMenu_help = BitmapFactory.decodeResource(getResources(), R.drawable.menu_help);
bmpMenu_play = BitmapFactory.decodeResource(getResources(), R.drawable.menu_play);
bmpMenu_exit = BitmapFactory.decodeResource(getResources(), R.drawable.menu_exit);
bmpMenu_resume = BitmapFactory.decodeResource(getResources(), R.drawable.menu_resume);
bmpMenu_replay = BitmapFactory.decodeResource(getResources(), R.drawable.menu_replay);
bmp_menubg = BitmapFactory.decodeResource(getResources(), R.drawable.menu_bg);
bmp_gamebg = BitmapFactory.decodeResource(getResources(), R.drawable.game_bg);
bmpMenuBack = BitmapFactory.decodeResource(getResources(), R.drawable.menu_back);
bmp_smallbg = BitmapFactory.decodeResource(getResources(), R.drawable.smallbg);
bmpMenu_menu = BitmapFactory.decodeResource(getResources(), R.drawable.menu_menu);
bmp_helpbg = BitmapFactory.decodeResource(getResources(), R.drawable.helpbg);
bmpBody_lost = BitmapFactory.decodeResource(getResources(), R.drawable.lostbody);
bmpBody_win = BitmapFactory.decodeResource(getResources(), R.drawable.winbody);
bmpWinbg = BitmapFactory.decodeResource(getResources(), R.drawable.gamewin);
bmpLostbg = BitmapFactory.decodeResource(getResources(), R.drawable.gamelost);
}
//SurfaceView创建
public void surfaceCreated(SurfaceHolder holder) {
//防止Home按键导致游戏重置
if (gameState == GAMESTATE_MENU) {
screenW = this.getWidth();
screenH = this.getHeight();
// 实例化按钮
hbPlay = new HButton(bmpMenu_play, screenW / 2 - bmpMenu_help.getWidth() / 2, 150);
hbHelp = new HButton(bmpMenu_help, hbPlay.getX(), hbPlay.getY() + 50);
hbExit = new HButton(bmpMenu_exit, hbPlay.getX(), hbHelp.getY() + 50);
hbBack = new HButton(bmpMenuBack, 0, screenH - bmpMenu_help.getHeight());
hbResume = new HButton(bmpMenu_resume, screenW / 2 - bmpMenu_help.getWidth() / 2, 200);
hbReplay = new HButton(bmpMenu_replay, hbResume.getX(), hbResume.getY() + 50);
hbMenu = new HButton(bmpMenu_menu, hbResume.getX(), hbReplay.getY() + 50);
// 创建主角小球
bodyBall = createCircle(bmpBall, bmpH.getHeight(), bmpH.getHeight(), bmpBall.getWidth() / 2, 5);
//创建胜负Body
lostBody1 = createCircle(bmpBody_lost, screenW - bmpH.getHeight() - bmpBody_lost.getWidth(), bmpH.getHeight(), bmpBody_lost.getWidth() / 2, 0);
lostBody2 = createCircle(bmpBody_lost, bmpH.getHeight(), screenH - bmpH.getHeight() - bmpBody_lost.getHeight(), bmpBody_lost.getWidth() / 2, 0);
winBody = createCircle(bmpBody_win, screenW - bmpH.getHeight() - bmpBody_win.getWidth(), screenH - bmpH.getHeight() - bmpBody_win.getHeight(),
bmpBody_win.getWidth() / 2, 0);
//设置传感器,发生碰撞,但无碰撞效果
lostBody1.getShapeList().m_isSensor = true;
lostBody2.getShapeList().m_isSensor = true;
winBody.getShapeList().m_isSensor = true;
// 创建边界
createRect(bmpH, 0, 0, bmpH.getWidth(), bmpH.getHeight(), 0);// 上
createRect(bmpH, 0, getHeight() - bmpH.getHeight(), bmpH.getWidth(), bmpH.getHeight(), 0);// 下
createRect(bmpS, 0, 0, bmpS.getWidth(), bmpS.getHeight(), 0);// 左
createRect(bmpS, getWidth() - bmpS.getWidth(), 0, bmpS.getWidth(), bmpS.getHeight(), 0);// 右
// -----创建障碍物
createRect(bmpSh, 0, 90, bmpSh.getWidth(), bmpSh.getHeight(), 0);
createRect(bmpSh, 110, 170, bmpSh.getWidth(), bmpSh.getHeight(), 0);
createRect(bmpSs, 110, 170, bmpSs.getWidth(), bmpSs.getHeight(), 0);
createRect(bmpSs, getWidth() - 102, screenH - bmpSs.getHeight(), bmpSs.getWidth(), bmpSs.getHeight(), 0);
//绑定监听器
world.setContactListener(this);
}
flag = true;
th = new Thread(this);
th.start();
}
//在物理世界中添加矩形Body
public Body createRect(Bitmap bmp, float x, float y, float w, float h, float density) {
PolygonDef pd = new PolygonDef();
pd.density = density;
pd.friction = 0.8f;
pd.restitution = 0.3f;
pd.setAsBox(w / 2 / RATE, h / 2 / RATE);
BodyDef bd = new BodyDef();
bd.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);
Body body = world.createBody(bd);
body.m_userData = new MyRect(bmp, x, y);
body.createShape(pd);
body.setMassFromShapes();
return body;
}
//在物理世界中添加圆形Body
public Body createCircle(Bitmap bmp, float x, float y, float r, float density) {
CircleDef cd = new CircleDef();
cd.density = density;
cd.friction = 0.8f;
cd.restitution = 0.3f;
cd.radius = r / RATE;
BodyDef bd = new BodyDef();
bd.position.set((x + r) / RATE, (y + r) / RATE);
Body body = world.createBody(bd);
body.m_userData = new MyCircle(bmp, x, y, r);
body.createShape(cd);
body.setMas