## 潜艇游戏第一天:

1. 创建了6个类,创建World类并测试

## 潜艇游戏第二天:

1. 给6个类设计构造方法,并测试

## 潜艇游戏第三天:

1. 设计侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组、水雷数组、炸弹数组,并测试

2. 设计SeaObject超类,设计6个类继承SeaObject

3. 在超类SeaObject中设计两个构造方法,6个派生类分别调用

4. 将侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组统一组合成SeaObject数组,并测试

## 潜艇游戏第四天:

1. 在6个类中重写move()移动
2. 给类中成员添加访问权限
3. 设计Images图片类

## 潜艇游戏第五天:

1. 设计窗口的宽和高为常量,适用地方做修改

2. 画窗口:--

- import JFrame+JPanel
   - 设计World类继承JPanel----------------这一步大家特别容易忘记
   - main中代码CV大法

3. 画对象:

```java
   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()即可---------不要求掌握
   ```

## 潜艇游戏第六天:---------要求:能够按照步骤写出来就OK

1. 潜艇入场:

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

- 潜艇入场为定时发生的,所以在run()中调用submarineEnterAction()实现潜艇入场

- 在submarineEnterAction()中:
       - 每400毫秒,获取潜艇对象obj,submarines扩容,将obj添加到submarines最后一个元素上

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

2. 水雷入场(上半段):

- 水雷对象是由水雷潜艇发射出来的,所以在MineSubmarine中设计shootMine()生成水雷对象
   - 水雷入场为定时发生的,所以在run()中调用mineEnterAction()实现水雷入场
     - 在mineEnterAction()中:
       - 每1000毫秒,......暂时搁置

3. 海洋对象移动:

- 海洋对象移动为共有的行为,所以在SeaObject中设计抽象方法move(),6个派生类中重写move()移动
   - 海洋对象移动为定时发生的,所以在run()中调用moveAction()实现海洋对象移动
     - 在moveAction()中:
       - 遍历所有潜艇,潜艇移动。遍历所有水雷,水雷移动,遍历所有炸弹,炸弹移动。

## 潜艇游戏第七天:---------要求:能够按照步骤写出来就OK

1. 炸弹入场:

- 炸弹是由战舰发射出来的,所以在Battleship中设计shootBomb()生成炸弹对象
   - 炸弹入场为事件触发的,所以在侦听器中重写keyReleased()按键抬起方法,方法中判断:
     - 若抬起的是空格键,则:
       - 获取炸弹对象obj,bombs扩容,将obj装到最后一个元素上

2. 战舰移动:

- 战舰移动为战舰的行为,所以在Battleship中设计moveLeft()左移、moveRight()右移
   - 战舰移动为事件触发的,所以在侦听器的重写keyReleased()按键抬起方法中判断:
     - 若抬起的是左箭头,则战舰左移
     - 若抬起的是右箭头,则战舰右移

3. 删除越界的海洋对象:

- 在SeaObject中设计isOutOfBounds()检测潜艇越界,在Bomb和Mine中重写isOutOfBounds()检测炸弹和水雷越界
   - 删除越界的海洋对象是定时发生的,所以在run()中调用outOfBoundsAction()删除越界的海洋对象
     - 在outOfBoundsAction()中:
       - 遍历所有潜艇/水雷/炸弹数组,判断若越界了,则:
         - 将越界元素替换为最后一个元素,缩容

4. 设计EnemyScore分的接口,侦察潜艇与鱼雷潜艇实现分的接口

设计EnemyLife命的接口,水雷潜艇实现命的接口

## 潜艇游戏第八天:---------要求:能够按照步骤写出来就OK

1. 水雷入场(下半段):

- 水雷对象是由水雷潜艇发射出来的,所以在MineSubmarine中设计shootMine()生成水雷对象
   - 水雷入场为定时发生的,所以在run()中调用mineEnterAction()实现水雷入场
     - 在mineEnterAction()中:
       - 每1000毫秒,遍历所有潜艇,判断若为水雷潜艇,则强转为水雷潜艇类型:
         - 获取水雷对象obj,扩容,将obj添加到最后一个元素上

2. 炸弹与潜艇的碰撞:

- 在SeaObject中设计isHit()检测碰撞、goDead()海洋对象去死

在Battleship中设计addLife()增命

- 炸弹与潜艇的碰撞为定时发生的,所以在run()中调用bombBangAction()实现炸弹与潜艇碰撞

- 在bombBangAction()中:
       - 遍历所有炸弹得炸弹,遍历所有潜艇得潜艇,判断若都活着并且还撞上了:
         - 潜艇去死、炸弹去死
         - 判断若是分,则强转为分的接口,玩家得分
         - 判断若是命,则强转为命的接口,获取命数,战舰得命

