> Java > java지도 시간 > 본문

'Java 미니게임 구현': 탱크 전투(계속 3)

黄舟
풀어 주다: 2016-12-27 13:21:19
원래의
1622명이 탐색했습니다.

블로그 게시물 "Java 미니 게임 구현": 탱크 전투(계속 2)에서 탱크가 총알을 발사하여 적 탱크를 공격할 수 있다는 것이 실현되었습니다. 이 블로그 게시물은 이를 기반으로 계속해서 더 많은 기능을 구현합니다.

완성된 기능: 폭발 효과 추가

이전 버전에서는 우리에게 익숙한 폭발과 유사한 효과를 내지 않고 적 탱크를 공격했는데 적 탱크가 그냥 사라졌습니다. 다음으로 이 폭발 효과를 추가합니다.

Java 미니게임 구현: 탱크 전투(계속 3)

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

먼저 모두, 폭발 클래스 Explode를 생성합니다.

폭발 클래스에는 다음과 같은 속성과 메서드가 있습니다

1. 위치 정보 x, y;

2. 살아있음을 식별하는 속성

3. 폭발을 일으키는 이미지 배열(여기서는 직경 그리기로 대체)

드로우 방법

코드는 다음과 같습니다.

<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>
로그인 후 복사

이 폭발 클래스를 작성한 후 TankClient 클래스에서 테스트할 수 있습니다. 테스트를 위해 추가해야 하는 코드는 다음과 같습니다.

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

테스트 결과 폭발과 유사한 효과가 나타났습니다.

전체 기능: 총알이 탱크에 닿을 때 폭발 효과 추가

이 문장에서 볼 수 있듯이 총알이 탱크에 닿을 때 폭발 효과를 추가합니다. 폭발 객체를 추가해야 합니다. 따라서 이 기능을 완료하려면 아래 두 단계를 따르십시오.

1. Explosion은 컬렉션 클래스에 존재해야 합니다.

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

TankClient 클래스에 다음 코드를 추가합니다.

<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. 총알이 탱크에 부딪힌 후 폭발 개체가 생성되어 TankClient의 폭발 컬렉션에 추가되어야 합니다. .

<code class="hljs cs"><code>在Missile类中hitTank方法中添加相关代码
</code></code>
로그인 후 복사

Missile 클래스의 hitTank 메소드 코드는 다음과 같습니다.

<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>
로그인 후 복사

위에서는 총알이 탱크에 맞았을 때 폭발 효과를 얻습니다.

완성된 기능: 다수의 적 탱크 추가

이전 버전에는 우리 탱크가 한 대 있었고, 이동하거나 총알을 발사할 수 없는 적 탱크가 있었습니다. 지루합니다. 따라서 A 버튼을 눌러 인터페이스에 여러 적 탱크를 추가하거나 무작위로 탱크를 생성할 수 있습니다.

실제 게임에서는 탱크가 무작위로 생성되는 것이 일반적입니다. 탱크를 파괴하면 또 다른 배치가 생성됩니다.

구현 과정은 다음과 같습니다.

1. 특정 수의 적 탱크 개체를 저장하려면 TankClient.java에 List 적 탱크 개체를 선언합니다.

2. 임의의 위치에 특정 개수의 탱크를 무작위로 생성하려면 다음 함수를 작성하세요.

<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. 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. 이때 적 탱크가 여러 대 있으므로 Missile에 hitTanks(탱크 나열) 메서드를 추가하여 일련의 탱크를 공격합니다. TankClient에서는 모든 총알이 탱크를 향해 발사됩니다.

<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>
로그인 후 복사

완성된 기능: 적 탱크를 더 똑똑하게 만들기(이동)

이전 버전에서는 특정 수의 탱크만 무작위로 생성할 수 있었지만, 이번 버전에서는 무작위로 이동할 수 없습니다. .

변경 사항은 다음과 같습니다.

1. Tank 클래스에 다음 생성자를 추가합니다.

<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. 그런 다음 TankClient의 producerTank 메소드에서 위의 내용을 사용합니다. class 새로운 각 적 탱크 객체

<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>
로그인 후 복사

의 생성자는 1단계와 2단계를 통해 이동할 수 있지만 이는 충분하지 않습니다. 왜냐하면 항상 그를 향해 초기화되기 때문입니다. 방향은 계속 움직입니다.

이 문제를 해결하려면. Tank 클래스의 draw 메소드에서는 이동 횟수 단계를 설정하여 적 탱크의 이동 횟수가 단계에 도달하면 방향을 무작위로 변경합니다.

위 아이디어를 바탕으로 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">        //坦克没走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>
로그인 후 복사

위에서는 다수의 적 탱크의 무작위 이동을 구현합니다.

완전한 기능: 적 탱크가 총알을 발사합니다

이 버전에는 적 탱크에 총알을 발사하는 기능이 추가되었습니다.

우리 탱크도 총알을 쏘고 적 탱크도 총알을 쏘기 때문에 총알과 총알의 구별이 있어야합니다. 따라서 글머리 기호에 good 속성을 추가하여 글머리 기호가 좋은지 나쁜지 식별합니다.

구체적인 단계는 다음과 같습니다.

1. Missile 클래스에 good 속성을 추가하고 다음과 같이 생성자를 추가합니다.

<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. 탱크 클래스 fire() 메소드에서 위의 생성자를 사용하여 글머리 기호를 구성합니다. Missile ms = new Missile(x,y,this.ptDir,this.good,this.tc);this.good은 탱크의 품질을 나타냅니다. , 탱크가 좋으면 총알 개체가 좋고 그렇지 않으면 총알 개체가 나쁩니다. 즉 탱크의 품질에 따라 총알 개체가 생성됩니다

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)!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