猿学-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;

    }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容