潜艇游戏需求:

  • 所参与的角色:

    • 战舰、深水炸弹、侦察潜艇、鱼雷潜艇、水雷潜艇、水雷
  • 角色间的关系:
    • 战舰发射深水炸弹
    • 深水炸弹可以打潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇),若打中:
      • 潜艇消失、深水炸弹消失
      • 得东西:
        • 打掉侦察潜艇,玩家得10分
        • 打掉鱼雷潜艇,玩家得40分
        • 打掉水雷潜艇,战舰得1条命
    • 水雷潜艇可以发射水雷
    • 水雷可以击打战舰,若击中:
      • 水雷消失
      • 战舰减1条命(命数为0时游戏结束)

潜艇游戏第一天:

  1. 根据参与的角色创建6个类,创建World类并测试;

潜艇游戏第二天:

  1. 给6个类添加构造方法,并测试;(以战舰类为例)

    /** 战舰 */
    public class Battleship {int width;  //宽int height; //高int x;      //x坐标int y;      //y坐标int speed;  //移动速度int life;   //命数/** 构造方法 */Battleship(){width = 66;height = 26;x = 270;y = 124;speed = 20;life = 5;}void move(){System.out.println("战舰移动啦!");}
    }

潜艇游戏第三天:

  1. 在World类中创建侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组,水雷数组,炸弹数组,并测试;

    /** 整个窗口世界 */
    public class World {public static void main(String[] args) {ObserveSubmarine[] oses = new ObserveSubmarine[3];oses[0] = new ObserveSubmarine();oses[1] = new ObserveSubmarine();oses[2] = new ObserveSubmarine();for(int i=0;i<oses.length;i++){ //遍历所有侦察潜艇System.out.println(oses[i].x+","+oses[i].y); //输出每个侦察潜艇的x和y坐标oses[i].move(); //每个侦察潜艇移动}Mine[] ms = new Mine[2];ms[0] = new Mine(100,200);ms[1] = new Mine(125,345);for(int i=0;i< ms.length;i++){ //遍历所有水雷System.out.println(ms[i].x+","+ms[i].y+","+ms[i].speed);ms[i].move();}TorpedoSubmarine[] tses = new TorpedoSubmarine[2];MineSubmarine[] mses = new MineSubmarine[3];Bomb[] bs = new Bomb[4];}
    }
  2. 设计SeaObject超类,6个类继承超类;(以战舰类为例)
    /** 战舰 */
    public class Battleship extends SeaObject {int life;   //命数/** 构造方法 */Battleship(){super(66,26,270,124,20);life = 5;}
    }
  3. 在SeaObject中设计两个构造方法,6个派生类分别调用;    
    import java.util.Random;
    /** 海洋对象 */
    public class SeaObject {int width;  //宽int height; //高int x;      //x坐标int y;      //y坐标int speed;  //移动速度/** 专门给侦察潜艇、鱼雷潜艇、水雷潜艇提供的 *///因为三种潜艇的width/height的值都是不一样的,所以数据不能写死,需传参写活//因为三种潜艇的x/y/speed的值都是一样的,所以数据可以写死,不需要传参SeaObject(int width,int height){this.width = width;this.height = height;x = -width; //负的潜艇的宽Random rand = new Random(); //随机数对象y = rand.nextInt(479-height-150+1)+150; //150到(窗口高-潜艇高)之间的随机数speed = rand.nextInt(3)+1; //1到3之内的随机数}/** 专门给战舰、水雷、炸弹提供的 *///因为三种对象的width/height/x/y/speed都是不一样的,所以数据不能写死,需传参写活SeaObject(int width,int height,int x,int y,int speed){this.width = width;this.height = height;this.x = x;this.y = y;this.speed = speed;}void move(){System.out.println("海洋对象移动啦!");}
    }

潜艇游戏第四天:

  1. 将侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组统一组合为SeaObject超类数组,在World类中改写并测试;

    /** 整个窗口世界 */
    public class World extends JPanel { //2.public static void main(String[] args) {ObserveSubmarine o1 = new ObserveSubmarine();System.out.println("侦察艇初始数据:    x:"+o1.x+", y:"+o1.y+", speed:"+o1.speed);o1.move();System.out.println("侦察艇移动后数据: x:"+o1.x+", y:"+o1.y+", speed:"+o1.speed);Mine o2 = new Mine(100,200);System.out.println("水雷初始数据:   x:"+o2.x+", y:"+o2.y+", speed:"+o2.speed);o2.move();System.out.println("水雷移动后数据: x:"+o2.x+", y:"+o2.y+", speed:"+o2.speed);SeaObject[] submarines = new SeaObject[5]; //潜艇数组submarines[0] = new ObserveSubmarine(); //向上造型submarines[1] = new ObserveSubmarine();submarines[2] = new TorpedoSubmarine();submarines[3] = new TorpedoSubmarine();submarines[4] = new MineSubmarine();for(int i=0;i<submarines.length;i++){ //遍历所有潜艇SeaObject s = submarines[i]; //获取每个潜艇System.out.println(s.x+","+s.y+","+s.speed);s.move();}Mine[] ms = new Mine[2];ms[0] = new Mine(100,200);ms[1] = new Mine(125,345);for(int i=0;i< ms.length;i++){ //遍历所有水雷Mine m = ms[i]; //获取每个水雷System.out.println(m.x+","+m.y);m.move();}Bomb[] bs = new Bomb[2];bs[0] = new Bomb(200,300);bs[1] = new Bomb(100,200);for(int i=0;i<bs.length;i++){Bomb b = bs[i];System.out.println(b.x+","+b.y);b.move();}}
    }
    
  2. 在6个类中重写move()移动,并测试;(以战舰类为例)
    /** 战舰 */
    public class Battleship extends SeaObject {int life;   //命数/** 构造方法 */Battleship(){super(66,26,270,124,20);life = 5;}/** 重写move()移动 */void move(){//暂时搁置}
    }
  3. 在World类中画窗口:  
    import javax.swing.JFrame;
    import javax.swing.JPanel; //1.第一步
    /** 整个窗口世界 */
    public class World extends JPanel { //2.第二步public static void main(String[] args) {JFrame frame = new JFrame(); //3.第三步World world = new World();world.setFocusable(true);frame.add(world);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(641+16, 479+39);frame.setLocationRelativeTo(null);frame.setVisible(true);}
    }
    

潜艇游戏第五天:

  1. 给类中成员添加访问控制修饰符;(以战舰类为例)访问控制修饰符可看:(13条消息) Java学习日记Day11(面向对象day05)_终为尘埃的博客-CSDN博客

    /** 战舰 */
    public class Battleship extends SeaObject {private int life;   //命数/** 构造方法 */public Battleship(){super(66,26,270,124,20);life = 5;}/** 重写move()移动 */public void move(){//暂时搁置}
    }
  2. 设计Images图片类;
    import javax.swing.ImageIcon;
    /*
    注意:点项目右键New一个Directory,起名img,将8张图片粘贴进来*/
    /** 图片类 */
    public class Images {public static ImageIcon sea;         //海洋图片public static ImageIcon gameover;    //游戏结束图片public static ImageIcon battleship;  //战舰图片public static ImageIcon obsersubm;   //侦察潜艇图片public static ImageIcon torpesubm;   //鱼雷潜艇图片public static ImageIcon minesubm;    //水雷潜艇图片public static ImageIcon mine;        //水雷图片public static ImageIcon bomb;        //炸弹图片static{ //初始化静态图片//将img中的sea.png读取到静态变量sea中sea = new ImageIcon("img/sea.png");gameover = new ImageIcon("img/gameover.png");battleship = new ImageIcon("img/battleship.png");obsersubm = new ImageIcon("img/obsersubm.png");torpesubm = new ImageIcon("img/torpesubm.png");minesubm = new ImageIcon("img/minesubm.png");mine = new ImageIcon("img/mine.png");bomb = new ImageIcon("img/bomb.png");}//测试图片是否读取成功public static void main(String[] args) {//返回8表示图片读取成功,返回其余数字表示图片读取失败System.out.println(sea.getImageLoadStatus()); //8System.out.println(gameover.getImageLoadStatus());System.out.println(battleship.getImageLoadStatus());System.out.println(obsersubm.getImageLoadStatus());System.out.println(torpesubm.getImageLoadStatus());System.out.println(minesubm.getImageLoadStatus());System.out.println(mine.getImageLoadStatus());System.out.println(bomb.getImageLoadStatus());}}
    

潜艇游戏第六天:

  1. 在World类中设计窗口的宽和高为常量,适当地方做修改,重写getImage()方法(以战舰类为例);

    import javax.swing.ImageIcon;
    /** 战舰 */
    public class Battleship extends SeaObject {private int life;   //命数/** 构造方法 */public Battleship(){super(66,26,270,124,20);life = 5;}/** 重写move()移动 */public void move(){//暂时搁置}/** 重写getImage()获取图片 */public ImageIcon getImage(){return Images.battleship; //返回战舰图片}
    }
    
  2. 画对象:

    1)想画对象需要获取对象的图片,每个对象都得获取图片,意味着获取图片行为为共有行为,所以设计在SeaObject超类中,每个对象获取图片的代码都是不一样的,所以设计为抽象方法----在SeaObject中设计为抽象方法getImage()获取对象的图片
    2)在派生类中重写getImage()获取对象图片----在6个类中重写getImage()返回不同的图片
    3)因为只有活着的对象才需要画到窗口中,所以需要设计对象的状态(活着还是死了),每个对象都有状态,意味着状态为共有属性,所以设计在SeaObject超类中,状态一般都设计为常量,同时再设计state变量表示当前状态----在SeaObject中设计LIVE、DEAD常量,state变量表示当前状态在后期的业务中经常需要判断对象的状态,每个对象都得判断,意味着判断状态的行为为共有行为,所以设计在SeaObject超类中,每个对象判断状态的代码都是一样的,所以设计为普通方法----在SeaObject中设计isLive()、isDead()判断对象的状态
    4)数据(状态、图片、x坐标、y坐标)都有了就可以开画了,每个对象都得画,意味着画对象行为为共有行为,所以设计在SeaObject超类中,每个对象画的代码都是一样的,所以设计为普通方法----在SeaObject中设计paintImage()画对象
    5)画对象的行为做好了,在窗口World类中调用即可5.1)准备对象5.2)重写paint()方法-----在paint()中调用paintImage()画对象即可
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.util.Arrays;/** 整个窗口世界 */
public class World extends JPanel {public static final int WIDTH = 641;  //窗口的宽public static final int HEIGHT = 479; //窗口的高//如下这一堆对象就是窗口中你所看到的对象了private Battleship ship = new Battleship(); //战舰对象private SeaObject[] submarines = {new ObserveSubmarine(),new TorpedoSubmarine(),new MineSubmarine()}; //潜艇数组private Mine[] mines = {new Mine(280,300)}; //水雷数组private Bomb[] bombs = {new Bomb(200,250)}; //炸弹数组/** 重写paint()画  g:系统自带的画笔 */public void paint(Graphics g){Images.sea.paintIcon(null,g,0,0); //画海洋图ship.paintImage(g); //画战舰for(int i=0;i<submarines.length;i++){ //遍历所有潜艇submarines[1].paintImage(g); //画潜艇}for(int i=0;i<mines.length;i++){ //遍历所有水雷mines[i].paintImage(g); //画水雷}for(int i=0;i<bombs.length;i++){ //遍历所有炸弹bombs[i].paintImage(g); //画炸弹}}public static void main(String[] args) {JFrame frame = new JFrame(); World world = new World(); //会创建窗口中的那一堆对象world.setFocusable(true);frame.add(world);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(WIDTH+16, HEIGHT+39);frame.setLocationRelativeTo(null);frame.setVisible(true); //系统自动调用paint()方法}
}