3. 画分和画命:

- 在Battleship中设计getLife()获取命数
   - 在paint()中:画分和画命---------------------不要求掌握

## 潜艇游戏第九天:---------要求:能够按照步骤写出来就OK

1. 水雷与战舰的碰撞:
   - 在Battleship中设计subtractLife()减命
   - 水雷与战舰的碰撞为定时发生的,所以在run()中调用mineBangAction()实现水雷与战舰碰撞
     - 在mineBangAction()中:
       - 遍历水雷获取水雷,判断若都活着并且还撞上了:
         - 水雷去死、战舰减命
2. 检测游戏结束:
   - 借用Battleship类的getLife()获取命数
   - 检测游戏结束为定时发生的,所以在run()中调用checkGameOverAction()检测游戏结束
     - 在checkGameOverAction()中:
       - 若战舰的命数<=0,表示游戏结束,则......
3. 画状态:
   - 在World类中设计RUNNING、PAUSE、GAME_OVER状态常量,state变量表示当前状态
   - 在checkGameOverAction()中,若游戏结束,则将state修改为GAME_OVER游戏结束状态
   - 在paint()设计:当游戏结束时画游戏结束图
   - 设计run中的那一堆代码为仅在运行状态时执行
   - 设计重写keyReleased()中的那一堆代码为仅在运行状态时执行
   - 设计若抬起的是P键,则运行状态变为暂停状态,暂停状态变为运行状态

以下代码为最终的

Battleship

