博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Java】Java小游戏之Shoot游戏源码及详解
阅读量:4305 次
发布时间:2019-05-27

本文共 12281 字,大约阅读时间需要 40 分钟。

【Java】Java小游戏之Shoot游戏源码及详解

Shoot游戏是模仿微信中打飞机小游戏,这个游戏虽然简单,但通过这个游戏小项目,可以练习很多小的知识点,提高对面向对象的理解,还能提高逻辑思维能力。总之,好处多多,下面我将对游戏的结构及代码进行详细说明:

游戏运行状态界面:

1)游戏中类的结构图:

2)游戏步骤01:

1.class FlyingObject{    image,width,height,x,y  }2.interface Enemy{    int getScore();  }3.interface Award{    DOUBLE_FILE,LIFE    int getType();  }4.class Airplane extends 1 implements 2{    speed    Airplane(){}    重写getScore()  }5.class Bee extends 1 implements 3{    xSpeed,ySpeed,awardType    Bee(){}    重写getType()  }6.class Bullet extends 1{    speed    Bullet(int x,int y){}  }7.class Hero extends 1{    life,doubleFire,images,index    Hero(){}  }8.class ShootGame extends JPanel{    WIDTH,HEIGHT    background,start,pause,gameover    airplane,bee,bullet,hero0,hero1    hero(Hero)    flyings(FlyingObject[])    bullets(Bullet[])    ShootGame(){初始化对象}    static{}    重写paint(g){       画背景图       paintHero(g);       paintFlyingObjects(g);       paintBullets(g);    }    paintHero(g){} //画英雄机    paintFlyingObjects(g){} //画敌人    paintBullets(g){} //画子弹    main(){      ...      frame.setVisible(true);    }  }
3)游戏步骤02:

1.敌人入场的实现步骤:  1)main(){ game.action(); }  2)action(){      ...      run(){ //10毫秒定时执行        enteredAction(); //敌人入场	repaint();      }    }  3)int index = 0;    enteredAction(){ //10毫秒      index++;      if(index%40==0){  //40*10毫秒        FlyingObject one = nextOne(); //创建一个敌人对象        flyings = Arrays.copyOf(flyings,flyings.length+1); //扩容        flyings[flyings.length-1] = one; //将敌人对象添加到敌人数组中      }    }  4)nextOne(){      生成0到19间的随机数      为0时return new Bee();      否则return new Airplane();    }2.飞行物走一步的实现步骤:  1)FlyingObject----抽象方法step();  2)Airplane,Bee,Bullet,Hero---重写step()  3)action(){      run(){        enterAction();	stepAction();	repaint(); //重画      }    }  4)stepAction(){      遍历所有敌人,调用step()      遍历所有子弹,调用step()      hero.step();    }3.子弹入场的实现步骤:  1)Hero---shoot()英雄机发射子弹  2)action(){      run(){        ...	shootAction(); //发射子弹	repaint();      }    }  3)int shootIndex = 0;    shootAction(){ //10毫秒走一次      shootIndex++;      if(shootIndex%30==0){ //300毫秒        调用Hero的shoot()得到发射出的子弹数组bs	将bullets扩容	将bs追加到bullets数组中--System.arraycopy()      }    }4.英雄机随着鼠标移动的实现步骤:  1)Hero---moveTo(int x,int y)  2)action(){      MouseAdapter l = new MouseAdapter(){         重写MouseMoved(){	   获取鼠标的x和y	   hero.moveTo(x,y); //移动	 }      };      this.addMouseMotionListener(l);      this.addMouseListener(l);      run(){        ...      }    }5.子弹和敌人碰撞的实现步骤:  1)FlyingObject---shootBy(Bullet b)  2)Hero----addDoubleFire(),addLife()  3)action(){      run(){        ...	bangAction(); //检查碰撞	repaint();      }    }  4)bangAction(){      遍历所有子弹,将子弹传给bang()方法    }  5)bang(Bullet b){ //1发子弹与所有敌人撞      遍历所有敌人,获取每一个敌人f      判断f是否与b撞上了      若撞上了:        5.1)得分或得奖励	      5.1.1)得到被撞敌人对象	      5.1.2)判断是敌人还是奖励	             若是敌人则增分		     若是奖励则得奖励类型		       判断不同的奖励类型:		         增命或增火力值	5.2)将被撞对象从flyings中删除	    5.2.1)将被撞敌人与最后一个元素交换(追尾并绕圈)	    5.2.2)缩容---删除最后一个元素(被撞的对象)    }

4)游戏步骤03:

1.画分和画命的实现步骤:  1)hero---getLife()获取命  2)paint(g){      ......      paintScore(g); //画分和命    }  3)paintScore(g){      设置颜色g.setColor(...)      设置字体g.setFont(...)      画分g.drawString(...);      画命g.drawString(...);    }2.删除越界的敌人和子弹的实现步骤:  1)FlyingObject----abstract outOfBounds();  2)Airplane,bee,bullet,Hero--重写outOfBounds()  3)action(){      run(){        ...	outOfBoundsAction(); //删除越界的	repaint();      }    }  4)outOfBoundsAction(){      1)声明活着的数组      2)遍历flyings/bullets数组        判断对象是否不越界:        若true:          将对象添加到活着的数组中      3)将活着的数组复制到flyings/bullets数组中    }3.英雄机与敌人碰撞、游戏结束检查的实现步骤:  1)Hero---boolean hit(FlyingObject other);  2)Hero---substractLife()                 setDoubleFire(int doubleFire)  3)action(){      重写run(){        ...	checkGameOverAction(); //检测英雄机与敌人撞	repaint();      }    }  4)checkGameOverAction(){      if(isGameOver()){      }    }  5)isGameOver(){ //检测游戏是否结束      遍历所有敌人,获取每一个敌人f      判断hero.hit(f){        减命	火力值清零	删除被撞的敌人(交换,缩容)      }      return hero.getLife()<=0;    }4.画状态的实现步骤:  1)START,RUNNING,PAUSE,GAME_OVER     state=0(存储当前状态)  2)paint(){      ...      paintState(g);    }  3)paintState(g){      START状态--贴start图      PAUSE状态--贴pause图      GAME_OVER状态--贴gameover图    }  4)run(){      if(state==RUNNING){        一堆action();      }      repaint();    }  5)mouseMoved(){      if(state== RUNNING){        获取x,y,调英雄机移动方法      }    }  6)重写mouseClicked(){      若为启动状态,则改为运行状态      若为游戏结束状态,则:        清理现场(hero,flyings,bullets,score)        改为启动状态    }  7)checkGameOverAction(){      if(isGameOver()){        state = GAME_OVER;      }    }  8)重写mouseExited(){      if(state == RUNNING){        state = PAUSE;      }    }  9)重写mouseEntered(){      if(state == PAUSE){        state = RUNNING;      }    }

5)类的作用及源码:

FlyingObject类:

