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

首先是主方法里定义的窗口(这些都是固定的格式,不会的也没什么事,直接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潜艇游戏的资料请关注编程教程其它相关文章!

在HTTP/1.1 发布了16 年之后,IETF在2015年终于通过了HTTP/2 协议。HTTP/2协议旨在降低延迟,满足当今时代对于信息响应时间的要求。在这篇文章中,我会简要的 ...