FlyingObject,作为飞行物的父类,这里的飞行物指的就是敌机,小蜜蜂,子弹,英雄机
package com.tarena.shoot;
import java.awt.image.BufferedImage;
//飞行物类
public abstract class FlyingObject {
protected BufferedImage image; //图片
protected int width; //宽
protected int height; //高
protected int x; //坐标
protected int y;
// 飞行物走一步
public abstract void step();
//检查是否出界,,返回true表示已越界
public abstract boolean outOfBounds();
public boolean shootBy(Bullet b) {
return false;
};
}
敌机类,图片取自ShootGame的入口类(在下面),打掉一个敌机得五分,敌机只能向下走
图片在主类 ShootGame中静态引入了
package com.tarena.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+1);
y = -this.height;
}
public int getScore() {
return 5; //打掉一个敌机得5分
}
// 重写
public void step() {
y+=speed;
}
// 重写是否越界函数---越界删除该对象
public boolean outOfBounds() {
if(y>ShootGame.HEIGHT) {
return true;
}else {
return false;
}
}
// 敌人被子弹射击----也就是检测图片与图片之间检测碰撞
public boolean shootBy(Bullet bullet) {
int x1 = this.x;
int x2 = this.x + this.width;
int y1 = this.y;
int y2 = this.y + this.height;
// x在 x1 和 x2 之间,y在y1和y2之间,既是碰撞了
if(bullet.xx1 && bullet.yy1) {
return true;
}else {
return false;
}
}
}
Bee,小蜜蜂类,也是敌人的一种,和上面敌机不同的是,小蜜蜂还会横着走,碰到边界反弹,打掉一个小蜜蜂还会获得奖励,也就是继承的接口 Award
package com.tarena.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+1);
y = -this.height;
awardType = rand.nextInt(2); //0到1之间
int xSymbol = rand.nextInt(2);
if(xSymbol == 0) {
xSpeed = -xSpeed;
}
}
public int getType() {
return awardType; //返回奖励类型 0/1 在ShootGame 中根据0、1判断奖励的类型分别调用方法
}
// 重写
public void step() {
y+=ySpeed;
x+=xSpeed;
if(x>ShootGame.WIDTH-this.width || x<=0) {
xSpeed = -xSpeed;
}
}
// 重写是否越界函数
public boolean outOfBounds() {
if(y>ShootGame.HEIGHT) {
return true;
}else {
return false;
}
}
// 敌人被子弹射击
public boolean shootBy(Bullet bullet) {
int x1 = this.x;
int x2 = this.x + this.width;
int y1 = this.y;
int y2 = this.y + this.height;
// x在 x1 和 x2 之间,y在y1和y2之间,既是碰撞了
if(bullet.xx1 && bullet.yy1) {
return true;
}else {
return false;
}
}
}
Award,,奖励,被小蜜蜂继承
package com.tarena.shoot;
public interface Award {
public int DOUBLE_FILE = 0; //火力值
public int LIFE = 1; //命
// 获取奖励
public int getType();
}
Enemy类,作为敌人(敌机+小蜜蜂)的公共接口,得分
package com.tarena.shoot;
public interface Enemy {
// 得分
public int getScore();
}
主角英雄机,Hero,有动态效果,两张图片来回切换
package com.tarena.shoot;
import java.awt.image.BufferedImage;
//英雄机
public class Hero extends FlyingObject {
private int life; //命
private int doubleFire=0; //火力值
private BufferedImage[] images; //两张图片切换
private int index; //协助图片切换
public Hero() {
image = ShootGame.hero0;
width = image.getWidth(); //获取图片的宽
height = image.getHeight(); //获取图片的高
x = 150; //x:初始值
y = 400; //y:初始值
life = 3; //默认3条命
images = new BufferedImage[] {ShootGame.hero0,ShootGame.hero1};
// 初始化images,两张图片
index = 0; //协助切换
}
// 重写
public void step() {
index++;
image = images[index/10%images.length]; //每100个毫秒切换一次
}
// 英雄机发射子弹
public Bullet[] shoot() {
int xStep = this.width/4;
int yStep = 20;
if(doubleFire > 0) {
Bullet[] bs = new Bullet[2];
bs[0] = new Bullet(this.x+1*xStep,this.y-yStep);
bs[1] = new Bullet(this.x+3*xStep,this.y-yStep);
doubleFire -=2; //发射一次双倍火力减2
return bs;
}else {
Bullet[] bs = new Bullet[1];
bs[0] = new Bullet(this.x+2*xStep,this.y-yStep);
return bs;
}
}
// 英雄机随着鼠标移动
public void moveTo(int x, int y) {
this.x = x - this.width/2; //使得英雄机中心对准在鼠标
this.y = y - this.height/2;
}
// 重写是否越界函数
public boolean outOfBounds() {
return false; //永不越界
}
// 加命
public void addLife() {
life++;
}
// 返回命
public int getLife() {
return life;
}
public void reduceLife() {
life--;
}
// 加火力
public void addDoubleFire() {
doubleFire += 40;
}
public void zeroDoubleFire() {
doubleFire = 0;
}
// 英雄机撞敌人,,true表示碰撞
public boolean hit(FlyingObject obj) {
int x1 = this.x - this.width/2;
int x2 = this.x + this.width/2;
int y1 = this.y - this.height/2;
int y2 = this.y + this.height/2;
if(obj.xx1 && obj.yy1) {
return true;
}else {
return false;
}
}
}
Bullet类,子弹类,也是飞行物的一种,它的x,y都是跟随英雄机
package com.tarena.shoot;
import java.util.Random;
public class Bullet extends FlyingObject{
private int speed = 3;
public Bullet(int x,int y) {
image = ShootGame.bullet;
width = image.getWidth(); //获取图片的宽
height = image.getHeight(); //获取图片的高
Random rand = new Random(); //随机数对象
this.x = x; //x跟随英雄机
this.y = y; //y跟随英雄机
}
// 重写
public void step() {
y-=speed;
}
// 重写是否越界函数
public boolean outOfBounds() {
if(y<-this.height) {
return true;
}else {
return false;
}
}
}
主类ShootGame,整个入口类,在这其中引入了所有的静态资源(图片),整个程序是用JFrame和JPanel来写的
检测鼠标事件,设定了一个定时器,画面是由定时器不断调用repaint方法刷新重画的
package com.tarena.shoot;
import java.awt.Component;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
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 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 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;
public static BufferedImage hero1;
private Hero hero = new Hero();
private FlyingObject[] flyings = {}; //敌人数组
private Bullet[] bullets = {}; //子弹数组
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();
}
}
// 随机生成敌人对象
public FlyingObject nextOne() {
Random rand = new Random();
int type = rand.nextInt(2);
if(type == 0) {
return new Bee();
}else {
return new Airplane();
}
}
// 敌人入场
int flyEnteredIndex = 0;
public void enterAction() {
//生成敌人对象,将对象添加到flyings数组中
flyEnteredIndex++;
if(flyEnteredIndex%40==0) {
FlyingObject one = nextOne();
flyings = Arrays.copyOf(flyings, flyings.length+1);
flyings[flyings.length-1] = one;
}
}
// 飞行物走一步
public void stepAction() {
hero.step();
for(int i=0; i
看看效果图啊,玩起来也是不错的。。。。
这个是开始界面,鼠标点击事件触发开始游戏。。
游戏界面,计分,得命
鼠标移出框外时触发 mouseExited 事件,暂停
游戏结束
编程经验:
先看功能是否是某个对象的行为
若是对象的行为,则写在相应的类中
若不是对象的行为,则写在ShooGame中
整个代码:链接:https://pan.baidu.com/s/1LBlG2y3QsYvfmpDy9U4ajw 密码:kdmp
(JDK版本1.7,编辑器Eclipse)