package cn.tedu.submarine;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()获取对象图片* @return 返回战舰图片*/public ImageIcon getImage(){return Images.battleship; //返回战舰图片}/*** 发射炸弹----生成炸弹对象* @return 炸弹对象*/public Bomb shootBomb(){return new Bomb(this.getX(),this.getY()); //炸弹的初始坐标就是战舰的坐标}/*** 战舰左移*/public void moveLeft(){setX(getX()-getSpeed()); //x-(向左)}/*** 战舰右移*/public void moveRight(){setX(getX()+getSpeed()); //x+(向右)}/*** 战舰增命* @param num 所增命的数量*/public void addLife(int num){life += num; //命数增num}/*** 获取战舰的命数* @return 返回战舰命数*/public int getLife(){return life; //返回命数}/** 战舰减命 */public void subtractLife(){life--; //命数减1}}

Bomb

package cn.tedu.submarine;import javax.swing.*;/*** 炸弹类*/
public class Bomb extends SeaObject {/*** 构造方法* @param x 炸弹的初始x坐标* @param y 炸弹的初始y坐标*/public Bomb(int x,int y){ //因为炸弹的初始坐标,是根据战舰的坐标计算出来的,所以不能写死super(9,12,x,y,3);}/*** 重写move()移动*/public void move(){setY(getY()+getSpeed()); //y+(向下)}/*** 重写getImage()获取对象图片* @return 返回炸弹图片*/public ImageIcon getImage(){return Images.bomb; //返回炸弹图片}/*** 重写isOutOfBounds()检测炸弹是否越界* @return 若越界则返回true,否则返回false*/public boolean isOutOfBounds(){return this.getY()>=World.HEIGHT; //炸弹的y>=窗口的高,即为越界了}}

EnemyLife  接口

package cn.tedu.submarine;/*** 命*/
public interface EnemyLife {/*** 得命* @return 命数*/public int getLife();
}

EnemyScore  得分

package cn.tedu.submarine;/*** 分*/
public interface EnemyScore {/*** 得分* @return 返回分数*/public int getScore();
}

Images  照片

package cn.tedu.submarine;
import javax.swing.ImageIcon;
//图片位置:点项目名称,右键New Directory,命名为img,将图片粘贴到img中/*** 图片类*/
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{ //初始化静态图片sea = new ImageIcon("img/sea.png"); //读取img下的sea.png到变量sea中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());}
}

Mine  

package cn.tedu.submarine;import javax.swing.*;/*** 水雷类*/
public class Mine extends SeaObject {/*** 构造方法* @param x 水雷的初始x坐标* @param y 水雷的初始y坐标*/public Mine(int x,int y){ //因为水雷的初始坐标,是根据水雷潜艇的坐标计算出来的,所以不能写死super(11,11,x,y,1);}/*** 重写move()移动*/public void move(){setY(getY()-getSpeed()); //y-(向上)}/*** 重写getImage()获取对象图片* @return 返回水雷图片*/public ImageIcon getImage(){return Images.mine; //返回水雷图片}/*** 重写isOutOfBounds()检测水雷是否越界* @return 若越界则返回true,否则返回false*/public boolean isOutOfBounds(){return this.getY()<=150-this.getHeight(); //水雷的y<=150-水雷的高,即为越界了}
}

MineSubmarine

package cn.tedu.submarine;import javax.swing.*;/*** 水雷潜艇类*/
public class MineSubmarine extends SeaObject implements EnemyLife {/*** 构造方法*/public MineSubmarine(){super(63,19);}/*** 重写move()移动*/public void move(){setX(getX()+getSpeed()); //x+(向右)}/*** 重写getImage()获取对象图片* @return 返回水雷潜艇图片*/public ImageIcon getImage(){return Images.minesubm; //返回水雷潜艇图片}/*** 发射水雷----生成水雷对象* @return 返回水雷对象*/public Mine shootMine(){//x:水雷潜艇的x+水雷潜艇的宽//y:水雷潜艇的y-11return new Mine(this.getX()+this.getWidth(),this.getY()-11); //this指的是水雷潜艇}/*** 重写getLife()得命* @return 返回命数*/public int getLife(){return 1; //打掉水雷潜艇,得1条命}
}

ObserveSubmarine

package cn.tedu.submarine;import javax.swing.*;/*** 侦察潜艇类*/
public class ObserveSubmarine extends SeaObject implements EnemyScore {/*** 构造方法*/public ObserveSubmarine(){super(63,19);}/*** 重写move()移动*/public void move(){setX(getX()+getSpeed()); //x+(向右)}/*** 重写getImage()获取对象图片* @return 返回侦察潜艇图片*/public ImageIcon getImage(){return Images.obsersubm; //返回侦察潜艇图片}/*** 重写getScore()得分* @return 返回分数*/public int getScore(){return 10; //打掉侦察潜艇,得10分}
}

SeaObject

package cn.tedu.submarine;import javax.swing.ImageIcon;
import java.awt.*;
import java.util.Random;/*** 海洋对象类,是所有类的超类*/
public abstract class SeaObject {/*** 活着的*/public static final int LIVE = 0;/*** 死了的*/public static final int DEAD = 1; //死了的private int state = LIVE; //当前状态(默认为活着的)private int width;  //宽private int height; //高private int x;      //x坐标private int y;      //y坐标private int speed;  //速度public int getState() {return state;}public void setState(int state) {this.state = state;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}//因为三种潜艇的width/height都是不一样的,所以数据不能写死,需传参写活//因为三种潜艇的x/y/speed代码都是一样的,所以数据可以写死,不需要传参/*** 专门给侦察潜艇、鱼雷潜艇、水雷潜艇提供的构造方法* @param width 潜艇的宽* @param height 潜艇的高*/public SeaObject(int width,int height){this.width = width;this.height = height;x = -width;Random rand = new Random(); //创建随机数对象y = rand.nextInt(World.HEIGHT-height-150+1)+150; //150到(窗口高-潜艇高)之内随机生成speed = rand.nextInt(3)+1; //1到3之内随机生成}//因为三种对象的width/height/x/y/speed都是不一样的,所以数据不能写死,需传参写活/*** 专门给战舰、水雷、炸弹提供的构造方法* @param width 宽* @param height 高* @param x x坐标* @param y y坐标* @param speed 速度*/public 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;}/*** 移动*/public abstract void move();/*** 获取对象的图片* @return 返回对象所对应的图片*/public abstract ImageIcon getImage();/*** 判断对象是否是活着的* @return 返回true表示活着的,否则表示死了的*/public boolean isLive(){return state==LIVE; //若state为LIVE,表示活着的,返回true,否则返回false}/*** 判断对象是否是死了的* @return 返回true表示死了的,否则表示活着的*/public boolean isDead(){return state==DEAD; //若state为DEAD,表示死了的,返回true,否则返回false}/*** 画对象* @param g 画笔*/public void paintImage(Graphics g){if(this.isLive()){ //若活着的this.getImage().paintIcon(null,g,this.x,this.y); //----不要求掌握}}/*** 检测潜艇是否越界* @return 若越界则返回true,否则返回false*/public boolean isOutOfBounds(){return this.x>=World.WIDTH; //潜艇的x>=窗口的宽,即为越界了}/*** 检测碰撞* @param other 另一个对象  this表示一个对象* @return 若撞上了则返回true,否则返回false*/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:炸弹的y     //练习-----------2:34继续return x>=x1 && x<=x2&&y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了}/*** 海洋对象去死*/public void goDead(){state = DEAD; //将当前状态修改为DEAD死了的}
}

TorpedoSubmarine

package cn.tedu.submarine;import javax.swing.*;/*** 鱼雷潜艇类*/
public class TorpedoSubmarine extends SeaObject implements EnemyScore {/*** 构造方法*/public TorpedoSubmarine(){super(64,20);}/*** 重写move()移动*/public void move(){setX(getX()+getSpeed()); //x+(向右)}/*** 重写getImage()获取对象图片* @return 返回鱼雷潜艇图片*/public ImageIcon getImage(){return Images.torpesubm; //返回鱼雷潜艇图片}/*** 重写getScore()得分* @return 返回分数*/public int getScore(){return 40; //打掉鱼雷潜艇,得40分}
}

World  整个游戏窗口

package cn.tedu.submarine;
import javax.swing.JFrame;
import javax.swing.JPanel; //1.
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;/*** 整个游戏窗口*/
public class World extends JPanel { //2./*** 窗口的宽*/public static final int WIDTH = 641;/*** 窗口的高*/public static final int HEIGHT = 479;/*** 运行状态*/public static final int RUNNING = 0;/*** 暂停状态*/public static final int PAUSE = 1;/*** 游戏结束状态*/public static final int GAME_OVER = 2;private int state = RUNNING; //当前状态(默认为运行状态)//如下这一堆对象就是窗口中你所看到的对象private Battleship ship = new Battleship(); //战舰对象private SeaObject[] submarines = {}; //潜艇数组private Mine[] mines = {}; //水雷数组private Bomb[] bombs = {}; //炸弹数组/*** 生成潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)对象* @return 返回潜艇*/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();}}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 int mineEnterIndex = 0; //水雷入场计数/*** 水雷入场*/private void mineEnterAction(){ //每10毫秒走一次mineEnterIndex++; //每10毫秒增1if(mineEnterIndex%100==0){ //每1000(100*10)毫秒走一次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最后一个元素上}}}}/*** 海洋对象移动*/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(); //炸弹动}}/*** 删除越界的海洋对象,意义:避免内存泄漏*/private void outOfBoundsAction(){ //每10毫秒走一次for(int i=0;i<submarines.length;i++){ //遍历所有潜艇if(submarines[i].isOutOfBounds() || submarines[i].isDead()){ //若越界了或死了的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].isDead()){ //若越界了或死了的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].isDead()){ //若越界了或死了的bombs[i] = bombs[bombs.length-1]; //将越界元素替换为最后一个元素bombs = Arrays.copyOf(bombs,bombs.length-1); //缩容}}}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); //战舰增命}}}}}/*** 水雷与战舰的碰撞*/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(); //战舰减命}}}/*** 检测游戏结束*/private void checkGameOverAction(){ //每10毫秒走一次if(ship.getLife()<=0){ //若战舰的命数<=0,表示游戏结束了state = GAME_OVER; //将当前状态修改为游戏结束状态}}/*** 启动程序的执行*/private void action(){KeyAdapter k = new KeyAdapter() { //不要求掌握/** 重写keyReleased()按键抬起事件 */ //keyPressed()按下事件public void keyReleased(KeyEvent e) { //不要求掌握--当按键抬起时会自动触发if(e.getKeyCode()==KeyEvent.VK_P){ //不要求掌握--若抬起的是P键if(state==RUNNING){ //运行状态时修改为暂停状态state = PAUSE;}else if(state==PAUSE){ //暂停状态时修改为运行状态state = RUNNING;}}if(state==RUNNING){ //仅在运行状态时执行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); //不要求掌握Timer timer = new Timer(); //定时器对象int interval = 10; //定时间隔(以毫秒为单位)timer.schedule(new TimerTask() {public void run() { //定时干的事----每10毫秒自动执行if(state==RUNNING){ //仅在运行状态时执行submarineEnterAction(); //潜艇入场mineEnterAction();      //水雷入场moveAction();           //海洋对象移动outOfBoundsAction();    //删除越界的海洋对象bombBangAction();       //炸弹与潜艇的碰撞mineBangAction();       //水雷与战舰的碰撞checkGameOverAction();  //检测游戏结束repaint(); //重画----系统自动调用paint()方法}}}, interval, interval); //定时计划表}/*** 重写paint()画* @param 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); //画命----不要求掌握if(state==GAME_OVER){ //若当前为游戏结束状态Images.gameover.paintIcon(null,g,0,0);}}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(WIDTH+16, HEIGHT+40);frame.setLocationRelativeTo(null);frame.setResizable(false);frame.setVisible(true); //自动调用paint()方法world.action(); //启动程序的执行}
}

点关注、不迷路

【潜艇游戏开发】最全的源代码相关推荐

  1. 游戏开发论坛_游戏开发制作全流程介绍

    近日,根据<2020年1-6月中国游戏产业报告>显示,我国上半年网络游戏用户规模达到6.6亿人,游戏市场实际营收1394.93亿元,同比增长了22.34%,其中手游占比75.04%,达10 ...

  2. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:// ...

  3. Blender游戏开发教程

    历时七个月,这本书终于写完了,直接发布两个版本:中文版和英文版. 这里是购买链接: ​​​​​​​Blender Market 资源商店(10美元) - 支持双币信用卡和PayPal Fast Spr ...

  4. Java游戏开发组件LGame简易测试版发布(版本号 0 1 5)

    LGame-Simple-0.1.5组件下载地址:http://code.google.com/p/loon-simple/downloads/list 2009-09-13 更新内容: Java游戏 ...

  5. 网易官宣:招30人![免费加入]网易游戏开发人才培养计划!

    游戏行业一直是公认最"吸金"的行业, 自2014年起中国游戏市场的用户规模和 市场收入都是逐年递增的. 网易作为国内最大的游戏开发公司,也参与开发了不少爆款游戏. 一个爆款游戏的诞 ...

  6. 网易官宣:免费培养30名游戏开发人才!

    ✦  游戏开发  ✦ 游戏行业一直是公认最"吸金"的行业, 自2014年起中国游戏市场的用户规模 和市场收入都是逐年递增的. GAME 网易作为国内最大的游戏开发公司, 参与开发了 ...

  7. 网易官宣|招30人!【免费加入】网易游戏开发人才培养计划!

    ✦  游戏开发  ✦ 游戏行业一直是公认最"吸金"的行业, 自2014年起中国游戏市场的用户规模 和市场收入都是逐年递增的. GAME 网易作为国内最大的游戏开发公司, 参与开发了 ...

  8. HTML5游戏开发/微信游戏开发--猜灯谜游戏源代码分析

    最近码友问我:"你的CSDN是不是废了?",我一看,握了个大草,1年半没更新了--工作.家里琐事太多,每天挤遍全身乳沟也不超过3个小时,所以--所以这全TMD都是借口!有好几个码友 ...

  9. C/C++游戏开发:从零开始,用C++编写一个潜艇大战游戏!

    C++编写的原汁原味的潜艇大战游戏,这是一个国外C++高手编写的潜艇大战,其玩法和界面效果均和windows电脑中自带的潜艇大战十分相似,从编译情况来看,游戏开发时未使用第三方控件,在VC6环境下,可 ...

最新文章

  1. 如何在asp.net mvc3中使用HttpStatusCode
  2. 华为云中国前二,全球前五,增速第一,凭什么?
  3. OpenGL ES之Swift使用GLSL语言渲染图片的显示
  4. 牛客NOIP2021提高组OI赛前模拟赛第一场T3——与巨(数学)
  5. 华强北AirPods洛达1562A固件升级教程,带空间音频(艾创力+东莞豪锐)
  6. java 反射创建对象并赋值_java使用反射创建并操作对象的方法
  7. 继承ListPreference后,去掉右边的图标
  8. (12)System Verilog随机变量
  9. Wireshark验证TCP三次握手四次挥手
  10. 为什么互联网公司需要测试人员?
  11. 百度10.55亿元入股创维酷开,李彦宏要为电视带来AI遥控器
  12. Pycharm 主题字体推荐(亮色)
  13. JDK17下载和配置及官网地址教程(新版JDK12之后,较简单)
  14. 图片/视频获取缩略图的几种方式
  15. 阿里巴巴校招笔试题整理
  16. 百度js推送没法用了?帝国CMS结合百度API推送方法来了
  17. 大数据时代信息轰炸来袭 购房四大黄金法则
  18. 图像的形状因子计算方法
  19. ZYNQ-定时器中断使用
  20. 处理导入的原理图库中Designator字体不对的问题

热门文章

  1. 重磅长篇精读:国内前端行业十日谈
  2. vba:inputbox
  3. JAVA修改AD账号密码
  4. 软件开发相关面经6——数据库篇
  5. ROS人机交互界面开发
  6. 基于MQTT的数据采集系统
  7. 北京信息科技大学第十一届程序设计竞赛(重现赛)E kotori和素因子
  8. 硬盘丢失的文件还能恢复吗丨用什么法恢复
  9. u盘中raw数据如何恢复?数据恢复软件管用吗
  10. 一个垃圾的网上论坛(Oracle+JavaWeb相关技术实现)