Java練習(xí)之潛艇小游戲的實(shí)現(xiàn)
首先是主方法里定義的窗口(這些都是固定的格式,不會(huì)的也沒(méi)什么事,直接Ctrl+c+v就行,基本上看一下數(shù)據(jù)都能看的懂)
寫一個(gè)超類,超類里需要有潛艇,深水炸彈,水雷和戰(zhàn)艦的寬,高,以及出場(chǎng)時(shí)的x,y坐標(biāo),和移動(dòng)速度。所有對(duì)象的圖片,所有對(duì)象的移動(dòng)方法,以及碰撞
然后再寫派生類,根據(jù)擊敗一個(gè)水雷潛艇,戰(zhàn)艦會(huì)獲得一條命,擊敗其他潛艇,戰(zhàn)艦會(huì)獲得分?jǐn)?shù),所以,需要定義兩個(gè)接口,一個(gè)是用來(lái)加命,另一個(gè)用來(lái)加分
完整代碼如下(圖片什么的可以自己去找,只需要改一下Image類和各個(gè)對(duì)象的寬高就可以)
游戲世界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;
//整個(gè)游戲世界
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;
//窗口所顯示的對(duì)象
private Battleship ship = new Battleship(); //戰(zhàn)艦
private SeaObject[] submarines = {}; //潛艇(偵察潛艇、魚雷潛艇、水雷潛艇)
private Mine[] mines = {}; //水雷
private Bomb[] bombs = {}; //深水炸彈
//隨機(jī)生成潛艇
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;
//潛艇入場(chǎng)
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;
//魚雷,水雷入場(chǎng)
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;
}
}
//海洋對(duì)象移動(dòng)
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();
}
}
//刪除越界對(duì)象
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();
}
}
}
/** 啟動(dòng)程序的運(yùn)行 */
public void action(){
KeyAdapter k = new KeyAdapter(){
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE){
Bomb obj = ship.shoot(); //深水炸彈入場(chǎng)
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(); //潛艇(偵察、水雷、魚雷)入場(chǎng)
MineEnterAction(); //水雷入場(chǎng)
moveAction(); //海洋對(duì)象移動(dòng)
BombsBangAction(); //深水炸彈和潛艇碰撞
mineBangAction(); //水雷和戰(zhàn)艦碰撞
outOfBoundsAction(); //刪除越界的對(duì)象
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();
}
}定義一個(gè)SeaObject的類當(dāng)作超類(父類),然后再寫其他的派生類(子類)
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;
//三個(gè)潛艇
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;
}
//水雷,戰(zhàn)艦,炸彈
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;
}
}戰(zhàn)艦類
package cn.tedu.sunarine;
import javax.swing.*;
//戰(zhàn)艦
public class Battleship extends SeaObject{
int life;
Battleship(){
super(66,26,270,124,20);
life=1;
}
@Override
public void move() {
System.out.println("戰(zhàn)艦移動(dòng)");
}
public ImageIcon getImage(){
return Images.battleship;
}
public Bomb shoot(){
return new Bomb(this.x,this.y+height);
}
//限制移動(dòng)范圍
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類(可根據(jù)自己的圖片改)
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練習(xí)之潛艇小游戲的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Java潛艇游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Java獲取系統(tǒng)信息的常用代碼整理總結(jié)
這篇文章主要介紹了使用Java獲取系統(tǒng)信息的常用代碼整理總結(jié),在服務(wù)器端一般經(jīng)常能夠用到,歡迎收藏,需要的朋友可以參考下2015-11-11
SpringBoot yaml語(yǔ)法與數(shù)據(jù)讀取操作詳解
YAML 是 “YAML Ain’t Markup Language”(YAML 不是一種標(biāo)記語(yǔ)言)的遞歸縮寫。在開發(fā)的這種語(yǔ)言時(shí),YAML 的意思其實(shí)是:“Yet Another Markup Language”(仍是一種標(biāo)記語(yǔ)言),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Java數(shù)據(jù)結(jié)構(gòu)及算法實(shí)例:樸素字符匹配 Brute Force
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)及算法實(shí)例:樸素字符匹配 Brute Force,本文直接給出實(shí)例代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下2015-06-06
Java使用OpenFeign管理多個(gè)第三方服務(wù)調(diào)用
最近開發(fā)了一個(gè)統(tǒng)一調(diào)度類的項(xiàng)目,需要依賴多個(gè)第三方服務(wù),這些服務(wù)都提供了HTTP接口供我調(diào)用。感興趣的可以了解一下2021-06-06
JDK1.8中的ConcurrentHashMap使用及場(chǎng)景分析
這篇文章主要介紹了JDK1.8中的ConcurrentHashMap使用及場(chǎng)景分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
JAVA實(shí)現(xiàn)單例模式的四種方法和一些特點(diǎn)
JAVA實(shí)現(xiàn)單例模式的四種方法和一些特點(diǎn),需要的朋友可以參考一下2013-03-03
Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存劃分)的深入講解
聽說(shuō)Java運(yùn)行時(shí)環(huán)境的內(nèi)存劃分是挺進(jìn)BAT的必經(jīng)之路,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存劃分)的相關(guān)資料,需要的朋友可以參考下2021-06-06

