基於JBox2D物理引擎開發的“雷電”小遊戲(五)——碰撞
阿新 • • 發佈:2019-01-22
不好意思,隔了這麼久才發這一篇文章,雖然部分原因是最近因為實習的事情很忙,還有一部分原因是比較懶,廢話不多說,現在開始正文。
碰撞
既然學到了這裡,想必大家都明白,物理引擎會幫我們做很多事情,省去從零開始碼程式碼的工作量,當然“碰撞”也會由我們的物理引擎做好很多工作。
碰撞檢測
什麼是碰撞檢測?碰撞檢測就是當兩個及兩個以上的物體發生碰撞時,程式能夠捕捉到是哪兩個物體發生了碰撞。對,沒錯,我們就只需要設定一個監聽器來幫助我們就好了。
public void initContactListener() { //載入碰撞監聽器
ContactListener cl = new ContactListener() { //內部類
@Override
public void add(ContactPoint arg0) {//重寫的方法
//碰撞後的行為
doAction(arg0.shape1.getBody(), arg0.shape2.getBody(), bl);
}
@Override
public void persist(ContactPoint arg0) {
} //重寫persist方法
@Override
public void remove(ContactPoint arg0) {
} //重寫remove方法
@Override
public void result(ContactResult arg0) {
}//重寫result方法
};
world.setContactListener(cl);
}
我們用這個函式為遊戲新增碰撞檢測的監聽器,每當有剛體發生碰撞時,ContactPoint型別的引數便能告訴程式是哪兩個物體發生了碰撞,我們便可以為碰撞的剛體安排接下來的動作。
碰撞反應
檢測到了是哪兩個剛體後,我們便需要讓剛體們在碰撞後“聽我們的話”,讓他們“按計劃行事”。
public void doAction(Body body1, Body body2, ArrayList<MyBody> bl) {
//遍歷剛體列表
for (MyBody mpi1 : bl) {
//匹配剛體
if (body1 == mpi1.body) {
//判斷剛體型別
if (mpi1 instanceof MyRectColor) {
//型別強制轉換
MyRectColor mrc = (MyRectColor) mpi1;
//判斷是否為敵方“戰機”
if (mrc.isObstacle) {
//遍歷剛體列表
for(MyBody mpi2 : bl){
//匹配剛體
if(body2 == mpi2.body){
//具體的碰撞反應
obstacleAction(mpi1, mpi2);
}
}
}
} else if(mpi1 instanceof Bullet){
for(MyBody mpi2:bl){
if(body2 == mpi2.body) {
bulletAction(mpi1, mpi2);
}
}
} else if(mpi1 instanceof Prop){
for(MyBody mpi2:bl){
if(body2 == mpi2.body){
propAction(mpi1,mpi2);
}
}
}
}else if (body2 == mpi1.body) {
if (mpi1 instanceof MyRectColor) {
MyRectColor mrc = (MyRectColor) mpi1;
if (mrc.isObstacle) {
for(MyBody mpi2 : bl){
if(body1 == mpi2.body){
obstacleAction(mpi1, mpi2);
}
}
}
} else if(mpi1 instanceof Bullet){
for(MyBody mpi2:bl){
if(body1 == mpi2.body) {
bulletAction(mpi1, mpi2);
}
}
}else if(mpi1 instanceof Prop){
for(MyBody mpi2:bl){
if(body1 == mpi2.body){
propAction(mpi1,mpi2);
}
}
}
}
}
}
上面我給了部分的註釋,其餘沒給註釋的地方和上面類似,相信大家都看得懂。這部分程式碼只是簡單將碰撞的剛體的型別分了個類,具體的碰撞反應在下面,不過在教學中,我就只給出obstacleAction(MyBody myBody1,MyBody myBody2)函式好了,其餘的具體函式請看我的原始碼,這裡就不粘上來了。
public void obstacleAction(MyBody myBody1,MyBody myBody2){
//強制型別轉換
MyRectColor mrc = (MyRectColor) myBody1;
//判斷剛體型別
if(myBody2 instanceof PlayerBall){
//玩家是否被保護
if(!isProtected) {
//強制型別轉換
PlayerBall playerBall = (PlayerBall) myBody2;
playerBall.HP = playerBall.HP - mrc.obstacleAD;
if(playerBall.bulletPower>0) {
playerBall.bulletPower = playerBall.bulletPower - 25;
if(playerBall.bulletPower<0){
playerBall.bulletPower=0;
}
}else{
if(playerBall.bulletLevel>1){
playerBall.bulletLevel--;
playerBall.bulletPower=100;
}
}
if(playerBall.playerAD>playerBall.playerStartAD*0.6){
playerBall.playerAD = playerBall.playerAD*0.8;
if(playerBall.playerAD<playerBall.playerStartAD*0.6){
playerBall.playerAD=playerBall.playerStartAD*0.6;
}
}
isProtected = true;
//保護玩家1秒
new Thread(){
@Override
public void run(){
try{
sleep(1000);
}catch (Exception e){
}
isProtected = false;
}
}.start();
}
//判斷是否是boss
if(mrc.level<bossLevel) {
//設定剛體isLive屬性
mrc.isLive = false;
}
Message msg = new Message();
if(mrc.level==1) {
msg.what = 2;
handler.sendMessage(msg);
}else if(mrc.level==3){
msg.what = 3;
handler.sendMessage(msg);
}else if(mrc.level==6){
msg.what = 4;
handler.sendMessage(msg);
}
}else if(myBody2 instanceof MyRectColor){
MyRectColor myRectColor = (MyRectColor) myBody2;
if(myRectColor.isBottom){
mrc.isLive = false;
}else if(mrc.level==bossLevel&&myRectColor.isLeft){
mrc.isGoToRight = true;
}else if(mrc.level==bossLevel&&myRectColor.isRight){
mrc.isGoToRight = false;
}
}
}
當然啦,具體的動作自己定就好啦~相信大家也明白了物理引擎中的“碰撞”的機制,希望大家能夠更加靈活的使用。