学Java有一段时间了,然后通过Java开发了一些简易安卓APP。最近很想实现以前自己很想写的飞机大战,也练练手。代码和界面参考(抄袭 )了许多,毕竟天下码农一家亲。
游戏大概长下面这样,鼠标点击即开始游戏,然后用鼠标操作飞机移动(鼠标到哪飞机移动到哪,超出游戏界面就暂停)。
package xyz.xinghai.game.bean;
public class GameStateBean {
//游戏启动
public static final int START = 0;
//游戏运行
public static final int RUNNING = 1;
//游戏暂停
public static final int PAUSE = 2;
//游戏结束
public static final int GAMEOVER = 3;
}
package xyz.xinghai.game.bean;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImgBean {
public static BufferedImage backgroundImg;
//游戏启动图
public static BufferedImage startImg;
//游戏暂停图
public static BufferedImage pauseImg;
//游戏结束图
public static BufferedImage gameOverImg;
//敌机图
public static BufferedImage enemyImg;
public static BufferedImage beeImg;
//子弹图
public static BufferedImage bulletImg;
public static BufferedImage hero0Img;
public static BufferedImage hero1Img;
public static BufferedImage bigBeeImg;
static {
try {
backgroundImg = ImageIO.read(ImgBean.class.getResource("background.png"));
startImg = ImageIO.read(ImgBean.class.getResource("start.png"));
pauseImg = ImageIO.read(ImgBean.class.getResource("pause.png"));
gameOverImg = ImageIO.read(ImgBean.class.getResource("gameover.png"));
enemyImg = ImageIO.read(ImgBean.class.getResource("airplane.png"));
beeImg = ImageIO.read(ImgBean.class.getResource("bee.png"));
bulletImg = ImageIO.read(ImgBean.class.getResource("bullet.png"));
hero0Img = ImageIO.read(ImgBean.class.getResource("hero0.png"));
hero1Img = ImageIO.read(ImgBean.class.getResource("hero1.png"));
bigBeeImg = ImageIO.read(ImgBean.class.getResource("bigBee.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package xyz.xinghai.game;
import java.awt.image.BufferedImage;
/**
* 飞行物体的抽象类
*/
public abstract class FlyingObject {
//飞行物的图片
protected BufferedImage image;
//飞行物的宽度
protected int width;
//飞行物的高度
protected int height;
//飞行物的x坐标
protected int x;
//飞行物的y坐标
protected int y;
//飞行物的移动
public abstract void move();
//是否飞出游戏界面
public abstract boolean outOfBounds();
//判断是否被击中 这个不是所有飞行物都有 所以不是抽象方法
public boolean shootBy(Bullet bullet) {
int x = bullet.x;
int y = bullet.y;
return (x > this.x && x < (this.x + this.width)) && (y > this.y && y < (this.y + this.height));
}
}
package xyz.xinghai.game;
import xyz.xinghai.game.bean.ImgBean;
/**
* 子弹类
*
*/
public class Bullet extends FlyingObject {
//子弹速度
private int speed = 3;
/**
* @param x 游戏界面上的x坐标
* @param y 游戏界面上的y坐标
*/
public Bullet(int x, int y) {
this.image = ImgBean.bulletImg;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
this.x = x;
this.y = y;
}
@Override
public void move() {
this.y -= speed;
}
@Override
public boolean outOfBounds() {
return this.y <= -this.height;
}
}
package xyz.xinghai.game;
import java.awt.image.BufferedImage;
import xyz.xinghai.game.bean.ImgBean;
public class Hero extends FlyingObject {
private int life;
private int doubleFire;
private BufferedImage[] images;
private int index;
public Hero() {
this.image = ImgBean.hero0Img;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
x = 150;
y = 400;
life = 3;
doubleFire = 0;
images = new BufferedImage[]{ImgBean.hero0Img,ImgBean.hero1Img};
index = 0;
}
@Override
public void move() {
image = images[index++/10%images.length];
}
@Override
public boolean outOfBounds() {
return false;
}
/**
* 根据doubleFire的值打不同数目的子弹
* @return 子弹数组
*/
public Bullet[] shoot() {
int xSpeed = this.width / 4;
int ySpeed = 20;
if (doubleFire >= 100) {
//三粒子弹 子弹的初始位置不同
Bullet[] bs=new Bullet[3];
bs[0] = new Bullet(this.x + 1 * xSpeed, this.y - ySpeed);
bs[1] = new Bullet(this.x + 2 * xSpeed, this.y - ySpeed);
bs[2] = new Bullet(this.x + 3 * xSpeed, this.y - ySpeed);
doubleFire -= 2;
return bs;
} else if (doubleFire < 100 && doubleFire > 0) {
Bullet[] bs=new Bullet[2];
//两粒子弹
bs[0]=new Bullet(this.x + 1* xSpeed, this.y - ySpeed);
bs[1]=new Bullet(this.x + 3* xSpeed, this.y - ySpeed);
doubleFire -= 2;
return bs;
} else{
//一粒子弹
Bullet[] bs = new Bullet[1];
bs[0] = new Bullet(this.x + 2 * xSpeed, this.y - ySpeed);
return bs;
}
}
/**
* 飞机移到指定坐标去
* @param x x坐标
* @param y y坐标
*/
public void moveTo(int x, int y) {
this.x=x-this.width/2;
this.y=y-this.height/2;
}
public void addLife(){
life+=2;
}
public int getLife(){
return life;
}
/**
* 加火力
*/
public void addDoubleFire(){
doubleFire += 20;
}
public int getDoubleFire(){
return doubleFire;
}
/**
* 生命减少
*/
public void subtractLife(){
life--;
}
/**
* 回到最初的发子弹速度
*/
public void clealDoubleFire(){
doubleFire = 0;
}
/**
* 是否发生碰撞
* @param other 其他继承自FlyingObject的飞行物
* @return
*/
public boolean hit(FlyingObject other) {
int x1 = other.x - this.width/2;
int x2 = other.x + this.width/2 + other.width;
int y1 = other.y - this.height/2;
int y2 = other.y + this.height/2 + other.height;
int x = this.x + this.width/2;
int y = this.y + this.height;
return (x>x1&&xy1&&y
package xyz.xinghai.game;
/**
* 敌人接口
*
*/
public interface Enemy {
public int getScore();
}
package xyz.xinghai.game;
/**
1. 奖励接口
2. */
public interface Award {
int DOUBLE_FIRE = 0;
int LIFE = 1;//生命
public int getType();
}
package xyz.xinghai.game;
import java.util.Random;
import xyz.xinghai.game.bean.ImgBean;
/**
* 敌机类
*
*/
public class EnemyPlane extends FlyingObject implements Enemy {
//速度
private int speed = 2;
//得分
private int score = 5;
public EnemyPlane() {
this.image = ImgBean.enemyImg;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
//随机初始化敌机位置
Random random = new Random();
x = random.nextInt(AircraftBattle.WIDTH - this.width);
y = -this.height;
}
public int getScore() {
return score;
}
@Override
public void move() {
y += speed;
}
@Override
public boolean outOfBounds() {
return this.y >= AircraftBattle.HEIGHT;
}
public void setScore(int score) {
this.score = score;
}
}
package xyz.xinghai.game;
import java.util.Random;
import xyz.xinghai.game.bean.ImgBean;
/**
* 打败后奖励积分更多
*
*/
public class BigBee extends FlyingObject implements Enemy {
private int speed = 1;
public BigBee() {
this.image = ImgBean.bigBeeImg;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
Random random = new Random();
x = random.nextInt(AircraftBattle.WIDTH - this.width);
y = -this.height;
}
@Override
public void move() {
y += speed;
}
@Override
public boolean outOfBounds() {
return this.y >= AircraftBattle.HEIGHT;
}
@Override
public int getScore() {
return 40;
}
}
package xyz.xinghai.game;
import java.util.Random;
import xyz.xinghai.game.bean.ImgBean;
/**
1. 打败后获得子弹加成
2. @author 15321
3. */
public class Bee extends FlyingObject implements Award {
private int xSpeed = 1;
private int ySpeed = 2;
private int awardType;
public int getType() {
return awardType;
}
public Bee() {
this.image = ImgBean.beeImg;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
Random rand=new Random();
this.x = rand.nextInt(AircraftBattle.WIDTH-this.width);
this.y = -this.height;
awardType=rand.nextInt(2);
}
@Override
public void move() {
y += ySpeed;
x += xSpeed;
if(x >= AircraftBattle.WIDTH-this.width){
xSpeed =-1;
}
if(x <= 0){
xSpeed =1;
}
}
@Override
public boolean outOfBounds() {
return this.height >= AircraftBattle.HEIGHT;
}
}
package xyz.xinghai.game;
import java.awt.Color;
import java.awt.Dimension;
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;
import xyz.xinghai.game.bean.GameStateBean;
import xyz.xinghai.game.bean.ImgBean;
/**
1. 主程序类
2. @author 15321
3. */
public class AircraftBattle extends JPanel {
private static final long serialVersionUID = 1L;
//游戏界面宽度
public static final int WIDTH = 400;
//游戏界面高度
public static final int HEIGHT = 645;
private int state = GameStateBean.START;
//主飞机
private Hero hero = new Hero();
//敌机数组
private FlyingObject[] flyings = {};
//子弹数组
private Bullet[] bullets = {};
//得分
private int score = 0;
@Override
public void paint(Graphics g) {
g.drawImage(ImgBean.backgroundImg, 0, 0, null);
paintHero(g);
paintFlyingObjects(g);
paintBullets(g);
paintScoreAndLife(g);
patintState(g);
}
/**
* 画得分和生命
* @param g 画笔
*/
private void paintScoreAndLife(Graphics g) {
g.setColor(new Color(0xFF0000));
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
g.drawString("SCORE:" + score, 10, 25);
g.drawString("LIFE:"+ hero.getLife(), 10, 50);
g.drawString("DoubleFire:" + hero.getDoubleFire(), 10, 75);
}
/**
* 画主飞机
* @param g 画笔
*/
private void paintHero(Graphics g) {
g.drawImage(hero.image, hero.x, hero.y, null);
}
/**
* 画屏幕中的敌机等飞行物体
* @param g 画笔
*/
private void paintFlyingObjects(Graphics g){
for(FlyingObject f : flyings)
g.drawImage(f.image, f.x, f.y, null);
}
/**
* 画子弹
* @param g 画笔
*/
private void paintBullets(Graphics g){
for(Bullet b : bullets)
g.drawImage(b.image, b.x, b.y, null);
}
/**
* 绘制游戏状态
* @param g 画笔
*/
private void patintState(Graphics g) {
switch(state){
case GameStateBean.START:
g.drawImage(ImgBean.startImg, 0, 0, null);
break;
case GameStateBean.PAUSE:
g.drawImage(ImgBean.pauseImg, 0, 0, null);
break;
case GameStateBean.GAMEOVER:
g.drawImage(ImgBean.gameOverImg, 0, 0, null);
}
}
/**
* 生成敌机
* @return 敌机
*/
private FlyingObject nextOne() {
Random rand = new Random();
int type = rand.nextInt(20);
if(type < 4) {
return new BigBee();
} else if (type == 5) {
return new Bee();
} else {
return new EnemyPlane();
}
}
//敌机入场的index
int flyEnteredIndex = 0;
/**
* 敌机入场的action
*/
private void enterAction() {
flyEnteredIndex++;
if(flyEnteredIndex % 40 ==0){
FlyingObject obj = nextOne();
//更新敌机数组
flyings = Arrays.copyOf(flyings, flyings.length+1);
flyings[flyings.length-1] = obj;
}
}
//子弹入场的index
int shootIndex = 0;
/**
* 主飞机发射子弹的Action 主飞机返回子弹数组 把返回的数组加到游戏子弹数组即可
*/
private void shootAction(){
shootIndex++;
if (shootIndex % 30 == 0) {
Bullet[] bs = hero.shoot();
//更新子弹数组
bullets = Arrays.copyOf(bullets, bullets.length+bs.length);
System.arraycopy(bs, 0, bullets, bullets.length-bs.length, bs.length);
}
}
/**
*飞行物移动的action 调用各自的移动方法即可
*/
private void moveAction(){
hero.move();
for(FlyingObject f : flyings)
f.move();
for(Bullet b : bullets)
b.move();
}
/**
* 飞行物飞出界面的action 就是把飞出界面的飞行物从数组中去掉
*/
private void outOfBoundsAction() {
int index = 0;
FlyingObject[] flyingLives = new FlyingObject[flyings.length];
for(FlyingObject f : flyings)
if(!f.outOfBounds())
flyingLives[index++] = f;
flyings=Arrays.copyOf(flyingLives, index);
index = 0;
Bullet[] bulletLives = new Bullet[bullets.length];
for(Bullet b : bullets)
if(!b.outOfBounds())
bulletLives[index++] = b;
bullets=Arrays.copyOf(bulletLives, index);
}
int j = 0;
/**
* 碰撞的action
*/
private void collisionAction() {
for(int i=0;i < bullets.length;i++){
collision(bullets[i],i);
}
}
/**
* 碰撞
* @param b 子弹
* @param bu 碰撞的子弹在子弹数组中的index
*/
private void collision(Bullet b, int bu) {
int index = -1;
for(int i=0;i