Java练习之潜艇小游戏的实现


Posted in Java/Android onMarch 16, 2022

首先是主方法里定义的窗口(这些都是固定的格式,不会的也没什么事,直接Ctrl+c+v就行,基本上看一下数据都能看的懂)

写一个超类,超类里需要有潜艇,深水炸弹,水雷和战舰的宽,高,以及出场时的x,y坐标,和移动速度。所有对象的图片,所有对象的移动方法,以及碰撞

然后再写派生类,根据击败一个水雷潜艇,战舰会获得一条命,击败其他潜艇,战舰会获得分数,所以,需要定义两个接口,一个是用来加命,另一个用来加分

完整代码如下(图片什么的可以自己去找,只需要改一下Image类和各个对象的宽高就可以)

游戏世界World类

package cn.tedu.sunarine;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
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 GAME_OVER=1;
    private int state = RUNNING;
 
    //窗口所显示的对象
    private Battleship ship = new Battleship(); //战舰
    private SeaObject[] submarines = {}; //潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)
    private Mine[] mines = {}; //水雷
    private Bomb[] bombs = {}; //深水炸弹
 
 
    //随机生成潜艇
    public SeaObject nextSubmarine(){
        Random rand = new Random();
        int type = rand.nextInt(30);
        if(type<10){
            return new ObserveSubmarine();
        }else if(type<15){
            return new TorpedoSubmarine();
        }else{
            return new MineSubmarine();
        }
    }
 
    private int subEnterIndex = 0;
    //潜艇入场
    public void submarineEnterAction(){ //每10毫秒走一次
        subEnterIndex++;
        if(subEnterIndex%40==0){ //每40毫秒
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = obj;
        }
    }
 
    private int mineEnterIndex = 0;
    //鱼雷,水雷入场
    public void MineEnterAction(){
        mineEnterIndex++;
        if(mineEnterIndex%100==0){
            for (int i=0;i<submarines.length;i++){
                if (submarines[i] instanceof  MineSubmarine){
                    if (submarines[i].isLIVE()) {
                        MineSubmarine ms = (MineSubmarine) submarines[i];
                        Mine obj = ms.shootMine();
                        mines = Arrays.copyOf(mines, mines.length + 1);
                        mines[mines.length - 1] = obj;
                    }
                }
            }
        }
    }
 
    public void gameOver(){
        if (ship.getLife()<=0){
            state = GAME_OVER;
        }
    }
 
    //海洋对象移动
    public 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();
        }
    }
 
    //删除越界对象
    public void outOfBoundsAction(){
        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);
            }
        }
    }
 
    private  int score = 0;
 
    public void BombsBangAction(){
//深水炸弹炸潜艇
        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)){
                    b.goDead();
                    s.goDead();
                    if (s instanceof EnemyScore){
                        EnemyScore es = (EnemyScore) s;
                        score += es.getScore();
                    }
                    if (s instanceof EnemyLife){
                        EnemyLife ea = (EnemyLife) s;
                        int num = ea.getLife();
                        ship.addLife(num);
                    }
 
                }
            }
        }
    }
 
    public 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.subtratLife();
            }
        }
    }
 
 
    /** 启动程序的运行 */
    public void action(){
        KeyAdapter k = new KeyAdapter(){
 
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_SPACE){
                    Bomb obj = ship.shoot(); //深水炸弹入场
                    bombs = Arrays.copyOf(bombs,bombs.length+1);
                    bombs[bombs.length-1] = 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() {
                submarineEnterAction(); //潜艇(侦察、水雷、鱼雷)入场
                MineEnterAction();      //水雷入场
                moveAction();           //海洋对象移动
                BombsBangAction();      //深水炸弹和潜艇碰撞
                mineBangAction();       //水雷和战舰碰撞
                outOfBoundsAction();    //删除越界的对象
                gameOver();
                repaint();
            }
        }, interval, interval);
    }
 
    public void paint (Graphics g ){
        switch (state) {
            case GAME_OVER:
                Images.gameover.paintIcon(null,g,0,0);
                break;
            case RUNNING:
            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);
        }
    }
 
 
 
 
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT+19);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        world.action();
    }
}

定义一个SeaObject的类当作超类(父类),然后再写其他的派生类(子类)

package cn.tedu.sunarine;
 
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.util.Random;
 
public abstract class SeaObject {
 
    public static final int LIVE = 0;
    public static final int DEAD = 1;
    protected int state=LIVE;
 
    protected int width;
    protected 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 rand = new Random();
        y = rand.nextInt(497 - height - 150 + 1) + 150;
        speed = rand.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 getImage();
 
