坦克大战代码

156 阅读1分钟

Bomb类

package yjh.Game2;

/**
 * @author YJH
 * 炸弹
 */
public class Bomb {
    int x,y;//炸弹的坐标
    int life=9;//炸弹的生命周期
    boolean isLive = true;//炸弹是否还存活

    public Bomb(int x, int y) {
        this.x = x;
        this.y = y;
    }

    //减少生命值
    public void lifeDown(){//配合出现图片的爆炸效果
        if(life>0){
            life--;
        }
        else
        {
            isLive=false;
        }
    }
}

EnemyTank类

package yjh.Game2;

import java.util.Vector;

/**
 * @author YJH
 */
public class EnemyTank extends Tank {
    //在敌人坦克类,使用Vector保存多个Shot
    Vector<Shot>shots = new Vector<>();
    boolean isLive = true;//判断敌人的坦克是否活着
    public EnemyTank(int x, int y) {
        super(x, y);
    }
}

Hero类

package yjh.Game2;

/**
 * @author YJH
 */
public class Hero extends Tank {
    //定义一个shot对象,表示一个射击(线程)
    Shot shot = null;
    public Hero(int x, int y){
        super(x,y);
    }
    //射击
    public void shotEnemyTank(){
       //创建shot对象,根据当前Hero对象的位置和方向来创建shot
        switch (getDirect()){//得到Hero的方向
            case 0://向上
                shot = new Shot(getX()+20,getY(),0);
                break;
            case 1://向右
                shot = new Shot(getX()+60,getY()+20,1);
                break;
            case 2://向下
                shot = new Shot(getX()+20,getY()+60,2);
                break;
            case 3://向左
                shot = new Shot(getX(),getY()+20,3);
                break;
            default:
                break;
        }
        //启动我们的Shot线程
        new Thread(shot).start();
    }
}

MyPanel类

package yjh.Game2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

/**
 * @author YJH
 * 绘图区
 */


