坦克大战3.1

1.画出坦克

2.我的坦克可以上下左右移动
3.批量生产敌方坦克
4.我方坦克要求可以打出移动的子弹,按下J键发射子弹
5.可以连发子弹(5颗吧)
 6.子弹击中敌方坦克时,敌方坦克消失

  所以我们此时要做的就是第四点,但是我想直接把代码写上。ok 就这样办

点开,Viem Code,这是其中的Member类

package re_code2;

import java.util.Vector;

//子弹类
class Shot implements Runnable{
    int x;
    int y;
    int direct;
    int speed=2;
    boolean isLive=true;
    
    public Shot(int x,int y,int direct) {
        this.x=x;
        this.y=y;
        this.direct=direct;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            switch(direct) {
            case 0:
                //
                y-=speed;
                break;
            case 1:
                //
                x+=speed;
                break;
            case 2:
                //
                y+=speed;
                break;
            case 3:
                //
                x-=speed;
                break;
                
            }
//            System.out.println("子弹的坐标为X="+x+"Y="+y);
        //子弹何时死亡?
        //判断子弹是否碰到墙壁边缘
            if(x < -2 || x > 800 || y< -2 || y > 600) {
                this.isLive=false;
                break;
            }
        }
    }
    
}
//坦克类
class Tank{

    int x=0;        //表示坦克的横坐标
    int y=0;        //表示坦克的纵坐标
    int direct =0;    //坦克方向 0表示上,1右面,2下,3左
    int speed = 2;    //坦克的移动速度
    int color;        //定义坦克的颜色
    public int getColor() {
        return color;
    }
    public void setColor(int color) {
        this.color = color;
    }
    public int getSpeed() {
        return speed;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public int getDirect() {
        return direct;
    }
    public void setDirect(int direct) {
        this.direct = direct;
    }
    public Tank(int x,int y) {
        this.x=x;
        this.y=y;
    }
    
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
}

//我的坦克
class Hero extends Tank{
    //子弹
    Vector <Shot> ss=new Vector<Shot>();        //存储子弹
    Shot s=null;
    
    public Hero(int x,int y) {
        super(x,y);
    }    
//开火 上下左右移动,这是我的坦克的所有行为
    /**
     * 关于开火,也取决于我的坦克的朝向
     * */
    public void shotEnmpy() {
        switch(this.direct) {
        case 0:
            s=new Shot(x,y-15,0);    
            ss.add(s);
            break;
        case 1:
            s=new Shot(x+20,y,1);  
            ss.add(s);
            break;
        case 2:
            s=new Shot(x,y+20,2);
            ss.add(s);
            break;
        case 3:
            s=new Shot(x-20,y,3);
            ss.add(s);
            break;
        }
        //启动子弹线程
        Thread t=new Thread(s);
        t.start();
        System.out.println("我方发射的存活子弹数量"+ss.size());
        
    }    
    public void move_up() {
        y-=speed;
    }
    public void move_down() {
        y+=speed;
    }
    public void move_left() {
        x-=speed;
    }
    public void move_right() {
        x+=speed;
    }
}


//敌人的坦克
class Enmpy extends Tank{
    boolean isLive = true;

    public Enmpy(int x, int y) {
        super(x, y);
        // TODO Auto-generated constructor stub
    }
    
}
View Code

这是主类

package re_code2;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

import javax.swing.*;
import javax.swing.event.*;
/**
 * 功能:坦克游戏的3.1版
 * 1.画出坦克
 * 2.我的坦克可以上下左右移动
 * 3.批量生产敌方坦克
 * 4.我方坦克要求可以打出移动的子弹,按下J键发射子弹 
 * 5.可以连发子弹(5颗吧)
 * 6.子弹击中敌方坦克时,敌方坦克消失
 * @author ybz
 *Last_update2018年9月24日下午7:30:40
 */

public class MyTankGame3 extends JFrame {
    MyPanel mp=null;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyTankGame3 mtg=new MyTankGame3();
        
    }

    public MyTankGame3() {
        mp=new MyPanel();
        //启动mp线程
        Thread tt=new Thread(mp);
        tt.start();
        this.addKeyListener(mp);
        this.add(mp);
        this.setSize(800,600);
        this.setTitle("坦克大战");
        this.setVisible(true);
    }
}


//我的面板
class MyPanel extends JPanel implements KeyListener,Runnable{

    Hero hero=null;                    //定义一个我的坦克
    Vector<Enmpy> ets=new Vector<Enmpy>();    //定义敌人的坦克组
    int enSize=3;                            //敌方坦克数量     
    //构造函数
    public MyPanel () {
        hero=new Hero(100,400); 
                                //初始化敌方坦克
        for(int i=0;i<enSize;i++) {
            Enmpy et=new Enmpy((i+1)*50,30);
            et.setColor(0);
            et.setDirect(2);
            ets.add(et);
        }
    }
    
