首先弄清有多少类及属性,类分为英雄机(Hero),大小敌机(BigPlane/SmallPlane),蜜蜂(Bee),子弹类(Bullet),背景(Sky),飞行物类的总类(FlyingObject)和画板类(World),接口为AddM(加命的)和AddF(加分的)。
属性为 图片高度,图片宽度,x坐标和y坐标,其中英雄机,背景,子弹为固定位置,有这四个属性;大小敌机,蜜蜂为随机位置,有图片高度,图片宽度。
添加了鼠标监听等方法。
包和效果图如下。需要添加图片,在每个类中更改相应的图片大小和添加图片的张数。
飞行物类
package Fly;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public abstract class FlyingObject {
public static final int dead = 1;// 机毁人亡的时候
public static final int life = 2;// 活着的时候
public static final int remove = 3;// 删除
protected int state = life;// 当前状态为活着
int weight; // 图片的大小
int height; // 图片的大小
int x; // 坐标
int y; // 坐标
// 用于大小飞机 蜜蜂
public FlyingObject(int weight, int height) {
// super();
this.weight = weight;
this.height = height;
// 随机生成
Random r = new Random();
// 让它可以出现
this.x = r.nextInt(World.WIDTH - weight);
this.y = -height;
}
// 用于英雄机 天空 子弹
public FlyingObject(int weight, int height, int x, int y) {
// super();
this.weight = weight;
this.height = height;
this.x = x;
this.y = y;
}
// 降落方法
public abstract void step();
// 越界的方法
public abstract boolean outof();
// 画图的方法
public abstract BufferedImage getImage();
// 获取图片的方法
public static BufferedImage readimg(String name) { // 加了static
// readimg出错,其它类加载都出错
try {
BufferedImage img = ImageIO.read(FlyingObject.class.getResource(name));
return img;// 获取图片并返回图片对象(适用于有图片的类)
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// 画图上 画板 World
public void paintObject(Graphics g) {
g.drawImage(getImage(), x, y, null);
}
// 活着的时候
public boolean isLife() {
return state == life;
}
// 机毁人亡的时候
public boolean isDead() {
return state == dead;
}
// 删除的时候
public boolean isRemove() {
return state == remove;
}
public boolean hit(FlyingObject bb) {
// 是否碰撞
int x1=this.x-bb.weight; //是飞行物x 减 子弹weight
int x2=this.x+this.weight;//?
int x=bb.x;//?
int y1=this.y-bb.height;
int y2=this.y+this.height;
int y=bb.y;
return x>x1&&x<x2&&y>y1&&y<y2;
}
public void godead() {
// TODO Auto-generated method stub
state=dead;
}
}
画板类
package Fly;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
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 pause = 2;
public static final int gameover = 3;
private int state = start;// 当前状态为开始状态
public static BufferedImage START;
public static BufferedImage PAUSE;
public static BufferedImage GAMEOVER;
static {
START = FlyingObject.readimg("start.png");
PAUSE = FlyingObject.readimg("pause.png");
GAMEOVER = FlyingObject.readimg("gameover.png");
}
Sky s = new Sky();
Hero h = new Hero();
// SmallPlane ap = new SmallPlane();
// 把他们放进FlyingObject集合中
List<FlyingObject> fly = new ArrayList<FlyingObject>();
List<Bullet> b = new ArrayList<Bullet>();
// 生成随机飞行物的方法
public FlyingObject nextone() {
Random r = new Random();
int type = r.nextInt(20);
if (type <= 4) {
return new Bee();
} else if (type > 4 && type < 12) {
return new SmallPlane();
}
return new BigPlane();
}
// 生成飞行物对象添加到集合中
int a = 0;
public void shootAction() {
if (a++ % 30 == 0) {
FlyingObject f = nextone();
fly.add(f);
}
}
// 生成子弹对象添加到子弹集合中
int b1 = 0;
public void bulletAction() {
if (b1++ % 40 == 0) {
// Bullet b1 = h.getBullet(); //英雄机的h
// b.add(b1);// 子弹添加进来了
Bullet s[]=h.getBullet();
for (int i = 0; i < s.length; i++) {
b.add(s[i]);
}
}
}
int score=0;
public void HitAction() { //碰撞方法 加分加命的是接下来的
for (int i = 0; i < b.size(); i++) {
Bullet bb = b.get(i);
for (int j = 0; j < fly.size(); j++) {
FlyingObject f = fly.get(j);// 每一个飞行物
if (bb.isLife() && f.isLife() && f.hit(bb)) { //f.hit(bb) 子弹撞到飞机
bb.godead();
f.godead();
if (f instanceof AddF) {//飞行物如果是小敌机或大敌机
AddF a =(AddF)f;
score+=a.getScore();
}
if (f instanceof AddM) {
AddM m=(AddM)f;
int t=m.lx();
switch (t) {
case AddM.doubleFire:
h.addDoubleFire();
break;
case AddM.lifee:
h.addLife();
break;
}
}
}
}
}
for (int i = 0; i < fly.size(); i++) {
FlyingObject f = fly.get(i);
if (f.isLife() && f.hit(h)) { //飞行物和飞行物的碰撞
f.godead();
if (f instanceof AddF) {//飞行物如果是小敌机或大敌机
AddF a =(AddF)f;
score+=a.getScore();
}
if (f instanceof AddM) {
AddM m=(AddM)f;
int t=m.lx();
switch (t) {
case AddM.doubleFire:
h.addDoubleFire();
break;
case AddM.lifee:
h.addLife();
break;
} //双倍火力可以在这判断
}
h.loseLife();
h.clearDoubleFire();
}
}
}
public void StepAction() {
for (int i = 0; i < fly.size(); i++) {
fly.get(i).step();
}
for (int i = 0; i < b.size(); i++) {
b.get(i).step();
}
}
public void RemoveAction() { // 删除越界飞行物
for (int i = 0; i < fly.size(); i++) {
FlyingObject f = fly.get(i); // 飞行物集合
boolean b2 = f.outof();
if (f.outof()) {
fly.remove(i);
}
}
for (int i = 0; i < b.size(); i++) {
Bullet b1 = b.get(i); // 子弹集合
boolean b3 = b1.outof();
if (b1.outof()) {
b.remove(i);
}
}
}
public void GameOverAction(){//结束方法
if (h.life==0) {
state=gameover;
}
}
public void paint(Graphics g) {
s.paintObject(g);
h.paintObject(g);
// bt.paintObject(g);
// ap.paintObject(g);
for (int i = 0; i < fly.size(); i++) {
FlyingObject f1 = fly.get(i);
f1.paintObject(g); // 将FlyingObject的元素都放进去 画板的画画方法
}
for (int i = 0; i < b.size(); i++) {
b.get(i).paintObject(g);
}
g.drawString("LIFE"+h.life, 10, 15); // 加命
g.drawString("SCROE"+score, 10, 30); // 加分
switch (state) { // 判断当前的状态
case start:
g.drawImage(START, 0, 0, null); // 从0 0 开始, X和Y的坐标都是0
break;
case pause:
g.drawImage(PAUSE, 0, 0, null);
break;
case gameover:
g.drawImage(GAMEOVER, 0, 0, null);
break;
}
}
void action() {
MouseAdapter l = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
int x = e.getX();
int y = e.getY();
h.moveTo(x, y);
}
// 开始点击运行
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if (state == start) {
state = running;
}
}
// 移入
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
if (state == pause) {
state = running;
}
}
// 移出
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
if (state == running) {
state = pause;
}
}
};
this.addMouseListener(l); //鼠标监听
this.addMouseMotionListener(l); //鼠标移动监听
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 如果是在运行状态下的话
if (state == running) {
repaint();// 刷新
shootAction();// 获取飞行物对象
bulletAction();// 获取子弹对象
RemoveAction();// 删除越界飞行物
HitAction();// 碰撞方法
StepAction();// 速度
GameOverAction();//游戏结束
}
}
}, 10, 10);// 每十秒运行一次
}
public static void main(String[] args) {
MySound m= new MySound();
m.play();
JFrame jf = new JFrame("飞机大战2.0");
jf.setSize(WIDTH, HEIGHT);
World w = new World();
jf.add(w);
jf.setVisible(true);
// jf.setResizable(false);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
w.action();
}
}
英雄机类
package Fly;
import java.awt.image.BufferedImage;
public class Hero extends FlyingObject {
public static BufferedImage[] image;
static {
image = new BufferedImage[5];// 引用数组
for (int i = 0; i < image.length; i++) {
image[i] = readimg("hero" + i + ".png");
}
}
int life=6;
private int doubleFire1;
// int doubleFire=0;
public void addLife(){
life++;
}
public void loseLife(){
life--;
}
public void addDoubleFire(){
doubleFire1 += 22;
}
public void clearDoubleFire(){
doubleFire1=0;
}
public Hero() {
super(97, 127, 180, 540);
// TODO Auto-generated constructor stub
}
@Override
public void step() {
// TODO Auto-generated method stub
}
int index = 1;
@Override
public BufferedImage getImage() {
if (state == life) {
return image[0];
} else if (state == dead) {
BufferedImage img = image[index++];
if (image.length == index) {
state = remove;
}
return img;
}
return null;
}
public Bullet[] getBullet() {
// Bullet b = new Bullet(this.x+this.weight/2,this.y-20);
if (doubleFire1==0) {
Bullet bs[]=new Bullet[1];
bs[0]=new Bullet(this.x+this.weight/2,this.y-20);
return bs;
}else if(doubleFire1>0&&doubleFire1<=20){
Bullet bs[]=new Bullet[2];
bs[0]=new Bullet(this.x+this.weight/4, this.y-20);
bs[1]=new Bullet(this.x+this.weight*3/4, this.y-20);
doubleFire1-=2;
return bs;
}else if (doubleFire1>20&&doubleFire1<=40) {
Bullet bs[]=new Bullet[3];
bs[0]=new Bullet(this.x+this.weight*2/6, this.y-20);
bs[1]=new Bullet(this.x+this.weight*3/6, this.y-20);
bs[2]=new Bullet(this.x+this.weight*5/6, this.y-20);
doubleFire1-=2;
return bs;
}else if (doubleFire1>40) {
Bullet bs[]=new Bullet[4];
bs[0]=new Bullet(this.x+this.weight*2/7, this.y-20);
bs[1]=new Bullet(this.x+this.weight*3/7, this.y-20);
bs[2]=new Bullet(this.x+this.weight*4/7, this.y-20);
bs[3]=new Bullet(this.x+this.weight*6/7, this.y-20);
doubleFire1-=2;
return bs;
}
return null;
}
@Override
public boolean outof() {
// TODO Auto-generated method stub
return false;
}
public void moveTo(int x, int y) {
// 使他处于中心点
this.x=x-this.weight/2;
this.y=y-this.height/2;
}
}
大敌机类
package Fly;
import java.awt.image.BufferedImage;
public class BigPlane extends FlyingObject implements AddF{
//加载图片
public static BufferedImage[] image;
static{ //因为static静态快可以加载 遍历得到图片
image=new BufferedImage[5];
for (int i = 0; i < image.length; i++) {
image[i]=readimg("bigplane"+i+".png");
}
}
private int speed=4;
public BigPlane() {
super(69, 95);
// TODO Auto-generated constructor stub
}
@Override
public void step() {
// TODO Auto-generated method stub
this.y+=speed;
}
//判断它的状态
int index=1;
@Override
public BufferedImage getImage() {
if(state==life) {
return image[0];
}else if(state==dead) {
BufferedImage img = image[index++];//将图片的下标自增
if(image.length==index) { //如果当图片的总长度和下标一致时,就机毁人亡
state=remove;
}
return img;
}
return null;
}
@Override
public boolean outof() {
// TODO Auto-generated method stub
return false;
}
@Override
public int getScore() {
// TODO Auto-generated method stub
return 10;
}
}
小敌机类
package Fly;
import java.awt.image.BufferedImage;
public class SmallPlane extends FlyingObject implements AddF{
public static BufferedImage[] image;
static{
image=new BufferedImage[5];
for (int i = 0; i < image.length; i++) {
image[i]=readimg("airplane"+i+".png");
}
}
private int speed=2;
public SmallPlane() {
super(49,36);
speed=2;
}
@Override
public void step() {
// TODO Auto-generated method stub
this.y+=speed; //向下飞
}
int index=1;
@Override
public BufferedImage getImage() {
if(state==life) {
return image[0];
}else if(state==dead) {
BufferedImage img = image[index++];
if(image.length==index){
state=remove;
}
return img;
}
return null;
}
@Override
public boolean outof() {
// TODO Auto-generated method stub
return false;
}
@Override
public int getScore() { //打中加分
// TODO Auto-generated method stub
return 5;
}
}
蜜蜂类
package Fly;
import java.awt.image.BufferedImage;
public class Bee extends FlyingObject implements AddM{
public static BufferedImage[] image;
static{
image= new BufferedImage[5];
for(int i=0;i<image.length;i++){
image[i]=readimg("bee"+i+".png");
}
}
private int xspeed;//左右移动
private int yspeed;//前后移动
public Bee() {
super(60,50);
xspeed=3;
yspeed=4;
}
@Override
public void step() {
// TODO Auto-generated method stub
this.x+=xspeed;
this.y+=yspeed;
if(this.x>400-weight||this.x<0){ //过界的判断
xspeed*=-1;
}
}
int index=1;
@Override
public BufferedImage getImage() {
if(state== life ) {
return image[0];
}else if(state==dead) {
BufferedImage img = image[index++];//将图片的下标自增
if(image.length==index) { //如果当图片的总长度和下标一致时,就机毁人亡
state=remove;
}
return img;
}
return null;
}
@Override
public boolean outof() {
// TODO Auto-generated method stub
return this.y>700;
}
int lx;
@Override
public int lx() {
// TODO Auto-generated method stub
return lx;
}
// @Override
// public int getLife() {
// // TODO Auto-generated method stub
// return 1;
// }
}
加命的接口
package Fly;
public interface AddM {
int doubleFire = 0;
int lifee=1;
public int lx();
}
加分数的接口
package Fly;
public interface AddF {
int getScore();
}
一位编程菜鸟的小项目总结:编程的过程因人而异,作为普通人,能做的是多练习和保持一颗平常心,把每一步走踏实就行。(Hunan International Economics University)