//为了监听键盘事件,实现接口KeyListener
//为了让Panel不停的重绘子弹,需要将Panel实现Runnable接口,当做一个线程使用
public class MyPanel extends JPanel implements KeyListener,Runnable {
    //定义我的坦克
    Hero hero = null;
    //定义敌人的坦克,放入到Vector中
    Vector<EnemyTank>enemyTanks=new Vector<>();
    //定义一个vector,用于存放炸弹
    //说明:当我们的子弹击中敌人的坦克,就加入一个Bomb对象到vector中
    Vector<Bomb>bombs=new Vector<>();
    int enemyTankSize=3;//敌人坦克数量为3
    //定义三张炸弹照片,用于显示爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;
    public MyPanel(){
        //初始化自己的坦克
        hero = new Hero(100,100);
        //hero.setSpeed(5);
        //初始化敌人的坦克
        for(int i=0;i<enemyTankSize;i++)
        {
            EnemyTank enemyTank = new EnemyTank(100*(i+1),0);
            //设置方向
            enemyTank.setDirect(2);//方向朝下
            //给该enemyTank加入一颗子弹
            Shot shot = new Shot(enemyTank.getX()+20,enemyTank.getY()+60,enemyTank.getDirect());
            //加入到enemyTank(vector)中
            enemyTank.shots.add(shot);
            //启动Shot  对象
            new Thread(shot).start();
            //加入
            enemyTanks.add(enemyTank);
        }
        //初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/1.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/2.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/3.png"));
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0,0,1000,750);   //填充矩形,默认是黑色
        //画出坦克-用封装方法
        drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);//1---我们的坦克
        //画出Hero射击的子弹
        if(hero.shot!=null&&hero.shot.isLive==true){
            System.out.println("子弹被绘制");
           //g.fill3DRect(hero.shot.x,hero.shot.y,3,2,false);
            g.draw3DRect(hero.shot.x,hero.shot.y,1,1,false);
        }
        //如果bombs 集合中有对象,就画出
        for(int i=0;i<bombs.size();i++){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前这个bomb对象的life值去画出对应的图片
            if(bomb.life>6){
                g.drawImage(image3,bomb.x,bomb.y,60,60,this);
            }
            else if(bomb.life>3){
                g.drawImage(image2,bomb.x,bomb.y,60,60,this);
            }
            else{
                g.drawImage(image1,bomb.x,bomb.y,60,60,this);
            }
            //让炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb life为0,就从bombs的集合中删除
            if(bomb.life==0){
                bombs.remove(bomb);
            }
        }
        //drawTank(hero.getX()+60, hero.getY(),g,1,0);//0---敌人的坦克
        //drawTank(hero.getX()+140, hero.getY(), g, 2,1);//1---我们的坦克
        //drawTank(hero.getX()+220, hero.getY(), g, 3,0);//0---敌人的坦克
        //画出敌人的坦克,遍历Vector
        for(int i=0;i<enemyTanks.size();i++)
        {
            //取出坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //判断当前坦克还活着,才去画该坦克
            if(enemyTank.isLive) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
                //画出enemyTank的所有子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    //取出子弹
                    Shot shot = enemyTank.shots.get(j);
                    //绘制
                    if (shot.isLive) {
                        g.draw3DRect(shot.x, shot.y, 1, 1, false);
                    } else {
                        //从vector中移除这颗子弹
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }
    }
    //编写方法,画坦克
    /**
     * x 坦克的左上角x坐标
     * y 坦克的左上角y坐标
     * g 画笔
     * direction 方向(上下左右)
     * type 坦克类型,敌人的或者自己的
     */
    public void drawTank(int x,int y,Graphics g,int direction,int type){//坦克类型,敌人的和自己的
        switch (type){
            case 0: //敌人的坦克
                g.setColor(Color.cyan);//青色
                break;
            case 1: //我的坦克
                g.setColor(Color.yellow); //黄色
                break;
        }
        //根据坦克的方向,来绘制对应形状的坦克
        //0表示向上 1表示向右  2表示向下 3表示向左
        switch (direction){
            case 0://表示向上
                g.fill3DRect(x, y,10,60,false);//画出坦克左边的轮子
                g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子
                g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子
                g.fillOval(x+10,y+20,20,20);//画出坦克圆盖
                g.drawLine(x+20,y+30,x+20,y);//画炮筒
                break;
            case 1://表示向右
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x+10,y+10,40,20,false);
                g.fill3DRect(x,y+30,60,10,false);
                g.fillOval(x+20,y+10,20,20);
                g.drawLine(x+30,y+20,x+60,y+20);
                break;
            case 2://表示向下
                g.fill3DRect(x, y,10,60,false);//画出坦克左边的轮子
                g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子
                g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子
                g.fillOval(x+10,y+20,20,20);//画出坦克圆盖
                g.drawLine(x+20,y+30,x+20,y+60);
                break;
            case 3://表示向左
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x+10,y+10,40,20,false);
                g.fill3DRect(x,y+30,60,10,false);
                g.fillOval(x+20,y+10,20,20);
                g.drawLine(x+30,y+20,x,y+20);
                break;
            default:
                System.out.println("暂时没有处理");
        }
    }
    //编写方法,判断我方的子弹是否击中敌人的坦克
    //什么时候判断 我方的子弹是否击中敌人的坦克? run方法
    public  void hitTank(Shot s, EnemyTank enemyTank){
        //判断s 击中坦克
        switch (enemyTank.getDirect()){
            case 0://向上
            case 2://向下
                //如果子弹打到了坦克,那么子弹和坦克都消亡
                if(s.x>enemyTank.getX()&&s.x<enemyTank.getX()+40&&s.y>enemyTank.getY()&&s.y<enemyTank.getY()+60){
                    s.isLive=false;
                    enemyTank.isLive=false;
                    //创建Bomb对象,加入到bombs集合
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1://向右
            case 3://向左
                //如果子弹打到了坦克,那么子弹和坦克都消亡
                if(s.x>enemyTank.getX()&&s.x<enemyTank.getX()+60&&s.y>enemyTank.getY()&&s.y<enemyTank.getY()+40){
                    s.isLive=false;
                    enemyTank.isLive=false;
                    //创建Bomb对象,加入到bombs集合
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;
            default:
                break;
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {

    }
    //处理wdsa键按下的情况
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_W)//按下w键
        {
            //改变坦克方向
            hero.setDirect(0);//上
            hero.moveUp();
        }
        else if(e.getKeyCode()==KeyEvent.VK_D)//按下D键
        {
            hero.setDirect(1);//右
            hero.moveRight();
        }
        else if(e.getKeyCode()==KeyEvent.VK_S)//按下S键
        {
            hero.setDirect(2);//下
            hero.moveDown();
        }
        else if(e.getKeyCode()==KeyEvent.VK_A)//按下A键
        {
            hero.setDirect(3);//左
            hero.moveLeft();
        }
        //如果用户按下的是J,就发射
        if(e.getKeyCode()==KeyEvent.VK_J){
            System.out.println("用户按下了J,开始射击....");
            hero.shotEnemyTank();
        }
        //让面板重绘
        this.repaint();

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {//每隔100ms,刷新(重绘)区域,子弹就移动
        while(true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断是否击中了敌人坦克
            //如果当前我的子弹还活着
            if(hero.shot!=null&&hero.shot.isLive){
                //遍历敌人所有的坦克
                for(int i=0;i<enemyTanks.size();i++){
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(hero.shot,enemyTank);//判断是否击中了敌人的坦克
                }
            }
            this.repaint();
        }
    }
}

Shot类

package yjh.Game2;

/**
 * @author YJH
 * 射击子弹
 */
public class Shot implements Runnable{
    int x;//子弹的x坐标
    int y;//子弹的y方向
    int direct=0;//子弹方向
    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() {//射击行为
        while(true){

            //休眠50ms
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //根据方向来改变x,y坐标
            switch (direct){
                case 0://向上
                    y-=speed;
                    break;
                case 1://向右
                    x+=speed;
                    break;
                case 2://向下
                    y+=speed;
                    break;
                case 3://向左
                    x-=speed;
                    break;
            }
            //测试,输出x,y的坐标
            System.out.println("子弹 x="+x+",y="+y);
            //当子弹移动到面板边界,就销毁子弹
            if(!(x>=0&&x<=1000&&y>=0&&y<=750&&isLive))
            {
                System.out.println("子弹线程退出");
                isLive = false;
                break;
            }
        }
    }
}

Tank类

package yjh.Game2;

/**
 * @author YJH
 */
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct;//坦克方向 0(上) 1(右) 2(下) 3(左)
    private int speed = 1;//坦克的速度,初始化为1
    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    //上右下左移动方法
    public void moveUp()//向上
    {
        y-=speed;
    }
    public void moveRight()//向右
    {
        x+=speed;
    }
    public void moveDown()//向下
    {
        y+=speed;
    }
    public void moveLeft()//向左
    {
        x-=speed;
    }
    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }

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

MyGame类

package yjh.Game2;

import javax.swing.*;

/**
 * @author YJH
 */
public class MyGame extends JFrame {
    //定义MyPanel
    MyPanel mp = null;
    public static void main(String[] args) {
        MyGame game = new MyGame();
    }
    public MyGame(){
        mp = new MyPanel();
        //将mp 放入到Thread,并启动
        new Thread(mp).start();
        this.add(mp); //把面板(就是游戏的绘图区域)
        this.setSize(1000,750);
        this.addKeyListener(mp);//让JFrame 监听键盘事件
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击×号,退出程序
        this.setVisible(true);//可视化
    }
}