飞机大战
飞机大战小游戏历经10天完成,主要用到的就是我们面向对象部分的知识:类,封装,继承,多态,静态代码块等等内容+swing部分内容。所以即使你是java小白,也不用担心欧!
游戏说明:游戏有3种敌机(大敌机,小敌机,小蜜蜂)和一个英雄机,子弹,天空;英雄机随鼠标移动,可以发射子弹,其它三种敌机不能发射子弹,但是可以移动,加载图片都有自己的大小,所以我们定义一个飞行物的抽象类,把这些飞行物的共有属性和行为给封装起来,让子类去继承,重写!
飞行物类抽象类
:
//飞行物
public abstract class FlyingObject {
public static final int LIVE = 0;//活着的
public static final int DEAD = 1;//死亡
public static final int REMOVE = 2;//删除
protected int state = LIVE;//默认状态 活着的
protected int width;//宽
protected int hight;//高
//坐标
protected int x;
protected int y;
//专门给小/大敌机和小蜜蜂用的
public FlyingObject(int width,int hight) {
this.width = width;
this.hight = hight;
Random r = new Random();
x = r.nextInt(World.WIDTH-width);//敌机x的活动范围
y = -hight;
}
//专门给英雄机,天空,子弹
public FlyingObject(int width, int hight, int x, int y) {
this.width = width;
this.hight = hight;
this.x = x;
this.y = y;
}
//飞行物移动
public abstract void step();
public abstract BufferedImage getImage();
//获取状态
public boolean isLive(){
return state == LIVE;
}
public boolean isDead(){
return state == DEAD;
}
public boolean isRemove(){
return state == REMOVE;
}
/*判断敌人越界*/
public boolean isOutOfBounds(){
return y>=World.HEIGHT;
}
/*检测敌人碰撞 子弹/英雄机*/
public boolean isHit(FlyingObject object){
int x1 = this.x-object.width;
int x2 = this.x+this.width;
int y1 = this.y-object.hight;
int y2 = this.y+this.hight;
int x = object.x;
int y = object.y;
return x>=x1 && x<=x2 && y>=y1 && y<=y2;
}
/*飞行物去死*/
public void goDead(){
state = DEAD;
}
}
大敌机
:
//大敌机
public class BigAirplane extends FlyingObject implements EnemyScore{
private int speed;//速度
//构造
public BigAirplane() {
super(66,89);
speed = 2;
}
//飞行物移动
public void step(){
y+=speed;
}
int index = 1;
public BufferedImage getImage() {
if (isLive()){
return Images.bigairplanes[0];
}else if (isDead()){
BufferedImage img = Images.bigairplanes[index++];
if (index==Images.bigairplanes.length){
state = REMOVE;
}
return img;
}
return null;
}
@Override
public int getScore() {
return 3;
}
}
小敌机:
//小敌机
public class Airplane extends FlyingObject implements EnemyScore{
private int speed;//速度
//构造
public Airplane() {
super(49,50);
speed = 2;
}
//飞行物移动
public void step(){
y+=speed;
}
int index = 1;
public BufferedImage getImage() {
if (isLive()){
return Images.airplanes[0];
}else if (isDead()){
BufferedImage img = Images.airplanes[index++];
if (index==Images.airplanes.length){
state = REMOVE;
}
return img;
}
return null;
}
@Override
public int getScore() {
return 1;
}
}
小蜜蜂
:
public class Bee extends FlyingObject implements EnemyAward{
private int xspeed;//速度
private int yspeed;
private int awardType;
//构造
public Bee() {
super(60,51);
xspeed = 1;
yspeed = 2;
Random r = new Random();
awardType = r.nextInt(2);
}
//飞行物移动
public void step(){
x+=xspeed;
y+=yspeed;
if (x<=0 || x>=World.WIDTH-this.width){
xspeed*=-1;
}
}
int index = 1;
public BufferedImage getImage() {
if (isLive()){
return Images.bees[0];
}else if (isDead()){
BufferedImage img = Images.bees[index++];
if (index==Images.bees.length){
state = REMOVE;
}
return img;
}
return null;
}
@Override
public int getAward() {
return awardType;
}
}
英雄机
:
//英雄机
public class Hero extends FlyingObject {
private int lift;//命
private int fire;//火力值
//无参构造
public Hero() {
super(97,139,140,400);
lift = 3;
fire = 0;//单倍火力
}
//飞行物移动
public void step(){
}
int index = 0;
public BufferedImage getImage() {
return Images.heros[index++%Images.heros.length];
}
/**
* 生成子弹对象
*/
public Bullet[] shoot(){
int xStep = this.width/4;//把英雄机 宽度默认分四分
int yStep = 20;
//单双子弹 和 火力有关系
if (fire>0){
Bullet []bt = new Bullet[2];//双
bt[0] = new Bullet(this.x+xStep,this.y-yStep);//位置
bt[1] = new Bullet(this.x+3*xStep,this.y-yStep);//位置
fire-=2;
return bt;
}
Bullet[]bt = new Bullet[1];//单发
bt[0] = new Bullet(this.x+2*xStep,this.y-yStep);
return bt;
}
/*英雄级随着鼠标动*/
public void moveTo(int x,int y){
this.x = x-this.width/2;
this.y = y-this.hight/2;
}
public int getLift() {
return lift;
}
//减命
public void subtractLife(){
lift--;
}
//清空活力
public void clearFire(){
fire = 0;
}
//加子弹
public void addFire(){
fire+=40;
}
//加命
public void addLife(){
lift++;
}
}
子弹
:
//子弹
public class Bullet extends FlyingObject{
private int speed;//速度
//构造
public Bullet(int x,int y){
super(8,20,x,y);
speed = 3;
}
//飞行物移动
public void step(){
y-=speed;
}
//获取图片
@Override
public BufferedImage getImage() {
if (isLive()){
return Images.bullet;
}else if (isDead()){
state = REMOVE;
}
return null;
}
//判断越界
public boolean isOutOfBounds(){
return y<-hight;
}
}
天空
:
这里说明下,我们天空做的时候用的两张图片,游戏开始,两个天空图同步向下运行,当底下的天空图刚好出窗口时候,又回到窗口上方,继续同步的向下运动!
//天空
public class Sky extends FlyingObject{
private int y1;//我们两张图片切换使用
private int speed;//速度
//构造
public Sky() {
super(World.WIDTH,World.HEIGHT,0,0);
speed = 1;
y1 = -World.HEIGHT;
}
//飞行物移动
public void step(){
y+=speed;
y1+=speed;
if (y>=World.HEIGHT){
y = -World.HEIGHT;
}
if (y1>=World.HEIGHT){
y1 = -World.HEIGHT;
}
}
//获取图片
public BufferedImage getImage() {
return Images.sky;
}
public int getY1() {
return y1;
}
}
我们既然要加载图片,那就要定义一个初始化图片的类,放在静态代码块里面,在类加载的时候就会把我们这些图片加载进来:Images
类
public class Images {
public static BufferedImage sky;
public static BufferedImage bullet;
public static BufferedImage[] airplanes;
public static BufferedImage[] bigairplanes;
public static BufferedImage[] bees;
public static BufferedImage[] heros;
//状态图
public static BufferedImage start;//启动图
public static BufferedImage pause;//启动图
public static BufferedImage gameover;//启动图
static{
start = loadImage("start.png");
pause = loadImage("pause.png");
gameover = loadImage("gameover.png");
sky = loadImage("background.png");
bullet = loadImage("bullet.png");
heros = new BufferedImage[2];
heros[0] = loadImage("hero0.png");
heros[1] = loadImage("hero1.png");
airplanes = new BufferedImage[5];
bigairplanes = new BufferedImage[5];
bees = new BufferedImage[5];
airplanes[0] = loadImage("airplane.png");
bigairplanes[0] = loadImage("bigairplane.png");
bees[0] = loadImage("bee.png");
for(int i=1;i<airplanes.length;i++){
airplanes[i] = loadImage("bom"+i+".png");
bigairplanes[i] = loadImage("bom"+i+".png");
bees[i] = loadImage("bom"+i+".png");
}
}
public static BufferedImage loadImage(String fileName){
try{
BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));
return img;
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException();
}
}
}
最后是我们的核心类:
我们游戏所有的核心代码:碰撞,删除打死的敌人和出界敌人,鼠标移动,飞行物入场等代码,都在这个类实现:
public class World extends JPanel{
public static final int WIDTH = 400;
public static final int HEIGHT = 700;
public static final int START = 0;//启动
public static final int RUNNING = 1;//运行
public static final int PAUSH = 2;//暂停
public static final int GOME_OVER = 3;//游戏结束
public int state = START;//默认启动
Sky s = new Sky();
Hero hero = new Hero() ;
Bullet[] bullets= {
};
FlyingObject[] enemies = {
};
/**
* 专门生成敌人对象 随机数范围生成
*/
public FlyingObject nextOne(){
Random r = new Random();
int type = r.nextInt(20);
if (type<4){
return new Bee();
}else if (type <13){
return new Airplane();
}else {
return new BigAirplane();
}
}
/**
* 敌人入场
*/
int enterIndex = 0;
public void enterAction(){
enterIndex++;
if (enterIndex%40==0){
FlyingObject obj = nextOne();
enemies = Arrays.copyOf(enemies,enemies.length+1);
enemies[enemies.length-1] = obj;
}
}
/**
* 子弹入场
*/
int shootIndex = 0;
public void shootAction(){
shootIndex++;
if (shootIndex%30==0){
Bullet []bt = hero.shoot();
bullets = Arrays.copyOf(bullets,bullets.length+bt.length);
System.arraycopy(bt,0,bullets,bullets.length-bt.length,bt.length);
}
}
//飞行物移动
public void stepAction(){
//10毫秒
s.step();
for (int i = 0;i<enemies.length;i++){
enemies[i].step();
}
for (int i = 0;i<bullets.length;i++){
bullets[i].step();
}
}
//删除越界飞行物
public void outOfBoundsAction(){
//飞行物
for (int i = 0;i<enemies.length;i++){
if (enemies[i].isOutOfBounds() || enemies[i].isRemove()){
enemies[i] = enemies[enemies.length-1];
enemies = Arrays.copyOf(enemies,enemies.length-1);
}
}
//子弹
for (int i = 0;i<bullets.length;i++){
if (bullets[i].isOutOfBounds()|| bullets[i].isRemove()){
bullets[i] = bullets[bullets.length-1];
bullets = Arrays.copyOf(bullets,bullets.length-1);
}
}
}
private int score = 0;//玩家得分
/**
* 子弹与敌人碰撞
*/
public void BulletBangAvtion(){
for (int i = 0;i<bullets.length;i++){
Bullet b = bullets[i];//取出每一个子弹
for (int j = 0;j<enemies.length;j++){
FlyingObject f = enemies[j];//f 飞行物
if (b.isLive() && f.isLive() && f.isHit(b)){
b.goDead();
f.goDead();
if (f instanceof EnemyScore){
EnemyScore e = (EnemyScore)f;
score+=e.getScore();
}
if (f instanceof EnemyAward){
EnemyAward s = (EnemyAward)f;
int ward = s.getAward();
switch (ward) {
case EnemyAward.FIRE:
hero.addFire();
break;
case EnemyAward.LIFE:
hero.addLife();
break;
}
}
}
}
}
}
//英雄级和敌人碰撞
public void heroBangAction(){
for(int i = 0;i<enemies.length;i++){
FlyingObject f = enemies[i];
if (f.isLive() && hero.isLive() && f.isHit(hero)){
f.goDead();
hero.subtractLife();//减命
hero.clearFire();//清空活力
}
}
}
//英雄机 没命了 ->游戏结束
public void checkGameOverAction(){
if (hero.getLift()<=0){
state = GOME_OVER;
}
}
//业务处理
void action(){
//倾侦听器对象
MouseAdapter m = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if (state == RUNNING) {
int x = e.getX();
int y = e.getY();
hero.moveTo(x, y);
}
}
//鼠标点击
public void mouseClicked(MouseEvent e) {
switch (state){
case START:
state = RUNNING;
break;
case GOME_OVER:
score = 0;
s = new Sky();
hero = new Hero();
enemies = new FlyingObject[0];
bullets = new Bullet[0];
state = START;
break;
}
}
//鼠标移出5
public void mouseExited(MouseEvent e) {
if (state == RUNNING){
state = PAUSH;
}
}
//鼠标移出
public void mouseEntered(MouseEvent e) {
if (state == PAUSH){
state = RUNNING;
}
}
};
this.addMouseListener(m);//处理鼠标操作
this.addMouseMotionListener(m);//处理鼠标滑动
Timer timer = new Timer();//定时器
int interVel = 10;//定时间隔 10(毫秒)
timer.schedule(new TimerTask() {
@Override
public void run() {
if (state == RUNNING) {
enterAction();//敌人入场
shootAction();//子弹入场
stepAction();//飞行物移动
outOfBoundsAction();//飞行物移动
BulletBangAvtion();//子弹与敌人碰撞
heroBangAction();//英雄级和敌人碰撞
checkGameOverAction();
}
repaint();
}
}, interVel, interVel);
}
public void paint(Graphics g){
//画 对象
g.drawImage(Images.sky,s.x,s.y,null);
g.drawImage(Images.sky,s.x,s.getY1(),null);
g.drawImage(hero.getImage(),hero.x,hero.y,null);
for (int i = 0;i<enemies.length;i++){
FlyingObject f = enemies[i];
g.drawImage(f.getImage(),f.x,f.y,null);
}
for (int i = 0;i<bullets.length;i++){
Bullet b = bullets[i];
g.drawImage(b.getImage(),b.x,b.y,null);
}
//画 分
g.drawString("SCORE"+score,10,25);
//画命
g.drawString("LIFE:"+hero.getLift(),10,45);
switch (state){
case START:
g.drawImage(Images.start,0,0,null);
break;
case PAUSH:
g.drawImage(Images.pause,0,0,null);
break;
case GOME_OVER:
g.drawImage(Images.gameover,0,0,null);
break;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
World world = new World();
frame.add(world);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
world.action();
}
}
代码呢,我就上传到百度网盘,考虑到大家可视化工具的不一致问题,我就上传了两份项目代码:idea和eclipse,下载后,导入项目即可畅玩,下面有运行图欧!
提取码:4897
eclipse:
https://pan.baidu.com/s/1xv94T3jWy_K0wchB97-slw
idea:
https://pan.baidu.com/s/1itHG2ScWLjmourPsiIzg0A
以下是飞机大战运行图: