Home  >  Article  >  Java  >  "Java Mini Game Implementation": Tank Battle (Continued 3)

"Java Mini Game Implementation": Tank Battle (Continued 3)

黄舟
黄舟Original
2016-12-27 13:21:191572browse

Blog post "Java Mini Game Implementation": In Tank Battle (continued 2), it has been realized that tanks can fire bullets and hit enemy tanks. This blog post continues to implement more functions on this basis.

Complete Feature: Add Explosion Effect

In the previous version, when we hit the enemy tank, the enemy tank just disappeared without producing an effect similar to the explosion we are familiar with. . Next we add this explosion effect.

Java Mini Game Implementation: Tank Battle (Continued 3)

##vcSjxOLV4tK7uabE3KGjPGJyIC8+DQo8aW1nIGFsdD0="" src="/uploadfile/Collfiles/20160623/20160623091322277.png" title="\" />

First , we create an explosion class Explode.

In the explosion class, there will be the following properties and methods

1. Position information x,y;

2. Identification of whether it is alive Attribute

3. Array of images that generate explosions (here replaced by diameter drawing)

4. Draw method

The code is as follows:

<code class="hljs java">    public class Explode {
        //爆炸所在的位置
        private int x;
        private int y;
 
        //爆炸图片的直径
        private int[] diameter={6,20,40,60,20,7};
 
        //标识爆炸对象是否存活的属性
        private boolean live =true;
 
        public boolean isLive() {
            return live;
        }
 
        //标识爆炸显示到第几步了
        private int step = 0;
 
        private TankClient tc;
 
        public Explode(int x ,int y , TankClient tc){
            this.x = x;
            this.y = y;
            this.tc = tc;
        }
 
        /*
         * 让爆炸显示出来
         * */
        public void draw(Graphics g){
            if(!live) return;
            //判断显示到第几步了,如果全部显示完了,则此对象已死,返回
            if(step>=diameter.length){
                live = false;
                step = 0;
                return;
            }
            Color c = g.getColor();
            g.setColor(Color.YELLOW);
            g.fillOval(x, y, diameter[step], diameter[step]);
            g.setColor(c);
            step++;
        }
 
 
    }</code>

In After we write this explosion class, we can test it in the TankClient class. The code that needs to be added for testing is as follows:

<code class="hljs java">    private Explode explode = new Explode(200,200,this);
    @Override
    public void paint(Graphics g) {
        //炸弹对象
        explode.draw(g);
    }
</code>

The test found that we did see an effect similar to an explosion.

Complete function: add an explosion effect when a bullet hits a tank

Add an explosion effect when a bullet hits a tank; as can be seen from this sentence, when we hit a tank, An explosion object needs to be added. So follow the two steps below to complete this function.

1. Explosion should exist in the collection class.

<code>与子弹类似,在TankClient类中加入集合
将集合中的爆炸逐一画出(如果死去就去除)
</code>

Add the following code to the TankClient class:

