经过三天的学习相信大家基本都完成了自己的飞机大战。
现在献上所有的代码。
airplane.png
background.png
bee.png
bullet.png
gameover.png
hero0.png
hero1.png
pause.png
start.png
以上图片需要的加qq群吧,群号:769674658(快满)
qq交流二群(296389054)
Airplane---
package cn.shoot;
import java.util.Random;
/** 敌机: 是飞行物,也是敌人 */
public class Airplane extends FlyingObject implements Enemy {
private int speed = 2; //移动的速度
/** 构造方法 */
public Airplane(){
image = ShootGame.airplane; //图片
width = image.getWidth(); //宽
height = image.getHeight(); //高
Random rand = new Random(); //随机数对象
x = rand.nextInt(ShootGame.WIDTH-this.width); //x:0到(窗口宽-敌机宽)之间的随机数
y = -this.height; //y:负的敌机的高
}
/** 重写getScore()得分 */
public int getScore(){
return 5; //打掉一个敌机得5分
}
/** 重写step()走步 */
public void step(){
y+=speed; //y+(向下)
}
/** 重写outOfBounds()检查是否越界 */
public boolean outOfBounds(){
return this.y>=ShootGame.HEIGHT; //敌机的y>=窗口的高,即为越界了
}
}
Award-----
package cn.shoot;
/** 奖励 */
public interface Award {
public int DOUBLE_FIRE = 0; //火力值
public int LIFE = 1; //命
/** 获取奖励类型(上面的0或1) */
public int getType();
}
Bee——
package cn.shoot;
import java.util.Random;
/** 小蜜蜂: 是飞行物, */
public class Bee extends FlyingObject implements Award {
private int xSpeed = 1; //x坐标移动速度
private int ySpeed = 2; //y坐标移动速度
private int awardType; //奖励的类型(0或1)
/** 构造方法 */
public Bee(){
image = ShootGame.bee; //图片
width = image.getWidth(); //宽
height = image.getHeight(); //高
Random rand = new Random(); //随机数对象
x = rand.nextInt(ShootGame.WIDTH-this.width); //x:0到(窗口宽-小蜜蜂宽)之间的随机数
y = -this.height; //y:负的小蜜蜂的高
awardType = rand.nextInt(2); //0和1之间的随机数
}
/** 获取奖励类型 */
public int getType(){
return awardType; //返回奖励类型
}
/** 重写step()走步 */
public void step(){
x+=xSpeed; //x+(向左或向右)
y+=ySpeed; //y+(向下)
if(x>=ShootGame.WIDTH-this.width){ //若x>=(窗口宽-蜜蜂宽),则xSpeed为-1,加-1即为向左
xSpeed=-1;
}
if(x<=0){ //若x<=0,则xSpeed为1,加1即为向右
xSpeed=1;
}
}
/** 重写outOfBounds()检查是否越界 */
public boolean outOfBounds(){
return this.y>=ShootGame.HEIGHT; //小蜜蜂的y>=窗口的高,即为越界了
}}
package cn.shoot;
/** 子弹: 是飞行物 */
public class Bullet extends FlyingObject {
private int speed = 3; //移动的速度
/** 构造方法 子弹的初始坐标随着英雄机定*/
public Bullet(int x,int y){
image = ShootGame.bullet; //图片
width = image.getWidth(); //宽
height = image.getHeight(); //高
this.x = x; //x:随英雄机
this.y = y; //y:随英雄机
}
/** 重写step()走步 */
public void step(){
y-=speed; //y-(向上)
}
/** 重写outOfBounds()检查是否越界 */
public boolean outOfBounds(){
return this.y<=-this.height; //子弹的y<=负的子弹的高,即为越界了
}
}
package cn.shoot;
/** 敌人 */
public interface Enemy {
/** 得分 */
public int getScore();
}
package cn.shoot;
import java.awt.image.BufferedImage;
/** 飞行物 */
public abstract class FlyingObject {
protected BufferedImage image; //图片
protected int width; //宽
protected int height; //高
protected int x; //x坐标
protected int y; //y坐标
/** 飞行物走一步 */
public abstract void step();
/** 检测是否出界 */
public abstract boolean outOfBounds();
/** 检测敌人(敌机+小蜜蜂)是否被子弹击中 this:敌人 bullet:子弹 */
public boolean shootBy(Bullet bullet){
int x1 = this.x; //x1:敌人的x
int x2 = this.x+this.width; //x2:敌人的x+敌人的宽
int y1 = this.y; //y1:敌人的y
int y2 = this.y+this.height; //y2:敌人的y+敌人的高
int x = bullet.x; //x:子弹的x
int y = bullet.y; //y:子弹的y
return x>=x1 && x<=x2
&&
y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了
}
}
package cn.shoot;
import java.awt.image.BufferedImage;
/** 英雄机: 是飞行物 */
public class Hero extends FlyingObject {
private int doubleFire; //火力值
private int life; //命
private BufferedImage[] images; //可切换的图片数组
private int index; //协助图片切换
/** 构造方法 */
public Hero(){
image = ShootGame.hero0; //图片
width = image.getWidth(); //宽
height = image.getHeight(); //高
x = 150; //x:固定的值
y = 400; //y:固定的值
doubleFire = 10000; //默认为0(单倍火力)
life = 3; //默认3条命
images = new BufferedImage[]{ShootGame.hero0,ShootGame.hero1}; //两张图片切换
index = 0; //协助图片切换
}
/** 重写step()走步 */
public void step(){ //10毫秒走一次
image = images[index++/10%images.length];
/*
//每100毫秒切换一次
index++;
int a = index/10;
int b = a%2;
image = images[b];
*/
/*
* 10M index=1 a=0 b=0
* 20M index=2 a=0 b=0
* 30M index=3 a=0 b=0
* ...
* 100M index=10 a=1 b=1
* 110M index=11 a=1 b=1
* ...
* 200M index=20 a=2 b=0
* ...
* 300M index=30 a=3 b=1
*/
}
/** 英雄机发射子弹(生成子弹对象) */
public Bullet[] shoot(){
int xStep = this.width/4; //xStep:1/4英雄机的宽
int yStep = 20; //yStep:固定的20
if(doubleFire>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
doubleFire-=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;
}
}
/** 英雄机随着鼠标动 x:鼠标的x y:鼠标的y*/
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英雄机的高
}
/** 重写outOfBounds()检查是否越界 */
public boolean outOfBounds(){
return false; //永不越界
}
/** 英雄机增命 */
public void addLife(){
life++; //命数增1
}
/** 获取英雄机的命 */
public int getLife(){
return life; //返回命数
}
/** 英雄机减命 */
public void subtractLife(){
life--; //命数减1
}
/** 英雄机增火力 */
public void addDoubleFire(){
doubleFire+=40; //火力值增40
}
/** 清空英雄机的火力值 */
public void clearDoubleFire(){
doubleFire = 0; //火力值归零
}
/** 英雄机与敌人的碰撞算法 this:英雄机 other:敌人 */
public boolean hit(FlyingObject other){
int x1 = other.x-this.width/2; //x1:敌人的x-1/2英雄机的宽
int x2 = other.x+other.width+this.width/2; //x2:敌人的x+敌人的宽+1/2英雄机的宽
int y1 = other.y-this.height/2; //y1:敌人的y-1/2英雄机的高
int y2 = other.y+other.height+this.height/2; //y2:敌人的y+敌人的高+1/2英雄机的高
int x = this.x+this.width/2; //x:英雄机的x+1/2英雄机的宽
int y = this.y+this.height/2; //y:英雄机的y+1/2英雄机的高
return x>=x1 && x<=x2
&&
y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了
}
}
package cn.shoot;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Arrays;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.Font;
//主窗口类
public class ShootGame extends JPanel {
public static final int WIDTH = 400; //窗口宽
public static final int HEIGHT = 654; //窗口高
public static BufferedImage background; //背景图
public static BufferedImage start; //启动图
public static BufferedImage pause; //暂停图
public static BufferedImage gameover; //游戏结束图
public static BufferedImage airplane; //敌机
public static BufferedImage bee; //小蜜蜂
public static BufferedImage bullet; //子弹
public static BufferedImage hero0; //英雄机0
public static BufferedImage hero1; //英雄机1
static{ //初始化静态图片
try{
background = ImageIO.read(ShootGame.class.getResource("background.png"));
start = ImageIO.read(ShootGame.class.getResource("start.png"));
pause = ImageIO.read(ShootGame.class.getResource("pause.png"));
gameover = ImageIO.read(ShootGame.class.getResource("gameover.png"));
airplane = ImageIO.read(ShootGame.class.getResource("airplane.png"));
bee = ImageIO.read(ShootGame.class.getResource("bee.png"));
bullet = ImageIO.read(ShootGame.class.getResource("bullet.png"));
hero0 = ImageIO.read(ShootGame.class.getResource("hero0.png"));
hero1 = ImageIO.read(ShootGame.class.getResource("hero1.png"));
}catch(Exception e){
e.printStackTrace();
}
}
private Hero hero = new Hero(); //一个英雄机
private FlyingObject[] flyings = {}; //一堆敌人(敌机+小蜜蜂)
private Bullet[] bullets = {}; //一堆子弹
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; //当前状态(默认启动状态)
/** 生成敌人(敌机+小蜜蜂)对象 */
public FlyingObject nextOne(){
Random rand = new Random(); //随机数对象
int type = rand.nextInt(20); //0到19之间的随机数
if(type<4){ //0到3时,生成小蜜蜂对象
return new Bee();
}else{ //4到19时,生成敌机对象
return new Airplane();
}
}
int flyIndex = 0; //敌人入场计数
/** 敌人(敌机+小蜜蜂)入场 */
public void enterAction(){ //10毫秒走一次
flyIndex++; //每10毫秒增1
if(flyIndex%40==0){ //400(10*40)毫秒走一次
FlyingObject obj = nextOne(); //获取敌人(敌机+小蜜蜂)对象
flyings = Arrays.copyOf(flyings,flyings.length+1); //扩容
flyings[flyings.length-1] = obj; //将敌人添加到最后一个元素上
}
}
/** 飞行物(敌机+小蜜蜂+子弹+英雄机)走一步 */
public void stepAction(){ //10毫秒走一次
hero.step(); //英雄机走一步
for(int i=0;i