1. 程式人生 > >基於JBox2D物理引擎開發的“雷電”小遊戲(五)——碰撞

基於JBox2D物理引擎開發的“雷電”小遊戲(五)——碰撞

不好意思,隔了這麼久才發這一篇文章,雖然部分原因是最近因為實習的事情很忙,還有一部分原因是比較懶,廢話不多說,現在開始正文。

碰撞

既然學到了這裡,想必大家都明白,物理引擎會幫我們做很多事情,省去從零開始碼程式碼的工作量,當然“碰撞”也會由我們的物理引擎做好很多工作。

碰撞檢測

什麼是碰撞檢測?碰撞檢測就是當兩個及兩個以上的物體發生碰撞時,程式能夠捕捉到是哪兩個物體發生了碰撞。對,沒錯,我們就只需要設定一個監聽器來幫助我們就好了。

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;
            }
        }
    }

當然啦,具體的動作自己定就好啦~相信大家也明白了物理引擎中的“碰撞”的機制,希望大家能夠更加靈活的使用。