猿学-java坦克大战小游戏

按照教程写了一个Java小游戏,花了19天时间去抄了一遍,今天终于抄完了?:.?ヽ(?????)??.:?+?

github地址:https://github.com/qq1367212627/kuaidi

坦克游戏主程序

packageTankClient;

importBlood.Blood;

importMissile.*;

importjava.awt.*;

importjava.awt.event.*;

importjava.util.ArrayList;

importTankClient.Tank.*;

importWall.Wall;

publicclassTankClient extendsFrame {

    publicstaticfinalintGAME_WIDTH = 800;

    publicstaticfinalintGAME_HEIGHT = 600;

    Tank myTank = newTank(400, 400,true, Direction.STOP,this);        //将本身的引用传递过去,实现获取Missile的数据

    publicArrayList missiles = newArrayList();

    publicArrayList expelodes =newArrayList();

    publicArrayList tanks = newArrayList();       //多个坦克

    Image offScreenImage = null;

    Wall w1=newWall(100,200,20,150,this);

    Wall w2=newWall(300,100,300,20,this);

    privateBlood b= newBlood();

    publicvoidpaint(Graphics g) {

        g.drawString("炮弹数量:"+missiles.size(),50,50);

        g.drawString("爆炸数量:"+expelodes.size(),50,70);

        g.drawString("敌人数量:"+tanks.size(),50,90);

        g.drawString("生命值:"+myTank.getLife(),50,110);

        if(tanks.size()<=0)addTanks();

        for(inti=0;i

坦克类

packageTankClient;

importBlood.Blood;

importMissile.Missile;

importWall.Wall;

importcom.sun.org.apache.bcel.internal.generic.DREM;

importjava.awt.*;

importjava.awt.event.*;

importjava.util.ArrayList;

importjava.util.Random;

publicclassTank {

    publicstaticfinalintXSPEED = 5;

    publicstaticfinalintYSPEED = 5;                 //坦克速度

    publicstaticfinalintWIDTH = 30;

    publicstaticfinalintHEIGHT = 30;

    publicTankClient tc = null;                                 //持有TankClient的引用实现数据传输

    privateDirection ptDir = Direction.D;                //炮筒的方向

    privateintx, y;

    privatebooleangood;                                //敌我标记

    privatebooleanbL = false, bU = false, bR = false, bD = false; //方向的确定

    publicenumDirection {L, LU, U, RU, R, RD, D, LD, STOP};   //方向

    privatestaticRandom r = newRandom();

    privateintstep = r.nextInt(8) + 3;                        //延时标记,使得坦克多移动一些距离

    intoldx, oldy;

    privatebooleanLive = true;                          //记录坦克是否存活

    privateDirection dir = Direction.STOP;                 //初始化为停止

    privateBloodBar bb = newBloodBar();

    publicintgetLife() {

        returnlife;

    }

    publicvoidsetLife(intlife) {

        this.life = life;

    }

    privateintlife=100;

    publicbooleanisGood() {

        returngood;

    }

    publicvoidsetGood(booleangood) {

        this.good = good;

    }

    publicbooleanisLive() {

        returnLive;

    }

    publicvoidsetLive(booleanlive) {

        Live = live;

    }

    publicTank(intx, inty, boolean_good) {

        this.x = x;

        this.y = y;

        this.oldx = x;

        this.oldy = y;

        this.good = _good;

    }

    publicTank(int_x, int_y, boolean_good, Direction _dir, TankClient _tc) {    //将TankClient 引用传递,实现Missile的交换

        this(_x, _y, _good);

        this.dir = _dir;

        tc = _tc;

    }

    publicvoiddraw(Graphics g) {          //画出

        if(!Live) {

            return;

        }

        if(this.isGood())bb.draw(g);                //若是好坦克,画出血条

        Color c = g.getColor();

        if(good) g.setColor(Color.RED); //我方坦克为红色

        elseg.setColor(Color.blue);    //敌方的颜色为蓝色

        g.fillOval(x, y, WIDTH, HEIGHT);

        g.setColor(c);

        switch(ptDir)                           //画出炮筒的方向

        {

            caseL:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT / 2);

                break;

            caseLU:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y);

                break;

            caseU:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y);

                break;

            caseRU:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y);

                break;

            caseR:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT / 2);

                break;

            caseRD:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT);

                break;

            caseD:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y + Tank.HEIGHT);

                break;

            caseLD:

                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT);

                break;

        }

        if(x < 0) x = 0;

        if(y < 30) y = 30;

        if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;

        if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;//判断坦克是否超出边界,如果超出就停下

        move();

    }

    voidmove() {               //运动函数

        this.oldx = x;

        this.oldy = y;

        switch(dir) {

            caseL:

                x -= XSPEED;

                break;

            caseLU:

                x -= XSPEED;

                y -= YSPEED;

                break;

            caseU:

                y -= YSPEED;

                break;

            caseRU:

                x += XSPEED;

                y -= YSPEED;

                break;

            caseR:

                x += XSPEED;

                break;

            caseRD:

                x += XSPEED;

                y += YSPEED;

                break;

            caseD:

                y += YSPEED;

                break;

            caseLD:

                x -= XSPEED;

                y += YSPEED;

                break;

            caseSTOP:

                break;

        }

        if(!good) {                              //随机产生方向

            if(step == 0) {

                step = r.nextInt(8) + 3;

                Direction[] dirs = Direction.values();

                intrn = r.nextInt(dirs.length);

                while(dirs[rn] == Direction.STOP)

                    rn = r.nextInt(dirs.length);

                dir = dirs[rn];

                ptDir = dir;

            }

            step--;

            if(r.nextInt(40) > 38) this.fire();

        }

    }

    publicvoidkeyPressed(KeyEvent e) {            //按键被按住的动作

        intkey = e.getKeyCode();

        switch(key) {

            caseKeyEvent.VK_LEFT:

                bL = true;

                break;

            caseKeyEvent.VK_UP:

                bU = true;

                break;

            caseKeyEvent.VK_RIGHT:

                bR = true;

                break;

            caseKeyEvent.VK_DOWN:

                bD = true;

                break;

        }

        locateDirection();

        if(this.dir != Direction.STOP)            //保存炮筒的方向

        {

            ptDir = this.dir;

        }

    }

    voidlocateDirection() {                        //判断方向

        if(bL && !bU && !bR && !bD) dir = Direction.L;

        elseif(bL && bU && !bR && !bD) dir = Direction.LU;

        elseif(!bL && bU && !bR && !bD) dir = Direction.U;

        elseif(!bL && bU && bR && !bD) dir = Direction.RU;

        elseif(!bL && !bU && bR && !bD) dir = Direction.R;

        elseif(!bL && !bU && bR && bD) dir = Direction.RD;

        elseif(!bL && !bU && !bR && bD) dir = Direction.D;

        elseif(bL && !bU && !bR && bD) dir = Direction.LD;

        elseif(!bL && !bU && !bR && !bD) dir = Direction.STOP;

    }

    publicvoidkeyReleased(KeyEvent e) {       //按键释放的操作

        intkey = e.getKeyCode();

        switch(key) {

            caseKeyEvent.VK_CONTROL:

                if(this.Live) this.fire();            //添加多个炮弹

                break;

            caseKeyEvent.VK_LEFT:

                bL = false;

                break;

            caseKeyEvent.VK_UP:

                bU = false;

                break;

            caseKeyEvent.VK_RIGHT:

                bR = false;

                break;

            caseKeyEvent.VK_DOWN:

                bD = false;

                break;

            caseKeyEvent.VK_A:

                if(this.isLive())superFire();

                break;

            caseKeyEvent.VK_F2:

                if(!tc.myTank.isLive()){

                    tc.myTank.setLive(true);

                    tc.myTank.setLife(100);

                }

                break;

        }

        locateDirection();

    }

    publicMissile fire() {                                          //开火方法

        int_x = this.x + Tank.WIDTH / 2- Missile.WIDTH / 2;

        int_y = this.y + Tank.HEIGHT / 2- Missile.HEIGHT / 2;     //使子弹从中心发出

        Missile m = newMissile(_x, _y, good, ptDir, this.tc);          //传递自身引用

        this.tc.missiles.add(m);

        returnm;

    }


    publicMissile fire(Direction Missiledir) {                                          //开火方法

        int_x = this.x + Tank.WIDTH / 2- Missile.WIDTH / 2;

        int_y = this.y + Tank.HEIGHT / 2- Missile.HEIGHT / 2;     //使子弹从中心发出

        Missile m = newMissile(_x, _y, good, Missiledir, this.tc);          //传递自身引用

        this.tc.missiles.add(m);

        returnm;

    }

    publicRectangle getRect() {

        returnnewRectangle(x, y, WIDTH, HEIGHT);

    }

    publicbooleancoollideWithWall(Wall w) {                   //判断坦克撞墙

        if(this.isLive() && this.getRect().intersects(w.getRect())) {

            this.dir = Direction.STOP;

            this.stay();

            returntrue;

        }

        returnfalse;

    }

    privatevoidstay(){                        //回溯到上一次的位置

        this.x=this.oldx;

        this.y=this.oldy;

    }

    publicbooleancoollideWithTank(Tank t){                             //与单辆坦克碰撞

            if(this!=t&&this.isLive() &&t.isLive() && this.getRect().intersects(t.getRect())) {

                this.stay();

                t.stay();

                returntrue;

            }

        returnfalse;

    }

    publicbooleancoollideWithTanks(ArrayList tanks){            //与多辆坦克碰撞

        booleanIscoollideWithTanks=false;

        for(inti = 0;i


爆炸类

packageTankClient;

importjava.awt.*;

/**

 * Created by lewis on 2016/10/5.

 */

publicclassExplode {

    intx,y;

    privatebooleanLive=true;

    intstep=0;                                             //数组下标,记录爆炸的状态

    TankClient tc=null;

    int[] diameter={4,7,12,18,26,32,49,30,14,6};           //爆炸直径大小


    publicbooleanisLive() {

        returnLive;

    }

    publicvoidsetLive(booleanlive) {

        Live = live;

    }

    publicExplode(int_x,int_y,TankClient _tc){

        x=_x;

        y=_y;

        tc=_tc;

    }

    publicvoiddraw(Graphics g){

        if(!Live)return;

        if(step==diameter.length){

            Live=false;

            step=0;

            return;

        }

        Color c = g.getColor();

        g.setColor(Color.ORANGE);

        g.fillOval(x,y,diameter[step],diameter[step]);

        step++;

    }

}

墙类

packageWall;

importTankClient.TankClient;

importjava.awt.*;

/**

 * Created by lewis on 2016/10/6.

 */

publicclassWall{

    intx,y,w,h;

    TankClient tc;

    publicWall(intx, inty, intw, inth, TankClient tc) {

        this.x = x;

        this.y = y;

        this.w = w;

        this.h = h;

        this.tc = tc;

    }

    publicvoiddraw(Graphics g){

        g.fillRect(x,y,w,h);

    }

    publicRectangle getRect(){

        returnnewRectangle(x,y,w,h);

    }

}

加血血块类

packageBlood;

importTankClient.TankClient;

importjava.awt.*;

/**

 * Created by lewis on 2016/10/6.

 *          加血模块

 *

 */

publicclassBlood {

    intx,y,w,h,step=0;

    TankClient tc;

    privatebooleanLive=true;

    privateint[][] pos={                       //血块 轨迹

            {350,300},{360,300},{375,275},{400,200},{360,270},{340,280}

    };

    publicBlood(intx, inty, intw, inth, TankClient tc) {

        this.x = x;

        this.y = y;

        this.w = w;

        this.h = h;

        this.tc = tc;

    }

    publicBlood() {

        x=pos[0][0];

        y=pos[0][1];

        w=h=15;

        step=0;

    }

    publicvoiddraw(Graphics g){

        if(!this.isLive())return;

        Color c = g.getColor();

        g.setColor( Color.MAGENTA);

        g.fillRect(x,y,w,h);

        g.setColor(c);

        move();

    }

    privatevoidmove(){

        step++;

        if(step==pos.length) {step=0;}

        x=pos[step][0];

        y=pos[step][1];

    }

    publicRectangle getRect(){

        returnnewRectangle(x,y,w,h);

    }

    publicbooleanisLive() {

        returnLive;

    }

    publicvoidsetLive(booleanlive) {

        Live = live;

    }

}

子弹类

packageMissile;

importTankClient.Tank;

importTankClient.TankClient;

importTankClient.Explode;

importWall.Wall;

importjava.awt.*;

importjava.util.ArrayList;

publicclassMissile {

    publicstaticfinalintXSPEED = 10;

    publicstaticfinalintYSPEED = 10;

    publicstaticfinalintWIDTH = 10;

    publicstaticfinalintHEIGHT = 10;

    intx, y;

    privateTankClient tc;

    privatebooleangood;

    privatebooleanLive=true;                       //判断炮弹是否存活

    Tank.Direction dir;

    publicbooleanisLive() {

        returnLive;

    }

    publicvoidsetLive(booleanlive) {

        Live = live;

    }

    publicMissile(intx, inty ,Tank.Direction dir) {

        this.x = x;

        this.y = y;

        this.dir = dir;

    }

    publicMissile(intx, inty,boolean_good, Tank.Direction dir,TankClient _tc) {

       this(x,y,dir);

        this.good=_good;

        this.tc=_tc;

    }

    publicvoiddraw(Graphics g) {

        if(!Live){

            tc.missiles.remove(this);

            return;

        }

        Color c = g.getColor();

        g.setColor(Color.BLACK);

        g.fillOval(x, y, WIDTH, HEIGHT);

        g.setColor(c);

        move();

    }

    privatevoidmove() {

        switch(dir) {

            caseL:

                x -= XSPEED;

                break;

            caseLU:

                x -= XSPEED;

                y -= YSPEED;

                break;

            caseU:

                y -= YSPEED;

                break;

            caseRU:

                x += XSPEED;

                y -= YSPEED;

                break;

            caseR:

                x += XSPEED;

                break;

            caseRD:

                x += XSPEED;

                y += YSPEED;

                break;

            caseD:

                y += YSPEED;

                break;

            caseLD:

                x -= XSPEED;

                y += YSPEED;

                break;

        }

        if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT) {       //判断炮弹是否跑出边界

            Live=false;

            tc.missiles.remove(this);        //若炮弹跑出边界则从集合中移除

        }

    }

    publicRectangle getRect(){

        returnnewRectangle(x,y,WIDTH, HEIGHT);

    }

    publicbooleanhitTank(Tank t){                                         //判断是否相交

        if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()) {

            if(t.isGood()){                                 //区分坦克对待

                t.setLife(t.getLife()-20);

                if(t.getLife()<=0)t.setLive(false);

            }

            else{

                t.setLive(false);

            }

            this.setLive(false);                            //炮弹死亡

            Explode e = newExplode(x,y,tc);

            tc.expelodes.add(e);

            returntrue;

        }

        returnfalse;

    }

    publicbooleanhitTanks(ArrayList tanks) {            //攻击多个坦克

        for(inti = 0; i < tanks.size(); i++){

            if(hitTank(tanks.get(i))){

                returntrue;

            }

        }

        returnfalse;

    }

    publicbooleanhitWall(Wall w){                 //判断子弹撞墙

        if(this.isLive()&&this.getRect().intersects(w.getRect())){

            this.setLive(false);                    //撞上墙则设为死亡

            returntrue;

        }

        returnfalse;

    }

}

你可能感兴趣的:(猿学-java坦克大战小游戏)