得分:

介绍

击杀潜艇得分

package cn.tedu.submarine;
/**得分接口*/
public interface EnemyScore {/**得分*/public int getScore();
}

得命:

介绍

击杀潜艇的命

package cn.tedu.submarine;
/**得命接口*/
public interface EnemyLife {/**得命*/public int getLife();
}

存档:

介绍

记录在游戏中的数据,包括命数,分数和上一次退出游戏时,战舰,潜艇的位置,再次,打开游戏时,会自动读取存档,就读取到上一次退出游戏时的画面

/*** 保存所有游戏信息* 使用这个类的实例作为存档对象*/
public class GameInfo implements Serializable {private Battleship ship ;private SeaObject[] submarines;private Mine[] mines ;private Bomb[] bombs ;private int subEnterIndex ;//潜艇入场记录private int mineEnterIndex ;//水雷入场记录private int score ;//玩家得分public GameInfo(Battleship ship, SeaObject[] submarines, Mine[] mines, Bomb[] bombs, int subEnterIndex, int mineEnterIndex, int score) {this.ship = ship;this.submarines = submarines;this.mines = mines;this.bombs = bombs;this.subEnterIndex = subEnterIndex;this.mineEnterIndex = mineEnterIndex;this.score = score;}public Battleship getShip() {return ship;}public void setShip(Battleship ship) {this.ship = ship;}public SeaObject[] getSubmarines() {return submarines;}public void setSubmarines(SeaObject[] submarines) {this.submarines = submarines;}public Mine[] getMines() {return mines;}public void setMines(Mine[] mines) {this.mines = mines;}public Bomb[] getBombs() {return bombs;}public void setBombs(Bomb[] bombs) {this.bombs = bombs;}public int getSubEnterIndex() {return subEnterIndex;}public void setSubEnterIndex(int subEnterIndex) {this.subEnterIndex = subEnterIndex;}public int getMineEnterIndex() {return mineEnterIndex;}public void setMineEnterIndex(int mineEnterIndex) {this.mineEnterIndex = mineEnterIndex;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}

判断潜艇是否越界:

介绍

当潜艇超出窗口时,自动停止移动,让其不再移动,减少无关对象对程序内存的影响

import javax.swing.*;
import java.io.Serializable;
import java.util.Random;
import java.awt.Graphics;
import javax.swing.ImageIcon;/**海洋对象*/
public abstract class SeaObject implements Serializable {public static final int LIVE = 0;//活public static final int DEAD = 1;//屎protected int state  = LIVE;//当前状态protected int width;//正常情况下成员变量都要private的,但是今天设计为protectedprotected int height;protected int x;protected int y;protected int speed;public SeaObject(int width,int height){this.width = width;this.height = height;x = -width;Random ra = new Random();y = ra.nextInt(World.HEIGHT-height-150)+150;speed = ra.nextInt(3) + 1;}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();public abstract ImageIcon getIamge();public boolean isDead(){return state == DEAD;//屎}public boolean isLive(){return state == LIVE;//活}public void paintImage(Graphics g){if (this.isLive()){this.getIamge().paintIcon(null,g,this.x,this.y);//假设:战舰调用paintIcon()-------this指的是战舰//假设:水雷调用paintIcon()-------this指的是水雷//假设:侦察潜艇调用paintIcon()-------this指的是侦察潜艇}}/**检测潜艇是否越界*/public boolean isOutOfBounds(){return this.x>=World.WIDTH;//潜艇的x>=窗口的宽,即为越界了}/**检测碰撞 this:一个对象*/public boolean isHit(SeaObject 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屎了的}}

窗口:

介绍

本游戏是在窗口中实现的,窗口的大小宽高是固定的,我们将其设置成了常量。
同样,整个游戏存在两种状态,当战舰命数不为0时,则游戏继续;当战舰命数减到0时,游戏结束。我们将运行状态和结束状态也设置为了常量,并且设置了一个私有变量用于表示当前状态(默认为运行状态)。
分析可以发现,海洋背景对象是一直存在于窗口的,战舰也是在游戏启动时就存在于窗口中。而潜艇对象是被定时随机生成后,从窗口的左端进入,一直移动到窗口右端,因此我们可以抽象理解为潜艇、战舰、海洋对象是由窗口产生的,应该在窗口类中new。(注:水雷是由水雷潜艇发射的,所以应该由水雷潜艇产生,即水雷对象的生成被放在了水雷潜艇类中。炸弹是由战舰发射的,所以应该由战舰产生,即战舰对象的生成被放在了战舰类中)
画窗口被放在了main方法中,又由于main方法是静态方法,无法访问实例变量(定义出来的各个对象),所以我们设置了一个启动程序执行的方法。在这个方法中分为定时需要调用的方法和由键盘监听器控制调用的方法

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;/**整个窗口世界*/
public class World extends JPanel {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 = {new ObserveSubmarine(),new TorpedoSubmarine(),new MineSubmarine()};private Mine[] mines = {};private Bomb[] bombs = {};/** 生成潜艇(侦察,鱼雷,水雷)潜艇对象*/private SeaObject nextSubmarine(){Random ra = new Random();int type = ra.nextInt(20);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(){//每十毫秒走一次subEnterIndex++;if (subEnterIndex%40 == 0){SeaObject obj = nextSubmarine();submarines = Arrays.copyOf(submarines,submarines.length+1);submarines[submarines.length-1] = obj;//将obj添加到submarines的最后一个元素上}}private int mineEnterIndex = 0;/**水雷入场*/private void mineEnterAction(){//每十毫秒走一次mineEnterIndex++;//每十毫秒增1if (mineEnterIndex%100 == 0) {//每一千毫秒走一次//暂时搁置\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;}}}}/**海洋对象移动*/private void moveAction(){//每十毫秒走一次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(){//每十毫秒走一次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(){//每十毫秒走一次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(){//每十毫秒走一次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(){//每十毫秒走一次if (ship.getLife()<=0){//若战舰的命数<=0,表示游戏结束state = GAME_OVER;}}/**启动程序的执行*/private void action(){//游戏一开始,先询问是否读去存档File file = new File("game.sav");if (file.exists()){//判断存档文件是否存在//若存档文件存在,则询问用户是否读取存档int r = JOptionPane.showConfirmDialog(World.this,"是否读取存档");if (r == JOptionPane.YES_OPTION){//如果用户点击的为“是”这个按钮//读取存档try {FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis);GameInfo gameInfo = (GameInfo)ois.readObject();ship = gameInfo.getShip();submarines = gameInfo.getSubmarines();mines = gameInfo.getMines();bombs = gameInfo.getBombs();subEnterIndex = gameInfo.getSubEnterIndex();mineEnterIndex = gameInfo.getMineEnterIndex();score = gameInfo.getScore();ois.close();}catch (Exception e){}}}//键盘监听器KeyAdapter k = new KeyAdapter() {/**重写keyReleased按键按下事件 keyPressed(KeyEvent e)键盘按下事件*/public void keyPressed(KeyEvent e) {if (e.getKeyCode()==KeyEvent.VK_P){state = PAUSE;//将游戏暂停//方法返回值表示用户在弹出窗口上点击的是哪个按钮int r = JOptionPane.showConfirmDialog(//在当前游戏窗口前弹出一个确认框World.this,//参数1:确认框在游戏窗口上弹出"保存游戏吗?"//确认框上的提示文字);//判断用户点击的是“是”这个按钮我们才进行存档if (r == JOptionPane.YES_OPTION){//将当前World中各项信息都传入到GameInfo中GameInfo gameInfo = new GameInfo(ship,  submarines,mines,  bombs, subEnterIndex, mineEnterIndex, score);try{FileOutputStream fos = new FileOutputStream("game.sav");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(gameInfo);//将当前游戏所有数据写入文件保存oos.close();}catch (Exception ex){}}state = RUNNING;//当确认窗口消失后,让游戏恢复运行}if (state == RUNNING) {//仅在运行状态下运行if (e.getKeyCode() == KeyEvent.VK_L) {//若抬起的是空格键Bomb obj = ship.shootBomb();//获取炸弹对象bombs = Arrays.copyOf(bombs, bombs.length + 1);bombs[bombs.length - 1] = obj;}if (e.getKeyCode() == KeyEvent.VK_A) {//按下左箭头ship.moveLeft();}if (e.getKeyCode() == KeyEvent.VK_D) {//按下右箭头ship.moveRight();}}}};//键盘的侦听器this.addKeyListener(k);//添加侦听,不要求掌握Timer timer  = new Timer();//定时器int interval = 10;//定时间隔timer.schedule(new TimerTask() {@Overridepublic void run() {//定时干的事if (state == RUNNING) {submarineEnterAction();//潜艇(侦察,鱼雷,水雷)入场mineEnterAction();     //水雷入场moveAction();          //海洋对象移动outOfBoundsAction();//删除越界的海洋对象bombBangAction();       //炸弹与潜艇相撞mineBangAction();       //水雷与战舰相撞checkGameOverAction();  //检测游戏结束repaint();             //重画-----系统自动调用paint()方法}}}, interval, interval);        //定时日程表}public void paint(Graphics g){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();World world = new World();world.setFocusable(true);frame.add(world);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(World.WIDTH+16,World.HEIGHT+39);frame.setLocationRelativeTo(null);frame.setVisible(true);world.action();//启动程序的执行}
}

潜艇小游戏(代码续)相关推荐

