Android基于box2d开发弹弓类游戏[五]-------------发射子弹&移动的镜头&添加目标

发表于2016-07-11
评论0 1.8k浏览
八、发射子弹
  我们前期的准备基本上已经完成了。发射臂已经准备就绪了。接下来,开始创建子弹!并且通过发射器发射子弹!
1、在世界中加入子弹
  首先创建一个子弹类Bullet.java类,实现BodyInterface 接口。实现方式与发射器类catapultArm.java类似,此处略。
  首先创建所需的变量:

1
2
3
//用于存放子弹对象的集合
private Set bullet = new HashSet< Body >();    private final int BulletCount = 4; //子弹数量
private Bitmap bulletBitmap; //子弹图片

  在MainView.java主类中,编写创建子弹CreateBulletBody方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
    * 创建子弹
    * @param bitmap
    * @param x
    * @param y
    * @param width
    * @param height
    * @param isStatic
    * @return
    */
   public void createBulletBody(int count)
   {
   float pos = 62.0f; //子弹距离场景左端的位置
   if(count >0)
   {
       float delta = 50f; //子弹之间的间隔
       
       for(int i=0;i

  子弹的物体创建完成了,接下来就需要在logic()与draw()方法中进行子弹的逻辑模拟以及绘画,在这里就不在赘述。
  此时可以运行游戏,查看一下效果。可以看到游戏开始,子弹在半空中下落到地面。与现实世界似乎相同。


2、子弹上膛
  现在已经成功把子弹添加到了模拟世界中。接下来我们要让子弹上膛,让子弹和发射器绑定在一起。这时候我们需要引进第三个关节---焊接关节。顾名思义,就是我们需要把子弹焊接在发射器上。
  首先创建所需要的变量。

1
private WeldJoint wj;//焊接关节

  然后创建createWeldJoint()创建焊接关节的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
//创建焊接关节
    public WeldJoint createWeldJoint() {
       Body body;
       Iterator aIterator = bullet.iterator(); //使用迭代器取出set集合中的数据
       while (aIterator.hasNext()) {   //判断时候还有数据
           body = aIterator.next(); //获取下一个数据,第一次是获取第一个数据
           body.setTransform(new Vec2((360f/RATE), (ScreenH-FLOOR_HEIGHT-bulletBitmap.getHeight()-227)/RATE), 0);
            WeldJointDef wd = new WeldJointDef();
            wd.initialize(body, catapultArmBody, catapultArmBody.getWorldCenter());
            return (WeldJoint) world.createJoint(wd);
       }
       return null;
    }

  方法创建完成之后,在surfaceCreated()方法中调用。

1
wj = createWeldJoint();

  此时焊接关节创建完成。运行游戏。可以看到效果。


3、发射子弹
  此时子弹已经上膛了。可以推动发射器看一下效果。子弹可以跟随发射器一起移动。但是这也不是我们想要的效果。我们需要的效果是推动发射器,然后发射器复原的时候凭借恢复力把子弹发射出去。接下来就去完成发射子弹的功能。
  完成这个功能我们之需要在发射器恢复到一定角度的时候,销毁焊接关节,使子弹脱离发射器。这样就可以完成子弹的发射。
  首先创建所需要的变量。

1
private boolean catapult_flag = false;//推动发射器标示

  这个变量的目的用于防治触摸到发射器,变使子弹发射的bug。只有推动发射器到达一定角度是,才算推动了发射器。
  接下来需要在logic()逻辑方法中,进行判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
//推动发射器到一定一角度
       if(catapultArmBody.getAngle()< - (float) (30f*Math.PI/180))
    {
        catapult_flag=true;
    }
       
       if(wj != null&&catapult_flag)
        {
        if(catapultArmBody.getAngle()>=-(float) (10f*Math.PI/180)){
            world.destroyJoint(wj);//销毁焊接关节
            wj = null;
        }
        }

  这里我们默认只有推动发射器到达30°的时候才能发射子弹。并且当发射器恢复到10°的时候,销毁焊接关节。此时子弹发出。运行游戏可以看下效果。


4、子弹续膛
  当一个子弹被我们发射出去之后,问题也就随之而来了。对!剩下的子弹怎么办。我们接下来就完成,子弹续膛!
  这里需要考虑两个问题。
  何时销毁已经发射的子弹?
  何时让新的子弹续膛?
  何时销毁子弹,可以设定两种情况,第一种当子弹超出场景的范围,第二种当子弹在场景内静止时。这两种情况满足一种便可销毁子弹。
  何时让薪资单续膛,这里考虑两种情况,第一种当前一个子弹脱离发射器时续膛。第二种是当前一个子弹销毁时续膛。这里第一种情况会出现一个bug。当前一个子弹脱离发射器,续膛的子弹会瞬间与发射器进行焊接,这样会影响前一个子弹的运行轨道。所以在这里才需第二种方式。
  首先定义变量。

1
private boolean moveing_flag = false; //子弹是否处于移动状态

  接下来就是要判断发射的子弹时候静止或者超出了场景范围,需要在logic方法中进行判断。

1
2
3
4
5
6
7
8
if(bullet.iterator().hasNext())//首先判断时候还有为发射的子弹
       {
           //只要发射的子弹静止或者超出了场景范围就执行
       if(!bullet.iterator().next().isAwake()||bullet.iterator().next().getPosition().x*RATE>background_bottom.getWidth())
        {
              moveing_flag = false;
        }
       }

  并且要在销毁焊接关节的方法中,加入一条语句。是moveing_flag初始化。

1
moveing_flag = true;

  然后我们在logic方法中编写子弹续膛的方法。

1
2
3
4
5
6
7
8
9
//子弹续膛
    if(wj == null&&!bullet.isEmpty()&&!moveing_flag)
    {
        //销毁已经发出去的子弹
        world.destroyBody(bullet.iterator().next());
        bullet.remove(bullet.iterator().next());
        catapult_flag = false;
        wj = createWeldJoint();//创建新的焊接关节
    }

  此时子弹续膛的功能已经完成。可以运行游戏进行测试。

九、移动的镜头
  子弹的发射已经完成了。下一个就是要增进用户体验的时候了。现在运行游戏,当子弹发射以后,我们还需要拖动屏幕才能看到子弹运行的轨迹,这样的体验是非常差的。接下来完成,移动的镜头功能。就是屏幕显示区域跟随子弹运动。
  这个功能之需要计算发射出去的子弹时时的位置就可以了。比较好实现。
  在logic方法的if((body.m_userData) instanceof Bullet)逻辑末尾加入。

1
2
3
4
5
6
7
if(moveing_flag)//判断子弹是否处于运动状态
         {
            //获取到移动的偏移量。(ScreenW/2.0f用于使子弹处于屏幕中间)
             float ww=this.bullet.iterator().next().getPosition().x * RATE - ScreenW / 2.0f;
             //防止镜头移出游戏场景
             move_X=(ww<5)?0:(ww>580)?586:ww;
         }

  此时,移动的镜头就已经完成了。运行下游戏,是不是非常酷啊!


十、创建目标
  此时所有的准备都已经就绪了,接下来就要引进需要攻击的目标了。
  有限创建一个Target.java类。并且实现BodyInterface接口。和之前创建子弹一样,在这里不再赘述了。
  回到MainView.java主类中,定义需要用到的变量。

1
private Set targetBodies = new HashSet();//创建存放目标的集合

  然后在游戏世界中创建出目标物体。和之前创建子弹一样。不再赘述。
  当创建目标之后,可以运行游戏。查看下效果。


  最后发射子弹吧!


  写到在这里我们系列的文章就暂时告一段落了。但是我们只是完成了一个简单的游戏界面。距离真正的游戏还有一段的距离。接下来就要各位博友自己去拓展功能了。我也会不定期的更新最新的功能的。尽请关注!~~

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引