飞机大战源代码
一款飞机大战游戏
·
Airplane:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
public class Airplane extends FlyingObject implements EnemyScore{
private int speed; //移动速度
public Airplane(){ //构造方法
super(48,50); //小敌机的宽高
speed = 2; //移动速度
}
/*重写step()移动*/
public void step() {
y+=speed; //y+向下
}
private int index = 1; //爆破图的下标
/*重写getImage()获取图片*/
public BufferedImage getImage() { //每十毫秒走一次
if(isLive()) {
return Images.airs[0];
}else if(isDead()) {
BufferedImage img = Images.airs[index++]; //获取爆破图
if(index==Images.airs.length) { //到最后一张了
state = REMOVE; //将当前状态修改为REMOVE删除状态
}
return img; //返回爆破图
}
return null; //删除状态不返回图片
/*
* index=1
* 10M img=airs[1] index=2 airs[1]
* 20M img=airs[2] index=3 airs[2]
* 30M img=airs[3] index=4 airs[3]
* 40M img=airs[4] index=5 airs[4]
* (REMOVE)
* 50M 不返回图片
*/
}
public int getScore() {
return 1; //打掉小敌机玩家得1 分
}
}
Bee:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
import java.util.Random;
public class Bee extends FlyingObject implements EnemyAward{
private int xSpeed;
private int ySpeed;
private int awardType;
public Bee(){
super(60,51);
Random rand = new Random();
xSpeed = 1;
ySpeed = 2;
awardType = rand.nextInt(2); //0到1之间
}
public void step() {
x+=xSpeed; //x向左向右
y+=ySpeed; //y+向下
if(x<=0 || x>=World.WIDTH-width){ //若x<=0或X>=(窗口宽-蜜蜂宽),表示到头了
xSpeed*=-1; //切换方向(正便=变负、负变正)
}
}
private int index = 1; //爆破图的下标
/*重写getImage()获取图片*/
public BufferedImage getImage() { //每十毫秒走一次
if(isLive()) {
return Images.bees[0];
}else if(isDead()) {
BufferedImage img = Images.bees[index++]; //获取爆破图
if(index==Images.bees.length) { //到最后一张了
state = REMOVE; //将当前状态修改为REMOVE删除状态
}
return img; //返回爆破图
}
return null; //删除状态不返回图片
}
public int getAwardType() {
return awardType; //返回奖励类型
}
}
BigAirplane:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
public class BigAirplane extends FlyingObject implements EnemyScore{
private int speed;
public BigAirplane(){
super(66,89);
speed = 2;
}
public void step() {
y+=speed; //y+向下
}
private int index = 1; //爆破图的下标
/*重写getImage()获取图片*/
public BufferedImage getImage() { //每十毫秒走一次
if(isLive()) {
return Images.bairs[0];
}else if(isDead()) {
BufferedImage img = Images.bairs[index++]; //获取爆破图
if(index==Images.bairs.length) { //到最后一张了
state = REMOVE; //将当前状态修改为REMOVE删除状态
}
return img; //返回爆破图
}
return null; //删除状态不返回图片
}
/*重写getScore()*/
public int getScore() {
return 3; //打掉大敌机,玩家得3分
}
}
Bullet:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
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; //y+向上
}
/*重写getImage()获取图片*/
public BufferedImage getImage() {
if(isLive()) {
return Images.bullet; //直接返回图片
}else if(isDead()){ //若死了的
state = REMOVE; //将状态修改为REMOVE删除状态
}
return null; //死了的和删除的,都不反图片
/*
//若活着的,返回bullet 图片
//若死了的,状态改为删除,同时不返回图片
//若删除的不返回图片
*/
}
/*重写isOutOfBounds()判断子弹是否越界*/
public boolean isOutOfBounds() {
return y<=-height; //敌人的y>=窗口的高,即为越界了
}
}
EnemyAward接口:
package cn.tedu.cn;
/*奖励接口*/
public interface EnemyAward {
public int FIRE = 0; //火力
public int LIFE = 1; //命
/*获取奖励类型*/
public int getAwardType();
}
EnemyScore接口:
package cn.tedu.cn;
/*得分接口*/
public interface EnemyScore {
public int getScore(); //得分
}
FlyingObject超类:
package cn.tedu.cn;
import java.util.Random;
import java.awt.image.BufferedImage;
/*飞行物*/
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 height; //高
protected int x; //x坐标
protected int y; //y坐标
//专门给小敌机,大敌机,小蜜蜂提供的
//因为三种敌人的宽高不同,所以数据得写活,自然传参
//因为三种敌人的x和y坐标相同,所以直接写死,不需要传参
public FlyingObject(int width,int height){
this.width=width;
this.height=height;
Random rand = new Random(); //随机数对象
x = rand.nextInt(World.WIDTH-width); //0到(窗口宽-小敌机宽)之间是随机数
y = -height; //y:负的敌人的高
}
/*专门给英雄机、天空、子弹提供的*/
//因为英雄机,天空,子弹的宽高xy都不同,所以数据都得写活,都得传参过来
public FlyingObject(int width,int height,int x,int y){
this.width=width;
this.height=height;
this.x=x;
this.y=y;
}
public abstract void step();
/*获取对象的图片*/
public abstract BufferedImage getImage();
/*判断是否活着的*/
public boolean isLive() {
return state==LIVE; //当前状态为LIVE则表示为活着的,返回true,否则返回flase
}
/*判断是死了着的*/
public boolean isDead() { //当前状态为DEAD则表示为活着的,返回true,否则返回flase
return state==DEAD;
}
/*判断是否删除的*/
public boolean isRemove() { //当前状态为REMOVE则表示为活着的,返回true,否则返回flase
return state==REMOVE;
}
/*判断敌人是否越界*/
public boolean isOutOfBounds() {
return y>=World.HEIGHT; //敌人的y>=窗口的高,即为越界了
}
/*检测敌人与子弹/英雄机的碰撞 this:敌人 other:子弹/英雄机*/
public boolean isHit(FlyingObject other) {
int x1 = this.x-other.width; //x1:敌人的x-子弹/英雄机的宽
int x2 = this.x+this.width; //x2:敌人的x+敌人的宽
int y1 = this.y-other.height; //y1:敌人的y-子弹/英雄机的高
int y2 = this.y+this.height; //y2:敌人的y+敌人的高
int x = other.x; //x:子弹/英雄机的x
int y = other.y; //y:子弹/英雄机的y
return x>=x1 && x<=x2 && y>=y1 && y<=y2;
}
/*飞行物去死*/
public void goDead() {
state = DEAD; //将当前状态修改为DEAD死了的
}
}
Hero:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
public class Hero extends FlyingObject {
private int life;
private int fire;
public Hero() {
super(97, 139, 140, 400);
life = 3;
fire = 0;
}
public void step() {
}
int index = 0; //下标
/*重写getImage()获取图片*/
public BufferedImage getImage() { //每十个毫毛走一次
return Images.heros[index++ % Images.heros.length]; //在0到1之间来回切换
/* index=0;
10M 返 回hero[0] index=1;
20M 返 回hero[1] index=2;
30M 返 回hero[0] index=3;
40M 返 回hero[1] index=4;
*/
}
/*英雄机发射子弹(生成子弹对象)*/
public Bullet[] shoot() {
int xStep = this.width / 4; //1/4英雄机的宽
int yStep = 2;
if (fire > 0) { //双倍火力
Bullet[] bs = new Bullet[2]; //2发子弹
bs[0] = new Bullet(this.x + 1 * xStep, this.y - yStep); //x:英雄机的x+1/4英雄机的宽 y:英雄机的y-固定的20
bs[1] = new Bullet(this.x + 3 * xStep, this.y - yStep); //x:英雄机的x+3/4英雄机的宽 y:英雄机的y-固定的20
fire -= 2; //发射一次双倍火力,则火力值减2
return bs;
} else { //单倍
Bullet[] bs = new Bullet[1]; //1发子弹
bs[0] = new Bullet(this.x + 2 * xStep, this.y - yStep); //x:英雄机的x+2/4英雄机的宽 y:英雄机的y-固定的20
return bs;
}
}
/*英雄机随着鼠标移动*/
public void moveTo(int x, int y) {
this.x = x - this.width / 2; //英雄机的x=鼠标的x-1/2英雄机的宽
this.y = y - this.height / 2; //英雄机的y=鼠标的y-1/2英雄机的高
}
/*英雄机增命*/
public void addLife() {
life++; //命数加1
}
/*获取英雄机的命*/
public int getLife() {
return life; //返回命数
}
/*英雄机减命*/
public void subtractLife() {
life--;//命数-1
}
/*清空火力值*/
public void clearFire() {
fire = 0; //火力值为零
}
/*英雄机增火力*/
public void addFire() {
fire += 40; //火力值增40
}
}
Images:
package cn.tedu.cn;
//图片工具类
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class Images {
// 公开的 静态的 数据类型 变量名
public static BufferedImage sky;
public static BufferedImage bullet;
public static BufferedImage[] heros;
public static BufferedImage[] airs;
public static BufferedImage[] bairs;
public static BufferedImage[] bees;
public static BufferedImage start;
public static BufferedImage pause;
public static BufferedImage gameover;
static {
start = readImage("img/start.png");
pause = readImage("img/pause.png");
gameover = readImage("img/gameover.png");
sky = readImage("img/background.png");
bullet = readImage("img/bullet.png");
heros = new BufferedImage[2];
heros[0] = readImage("img/hero0.png");
heros[1] = readImage("img/hero1.png");
airs = new BufferedImage[5];
airs[0] = readImage("img/airplane.png");
bairs = new BufferedImage[5];
bairs[0] = readImage("img/bigairplane.png");
bees = new BufferedImage[5];
bees[0] = readImage("img/bee.png");
for(int i=1;i<airs.length;i++) { //赋值爆破图
airs[i] = readImage("img/bom"+i+".png");
bairs[i] = readImage("img/bom"+i+".png");
bees[i] = readImage("img/bom"+i+".png");
}
}
public static BufferedImage readImage(String fileName){
try{
BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));
return img;
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException();
}
}
}
Sky:
package cn.tedu.cn;
import java.awt.image.BufferedImage;
/*天空:是飞行物*/
public class Sky extends FlyingObject{
private int speed;;//移动速度
private int y1; //第二张图的y坐标
/*构造方法*/
public Sky(){
super(World.WIDTH,World.HEIGHT,0,0);
speed = 1;
y1 = -World.HEIGHT;
}
public void step() {
y += speed; //y+(向下)
y1+= speed; //y+(向下)
if(y>=World.HEIGHT) { //若y>=窗口的高,意味着y移出去了
y=-World.HEIGHT; //则修改y的值为负的窗口的高(挪到最上面去了)
}
if(y1>World.HEIGHT) { //若y1>=窗口的高,意味着y1一出去了
y1=-World.HEIGHT; //则修改y1的值为负的窗口的高(挪到最上面去了)
}
}
/*重写getImage()获取图片*/
public BufferedImage getImage() {
return Images.sky; //直接返回sky图片即可
}
/*获取y1坐标*/
public int getY1() {
return y1;
}
}
World主程序:
package cn.tedu.cn;
import javax.swing.*;
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Arrays;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
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 GAME_OVER = 3; //游戏结束状态
private int state = START; //当前状态(默认为启动状态)
private Sky sky = new Sky(); // 天空对象
private Hero hero = new Hero(); // 英雄机
private FlyingObject[] enemies = {}; // 敌人组
private Bullet[] bullets = {}; // 子弹数组
/* 敌人生成(小敌机,大敌机,小蜜蜂)对象 */
public FlyingObject nextOne() {
Random rand = new Random();
int type = rand.nextInt(20); // 0到19之间的随机数
if (type < 5) { // 0到4返回小蜜蜂对象
return new Bee();
} else if (type < 13) { // 5到12返回小蜜蜂对象
return new Airplane();
} else { // 13到19返回大敌机对象
return new BigAirplane();
}
}
private int enterIndex = 0;
/* 敌人(小敌机,大敌机,小蜜蜂)入场 */
public void enterAction() { // 每10毫秒做一次
enterIndex++; // 每10毫秒增1
if (enterIndex % 40 == 0) { // 每400毫秒走一次
FlyingObject obj = nextOne(); // 获取敌人对象
enemies = Arrays.copyOf(enemies, enemies.length + 1); // 扩容
enemies[enemies.length - 1] = obj; // 将obj添加到最后一个元素上
}
}
private int shootIndex = 0; // 子弹入场计数
/* 子弹入场 */
public void shootAction() { // 每10毫秒走一次
shootIndex++; // 每10毫秒走一次
if (shootIndex % 30 == 0) { // 每300毫秒走一次
Bullet[] bs = hero.shoot(); // 获取子弹数组对象
bullets = Arrays.copyOf(bullets, bullets.length + bs.length); // 扩容(bs有几个元素就扩大几个元素)
System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length); // 数组的追加
}
}
/*飞行物移动*/
public void stepAction() {
sky.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() { //每10毫秒走一次
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 bulletBangAction() {
for (int i = 0; i < bullets.length; i++) { //遍历所有子弹
Bullet b = bullets[i]; //获取每个子弹
for (int j = 0; j < enemies.length; j++) { //遍历所有敌人
FlyingObject f = enemies[j]; //获取每个敌人
if (b.isLive() && f.isLive() && f.isHit(b)) { //若都活着并且还撞上了
b.goDead(); //子弹去死
f.goDead(); //敌人去死
if (f instanceof EnemyScore) { //若被撞对象能得分--所有实现EnemyScore的类
EnemyScore es = (EnemyScore) f; //将被撞敌人强转为得分接口
score += es.getScore(); //玩家得分
}
if (f instanceof EnemyAward) { //若被撞敌人为奖励--所有实现EnemyAward的类
EnemyAward ea = (EnemyAward) f; //将被撞敌人强转为奖励接口
int type = ea.getAwardType(); //获取奖励类型
switch (type) { //根据奖励类型来获取不同的奖励
case EnemyAward.FIRE: //若奖励类型为火力
hero.addFire(); //则英雄机增火力
break;
case EnemyAward.LIFE: //若奖励类型为命
hero.addLife(); //则英雄机增命
break;
}
}
}
}
}
}
/*英雄机与敌人撞*/
public void heroBangAction() { //每10毫秒走一次
for (int i = 0; i < enemies.length; i++) { //遍历所有敌人
FlyingObject f = enemies[i]; //获取每个敌人
if (hero.isLive() && f.isLive() && f.isHit(hero)) {
f.goDead(); //敌人去死
hero.subtractLife(); //英雄机减命
hero.clearFire(); //英雄机清空火力
}
}
}
public void checkGameOverAction() {
if (hero.getLife() <= 0) { //表示游戏结束了
state = GAME_OVER; //将当前状态修改为游戏结束状态
}
}
/* 启动程序的执行 */
public void action() {
MouseAdapter m = new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
if (state == RUNNING) {
int x = e.getX(); //获取鼠标的x坐标
int y = e.getY(); //获取鼠标的y坐标
hero.moveTo(x, y); //英雄机随着鼠标移动
}
}
public void mouseClicked(MouseEvent e) {
switch (state) { //根据当前状态做不同的处理
case START: //启动状态时修改为运行状态
state = RUNNING;
break;
case GAME_OVER: //游戏结束状态时修改为启动状态
score = 0; //先清理现场,在修改为启动状态
sky = new Sky();
hero = new Hero();
enemies = new FlyingObject[0];
bullets = new Bullet[0];
state = START;//修改为启动状态
break;
}
}
/*重写mouseExited()鼠标移出事件*/
public void mouseExited(MouseEvent e) {
if (state == RUNNING) { //运行状态时修改为暂停状态
state = PAUSE;
}
}
/* 重写mouseEntered()鼠标移入事件*/
public void mouseEntered(MouseEvent e) {
if (state == PAUSE) { //暂停状态时修改为运行状态
state = RUNNING;
}
}
};
this.addMouseListener(m);
this.addMouseMotionListener(m);
Timer timer = new Timer(); // 定时器对象
int intervel = 10; // 定时间隔(以毫秒为单位)
timer.schedule(new TimerTask() {
public void run() { // 定时器干的事(每十毫秒走一次)
// 敌人入场 子弹入场 飞行物移动 子弹与敌人碰撞 英雄机与敌人碰撞
if (state == RUNNING) { //仅在运行状态下执行
enterAction(); //敌人(小敌机,大敌机,小蜜蜂)入场
shootAction(); //子弹入场
stepAction(); //飞行物移动
outOfBoundsAction(); //删除越界敌人
bulletBangAction(); //子弹与敌人碰撞
heroBangAction(); //英雄机与敌人的碰撞
checkGameOverAction(); //检测游戏结束
}
repaint(); // 重画 调用repaint() 画笔
}
}, intervel, intervel); //定时计划表
}
/* 重写paint()画 */
public void paint(Graphics g) { // 每10毫秒走一次
g.drawImage(sky.getImage(), sky.x, sky.y, null); // 画天空1
g.drawImage(sky.getImage(), sky.x, sky.getY1(), null); // 画天空2
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, 10, 25); //画分
g.drawString("生命:" + hero.getLife(), 10, 45); //画命
/*画启动图,暂停图,结束图*/
switch (state) {
case START:
g.drawImage(Images.start, 0, 0, null);
break;
case PAUSE:
g.drawImage(Images.pause, 0, 0, null);
break;
case GAME_OVER:
g.drawImage(Images.gameover, 0, 0, null);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("飞机大战");
World world = new World();
frame.add(world);
Image icon = Toolkit.getDefaultToolkit().getImage("C:\\Users\\才哥\\Desktop\\Shoot\\src\\cn\\tedu\\cn\\img\\1.png");
frame.setIconImage(icon);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true); // 设置窗口可见 尽快调用
world.action();
}更多推荐


所有评论(0)