潜艇游戏第七天:

  1. 潜艇入场:

    • 潜艇是由窗口产生的,所以在窗口World类中设计nextSubmarine()生成潜艇对象;

      /** 生成潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)对象 */
      private SeaObject nextSubmarine(){Random rand = new Random(); //随机数对象int type = rand.nextInt(20); //0到19之间的随机数if(type<10){ //0到9时,返回侦察潜艇对象return new ObserveSubmarine();}else if(type<16){ //10到15时,返回鱼雷潜艇对象return new TorpedoSubmarine();}else{ //16到19时,返回水雷潜艇对象return new MineSubmarine();}
      }
    • 潜艇入场为定时发生的,所以在run()中调用submarineEnterAction()实现潜艇入场

      在submarineEnterAction()中:

      ​ 每400毫秒,获取潜艇对象obj,submarines扩容,将obj添加到最后一个元素上 ;

      private int subEnterIndex = 0; //潜艇入场计数
      /** 潜艇(侦察潜艇、鱼雷潜艇、水雷入场)入场 */
      private void submarineEnterAction(){ //每10毫秒走一次subEnterIndex++; //每10毫秒增1if(subEnterIndex%40==0){ //每400(40*10)毫秒走一次SeaObject obj = nextSubmarine(); //获取潜艇对象submarines = Arrays.copyOf(submarines,submarines.length+1); //扩容submarines[submarines.length-1] = obj; //将obj添加到submarines的最后一个元素上}
      }
      /** 启动程序的执行 */
      private void action(){Timer timer = new Timer(); //定时器对象int interval = 10; //定时间隔(以毫秒为单位)timer.schedule(new TimerTask() {public void run() { //定时干的事---每10毫秒自动调用submarineEnterAction(); //潜艇(侦察潜艇、鱼雷潜艇、水雷入场)入场repaint(); //重画---系统自动调用paint()方法}}, interval, interval); //定时日程表
      }

      注意:在run()中调用submarineEnterAction()之后,一定要调用repaint()来重画

  2. 水雷入场:

    • 水雷是由水雷潜艇发射出来的,所以在MineSubmarine中设计shootMine()生成水雷对象

    • 水雷入场为定时发生的,所以在run()中调用mineEnterAction()实现水雷入场

      在mineEnterAction()中:

      ​ 每1000毫秒,

      private int mineEnterIndex = 0; //水雷入场计数
      /** 水雷入场 */
      private void mineEnterAction(){ //每10毫秒走一次mineEnterIndex++; //每10毫秒增1if(mineEnterIndex%100==0) { //每1000毫秒走一次//暂时搁置}
      }
  3. 海洋对象移动:

    • 海洋对象移动为共有行为,所以在SeaObject中设计抽象方法move()实现移动,派生类中重写

    • 海洋对象移动为定时发生的,所以在run()中调用moveAction()实现海洋对象移动

      在moveAction()中:

      ​ 遍历所有潜艇--潜艇动,遍历所有水雷--水雷动,遍历所有炸弹--炸弹动

      /** 海洋对象移动 */
      private void moveAction(){ //每10毫秒走一次for(int i=0;i<submarines.length;i++){ //遍历所有潜艇submarines[i].move(); //潜艇移动}for(int i=0;i<mines.length;i++){ //遍历所有水雷mines[i].move(); //水雷移动}for(int i=0;i<bombs.length;i++){ //遍历所有炸弹bombs[i].move(); //炸弹移动}
      }