    //重写paint方法
    public void paint(Graphics g) {
        super.paint(g);
        //画出我的坦克(到时再封装成一个函数)
        //1.画出左边矩形
        g.fillRect(0,0,800,600);
    //画出自己的坦克
        this.drawTank(hero.getX(), hero.getY(), g,this.hero.direct, 1);
    //绘制炮弹
        for(int i=0;i<this.hero.ss.size();i++) {
            Shot Myshot = hero.ss.get(i);
            if(Myshot != null && Myshot.isLive ==true) {
                g.draw3DRect(Myshot.x, Myshot.y, 2, 2, false);
            }
            if(Myshot.isLive == false) {
                this.hero.ss.remove(Myshot);
            }
        }

    //画出敌方坦克
            //重新绘制坦克,过滤掉isLive = false 的坦克
        for(int i=0;i<ets.size();i++) {//-------------------------------------------new
            //取出每辆坦克,判断状态
            Enmpy em =ets.get(i);
            if(em.isLive == true) {        //符合状态的敌方坦克才会被绘制出来
                for(int j=0;j<ets.size();j++) {
                    this.drawTank(em.getX(), em.getY(), g, em.getDirect(), 0 );                    
                }
            }
        }
    }
    //构建一个函数用来判断子弹是否击中坦克----------------------------------------new
    public void HitTank(Shot s,Enmpy e) {
        switch(e.direct) {
        case 0:
        case 2:
            if(s.x > (e.x - 10)&&s.x < (e.x + 10)&&s.y>(e.y-20)&&s.y<(e.y+20))
            {
                s.isLive = false;
                e.isLive = false;
            }break;
        case 1:
        case 3:
            if(s.x > (e.x - 20)&&s.x < (e.x + 20)&&s.y>(e.y-10)&&s.y<(e.y+10)) {
                s.isLive = false;
                e.isLive = false;
            }
        }
    }
    //画出坦克的函数
    public void drawTank(int x,int y,Graphics g,int direct,int type) {
        //判断是什么类型的坦克
        switch(type) {
        case 0:
            g.setColor(Color.red);
            break;
        case 1:
            g.setColor(Color.yellow);
            break;
        }
        //判断方向
        switch(direct) {
        //向上
        case 0:

            g.fill3DRect(x-10, y-10, 5, 30,false);
            //2.画出右边矩形
            g.fill3DRect(x+5, y-10, 5, 30,false);
            //3.画出中间矩形
            g.fill3DRect(x-5, y-5, 10, 20,false);
            //4.画出圆形
            g.fillOval(x-5, y, 10, 10);
            //5.画出炮管
            g.drawLine(x, y,x,y-15);
            break;
        case 1:
            g.fill3DRect(x-15, y-10, 30, 5,false);
            //2.画出右边矩形
            g.fill3DRect(x-15, y+5, 30, 5,false);
            //3.画出中间矩形
            g.fill3DRect(x-10, y-5, 20, 10,false);
            //4.画出圆形
            g.fillOval(x-5, y-5, 10, 10);
            //5.画出炮管
            g.drawLine(x, y,x+20,y);
            break;
        case 2:
            g.fill3DRect(x-10, y-10, 5, 30,false);
            //2.画出右边矩形
            g.fill3DRect(x+5, y-10, 5, 30,false);
            //3.画出中间矩形
            g.fill3DRect(x-5, y-5, 10, 20,false);
            //4.画出圆形
            g.fillOval(x-5, y, 10, 10);
            //5.画出炮管
            g.drawLine(x, y,x,y+25);
            break;
        case 3:
            g.fill3DRect(x-15, y-10, 30, 5,false);
            //2.画出右边矩形
            g.fill3DRect(x-15, y+5, 30, 5,false);
            //3.画出中间矩形
            g.fill3DRect(x-10, y-5, 20, 10,false);
            //4.画出圆形
            g.fillOval(x-5, y-5, 10, 10);
            //5.画出炮管
            g.drawLine(x, y,x-20,y);
            break;
        }
    }

    @Override    //键值处理
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override    //键按下处理 w s a d
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W) {
            this.hero.setDirect(0);
            this.hero.move_up();
        }else if(e.getKeyCode() == KeyEvent.VK_D) {
            this.hero.setDirect(1);
            this.hero.move_right();
        }else if(e.getKeyCode() == KeyEvent.VK_S) {
            this.hero.setDirect(2);
            this.hero.move_down();
        }else if(e.getKeyCode() == KeyEvent.VK_A) {
            this.hero.setDirect(3);
            this.hero.move_left();
        }
        
        //判断玩家是否按下J键
        if(e.getKeyCode() == KeyEvent.VK_J) {
            //开火
            if(this.hero.ss.size() < 5) {        //控制我方坦克发射子弹的数量
                this.hero.shotEnmpy();                
            }
            
        }
        this.repaint();
    }

    @Override    //键释放处理
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        //每隔100毫秒去重绘
        while(true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            for(int i=0;i<hero.ss.size();i++) {//--------------------------------------new
                //取出每颗炮弹
                Shot myshot = hero.ss.get(i);
                if(myshot.isLive == true) {        //判断状态是否符合要求,只有存活的子弹 才能击中坦克
                    for(int j=0;j<ets.size();j++) {    //别写成hero.ets了,ets不是hero对象上的
                        //取出每辆敌方坦克
                        Enmpy ee = ets.get(j);
                        if(ee.isLive == true) {    //判断状态是否符合要求,只有存活的坦克 才能 被击中
                            //取出了每辆坦克和每个子弹,确保是符合状态的,然后调用方法判断是否击中
                            this.HitTank(myshot, ee);
                        }
                    }
                }
            }
            //重绘
            this.repaint();
        }
    }
    
}
View Code

   看着是挺麻烦挺乱的,但是机构还不错,拓展性很好,后面的所有功能的实现也是基于主类来写的。

行吧,慢慢来,有时候我也得写好几遍才能弄懂的。

猜你喜欢

转载自www.cnblogs.com/ybzmy/p/9715113.html