package shootgame;import java.awt.image.BufferedImage;/** * 飞行物类 * @author long * */public abstract class FlyingObject {	protected BufferedImage image; //图片	protected int x; //x坐标	protected int y; //y坐标	protected int width; //图片宽度	protected int height; //图片高度		public abstract void step(); //走步方法		public abstract boolean outOfBounds();		public boolean shootBy(Bullet b){		int x1 = this.x - b.width;		int x2 = this.x + this.width;		int y1 = this.y;		int y2 = this.y + this.height;		int x = b.x;		int y = b.y;		return (x>x1&&x
y1&&y

Award接口:

package shootgame;/** * 奖励接口 * @author long * */public interface Award {	public int LIFE = 0; //命	public int DOUBLE_FIRE = 1; //双倍火力		public int getType(); //获取奖励类型}

Enemy接口:

package shootgame;/** * 敌机接口 * @author long * */public interface Enemy {	public int getScore(); //得分}

Constant类:

package shootgame;import java.awt.image.BufferedImage;import java.io.IOException;import javax.imageio.ImageIO;/** * 常量类 * @author long * */public class Constant {	public static final int WIDTH = 400;	public static final int HEIGHT = 650;		public static BufferedImage background;	public static BufferedImage start;	public static BufferedImage pause;	public static BufferedImage gameover;	public static BufferedImage airplane;	public static BufferedImage bee;	public static BufferedImage bullet;	public static BufferedImage hero0;	public static BufferedImage hero1;		public static final int START = 0;	public static final int PAUSE = 1;	public static final int RUNNING = 2;	public static final int GAME_OVER = 3;		static {		try {			background=ImageIO.read(Constant.class.getResource("background.png"));			start=ImageIO.read(Constant.class.getResource("start.png"));			pause=ImageIO.read(Constant.class.getResource("pause.png"));			gameover=ImageIO.read(Constant.class.getResource("gameover.png"));			airplane=ImageIO.read(Constant.class.getResource("airplane.png"));			bee=ImageIO.read(Constant.class.getResource("bee.png"));			bullet=ImageIO.read(Constant.class.getResource("bullet.png"));			hero0=ImageIO.read(Constant.class.getResource("hero0.png"));			hero1=ImageIO.read(Constant.class.getResource("hero1.png"));		} catch (IOException e) {			System.out.println("图片加载异常");			e.printStackTrace();		}	}	}

Airplane类:

package shootgame;import java.util.Random;/** * 敌机类 * @author long * */public class Airplane extends FlyingObject implements Enemy{	private int speed = 3; //飞行速度		public Airplane(){		this.image = Constant.airplane;		this.width = image.getWidth();		this.height = image.getHeight();		this.y = -height;		Random rand = new Random();		this.x = rand.nextInt(Constant.WIDTH-this.width);		rand = null;	}		/**	 * 打掉一个敌机获得的分数	 */	public int getScore(){		return 5;	}	/**	 * 重写走步方法	 * 向下走一步	 */	public void step(){		y += speed;	}		/**	 * 重写边界检测方法	 * 当敌机到最小面的时候越界	 */	public boolean outOfBounds(){		return y>Constant.HEIGHT;	}}

Bee类:

package shootgame;import java.util.Random;/** * 小蜜蜂类 * @author long * */public class Bee extends FlyingObject implements Award{	private int xSpeed = 2; //水平方向移动速度	private int ySpeed = 3; //垂直方向移动速度	private int awardType; //奖励类型		public Bee(){		this.image = Constant.bee;		this.width = image.getWidth();		this.height = image.getHeight();		this.y = -height;		Random rand = new Random();		this.x = rand.nextInt(Constant.WIDTH-this.width);		this.awardType = rand.nextInt(2);				rand = null;	}		/**	 * 打死一只小蜜蜂可以获取的奖励类型	 * 生命或值双倍子弹	 */	public int getType(){		return awardType;	}	/**	 * 重写走步方法	 * 小蜜蜂可以左右走	 * 到最左边或者最右边的时候转向	 */	public void step(){		x += xSpeed;		y += ySpeed;		if(x>Constant.WIDTH-this.width){			xSpeed = -1;		}		if(x<0){			xSpeed = 1;		}	}		/**	 * 小蜜蜂边界检测	 */	public boolean outOfBounds(){		return y>Constant.HEIGHT;	}	}

Bullet类:

package shootgame;import java.util.Random;/** * 子弹类 * @author long * */public class Bullet extends FlyingObject{	private int speed = 5; //子弹的速度		public Bullet(int x,int y){		this.image = Constant.bullet;		this.width = image.getWidth();		this.height = image.getHeight();				this.x = x;		this.y = y;	}	/**	 * 重写step方法	 * 子弹向上走步	 */	public void step(){		y -= speed;	}		/**	 * 子弹边界检测	 * 当子弹到最上边的时候越界	 */	public boolean outOfBounds(){		return y<-this.width;	}}

Hero类:

package shootgame;import java.awt.image.BufferedImage;/** * 英雄机类 * @author long * */public class Hero extends FlyingObject{	BufferedImage[] images; //图片数组	private int index; //图片数组索引	private int life; //命	private int doubleFire; //双倍火力		public Hero(){		this.image = Constant.hero0;		this.width = image.getWidth();		this.height = image.getHeight();		this.x = 150;		this.y = 400;				this.life = 3;		this.doubleFire = 20;		this.index = 0;		this.images = new BufferedImage[]{Constant.hero0,Constant.hero1};	}		/**	 * 获取生命值	 * @return	 */	public int getLife() {		return life;	}		/**	 * 增加一条命	 */	public void addLife(){		life++;	}		/**	 * 减一条命	 */	public void substractLife(){		life--;	}		/**	 * 设置双倍火力	 * @param doubleFire	 */	public void setDoubleFire(int doubleFire) {		this.doubleFire = doubleFire;	}		public void addDoubleFire(){		doubleFire += 40;	}	/**	 * 重写走步方法	 * 英雄机走步即切换图片,实现动画效果	 */	public void step(){		image = images[index++/10%images.length];	}		/**	 * 英雄机射出子弹	 * @return	 */	public Bullet[] shoot(){		Bullet[] b;		int temp = this.width/4;		if(doubleFire>0){			b = new Bullet[2];			b[0] = new Bullet(this.x+1*temp-1,this.y-10);			b[1] = new Bullet(this.x+3*temp-1,this.y-10);			doubleFire -= 2;		}else{			b = new Bullet[1];			b[0] = new Bullet(this.x+2*temp-1,this.y-10);		}		return b;	}		/**	 * 英雄机随鼠标移动方法	 * @param x	 * @param y	 */	public void move(int x,int y){		this.x = x-this.width/2;		this.y = y-this.height/2;	}		/**	 * 英雄机永不越界	 */	public boolean outOfBounds(){		return false;	}		public boolean hit(FlyingObject f){		int x1 = f.x-this.width/2;		int x2 = f.x+f.width+this.width/2;		int y1 = f.y-this.height/2;		int y2 = f.y+f.height+this.height/2;		int x = this.x+this.width/2;		int y = this.y+this.height/2;		return (x>x1&&x
y1&&y

ShootGame类:

package shootgame;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.util.Arrays;import java.util.Random;import java.util.Timer;import java.util.TimerTask;import javax.swing.JFrame;import javax.swing.JPanel;/** * 游戏主界面类 * @author long * */public class ShootGame extends JPanel{	private FlyingObject[] flyings = {}; //飞行物数组	private Bullet[] bullets = {}; //子弹数组	private Hero hero = new Hero(); //英雄机		private int score = 0; //得分		private int state = 0; //游戏状态		/**	 * 重写paint方法	 */	@Override	public void paint(Graphics g) {		g.drawImage(Constant.background,0,0,null);		paintHero(g);		paintFlyings(g);		paintBullets(g);		paintScore(g);		paintState(g);	}		/**	 * 画游戏的开始、运行、暂停、结束四中状态	 * @param g	 */	public void paintState(Graphics g){		switch (state) {		case Constant.START:			g.drawImage(Constant.start,0,0,null);			break;		case Constant.PAUSE:			g.drawImage(Constant.pause,0,0,null);			break;		case Constant.GAME_OVER:			g.drawImage(Constant.gameover,0,0,null);			break;		default:			break;		}	}		/**	 * 画分数和命	 * @param g	 */	public void paintScore(Graphics g){		Color c = g.getColor();		g.setColor(new Color(0x8A2BE2));		g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,20));		g.drawString("SCORE:"+score,10,25);		g.drawString("LIFE:"+hero.getLife(),10,50);		g.setColor(c);	}		/**	 * 画英雄机	 * @param g	 */	private void paintHero(Graphics g) {		g.drawImage(hero.image,hero.x,hero.y,null);	}	/**	 * 画飞行物	 * @param g	 */	private void paintFlyings(Graphics g) {		for(int i=0;i
注:每个类的作用及每个方法的作用都已在注释中详细说明。

你可能感兴趣的文章
学习笔记_vnpy实战培训day04_作业
查看>>
OCO订单(委托)
查看>>
学习笔记_vnpy实战培训day05
查看>>
学习笔记_vnpy实战培训day06
查看>>
Python super钻石继承
查看>>
回测引擎代码分析流程图
查看>>
Excel 如何制作时间轴
查看>>
股票网格交易策略
查看>>
matplotlib绘图跳过时间段的处理方案
查看>>
vnpy学习_04回测评价指标的缺陷
查看>>
ubuntu终端一次多条命令方法和区别
查看>>
python之偏函数
查看>>
vnpy学习_06回测结果可视化改进
查看>>
读书笔记_量化交易如何建立自己的算法交易01
查看>>
设计模式03_工厂
查看>>
设计模式04_抽象工厂
查看>>
设计模式05_单例
查看>>
设计模式06_原型
查看>>
设计模式07_建造者
查看>>
设计模式08_适配器
查看>>