潜艇游戏第八天:

  1. 炸弹入场:

    • 炸弹是由战舰发射出来的,所以在Battleship类中设计shootBomb()生成炸弹对象;

      /** 发射炸弹---生成炸弹对象 */
      public Bomb shootBomb(){return new Bomb(this.x,this.y); //炸弹的初始坐标就是战舰的坐标
      }
    • 炸弹入场为按空格键事件触发的,所以在侦听器中重写keyReleased()按键抬起事件,在抬起事件中:

      • 判断若抬起的是空格键,则:

        ​ 获取炸弹对象obj,bombs扩容,将obj添加到bombs的最后一个元素上

  2. 战舰移动:

    • 战舰移动为战舰的行为,所以在Battleship中设计moveLeft()左移、moveRight()右移
    • 战舰移动为事件触发的,所以在侦听器的重写keyReleased()按键抬起事件中:
      • 判断若抬起的是左箭头,则战舰左移
      • 判断若抬起的是右箭头,则战舰右移 
        //键盘侦听器
        KeyAdapter k = new KeyAdapter() {/** 重写keyReleased按键抬起事件 keyPressed()键盘按下事件 */public void keyReleased(KeyEvent e) { //当按键抬起时会自动触发if(e.getKeyCode()==KeyEvent.VK_SPACE){ //若抬起的是空格键Bomb obj = ship.shootBomb(); //获取炸弹对象bombs = Arrays.copyOf(bombs,bombs.length+1); //扩容bombs[bombs.length-1] = obj; //将obj添加到最后一个元素上}if(e.getKeyCode()==KeyEvent.VK_LEFT){ //若抬起的是左箭头ship.moveLeft(); //战舰左移}if(e.getKeyCode()==KeyEvent.VK_RIGHT) { //若抬起的是右箭头ship.moveRight(); //战舰右移}}
        };
        this.addKeyListener(k); //添加侦听
  3. 删除越界的海洋对象:

    • 在SeaObject中设计isOutOfBounds()检测潜艇是否越界,在Bomb和Mine中重写isOutOfBounds()检测炸弹和水雷是否越界;

    • 删除越界海洋对象为定时发生的,所以在run()中调用outOfBoundsAction()删除越界海洋对象

      在outOfBoundsAction()中:

      ​ 遍历所有潜艇/水雷/炸弹,判断若越界了:

      ​ 将越界元素替换为数组的最后一个元素,缩容;

      /** 删除越界的海洋对象 */
      private void outOfBoundsAction(){ //每10毫秒走一次for(int i=0;i<submarines.length;i++){ //遍历所有潜艇if(submarines[i].isOutOfBounds()){ //若出界了submarines[i] = submarines[submarines.length-1]; //将越界元素替换为最后一个元素submarines = Arrays.copyOf(submarines,submarines.length-1); //缩容}}for(int i=0;i<mines.length;i++){ //遍历所有水雷if(mines[i].isOutOfBounds()){ //若出界了mines[i] = mines[mines.length-1]; //将越界元素替换为最后一个元素mines = Arrays.copyOf(mines,mines.length-1); //缩容}}for(int i=0;i<bombs.length;i++){ //遍历所有炸弹if(bombs[i].isOutOfBounds()){ //若出界了bombs[i] = bombs[bombs.length-1]; //将越界元素替换为最后一个元素bombs = Arrays.copyOf(bombs,bombs.length-1); //缩容}}
      }
      
  4. 设计EnemyScore得分接口,ObserveSubmarine和TorpedoSubmarine实现得分接口;

    /** 得分接口 */
    public interface EnemyScore {/** 得分 */public int getScore();
    }

    设计EnemyLife得命接口,MineSubmarine实现得命接口;

    /** 得命接口 */
    public interface EnemyLife {/** 得命 */public int getLife();
    }

潜艇游戏第九天:

  1. 水雷入场:--------------后半段

    • 水雷是由水雷潜艇发射出来的,所以在MineSubmarine中设计shootMine()生成水雷对象;

      /** 发射水雷---生成水雷对象 */
      public Mine shootMine(){//水雷的x:水雷潜艇的x+水雷潜艇的width//水雷的y:水雷潜艇的y-水雷的高(11)return new Mine(this.x+this.width,this.y-11); //this指水雷潜艇对象
      }
    • 水雷入场为定时发生的,所以在run()中调用mineEnterAction()实现水雷入场

      在mineEnterAction()中:

      ​ 每1000毫秒,遍历所有潜艇,判断若为水雷潜艇,则强转为水雷潜艇类型,

      ​ 获取水雷对象obj,mines扩容,将obj装到最后一个元素上;

      private int mineEnterIndex = 0; //水雷入场计数
      /** 水雷入场 */
      private void mineEnterAction(){ //每10毫秒走一次mineEnterIndex++; //每10毫秒增1if(mineEnterIndex%100==0) { //每1000毫秒走一次for(int i=0;i<submarines.length;i++){ //遍历所有潜艇if(submarines[i] instanceof MineSubmarine){ //若潜艇为水雷潜艇MineSubmarine ms = (MineSubmarine)submarines[i]; //将潜艇转换为水雷潜艇类型Mine obj = ms.shootMine(); //获取水雷对象mines = Arrays.copyOf(mines,mines.length+1); //扩容mines[mines.length-1] = obj; //将obj添加到mines最后一个元素上}}}
      }
  2. 炸弹与潜艇的碰撞:

    • 在SeaObject中设计isHit()检测碰撞、goDead()去死;

      /** 检测碰撞 this:一个对象 other:另一个对象 */
      public boolean isHit(SeaObject other){//假设:this表示潜艇 other表示炸弹int x1 = this.x-other.width;  //x1:潜艇的x-炸弹的宽int x2 = this.x+this.width;   //x2:潜艇的x+潜艇的宽int y1 = this.y-other.height; //y1:潜艇的y-炸弹的高int y2 = this.y+this.height;  //y2:潜艇的y+潜艇的高int x = other.x; //x:炸弹的xint y = other.y; //y:炸弹的yreturn x>=x1 && x<=x2 && y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了
      }/** 海洋对象去死 */
      public void goDead(){state = DEAD; //将当前状态修改为DEAD死了的
      }
    • 在Battleship中设计addLife()增命;

      /** 战舰增命 */
      public void addLife(int num){life += num; //命数增num
      }
    • 炸弹与潜艇的碰撞为定时发生的,所以在run()中设计bombBangAction()实现炸弹与潜艇碰撞

      在bombBangAction()中:

      ​ 遍历所有炸弹得炸弹,遍历所有潜艇得潜艇,判断若都活着并且还撞上了:

      ​ 炸弹去死、潜艇去死;

      ​ 判断若是分,则强转为得分接口,玩家得分;

      ​ 判断若是命,则强转为得命接口,获取命数,战舰得命;

      private int score = 0 ; //玩家得分
      /** 炸弹与潜艇的碰撞 */
      private void bombBangAction(){ //每10毫秒走一次for(int i=0;i<bombs.length;i++){ //遍历所有炸弹Bomb b = bombs[i]; //获取每一个炸弹for(int j=0;j<submarines.length;j++){ //遍历所有潜艇SeaObject s = submarines[j]; //获取每一个潜艇if(b.isLive() && s.isLive() && s.isHit(b)){ //若都活着并且还撞上了s.goDead(); //潜艇去死b.goDead(); //炸弹去死if(s instanceof EnemyScore){ //若被撞潜艇为分EnemyScore es = (EnemyScore)s; //将被撞潜艇强转为得分接口score += es.getScore(); //玩家得分}if(s instanceof EnemyLife){ //若被撞潜艇为命EnemyLife el = (EnemyLife)s; //将被撞潜艇强转为得命接口int num = el.getLife(); //获取命数ship.addLife(num); //战舰增命}}}}
      }
  3. 画分和画命:

    • 在Battleship中设计getLife()获取命数;

      /** 获取命数 */
      public int getLife(){return life; //返回命数
      }
    • 在World的paint()中:画分和画命;                                                                                     
      /** 重写paint()画  g:系统自带的画笔 */
      public void paint(Graphics g){ //每10毫秒走一次Images.sea.paintIcon(null,g,0,0); //画海洋图ship.paintImage(g); //画战舰for(int i=0;i<submarines.length;i++){ //遍历所有潜艇submarines[i].paintImage(g); //画潜艇}for(int i=0;i<mines.length;i++){ //遍历所有水雷mines[i].paintImage(g); //画水雷}for(int i=0;i<bombs.length;i++){ //遍历所有炸弹bombs[i].paintImage(g); //画炸弹}g.drawString("SCORE: "+score,200,50); //画分g.drawString("LIFE: "+ship.getLife(),400,50); //画命
      }

潜艇游戏第十天:

  1. 水雷与战舰的碰撞:

    • 在Battleship中设计subtractLife()减命;

      /** 战舰减命 */
      public void subtractLife(){life--; //命数减1
      }
    • 水雷与战舰碰撞为定时发生的,所以在run()中调用mineBangAction()实现水雷与战舰的碰撞;

      在mineBangAction()中:

      ​ 遍历所有水雷,得水雷,判断若都活着并且还撞上了:

      ​ 水雷去死、战舰减命;

      /** 水雷与战舰的碰撞 */
      private void mineBangAction(){ //每10毫秒走一次for(int i=0;i<mines.length;i++){ //遍历所有水雷Mine m = mines[i]; //获取每一个水雷if(m.isLive() && ship.isLive() && m.isHit(ship)){ //若都活着,并且还撞上了m.goDead(); //水雷去死ship.subtractLife(); //战舰减命}}
      }
  2. 检测游戏结束:

    • 借用Battleship的getLife()获取命数;

    • 检测游戏结束为定时发生的,所以在run()中调checkGameOverAction()检测游戏结束

      在checkGameOverAction()中:

      ​ 判断若战舰的命数<=0,表示游戏结束了;

      /** 检测游戏结束 */
      private void checkGameOverAction(){ //每10毫秒走一次if(ship.getLife()<=0){ //若战舰的命数<=0,表示游戏结束了state = GAME_OVER; //则将当前状态修改为GAME_OVER游戏结束状态}
      }
  3. 画状态:

    • 在World类中设计RUNNING、PAUSE、GAME_OVER状态常量,state变量表示当前状态;

    • 在checkGameOverAction()中,若游戏结束, 则将当前状态修改为GAME_OVER游戏结束状态;

    • 在paint()中设计:若为游戏结束状态则画游戏结束图;

    • 设计run()中那一堆代码,为仅在运行状态下执行;

    • 设计键盘抬起时,按下空格键、左移键、右移键,也为仅在运行状态下执行;

    • 在键盘抬起时,设计若按的是P键,则运行状态变暂停状态,暂停状态变运行状态。

      另外还实现一个飞机小游戏,过程相似。结果如图:

      如有需要,可评论区留下邮箱,后会发送。

Java面向对象学习练习———潜艇游戏(飞机游戏)相关推荐

  1. java面向对象思想编写原谅帽小游戏 原谅帽游戏思路解析

    java面向对象思想编写原谅帽小游戏 原谅帽游戏思路解析: 面向对象思想 作品展示 类(游戏端)继承Frame: 首先要创建一个方法去让游戏开始和结束 使用text执行这个游戏的方法(需要有游戏标题和 ...

  2. JAVA面向对象学习心得

    JAVA面向对象学习心得 ​ Java是面向对象编程的语言,在学习完Java基础语法后,下一个内容就是面向对象的内容了.那么什么是面向对象呢?下面就简单解释一下. 面向过程编程和面向对象编程 ​ 提到 ...

  3. Java面向对象(6) —— 射击小游戏

    这里做一个射击小游戏,作为对前面Java学习的一个小结. 1.设计 2.知识点总结 主要是在主程序ShootGame.java中引入了一些新知识,swing画图.定时器.鼠标事件处理.其他程序则主要体 ...

  4. Java开发学习之如何编写小游戏

    教大家如何用JAVA写一个简单的桌球小游戏,实现的效果是一个桌球能指定在球台内滚动,实现效果如下: 1.第一步创建窗口,引用两个包,后面要继承它的类 import java.awt.*; import ...

  5. 【c语言】小程序游戏——飞机游戏(三)

    接下来,我们需要在进行以下操作: 1.在程序里面添加敌机 2.为敌机添加基本属性 ---------------------------------------- NO.1  在程序里面添加敌机 国际 ...

  6. 植物大战僵尸源代码java面向对象,植物大战僵尸:实现游戏内自动收集阳光

    1.首先我们找出阳光的动态地址,找到之后我们双击这个地址,将其加入到地址列表中,阳光的查找技巧相信你已经能够掌握了,这里就不再罗嗦了. 2.接着我们选择最下方的地址列表,然后按下[F6键],也就是下一 ...

  7. 面向对象实战(潜艇大战小游戏)

    潜艇游戏需求: 所参与的角色: 战舰.深水炸弹.侦察潜艇.鱼雷潜艇.水雷潜艇.水雷 角色间的关系: 战舰发射深水炸弹 深水炸弹可以打潜艇(侦察潜艇.鱼雷潜艇.水雷潜艇),若打中: 潜艇消失.深水炸弹消 ...

  8. Java课程学习十一:图片匹配游戏

    图片匹配游戏 引用转载请注明出处,Thanks! 通过为标签空间添加图形以及鼠标事件,完成图片配对的游戏.[1] JFrame 简介: Swing的三个基本构造块:标签.按钮和文本字段:但是需要个地方 ...

  9. Cocos2d-x学习笔记三之飞机游戏详解之GameOver类的讲解

    游戏下载链接:http://download.csdn.net/detail/a402813378/6275427 这个Demo的最后一篇,是制作GameOver窗口,这个窗口是游戏结束的窗口,讲完这 ...

最新文章

  1. YOLOv5是真的吗?并不比YOLOv4强,不配这个名字
  2. JAVA并发编程实战---第三章:对象的共享
  3. 分类算法之K-近邻算法
  4. ASP.Net中调用CSS
  5. 中源数聚携手中科点击共推管理咨询变革
  6. 2021年南阳市五中高考成绩查询,南阳市“赫赫有名”的五大高中,2020年高考成绩一目了然!...
  7. UITableView+UITableViewStyleGrouped 处理section之间间隙
  8. ubuntu从源码编译安装python
  9. ENSP直连路由和静态路由配置(含路由表结构分析)
  10. Jmeter个人使用部分整理2021
  11. IDEA使用技巧之教你一招:隐藏指定文件/文件夹
  12. nginx 403错误
  13. TZOJ 数据结构实验:一元多项式相加
  14. 基于Go语言GoFrame+Layui搭建MVC项目教程
  15. 窥尽大数据背后被遮掩起来的财富
  16. BZOJ 4416: [Shoi2013]阶乘字符串【状压DP
  17. 小程序利用canvas实现波浪动态图,原生canvas的部分限制
  18. J0ker的CISSP之路:How CISSP(2)
  19. Java-反射概述、操作、作用(含有代码演示)
  20. rpg游戏发展史计算机网络,PC Gamer盘点史上最经典RPG游戏TOP15

热门文章

  1. 淘宝商家批量上架宝贝的方式有哪些
  2. 上市公司融资流程有哪些
  3. html table表格设置滚动条
  4. [bzoj4094][Usaco2013 Dec]Optimal Milking 线段树
  5. 看图猜成语微信小程序源码
  6. 2018看得见的未来:超融合六大趋势
  7. 对接mysql采集_关于西门子PLC设备数据采集与SQL数据库对接(带边缘计算)的案例...
  8. Windows10怎么卸载删除微软拼音输入法
  9. 通过BL102实现Modbus PLC接入Thingsboard
  10. 中首清算质疑偶像演员不适合演抗战剧?《雷霆战将》三大还原引争议