目录
项目简单简介
飞机大战是集成这段时间实训以来的成果,其中包括了所学的封装,继承,多态,方法的重载等多个知识点构成的一款简单的小游戏。经过一个礼拜多的时间将此项目完成,由多个模块组成。
项目游戏成效图
类介绍
9个类,两个接口,
一、类:
1.子弹类:简单的
Bullet子弹类的设计也很简单,它设计好了,那么对于天空类就非常容见了,因为都是飞行物类
2.敌机类:简单的
BigAirPlane SmallAirPlane
三个数机中所干的事情是一样的,因为都是数机,所以只要把其中一个搞定。另外两个就不是问题了。对于子弹类,和天空类的设计,也是有帮助的,因为都是飞行物,大同小异,
英雄机类:简单的,因为也是飞行物的一种,代表的是我方英雄机
HeroAirPlane
3.天空类:简单的
Sky
4.飞行物参考的标准类:
FlyingObject
5.主程序加载类:
MainFrame:
6. ShootMain只是一个方法的调用而已
二、接口:
1.Enemy
2.Award
ShootMain类
package com.pleanwar.main;
import com.pleanwar.mainframe.MainFrame;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:32
*/
public class ShootMain {
public static void main(String[] args) {
MainFrame mainFrame=new MainFrame();
mainFrame.LoadGrme();
}
}
MainFrame类
package com.pleanwar.mainframe;
import com.pleanwar.bullet.Bullet;
import com.pleanwar.diji.Bee;
import com.pleanwar.diji.BigAirPlean;
import com.pleanwar.diji.SmallAirPlean;
import com.pleanwar.fiying.FlyingObject;
import com.pleanwar.hero.HeroAirPlean;
import com.pleanwar.inter.Awared;
import com.pleanwar.inter.Enemy;
import com.pleanwar.sky.Sky;
import javax.management.timer.TimerMBean;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:34
*/
public class MainFrame extends JPanel{
/*
*设置窗体宽度高度
* */
public static final int SCREEN_WIDTH=400;//宽度
public static final int SCREEN_HEIGHT=700;//高度
static BufferedImage start ;//全局共享
static BufferedImage pause;
static BufferedImage gameover;
/*
* 游戏状态
* */
public static final int START=0;//开始状态
public static final int RUNING=1;//游戏运行状态
public static final int PAUSE=2;//游戏暂停状态
public static final int GAME_OVER=3;//游戏结束状态
public int state=START;//默认状态
HeroAirPlean hero=new HeroAirPlean();//提供英雄机
Sky sky=new Sky();//天空
Bullet[]bullets={};//用于储存最终的子弹
FlyingObject[]flys={};//用来存储最终敌机
//此方法用于绘画
@Override
public void paint(Graphics g) {
super.paint(g);
sky.printObject(g);
//System.out.println(start); 变量BufferedImage start如果不加static 就会输出null
hero.printObject(g);//在窗体上运行FlyingObject中的printObject方法 hero机
//绘画子弹
for (int i=0;i<bullets.length;i++){
bullets[i].printObject(g);
}
//绘画敌机
for (int i=0;i<flys.length;i++){
flys[i].printObject(g);
}
g.drawString("分数:"+score,20,30);
g.drawString("生命:"+hero.getlife(),20,50 );
//开始状态 图片
if (state == START) {
g.drawImage(start, 0, 0, null);
}else if (state==GAME_OVER ){
g.drawImage(gameover, 0, 0, null);
}else if (state==PAUSE){
g.drawImage(pause, 0, 0, null);
}
}
/*
* 根据随机数产生敌机
* */
public FlyingObject nextone(){
Random random=new Random();
int type=random.nextInt(20);
if (type < 6) {
return new BigAirPlean();
} else if(type<12) {
return new SmallAirPlean();
}else {
return new Bee();
}
}
/*
* 敌机入场
* */
//用来控制敌机速度的索引
int enterAction=0;
public void enterAction(){
enterAction++;
if (enterAction%40==0) {
//FlyingObject f = new BigAirPlean();//声明数组来接受产生敌机
FlyingObject f = nextone();//具体产生敌机的方法
//确定敌机数量的
flys = Arrays.copyOf(flys, flys.length + 1);
flys[flys.length - 1] = f;
}
}
/*
* 子弹入场
*
* 调用英雄机子弹发射的方法,将返回的子弹存储在到数组中
*
* */
//用来控制子弹速度的索引
int shootIndex=0;
public void shootAction(){
shootIndex++;
if (shootIndex%30==0) {
//产生子弹的数组
Bullet[] bs = hero.shoot();
//元素数组储存
bullets = Arrays.copyOf(bullets, bullets.length + bs.length);
//将产生子弹的数组中所有的元素拷贝到 原数组中bullets 最后位子
System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);
}
}
/*
*自由飞行物的方法
* */
public void stepAction(){
sky.step();
//子弹移动
for (int i=0;i<bullets.length;i++){
bullets[i].step();
}
//敌机
for (int i=0;i<flys.length;i++){
flys[i].step();
}
}
/*
* 实现子弹与每个敌机碰撞
* 大敌机 小敌机 蜜蜂
* 分数的统计
* 火力变化
* 生命值的统计
* */
int score= 1;
public void bulletBangAction(){
for (int i = 0; i <bullets.length ; i++) {
//获取每一个子弹的碰撞
Bullet b=bullets[i];
for (int j=0;j<flys.length;j++){
//获取每一个敌机
FlyingObject f=flys[j];
//碰撞过程
if (f.islife() && b.islife() && f.hit(b) ){
f.goDead();//敌机死亡
b.goDead();//子弹死亡
/*
* 碰撞具体的判断
* 子弹与敌机的碰撞
* 大敌机 小敌机 分数增加、
* 蜜蜂 奖励增加 火力变化 生命值的增加
*
* */
if(f instanceof Enemy){
//接口实现类调用
Enemy e =(Enemy) f;
//分数统计
score +=e.getScore();
}
if(f instanceof Awared){
//奖励类型确定
Awared a =(Awared)f;
int type=a.getAwaredType();
switch (type) {
case Awared.DOUBLE_LIFE://火力
hero.addDoublefire();
//双倍火力
break;
case Awared.LIFE://生命
hero.addlife();
//生命值奖励
break;
}
}
}
}
}
}
/*
* 敌机与英雄机碰撞
* */
public void heroBangAction(){
//遍历敌机
for (int i = 0; i <flys.length ; i++) {
//获取每个敌机
FlyingObject f=flys[i];
if (hero.islife()&&f.islife()&&f.hit(hero)){
//碰撞进行中
f.goDead();//敌机死亡
//生命值不断减少
hero.substractionlife();
//清空活力值
hero.clearDoublefire();
}
}
}
/*
*
* */
public void cheakGameoveraCtion(){
if (hero.getlife()<=0){
state= GAME_OVER;
}
}
/*
* 鼠标适配器点击的方法
*
* */
public void action(){
MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (state==START){
state=RUNING;
}else if (state==GAME_OVER){
score=0;
sky=new Sky();
hero=new HeroAirPlean();
bullets=new Bullet[0];
state=START;
}
//repaint();//重画
}
//移动
@Override
public void mouseMoved(MouseEvent e) {
int x=e.getX();
int y=e.getY();
hero.MovedTo(x,y);
}
//鼠标移出事件
@Override
public void mouseExited(MouseEvent e) {
//鼠标移出事件 游戏处于暂停状态
if (state==RUNING){
state=PAUSE;
}
}
//鼠标移入事件
@Override
public void mouseEntered(MouseEvent e) {
//鼠标移入时恢复运行
if (state==PAUSE){
state=RUNING;
}
}
};
this.addMouseListener(mouseAdapter);//处理鼠标点击事件,否则点击没有效果
this.addMouseMotionListener(mouseAdapter);//处理鼠标移动事件
//时间定位器
/*
*重绘不断执行 repaint()
* */
Timer timer=new Timer();
timer.schedule(new TimerTask() {
//游戏开始后
@Override
public void run() {
if(state==RUNING){
shootAction();
//sky.step();
stepAction();
enterAction();
bulletBangAction();
heroBangAction();
cheakGameoveraCtion();
}
//重画
repaint();
}
},10,10);
}
/*
* 声明locdGram方法 加载游戏
* */
public void LoadGrme() {
//图片加入
start = FlyingObject.loadImage("/com/pleanwar/images/start.png");
gameover= FlyingObject.loadImage("/com/pleanwar/images/gameover.png");
pause = FlyingObject.loadImage("/com/pleanwar/images/pause.png");
MainFrame mainFrame=new MainFrame();
//窗体设计
JFrame jFrame=new JFrame();
//将画布装在窗体上
jFrame.add(mainFrame);
//设置窗体可显示
jFrame.setVisible(true);
//对高度宽度设置
jFrame.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
//对窗体标题设置
jFrame.setTitle("飞机大战");
//对窗体进行居中处理
jFrame.setLocationRelativeTo(null);
mainFrame.action();
}
}
FlyingObject抽象类
package com.pleanwar.fiying;
import com.pleanwar.mainframe.MainFrame;
import com.sun.org.apache.regexp.internal.RE;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:39
* 飞行物标准类
*/
public abstract class FlyingObject {
/*
* 提供对应的高度宽度x,y
* */
public int width;
public int height;
public int x;
public int y;
public int start=LIFE;//状态
public static final int LIFE=0;//存活
public static final int DEAO=1;//死亡
public static final int REMOVE=2;//死亡解锁
//无参构造
public FlyingObject() {
}
//提供对应敌机
public FlyingObject(int width,int height){
this.height=height;
this.width=width;
Random random=new Random();
this.x= random.nextInt(MainFrame.SCREEN_WIDTH-this.width);
this.y=-this.height;
}
//有参构造 提供对应的英雄机
public FlyingObject(int width,int height,int x,int y){
this.height=height;
this.width=width;
this.x=x;
this.y=y;
}
//飞行物的获取
public abstract BufferedImage getImage();
//提供标准的飞行物绘画的方法
public void printObject(Graphics graphics){
graphics.drawImage(this.getImage(), this.x, this.y, null);//hero
}
/*
* 声明一个图片加载
* */
public static BufferedImage loadImage(String filename) {
BufferedImage img= null;
//具体加载图片 反射
try {
img = ImageIO.read(FlyingObject.class.getResource(filename));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
//自由飞行物移动方法
public void step(){
}
//获取状态的方法
public boolean islife(){
//存活
return start==LIFE;
}
public boolean isdead(){
//死亡
return start==DEAO;
}
//碰撞
public boolean hit(FlyingObject other){
int x1=this.x-other.width;//横向:最小宽度
int y1=this.y-other.height;//纵向:最小高度
int x2=this.x+this.width;//横向:最小宽度
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(){
start=DEAO;
}
}
HeroAirPlean类
package com.pleanwar.hero;
import com.pleanwar.bullet.Bullet;
import com.pleanwar.fiying.FlyingObject;
import java.awt.image.BufferedImage;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:36
*
*英雄机设置 */
public class HeroAirPlean extends FlyingObject {
//提供英雄机声明数组
public static BufferedImage[]images=null;
static{
//希望加载的图片第一时间加载
images = new BufferedImage[2];//两个hero照片
for (int i =0;i <images.length;i++) {
images[i] = loadImage("/com/pleanwar/images/hero" + i + ".png");
//System.out.println(images[0]);
//System.out.println(images[1]);
}
}
/*
*声明两个变量 火力和生命值
* */
//生命值
private int life=6;
//火力
private int doublefire;
//提供英雄机的构造方法
public HeroAirPlean(){
super(97,124,140,400);
}
//获取加载的图片
@Override
public BufferedImage getImage() {
return images[0];
}
//提供英雄机移动坐标算法
public void MovedTo(int x, int y){
this.x= x -this.width/2;
this.y= y -this.height/2;
}
//增加英雄机发射子弹的方法,自动发射子弹
public Bullet[] shoot(){
int xStep=this.width/4;
int yStep=15;
/*//用来存储一个子弹
Bullet[]bullets=new Bullet[1];
//赋值
bullets[0]=new Bullet(this.x+xStep*2,this.y-yStep);//子弹发射坐标
return bullets;*/
if (doublefire >0) {
Bullet[] bs=new Bullet[2];
bs[0]=new Bullet(this.x+xStep*1,this.y-yStep);
bs[1]=new Bullet(this.x+xStep*3,this.y-yStep);
doublefire-=2;
return bs;
}else {
//用来存储一个子弹
Bullet[]bullets=new Bullet[1];
//赋值
bullets[0]=new Bullet(this.x+xStep*2,this.y-yStep);//子弹发射坐标
return bullets;
}
}
//增加火力
public void addDoublefire(){
doublefire+=10;
}
//增加生命值
public void addlife(){
life++;
}
//获得生命值的方法 用于判断游戏是否结束
public int getlife(){
return life;
}
//敌机与英雄机碰撞后生命值减少
public void substractionlife(){
life--;
}
//清空活力值
public void clearDoublefire(){
doublefire=0;
}
}
BigAirPlean类
package com.pleanwar.diji;
import com.pleanwar.fiying.FlyingObject;
import com.pleanwar.inter.Enemy;
import java.awt.image.BufferedImage;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:35
*/
public class BigAirPlean extends FlyingObject implements Enemy {
//大敌机加载
public static BufferedImage[]images;
static {
images=new BufferedImage[5];//代表储存5张大敌机
for (int i=0;i<images.length;i++){
images[i]=loadImage("/com/pleanwar/images/A"+i+".png");
}
}
//大敌机速度
public int speed;
//
public BigAirPlean(){
super(99,89);//
this.speed=2;
}
//获取加载后的敌机照片
//存活 消灭 敌机状态
int index= 1;
@Override
public BufferedImage getImage() {
BufferedImage img = null;
if (islife()) {
return images[0];
} else if (isdead()) {
img = images[index++];
if (index == images.length) {
start = REMOVE;
}
return img;
}
return null;
}
@Override
public void step() {
this.y+=speed;
}
//用于击败大敌机之后
@Override
public int getScore() {
return 3;//击败大敌机3分
}
}
SmallAirPlean类
package com.pleanwar.diji;
import com.pleanwar.fiying.FlyingObject;
import com.pleanwar.inter.Enemy;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:35
*/
public class SmallAirPlean extends FlyingObject implements Enemy {
public static BufferedImage[]images;
static {
images=new BufferedImage[5];
for (int i = 0; i < images.length; i++) {
images[i]=loadImage("/com/pleanwar/images/enemy"+i+".png");
}
}
//小敌机的速度
public int speed;
//提供小敌机
public SmallAirPlean(){
super(49,36);
this.speed=2;
}
//获取加载后的图片
int index=1;
//加载后图片
@Override
public BufferedImage getImage() {
BufferedImage img=null;
if(islife()){
return images[0];
}else if (isdead()){
img=images[index++];
if (index==images.length){
start=REMOVE;
}
return img;
}
return null;
}
//小敌机移动
@Override
public void step() {
this.y+=speed;
}
//击碎小敌机加一分
@Override
public int getScore() {
return 1;
}
}
Bee类
package com.pleanwar.diji;
import com.pleanwar.fiying.FlyingObject;
import com.pleanwar.inter.Awared;
import com.pleanwar.inter.Enemy;
import com.pleanwar.mainframe.MainFrame;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:35
*/
public class Bee extends FlyingObject implements Awared {
/*
* 蜜蜂图片加载
* */
public static BufferedImage[]images;
static {
//指定空间长度
images=new BufferedImage[5];
for (int i = 0; i <images.length ; i++) {
images[i]=loadImage("/com/pleanwar/images/mi"+i+".png");
}
}
//横向速度
public int xspeed;
//纵向速度
public int yspeed;
//确定奖励类型
public int awardtype;
//提供密封的构造方法
public Bee(){
super(60,60);
xspeed=1;
yspeed=2;
Random random=new Random();
awardtype=random.nextInt(2);
}
//获取加载后的图片
int index=1;
//图片的返回
@Override
public BufferedImage getImage() {
BufferedImage img=null;
if(islife()){
return images[0];
}else if (isdead()){
img=images[index++];
if (index==images.length){
start=REMOVE;
}
return img;
}
return null;
}
@Override
public int getAwaredType() {
return awardtype;
}
//移动
@Override
public void step() {
x+=xspeed;
y+=yspeed;
if (x<0||x>= MainFrame.SCREEN_WIDTH-this.width){
xspeed*=-1;
}
}
}
Bullet 类
package com.pleanwar.bullet;
import com.pleanwar.fiying.FlyingObject;
import java.awt.image.BufferedImage;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:38
*/
public class Bullet extends FlyingObject {
/*
* 子弹类设置
* */
public static BufferedImage img=null;
static {
img =loadImage("/com/pleanwar/images/bullet1.png");
}
//代表子弹移动的速度
private int speed;
//提供子弹
public Bullet(int x ,int y){
super(8,14,x,y);
this.speed=2;
}
//返回加载的图片
@Override
public BufferedImage getImage() {
return img ;
}
//子弹移动
@Override
public void step() {
this.y-=speed;
}
}
Sky类
package com.pleanwar.sky;
import com.pleanwar.fiying.FlyingObject;
import com.pleanwar.mainframe.MainFrame;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* @author fengxun
* @version 1.0
* @date 2020/5/2 17:39
* 天空类
*/
public class Sky extends FlyingObject {
//静态方法只允许访问静态属性
static BufferedImage img=null;
/*
* 加载天空块
* */
static {
img=loadImage("/com/pleanwar/images/background.png");
}
//天空移动的速度
private int speed;
/*
* 两张天空图片根据Y坐标 切换
* */
//第二张图片的纵坐标
private int y1;
//提供天空初始化
public Sky(){
super(MainFrame.SCREEN_WIDTH,MainFrame.SCREEN_HEIGHT,0,0);
this.speed=2;
y1=MainFrame.SCREEN_HEIGHT;
}
//返回加载得到的天空图片
@Override
public BufferedImage getImage() {
return img;
}
//绘画两张背景图片按照
@Override
public void printObject(Graphics graphics) {
graphics.drawImage(getImage(),x,y,null);
graphics.drawImage(getImage(),x,y1,null);
}
//自由移动方法 天空 子弹
@Override
//重写每一个自由飞行物滚动的方法
public void step() {
y += speed;
y1 += speed;
if (y >= MainFrame.SCREEN_HEIGHT) {
y = -MainFrame.SCREEN_HEIGHT;
}
if (y1 >= MainFrame.SCREEN_HEIGHT) {
y1 = -MainFrame.SCREEN_HEIGHT;
}
}
}
Awared 接口
package com.pleanwar.inter;
public interface Awared {
public static final int DOUBLE_LIFE=0;//火力类型
public static final int LIFE=1;//生命值
int getAwaredType();//奖励类型
}
Enemy 接口
package com.pleanwar.inter;
public interface Enemy {
//统计击败敌机分数
int getScore();
}
想要飞机模型素材的找我