  1. python猜拳小游戏代码200行左右_python简单小游戏代码,python简单小游戏代码200行...

    如何看懂python杨辉三角代码? 第一步先找规律,抽象化问题.首先我们观察到,第一行为[1],我们直接赋给一个变量:初始化数列 p = [1].核心点是这个除去首位两个 [1] 的中间部分:[p[0 ...

  2. java游戏小程序_javaCode 158个经典小程序,里面包含各种小游戏代码,能提高初学者 趣,同事可以从中学习 Games 246万源代码下载- www.pudn.com...

    文件名称: javaCode下载  收藏√  [ 5  4  3  2  1 ] 所属分类: Games 开发工具: Java 文件大小: 543 KB 上传时间: 2015-10-25 下载次数: ...

  3. python手机版做小游戏代码大全-python简单小游戏代码 怎么用Python制作简单小游戏...

    1.Python猜拳小游戏代码: 2.import random #导入随机模块 3. 4.num = 1 5.yin_num = 0 6.shu_num = 0 7.while num <= ...

  4. python小游戏代码大全-python简单小游戏代码 怎么用Python制作简单小游戏

    1.Python猜拳小游戏代码: 2.import random #导入随机模块 3. 4.num = 1 5.yin_num = 0 6.shu_num = 0 7.while num <= ...

  5. python小游戏代码大全-Python编写的点灯小游戏代码

    Python语言编写的点灯小游戏代码及思路如下: 点灯游戏及其求解的方法, 点灯游戏的游戏规则: (1)有个N行N列的灯板,当你开关其中一盏灯: (2)它和上下左右的灯的状态全部反转,目标是将全部的灯 ...

  6. c语言小游戏代码矿井逃生_如何选择编程语言和逃生教程炼狱

    c语言小游戏代码矿井逃生 A few weeks ago, I posted about my experience attempting to learn JavaScript, C#, Pytho ...

  7. 飞机大战h5微信小游戏代码

    下载地址飞机大战h5微信小游戏代码,JavaScript手绘风格的飞机小游戏源码. dd:

  8. html数字拼图游戏,JavaScript_JS写的数字拼图小游戏代码[学习参考],复制代码 代码如下:html - phpStudy...

    JS写的数字拼图小游戏代码[学习参考] 复制代码 代码如下: 拼图 td.numTd{ width : 20px ; height : 20px ; } div.numDiv{ width : 100 ...

  9. 一款使用JavaScript实现的篮球投篮游戏源代码,在浏览器里就能玩的篮球小游戏代码

    一款使用JavaScript实现的篮球投篮游戏源代码,在浏览器里就能玩的篮球小游戏代码 -根据光标的移动,沿某个方向击球 -球改变大小以使体验像3D一样 -音效让体验像真实生活! -球与轮辋碰撞并反弹 ...

  10. 基于HTML5canvars的小游戏,利用HTML5实现Canvas激流勇进小游戏代码

    特效描述:利用HTML5实现 Canvas 激流勇进 小游戏代码.利用HTML5实现Canvas激流勇进小游戏代码 代码结构 1. 引入JS 2. HTML代码 进入游戏 游戏玩法:使用左键.右键和上 ...

最新文章

  1. Nginx和uWSGI和Flask的关系
  2. hive 行转列和列转行的方法_Hive超详细存储
  3. python中的items方法_Python 字典的items()方法和iteritems()方法有什么不同?【面试题详解】...
  4. Mysql 插入中文错误:Incorrect string value: '...' for column 'xx' at row 1
  5. 使用统计异常消除滤波器来消除异常
  6. CORS漏洞的利用方式(精)
  7. 【Flink】Too many fields referenced from an atomic type
  8. tcga数据下载_手把手教你用R下载TCGA数据:CGDSR包
  9. 第一届“百度杯”信息安全攻防总决赛 find the flag WP
  10. 软件开发系统类别记录
  11. Ajax 传参的两种方式
  12. [代码审计]信呼协同办公系统2.2存在文件上传配合云处理函数组合拳RCE
  13. Android cer转bks
  14. 任正非,你也太能装逼了吧?
  15. 用ios企业证书发布ipa到服务器上扫码下载
  16. excel处理几十万行数据_EXCEL的重生!处理百万行数据竟如此简单
  17. 3种团队分组适应项目_对于新组建的团队,项目经理可以采用这5个破冰练习
  18. Image Pyramid
  19. DB2的HADR的搭建
  20. CVPR 2020 论文大盘点-行人检测与重识别篇

热门文章

  1. 视频转GIF制作工具哪个好用
  2. 韦伯-费希纳定律与对数关系的深意
  3. 职场生存之道,如何与领导相处
  4. 工具推荐:15款代码生成器
  5. 入门PCB设计之AD9电路板设计_杜洋工作室_学习笔记
  6. lintel安装成功记与血泪史
  7. 大数据舆情监控应用平台,TOOM大数据舆情监控系统的作用
  8. 多项式拟合一般方程法详细推导
  9. 班章管家正规可靠20万存定时5年合算吗?3年期比照5年期哪个好?
  10. linux nc下载,ncview 用来处理LINUX虚拟机中的nc文件 - 下载 - 搜珍网