猿学-java实现坦克大战游戏--坦克发射子弹

一、任务需求

添加hero坦克子弹并且发射。

二、思路

1.创建子弹类

1.由于每颗子弹都是一个独立的线程,会不断变换子弹坐标,所以子弹类要实现Runnable接口。

2.子弹需要坐标x,y以及方向,所以构造函数有三个参数。

3.实现Runnable接口后,要覆盖run方法:

    1.如果不让线程sleep,子弹飞出去很快,快到在屏幕如上瞬间消失。

    2.所以增加一个sleep()

    3.另外,子弹需要判断四个方向,增加switch语句

    4.子弹跑出屏幕需要死亡,增加变量islive判断是否存活。否则无限制飞行,不断占用内存空间。

2.hero坦克类中加入shotEnemy()方法,表示发射子弹

1.新建子弹变量s

    Shot s = null;

2.判断开火的方向,增加switch语句。

3.开火后,启动线程。

Thread t =newThread(s);

    t.start();

3.完成子弹实现过程,接着要在屏幕中让子弹显示,即画出子弹

1.paintComponent方法里加入,画出子弹

    判断子弹是否存活

    hero.s!=null很重要,游戏刚开始没有发射子弹,hero.s=null,此时进入if去画子弹会出现异常。

    if(hero.s!=null&&hero.s.isLive==true){

        g.setColor(Color.red);

        g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false);

    }

2.在KeyPressed监听器处添加,按下J键发射一颗子弹

    if(e.getKeyCode()==KeyEvent.VK_J){

        hero.shotEnemy();

    }

4.MyPanel实现Runnable接口