    public boolean isLIVE(){
        return state ==LIVE;
    }
    public void paintImage(Graphics g){
        if (isLIVE()){
            this.getImage().paintIcon(null,g,this.x,this.y);
        }
    }
    public boolean isOutOfBounds(){
        return x>=World.WIDTH;
    }
    public boolean isHit(SeaObject other){
        int x1 = this.x-other.width;
        int x2 = this.x+this.width;
        int y1 = this.y-other.height;
        int y2 = this.y+this.height;
        int x=other.x;
        int y=other.y;
        return x>=x1 && x<=x2 && y>=y1 && y<=y2;
    }
 
    public void goDead(){
        state =DEAD;
    }
}

在派生类的引用超类

鱼雷潜艇类

package cn.tedu.sunarine;
import javax.swing.ImageIcon;
 
//鱼雷潜艇
public class TorpedoSubmarine extends SeaObject implements EnemyScore{
    TorpedoSubmarine(){
        super(64,20);
    }
 
    @Override
    public void move() {
        x+=speed;
    }
    public ImageIcon getImage(){
        return Images.torpedo;
    }
    public boolean isOutOfBounds() {
        return x>=World.WIDTH;
    }
    public int getScore(){
        return 20;
    }
}

水雷潜艇类

package cn.tedu.sunarine;
import javax.swing.ImageIcon;
 
//水雷潜艇
public class MineSubmarine extends SeaObject implements EnemyScore{
    MineSubmarine(){
       super(63,19);
    }
 
    @Override
    public void move() {
        x+=speed;
    }
    public ImageIcon getImage(){
        return Images.minesubm;
    }
    public Mine shootMine(){
        int x = this.x+(this.width/2);
        int y =this.y;
        return new Mine(x,y);
    }
    public boolean isOutOfBounds() {
        return x>=World.WIDTH;
    }
    public int getLife(){
        return 1;
    }
}

侦察潜艇类

package cn.tedu.sunarine;
import javax.swing.ImageIcon;
 
//侦察潜艇
public class ObserveSubmarine extends SeaObject implements EnemyScore{
    ObserveSubmarine(){
        super(63,19);
    }
 
    @Override
    public void move() {
        x+=speed;
    }
    public ImageIcon getImage(){
        return Images.observesubm;
    }
    public boolean isOutOfBounds() {
        return x>=World.WIDTH;
    }
    public int getScore(){
        return 10;
    }
}

鱼雷类

package cn.tedu.sunarine;
//鱼雷
import javax.swing.ImageIcon;
public class Mine extends SeaObject{
        Mine(int x,int y){
            super(11,11,x,y,1);
        }
 
    @Override
    public void move() {
        y-=speed;
    }
 
    public ImageIcon getImage(){
            return Images.mine;
    }
    public boolean isOutOfBounds(){
            return y<=150-(height/2);
    }
}

深水炸弹类

package cn.tedu.sunarine;
//深水炸弹
import javax.swing.ImageIcon;
public class Bomb extends SeaObject{
    Bomb(int x,int y){
        super(9,12,x,y,3);
    }
 
    @Override
    public void move() {
        y+=speed;
    }
    public ImageIcon getImage(){
        return Images.bomb;
    }
    public boolean isOutOfBounds(){
        return y>=World.HEIGHT;
    }
}

战舰类

package cn.tedu.sunarine;
 
import javax.swing.*;
 
//战舰
public class Battleship extends SeaObject{
    int life;
    Battleship(){
       super(66,26,270,124,20);
       life=1;
    }
 
    @Override
    public void move() {
        System.out.println("战舰移动");
    }
    public ImageIcon getImage(){
        return Images.battleship;
    }
    public Bomb shoot(){
        return new Bomb(this.x,this.y+height);
    }
    //限制移动范围
    public void moveLeft(){
        x-=speed;
        x=Math.max(0,x);
    }
    public void moveRight(){
        x+=speed;
        x=Math.min(x,World.WIDTH-this.width);
    }
    public void addLife(int num){
        life+=num;
    }
    public int getLife(){
        return life;
    }
    public void subtratLife(){
        life--;
    }
}

加命接口

package cn.tedu.sunarine;
 
public interface EnemyLife {
    public int getLife();
}

加分接口

package cn.tedu.sunarine;
 
public interface EnemyScore {
    public int getScore();
}

最后,Image类(可根据自己的图片改)

package cn.tedu.sunarine;
import javax.swing.*;
public class Images {
    public static ImageIcon battleship;
    public static ImageIcon observesubm;
    public static ImageIcon mine;
    public static ImageIcon bomb;
    public static ImageIcon sea;
    public static ImageIcon torpedo;
    public static ImageIcon minesubm;
    public static ImageIcon gameover;
    static {
        battleship = new ImageIcon("./img/battleship.png");
        bomb = new ImageIcon("./img/bomb.png");
        gameover = new ImageIcon("./img/gameover.png");
        mine = new ImageIcon("./img/mine.png");
        minesubm = new ImageIcon("./img/minesubm.png");
        observesubm = new ImageIcon("./img/obsersubm.png");
        sea = new ImageIcon("./img/sea.png");
        torpedo = new ImageIcon("./img/torpesubm.png");
    }
 
