潜艇游戏需求:
- 所参与的角色:
- 战舰、深水炸弹、侦察潜艇、鱼雷潜艇、水雷潜艇、水雷
- 角色间的关系:
- 战舰发射深水炸弹
- 深水炸弹可以打潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇),若打中:
- 潜艇消失、深水炸弹消失
- 得东西:
- 打掉侦察潜艇,玩家得10分
- 打掉鱼雷潜艇,玩家得40分
- 打掉水雷潜艇,战舰得1条命
- 水雷潜艇可以发射水雷
- 水雷可以击打战舰,若击中:
- 水雷消失
- 战舰减1条命(命数为0时游戏结束)
潜艇游戏第一天:
- 根据参与的角色创建6个类,创建World类并测试;
潜艇游戏第二天:
- 给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("战舰移动啦!"); } }
潜艇游戏第三天:
- 在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]; } }
- 设计SeaObject超类,6个类继承超类;(以战舰类为例)
/** 战舰 */ public class Battleship extends SeaObject { int life; //命数 /** 构造方法 */ Battleship(){ super(66,26,270,124,20); life = 5; } }
- 在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("海洋对象移动啦!"); } }
潜艇游戏第四天:
- 将侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组统一组合为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(); } } }
- 在6个类中重写move()移动,并测试;(以战舰类为例)
/** 战舰 */ public class Battleship extends SeaObject { int life; //命数 /** 构造方法 */ Battleship(){ super(66,26,270,124,20); life = 5; } /** 重写move()移动 */ void move(){ //暂时搁置 } }
- 在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); } }
潜艇游戏第五天:
- 给类中成员添加访问控制修饰符;(以战舰类为例)访问控制修饰符可看:(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(){ //暂时搁置 } }
- 设计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()); //8 System.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()); } }
潜艇游戏第六天:
-
在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; //返回战舰图片 } }
-
画对象:
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()方法 } }
潜艇游戏第七天:
-
潜艇入场:
-
潜艇是由窗口产生的,所以在窗口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毫秒增1 if(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()来重画
-
-
水雷入场:
-
水雷是由水雷潜艇发射出来的,所以在MineSubmarine中设计shootMine()生成水雷对象
-
水雷入场为定时发生的,所以在run()中调用mineEnterAction()实现水雷入场
在mineEnterAction()中:
每1000毫秒,
private int mineEnterIndex = 0; //水雷入场计数 /** 水雷入场 */ private void mineEnterAction(){ //每10毫秒走一次 mineEnterIndex++; //每10毫秒增1 if(mineEnterIndex%100==0) { //每1000毫秒走一次 //暂时搁置 } }
-
-
海洋对象移动:
-
海洋对象移动为共有行为,所以在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(); //炸弹移动 } }
-
潜艇游戏第八天:
-
炸弹入场:
-
炸弹是由战舰发射出来的,所以在Battleship类中设计shootBomb()生成炸弹对象;
/** 发射炸弹---生成炸弹对象 */ public Bomb shootBomb(){ return new Bomb(this.x,this.y); //炸弹的初始坐标就是战舰的坐标 }
-
炸弹入场为按空格键事件触发的,所以在侦听器中重写keyReleased()按键抬起事件,在抬起事件中:
-
判断若抬起的是空格键,则:
获取炸弹对象obj,bombs扩容,将obj添加到bombs的最后一个元素上
-
-
-
战舰移动:
- 战舰移动为战舰的行为,所以在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); //添加侦听
-
删除越界的海洋对象:
-
在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); //缩容 } } }
-
-
设计EnemyScore得分接口,ObserveSubmarine和TorpedoSubmarine实现得分接口;
/** 得分接口 */ public interface EnemyScore { /** 得分 */ public int getScore(); }
设计EnemyLife得命接口,MineSubmarine实现得命接口;
/** 得命接口 */ public interface EnemyLife { /** 得命 */ public int getLife(); }
潜艇游戏第九天:
-
水雷入场:--------------后半段
-
水雷是由水雷潜艇发射出来的,所以在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毫秒增1 if(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最后一个元素上 } } } }
-
-
炸弹与潜艇的碰撞:
-
在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:炸弹的x int y = other.y; //y:炸弹的y return 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); //战舰增命 } } } } }
-
-
画分和画命:
- 在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); //画命 }
- 在Battleship中设计getLife()获取命数;
潜艇游戏第十天:
-
水雷与战舰的碰撞:
-
在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(); //战舰减命 } } }
-
-
检测游戏结束:
-
借用Battleship的getLife()获取命数;
-
检测游戏结束为定时发生的,所以在run()中调checkGameOverAction()检测游戏结束
在checkGameOverAction()中:
判断若战舰的命数<=0,表示游戏结束了;
/** 检测游戏结束 */ private void checkGameOverAction(){ //每10毫秒走一次 if(ship.getLife()<=0){ //若战舰的命数<=0,表示游戏结束了 state = GAME_OVER; //则将当前状态修改为GAME_OVER游戏结束状态 } }
-
-
画状态:
-
在World类中设计RUNNING、PAUSE、GAME_OVER状态常量,state变量表示当前状态;
-
在checkGameOverAction()中,若游戏结束, 则将当前状态修改为GAME_OVER游戏结束状态;
-
在paint()中设计:若为游戏结束状态则画游戏结束图;
-
设计run()中那一堆代码,为仅在运行状态下执行;
-
设计键盘抬起时,按下空格键、左移键、右移键,也为仅在运行状态下执行;
-
在键盘抬起时,设计若按的是P键,则运行状态变暂停状态,暂停状态变运行状态。
另外还实现一个飞机小游戏,过程相似。结果如图:
如有需要,可评论区留下邮箱,后会发送。
-