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

当然啦,具体的动作自己定就好啦~相信大家也明白了物理引擎中的“碰撞”的机制,希望大家能够更加灵活的使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值