1.由于子弹打出去后,需要不断让它显示,屏幕每隔一段时间需要repaint()

    所以重载run()方法,让MyPanel每隔一段时间repaint()一次

    publicvoidrun() {

    while(true){

        try{

            Thread.sleep(100);//休息100ms,重画一次MyPanel

        } catch(Exception e) {

            e.printStackTrace();

        }

        repaint();

    }

5.由于MyPanel实现了Runnable接口,所以让该线程跑起来

1.在MyTankGame方法中启动线程即可

    p1 = newMyPanel();

        Thread t = newThread(p1);

        t.start();

三、代码如下

MyTankGame.java

<�喎�"https://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> /** * 功能:坦克游戏的2.0 * 1.画出坦克 * 2.坦克的移动 * 3.坦克发射子弹 */ package Tank_03; import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class MyTankGame2 extends JFrame{ MyPanel p1 = null; public MyTankGame2(){ p1 = new MyPanel(); Thread t = new Thread(p1); t.start(); add(p1); setSize(400, 300); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addKeyListener(p1);//注册监听 } public static void main(String[] args) { new MyTankGame2(); } } //画图 @SuppressWarnings("serial") class MyPanel extends JPanel implements KeyListener,Runnable{ Hero hero = null; Vector ets = new Vector(); int enSize = 3; public MyPanel(){ hero = new Hero(100,100);//设置坦克出现的位置(10,10) // 初始化敌人的坦克 for(int i=0;i坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标 * * 如果type是default 则默认颜色为画出黑色坦克 * * 封装性:将坦克封装到方法中。 * */ public void drawTank(int x,int y,Graphics g,int direct,int type){ switch (type) { case 0: g.setColor(Color.cyan); break; case 1: g.setColor(Color.yellow); default: break; } switch (direct) { case 0: //向上 g.fill3DRect(x , y , 5 , 30, false); g.fill3DRect(x+15, y , 5 , 30, false); g.fill3DRect(x+5 , y+5 , 10, 20, false); g.fillOval(x+4, y+10, 10 , 10); g.drawLine(x+9, y+15, x+9, y ); break; case 1: //向下w g.fill3DRect(x , y , 5 , 30, false); g.fill3DRect(x+15, y , 5 , 30, false); g.fill3DRect(x+5 , y+5 , 10, 20, false); g.fillOval(x+4, y+10, 10 , 10); g.drawLine(x+9, y+15, x+9, y+30 ); break; case 2: //向左 g.fill3DRect(x , y , 30, 5 , false); g.fill3DRect(x , y+15 , 30, 5 , false); g.fill3DRect(x+5 , y+5 , 20, 10, false); g.fillOval(x+9 , y+4, 10 , 10 ); g.drawLine(x+5, y+9, x-4, y+9); break; case 3: //向右 g.fill3DRect(x , y , 30, 5 , false); g.fill3DRect(x , y+15 , 30, 5 , false); g.fill3DRect(x+5 , y+5 , 20, 10, false); g.fillOval(x+9 , y+4, 10 , 10 ); g.drawLine(x+15, y+9, x+30, y+9); break; default: break; } //repaint(); 因为监听器里面有repaint() 所以不用在加repaint()了 } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) {//实现接口 根据按键上下左右移动 可以控制速度和移动 if(e.getKeyCode()==KeyEvent.VK_W){ hero.setDirect(0); hero.moveUp(); }else if(e.getKeyCode()==KeyEvent.VK_S){ hero.setDirect(1); hero.moveDown(); }else if(e.getKeyCode()==KeyEvent.VK_A){ hero.setDirect(2); hero.moveLeft(); }else if(e.getKeyCode()==KeyEvent.VK_D){ hero.setDirect(3); hero.moveRight(); } if(e.getKeyCode()==KeyEvent.VK_J){ //开火 hero.shotEnemy(); } //判断玩家是否按下J攻击键 repaint(); } @Override public void keyReleased(KeyEvent e) { } //@Override public void run() { //每隔100毫秒 重新画图 while(true){ try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } repaint(); } } }

members.java

packageTank_03;

//坦克父类  可以设置坦克出现位置(x,y)

classTank {

    intx = 0;

    inty = 0;

    intspeed = 10;

    intDirect = 0;

    intcolor;

    publicintgetColor() {

        returncolor;

    }

    publicvoidsetColor(intcolor) {

        this.color = color;

    }

    publicintgetDirect() {

        returnDirect;

    }

    publicvoidsetDirect(intdirect) {

        Direct = direct;

    }

    publicintgetSpeed() {

        returnspeed;

    }

    publicvoidsetSpeed(intspeed) {

        this.speed = speed;

    }

    publicTank (intx,inty){

        this.x = x;

        this.y = y;

    }

    publicintgetX() {

        returnx;

    }

    publicvoidsetX(intx) {

        this.x = x;

    }

    publicintgetY() {

        returny;

    }

    publicvoidsetY(inty) {

        this.y = y;

    }



    //视频中是把移动放在hero类中


}

//敌方坦克

classEnemyTank extendsTank{


    publicEnemyTank(intx, inty) {

        super(x, y);

    }

}

//我的英雄坦克

classHero extendsTank{


    //子弹

    Shot s = null;


    publicHero(intx,inty){

        super(x, y);

    }

    //开火

    publicvoidshotEnemy(){


        switch(Direct) {

        case0:

            s = newShot(x+8,y-4,0);

            break;

        case1:

            s = newShot(x+9,y+32,1);

            break;

        case2:

            s = newShot(x-8,y+8,2);

            break;

        case3:

            s = newShot(x+32,y+9,3);

            break;

        default:

            break;

        }

        Thread t =newThread(s);

        t.start();

    }

    publicvoidmoveUp(){

        y-=speed;

    }

    publicvoidmoveDown(){

        y+=speed;

    }

    publicvoidmoveLeft(){

        x-=speed;

    }

    publicvoidmoveRight(){

        x+=speed;

    }

}

//子弹类

classShot implementsRunnable{

    intx;

    inty;

    intDirect;

    intspeed = 5;

    booleanisLive = true;

    publicShot(intx,inty,intDirect){

        this.x=x;

        this.y=y;

        this.Direct = Direct;

    }

    @Override


    publicvoidrun() {

        while(true){

            try{

                Thread.sleep(50);

            } catch(Exception e) {

                // TODO: handle exception

            }

            switch(Direct){

            case0:

                y-=speed;

                break;

            case1:

                y+=speed;

                break;

            case2:

                x-=speed;

                break;

            case3:

                x+=speed;

                break;

            default:

                break;

            }


//          System.out.println(""+x+" "+y);

            //子弹何时死亡

            if(x<0||x>400||y<0||y>300){

                isLive = false;

                break;

            }

        }

    }

}

四、效果图

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

推荐阅读更多精彩内容