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练习之潜艇小游戏的实现
- Author -
Yinb- Original Sources -
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@