    public static void main(String[] args) {
        System.out.println(battleship.getImageLoadStatus());
        System.out.println(observesubm.getImageLoadStatus());
        System.out.println(mine.getImageLoadStatus());
        System.out.println(battleship.getImageLoadStatus());
        System.out.println(bomb.getImageLoadStatus());
        System.out.println(gameover.getImageLoadStatus());
        System.out.println(minesubm.getImageLoadStatus());
        System.out.println(sea.getImageLoadStatus());
    }
}

以上就是Java练习之潜艇小游戏的实现的详细内容,更多关于Java潜艇游戏的资料请关注三水点靠木其它相关文章!

Java/Android 相关文章推荐
Java常用函数式接口总结
Jun 29 Java/Android
Java日常练习题,每天进步一点点(38)
Jul 26 Java/Android
mybatis3中@SelectProvider传递参数方式
Aug 04 Java/Android
Logback 使用TurboFilter实现日志级别等内容的动态修改操作
Aug 30 Java/Android
Spring-cloud Config Server的3种配置方式
Sep 25 Java/Android
Dubbo+zookeeper搭配分布式服务的过程详解
Apr 03 Java/Android
Java 垃圾回收超详细讲解记忆集和卡表
Apr 08 Java/Android
教你在 Java 中实现 Dijkstra 最短路算法的方法
Apr 08 Java/Android
mybatis-plus模糊查询指定字段
Apr 28 Java/Android
Java版 简易五子棋小游戏
May 04 Java/Android
Java数据结构之堆(优先队列)
May 20 Java/Android
Android移动应用开发指南之六种布局详解
Sep 23 Java/Android
你知道Java Spring的两种事务吗
Java并发编程之原子性-Atomic的使用
Java9新特性之Module模块化编程示例演绎
Mar 16 #Java/Android
JVM的类加载器和双亲委派模式你了解吗
Java生成日期时间存入Mysql数据库的实现方法
Mar 03 #Java/Android
Java设计模式之享元模式示例详解
解析探秘fescar分布式事务实现原理
You might like
PHP实时显示输出
2008/10/02 PHP
PHP 中执行排序与 MySQL 中排序
2009/04/21 PHP
php $_SERVER[&quot;REQUEST_URI&quot;]获取值的通用解决方法
2010/06/21 PHP
关于Zend Studio 配色方案插件的介绍
2013/06/24 PHP
详解EventDispatcher事件分发组件
2016/12/25 PHP
php获取用户真实IP和防刷机制的实例代码
2018/11/28 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
Opacity.js
2007/01/22 Javascript
javascript 字符 Escape,encodeURI,encodeURIComponent
2009/07/09 Javascript
基于jQuery的ajax功能实现web service的json转化
2009/08/29 Javascript
JavaScript.Encode手动解码技巧
2010/07/14 Javascript
无缝滚动改进版支持上下左右滚动(封装成函数)
2012/12/04 Javascript
微信小程序 获取微信OpenId详解及实例代码
2016/10/31 Javascript
jquery实现简单的瀑布流布局
2016/12/11 Javascript
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
2017/04/21 jQuery
微信小程序搭建自己的Https服务器
2019/05/02 Javascript
Vue-CLI项目中路由传参的方式详解
2019/09/01 Javascript
vue 获取及修改store.js里的公共变量实例
2019/11/06 Javascript
JavaScript直接调用函数与call调用的区别实例分析
2020/05/22 Javascript
使用wxPython获取系统剪贴板中的数据的教程
2015/05/06 Python
Python中的ceil()方法使用教程
2015/05/14 Python
Python使用folium excel绘制point
2019/01/03 Python
python+openCV利用摄像头实现人员活动检测
2019/06/22 Python
纯css实现照片墙3D效果的示例代码
2017/11/13 HTML / CSS
eBay法国购物网站:eBay.fr
2017/10/21 全球购物
Skyscanner澳大利亚:全球领先的旅游搜索网站
2018/03/24 全球购物
Ancheer官方户外和运动商店:销售电动自行车
2019/08/07 全球购物
排序都有哪几种方法?请列举。用JAVA实现一个快速排序
2014/02/16 面试题
管道维修工岗位职责
2013/12/27 职场文书
兼职业务员岗位职责
2014/01/01 职场文书
自我鉴定三原则
2014/01/13 职场文书
销售总经理岗位职责
2014/03/15 职场文书
竞选团支书演讲稿
2014/04/28 职场文书
民间借贷纠纷案件代理词
2015/05/26 职场文书
python开发实时可视化仪表盘的示例
2021/05/07 Python
Python加密与解密模块hashlib与hmac
2022/06/05 Python