<code class="hljs cs">    /*
     * 为每个被击中的坦克添加一个爆炸对象
     * */
    private List<explode> explodes = new ArrayList<explode>(); 
 
    @Override
    public void paint(Graphics g) {
        //炸弹对象
        for(int i=0;i<explodes.size();i++){ code="" e="explodes.get(i);" explode=""></explodes.size();i++){></explode></explode></code>

2. After a bullet hits a tank, an explosion object should be generated and added to the explosion collection of TankClient.

<code class="hljs cs"><code>在Missile类中hitTank方法中添加相关代码
</code></code>

The code of the hitTank method in the Missile class is as follows:

<code class="hljs cs"><code class="hljs java">    public boolean hitTank(Tank t){
        //先判断该坦克是否还是存活,如果已经死了,子弹就不打他了
        if(!t.isLive()){
            return false;
        }
        if(this.getRect().intersects(t.getRect())){//判断是否有碰撞
            //碰撞之后,子弹和该坦克就应该都死了
            this.live = false;//子弹死了
            t.setLive(false);//坦克死了
            Explode e = new Explode(x,y,tc);
            tc.getExplodes().add(e);
            return true;
        }
        else{
            return false;
        }
    }
</code></code>

The above achieves an explosion effect when a bullet hits the tank.

Completed function: Add multiple enemy tanks

In the previous version, there was one our tank and one enemy tank that could not move or fire bullets. We will die as soon as we fight, which is boring. Therefore, we can add multiple enemy tanks to the interface by pressing the A button, or we can randomly generate tanks.

In our actual game, tanks are generally generated randomly. When we destroy them, another batch will be generated. This is such a process.

The implementation process is as follows:

1. Declare a List enemyTanks object in TankClient.java to store a certain number of enemy tank objects.

2. Write the following function to randomly generate a certain number of tanks at random positions.

<code class="hljs cs"><code class="hljs cs">    /*
     * 函数功能:产生敌方坦克
     * */
    public void produceTank(){
 
        int totalNum =r.nextInt(4)+3 ;
 
        for(int i=0;i<totalnum;i++){ code="" enemy="new" int="" tank="" x="(r.nextInt(10)+1)*40;"
         y="(r.nextInt(10)+1)*30;"></totalnum;i++){></code></code>

3. Just draw it in the draw function in TankClient.java.

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs">    @Override
    public void paint(Graphics g) {
 
        //直接调用坦克类的draw方法
        tk.draw(g); 
 
        /*
         * 将敌方坦克也画出来,如果没有了敌方坦克,则产生一定数量的地方坦克
         * */
        if(enemyTanks.size()==0){
            this.produceTank();
        }
        for(int i=0;i<enemytanks.size();i++){ code="" e="explodes.get(i);" enemy="enemyTanks.get(i);" explode="" i="0;i<explodes.size();i++)
        {" int="" missile="" ms="missiles.get(i);" tank=""></enemytanks.size();i++){></code></code></code>

4. Since there are multiple enemy tanks at this time, a hitTanks (List tanks) method is added in Missile to hit a series of tanks. In TankClient, every bullet is fired into tanks.

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">    public boolean hitTank(Tank t){
        //先判断该坦克是否还是存活,如果已经死了,子弹就不打他了
        if(!t.isLive()){
            return false;
        }
        if(this.getRect().intersects(t.getRect())){//判断是否有碰撞
            //碰撞之后,子弹和该坦克就应该都死了
            this.live = false;//子弹死了
            t.setLive(false);//坦克死了
            Explode e = new Explode(x,y,tc);
            tc.getExplodes().add(e);
            return true;
        }
        else{
            return false;
        }
    }
    /*
     * 一颗子弹打List中的坦克
     * */
    public boolean hitTanks(List<tank> tanks){
        for(int i=0;i<tanks.size();i++){ code="" return=""></tanks.size();i++){></tank></code></code></code></code>

Complete function: Make the enemy tanks smarter (move)

The previous version could only generate a certain random number of tanks, but they could not move. This version makes them random. Get moving.

Changes are as follows:

1. In the Tank class, add the following constructor

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java"><code class="hljs java">        
public Tank(int x, int y,boolean good,Direction dir, TankClient tc) {
            this(x,y,good);
            this.dir = dir;
            this.tc = tc;
        }</code></code></code></code></code>

2. Then use the above construct in the produceTank method in the TankClient class Function to new each enemy tank object

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java"><code class="hljs cs">    /*
     * 函数功能:产生敌方坦克
     * */
    public void produceTank(){
 
        int totalNum =r.nextInt(4)+3 ;
 
        for(int i=0;i<totalnum;i++){ code="" dir="dirs[rn];" direction="" dirs="Direction.values();" enemy="new" int="" 
        rn="r.nextInt(dirs.length);" tank="" x="(r.nextInt(10)+1)*40;" y="(r.nextInt(10)+1)*30;"></totalnum;i++){></code></code></code></code></code>

The enemy tank can move through steps 1 and 2, but this is not good enough, because he will keep moving in the direction he just initialized. Go down.

To solve this problem. In the draw method in the Tank class, we set a number of movements step. When the number of movements of an enemy tank reaches step, we randomly change its direction.

Based on the above idea, the code of the draw method in the Tank class is as follows:

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs">
<code class="hljs java"><code class="hljs cs"><code class="hljs cs">        //坦克没走step步,随机换一个方向
        private Random r = new Random();
        private int step = r.nextInt(7)+3;
 
 
        public void draw(Graphics g){
            if(!live){      //判断坦克是否存活,如果死了,则不绘画出来,直接返回     
                return ;
            }
            if(!this.good){
                if(step==0){
                    Direction[] dirs =Direction.values();
                    int rn = r.nextInt(dirs.length);
                    this.dir = dirs[rn];
                    step = r.nextInt(7)+3;
                }
            }
 
            Color c = g.getColor();
            if(good){
                g.setColor(Color.RED);
            }
            else{
                g.setColor(Color.BLUE);
            }
 
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            //画一个炮筒
            drawGunBarrel(g);
 
            move();//根据键盘按键的结果改变坦克所在的位置
 
            step--;
        }</code></code></code></code></code></code>

The above realizes the random movement of multiple enemy tanks.

Complete function: enemy tanks fire bullets

This version adds the function of firing bullets to enemy tanks.

Since our tanks also fire bullets and enemy tanks also fire bullets, there must be a distinction between bullets and bullets. Therefore, add a good attribute to the bullet to identify whether the bullet is good or bad.

The specific steps are as follows:

1. Add the good attribute to the Missile class and add a constructor as follows

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">
<code class="hljs cs"><code class="hljs java">    private boolean good =true;
 
    public Missile(int x,int y,Direction dir,boolean good,TankClient tc){
        this(x,y,dir);
        this.good = good;
        this.tc = tc;
 
    }</code></code></code></code></code></code>

2. Generate bullet fire in the Tank class () method, use the above constructor to construct the bullet Missile ms = new Missile(x,y,this.ptDir,this.good,this.tc);this.good refers to the quality of the tank, just the tank is good, the bullet object is good, otherwise the bullet object is bad, that is, the good or bad object of the bullet is generated according to the quality of the tank

Tank类中fire方法的具体代码如下:

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java"><code class="hljs cs">
<code class="hljs cs">        public Missile fire(){
            //计算子弹的位置,并利用炮筒的方向来new一个子弹对象
            int x = this.x +(this.WIDTH)/2 - (Missile.WIDTH)/2;
            int y = this.y + (this.HEIGHT)/2 -(Missile.HEIGHT)/2;
            //根据坦克的类型(good)来new与之对应的子弹类型
            Missile ms = new Missile(x,y,this.ptDir,this.good,this.tc);
            return ms;
        }
</code></code></code></code></code></code>

3、更改以上两点,则在Tank类中draw方法中为坏坦克添加发射子弹这一功能。

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">
<code class="hljs cs"><code class="hljs cs">        public void draw(Graphics g){
            if(!live){      //判断坦克是否存活,如果死了,则不绘画出来,直接返回     
                return ;
            }
            //为坏坦克添加随机的方向
            if(!this.good){
                if(step==0){
                    Direction[] dirs =Direction.values();
                    int rn = r.nextInt(dirs.length);
                    this.dir = dirs[rn];
                    step = r.nextInt(7)+3;
                }
            }
            //根据坦克的好坏来设置不同的颜色
            Color c = g.getColor();
            if(good){
                g.setColor(Color.RED);
            }
            else{
                g.setColor(Color.BLUE);
            }
 
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            //画一个炮筒
            drawGunBarrel(g);
 
            move();//根据键盘按键的结果改变坦克所在的位置
 
            step--;
 
            //敌方子弹开火
            if(!this.good&&r.nextInt(40)>38){
                this.tc.getMissiles().add(fire());
            }
 
        }
</code></code></code></code></code></code>

4、此时,经过上面的三步之后,我方和敌方都能够发射子弹了,但是敌方能够打死敌方的坦克。因此,还需要对Missile的hitTank(Tank t)方法进行修正。

即在碰撞检测条件中添加这一条:this.good!=t.isGood(),即只有子弹和坦克不是同一类型的,才能打死对方。

具体完整代码如下:

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">
<code class="hljs cs"><code class="hljs java">    public boolean hitTank(Tank t){
        //先判断该坦克是否还是存活,如果已经死了,子弹就不打他了
        if(!t.isLive()){
            return false;
        }
        if(this.live&&this.good!=t.isGood()&&this.getRect().intersects(t.getRect())){//判断是否有碰撞
            //碰撞之后,子弹和该坦克就应该都死了
            this.live = false;//子弹死了
            t.setLive(false);//坦克死了
            Explode e = new Explode(x,y,tc);
            tc.getExplodes().add(e);
            return true;
        }
        else{
            return false;
        }
    }
</code></code></code></code></code></code>

5、在Missile的draw方法中,根据子弹的好坏给出不同的颜色。这里采用好子弹采用红色,坏子弹采用蓝色进行区分。

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">
<code class="hljs cs"><code class="hljs cs">    public void draw(Graphics g){
        //如果该子弹不是存活的,则不进行绘图
        if(!live){
            return ;
        }
        Color c = g.getColor();
        //根据子弹的好坏来设置不同的颜色
        if(this.good){
            g.setColor(Color.RED);
        }
        else{
            g.setColor(Color.BLUE);
        }
 
        g.fillOval(x, y, WIDTH, HEIGHT);
        g.setColor(c);
        move();
    }
</code></code></code></code></code></code>

6、现在差不多就算完成了,但是,我们还需要在TankClient类中的draw方法中做一些改善,例如:1)将我方的坦克置于被敌方子弹攻击的范围内,2)我方坦克被打死之后,应该如何处理。

本项目中,处理的方法为,在我方坦克死亡之后,提示“Game Over,按键A可以复活!!!”字样,并按下键盘A产生一个新的我方坦克。

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java"><code class="hljs cs"><code class="hljs cs">    @Override
    public void paint(Graphics g) {
 
        /*
         * 画出我们自己的坦克,首先判断自己的坦克是否是活的,如果是,则画出来
         * 否则,则提示 Game  Over ,并休眠100000毫秒
         * */
        if(tk.isLive()){
            tk.draw(g); 
        }
        else{
            g.drawString("Game Over,按键A可以复活!!!",GAME_WIDTH/2 , GAME_HEIGHT/2);
        }   
 
        /*
         * 将敌方坦克也画出来,如果没有了敌方坦克,则产生一定数量的地方坦克
         * */
        if(enemyTanks.size()==0){
            this.produceTank();
        }
        for(int i=0;i<enemytanks.size();i++){ code="" e="explodes.get(i);" enemy="enemyTanks.get(i);" explode="" i="0;i<explodes.size();i++){" 
        int="" missile="" ms="missiles.get(i);" tank=""></enemytanks.size();i++){></code></code></code></code></code></code>

在Tank类中的keyReleased方法中添加键盘A的事件。具体代码如下:

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs"><code class="hljs java">
<code class="hljs cs"><code class="hljs cs"><code class="hljs cs">        //键盘按键松下时,也要进行记录
        public void keyReleased(KeyEvent e) {
            int key=e.getKeyCode();
            switch(key){
            case KeyEvent.VK_A:
                produceMainTank();
                break;
            //.....一些其它的case
            }
        }
 
        private void produceMainTank() {
            Tank t=this.tc.getTk();
            if(!t.isLive()){
                int x = r.nextInt(100)+200;
                int y = r.nextInt(150)+300;
                Tank newTank =new Tank(x,y,true,Direction.STOP,this.tc);
                this.tc.setTk(newTank);
            }           
        }
</code></code></code></code></code></code></code>

以上就基本上实现了坦克大战的敌我双方的游戏了。但是,还有一些需要我们完善的功能,例如,加入一些墙等等。在后面,将会慢慢实现。也会在博文中进行记录。

 以上就是《Java小游戏实现》:坦克大战(续三)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn