/**
主机
@author Administrator
*/
public class Hero extends FlyingObiect{
private static BufferedImage[] images;
static{
images = new BufferedImage[2];
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(“hero” + i + “.png”);
}
}
private int life ;
private int doubleFire;
public Hero() {
super(97, 124, 140, 400);
life = 6;
doubleFire = 0;
}
public void moveTo(int x,int y){
this.x = x - this.width/2;
this.y = y - this.height/2;
}
public void step(){
System.out.println(“图片的切换”);
}
@Override
public BufferedImage getImage() {
return images[0];
}
/*英雄机产生子弹/
public Bullet[] shoot() {
int xStep = this.width/4;
int yStep = 15;
if (doubleFire >0) {//双倍火力
Bullet[] bs = new Bullet[2];
bs[0] = new Bullet(this.x + xStep * 1, this.y - yStep);
bs[1] = new Bullet(this.x + xStep * 3, this.y - yStep);
return bs;
}else {
Bullet[] bs = new Bullet[1];
bs[0] = new Bullet(this.x + xStep * 2, this.y - yStep);
return bs;
}
}
public void addDoubleFire() {
doubleFire +=10;
}
public void addLife() {
life++;
}
public int getLife() {
return life;
}
public void substractLife() {
life–;
}
public void clearDoublieFire() {
// TODO Auto-generated method stub
doubleFire = 0;
}
}
public class AirPlane extends FlyingObiect implements Enemy{
private static BufferedImage[] images;
static{
images = new BufferedImage[5];
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(“airplane” + i + “.png”);
}
}
//成员变量
private int speed;//速度
//方法
/构造方法/
public AirPlane () {
super(49, 36);
//小敌机出现的位置
this.speed = 2;
}
/移动/
public void step(){
this.y += speed;
}
//得到图片
int index = 1;
@Override
public BufferedImage getImage() {
if (isLife()) {
return images[0];
} else if(isDead()){//图片切换
BufferedImage img = images[index++];
if (index == images.length) {
state = REMOVE;
}
return img;
}
return null;
}
/*得分奖励/
@Override
public int getScore() {
return 1;
}
}
public class BigAirplane extends FlyingObiect implements Enemy{
private static BufferedImage[] images;
static{
images = new BufferedImage[5];
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(“bigplane” + i + “.png”);
}
}
//成员变量
private int speed;//速度
//方法
/构造方法/
public BigAirplane () {
super(98, 72);
this.speed = 2;
}
/移动/
public void step(){
this.y += speed;
}
int index = 1;
@Override
public BufferedImage getImage() {
if (isLife()) {
return images[0];
} else if(isDead()){//图片切换
BufferedImage img = images[index++];
if (index == images.length) {
state = REMOVE;
}
return img;
}
return null;
}
/*得分奖励/
@Override
public int getScore() {
return 3;
}
}
public class Bee extends FlyingObiect implements Award{
private static BufferedImage[] images;
static {
images = new BufferedImage[5];
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(“bee” + i + “.png”);
}
}
//成员变量
private int xspeed;
private int yspeed;
private int awardType;
//方法
/构造方法/
public Bee () {
super(20, 60);
xspeed = 1;
yspeed = 2;
Random rand = new Random();
awardType = rand.nextInt(2);
}
/移动/
public void step(){
x += xspeed;
y += yspeed;
if (x < 0 || x >= ShootMain.SCREEN_WIDTH - this.width) {
xspeed *= -1;
}
}
int index = 1;
@Override
public BufferedImage getImage() {
if (isLife()) {
return images[0];
} else if(isDead()){//图片切换
BufferedImage img = images[index++];
if (index == images.length) {
state = REMOVE;
}
return img;
}
return null;
}
@Override
public int getAwardType() {
return awardType;
}
}
public class Bullet extends FlyingObiect{
private static BufferedImage images;
static{
images = loadImage(“bullet.png”);
}
//成员变量
private int speed;//速度
private int height;
public Bullet(int x ,int y) {
super(8, 14,x , y);
speed = 69;
}
/移动/
public void step(){
this.y -= speed;
}
/*重写getImage()方法获取/
@Override
public BufferedImage getImage() {
if (isLife()) {
return images;
} else if (isDead()) {
state = REMOVE;//修改状态为删除为删除状态
}
return null;
}
//检测越界的方法
@Override
public boolean outOfBounds() {
return this.y <= -this.height;
}
public BufferedImage getImages() {
// TODO Auto-generated method stub
return null;
}
}
public class Sky extends FlyingObiect{
private static BufferedImage images;
static{
images = loadImage(“10.jpg”);
}
private int speed;
public int y1;//第二张图片的坐标
public Sky() {
super(ShootMain.SCREEN_WIDTH, ShootMain.SCREEN_HEIGHT, 0, 0);
speed = 1;
y1 = -ShootMain.SCREEN_HEIGHT;
}
/**移动**/
public void step(){
y += speed;
y1 += speed;
if (y >= ShootMain.SCREEN_HEIGHT) {
y = -ShootMain.SCREEN_HEIGHT;
}
if (y1 >= ShootMain.SCREEN_HEIGHT) {
y1 = -ShootMain.SCREEN_HEIGHT;
}
}
@Override
public BufferedImage getImage() {
return images;
}
/**重写父类的方法*/
@Override
public void paintObject(Graphics g) {
g.drawImage(getImage(), x, y, null);
g.drawImage(getImage(), x, y1, null);
}
}
public abstract class FlyingObiect {
protected int width;//宽
protected int height;//高
protected int x;//x坐标
protected int y;//Y坐标
public static final int LIFE=0;
public static final int DEAD=1;
public static final int REMOVE=2;
public int state=LIFE;//当前状态为存活;
public FlyingObiect(int width ,int height) {
this.width = width;
this.height = height;
Random rand = new Random();
this.x = rand.nextInt(ShootMain.SCREEN_WIDTH- this.width);
this.y = -this.height ;
}
public FlyingObiect(int width, int height,int x ,int y) {
this.height = height;
this.width = width;
this.x = x ;
this.y = y;
}
public void step(){
System.out.println(“飞行物移动”);
}
/*读取图片/
public static BufferedImage loadImage(String fileName) {
try {
BufferedImage img = ImageIO.read(FlyingObiect.class.getResource(fileName));
return img;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public abstract BufferedImage getImage() ;
public void paintObject(Graphics g){
g.drawImage(this.getImage(), x, y, null);
}
/*判断当前状态是否存活/
public boolean isLife(){
return state == LIFE;
}
/*判断当前状态是否over/
public boolean isDead(){
return state ==DEAD;
}
/*判断当前状态是否删除/
public boolean isRemove() {
return state ==REMOVE;
}
/*检测越界的方法/
public boolean outOfBounds() {
return this.y >= ShootMain.SCREEN_HEIGHT;
}
/*实现检测子弹与敌人碰撞 this:敌人 other:子弹/
public boolean hit(FlyingObiect other){
int x1 = this.x - other.width;
int y1 = this.y - other.height;
int x2 = this.x + this.width;
int y2 = this.y + this.height;
int x = other.x;
int y = other.y;
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
/*飞行物over/
public void goDead() {
state = DEAD;//将对象的状态修改为DEAD
}
}
public class ShootMain extends JPanel {
public static final int SCREEN_WIDTH = 400;
public static final int SCREEN_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; //当前状态(默认启动状态)
public static BufferedImage start;
public static BufferedImage pause;
public static BufferedImage gameover;
static{
start = FlyingObiect.loadImage("start.png");
pause = FlyingObiect.loadImage("pause.png");
gameover = FlyingObiect.loadImage("gameover.png");
}
FlyingObiect[] flys = new FlyingObiect[0];
Sky sky = new Sky();
Hero hero = new Hero();
private Bullet[] bullets = {};
public FlyingObiect anamy() {
Random rand = new Random();
int type = rand.nextInt(20);
if (type < 5) {
return new AirPlane();
} else if (type < 12) {
return new Bee();
} else {
return new BigAirplane();
}
}
// 实现敌人入场
int enterIndex = 0;
public void enterAction() {
enterIndex++;
if (enterIndex % 40 == 0) {
// 获取敌人
FlyingObiect f = anamy();
// 敌人添加到数组的最后一位;
flys = Arrays.copyOf(flys, flys.length + 1);// 将数组的内存扩大
flys[flys.length - 1] = f;
}
}
// 子弹入场
int shootIndex = 0;
public void shootAction() {
shootIndex++;
if (shootIndex % 40 == 0) {
Bullet[] bs = hero.shoot();// 获取子弹
bullets = Arrays.copyOf(bullets, bullets.length + bs.length);
// 将产生的子弹数组放到原数组中的最后一个位置
System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);
}
}
/** 飞行物移动 */
public void stepAction() {
sky.step();
for (int i = 0; i < flys.length; i++) {
flys[i].step();
}
for (int i = 0; i < bullets.length; i++) {
bullets[i].step();
}
}
/** 删除越界的飞行物 */
public void outOfBoundsAction() {
int index = 0;// 存放不越界数组下标,个数
//
FlyingObiect[] flysLive = new FlyingObiect[flys.length];
for (int i = 0; i < flys.length; i++) {
// 获取到每一个敌人
FlyingObiect f = flys[i];
// 判断是否不越界
if (!f.outOfBounds()) { // 如果不越界
flysLive[index] = f;
index++;
}
// 将不越界的敌人存放到不越界的数组中
}
flys = Arrays.copyOf(flysLive, index);
index = 0;
Bullet[] bulletLive = new Bullet[bullets.length];
for (int i = 0; i < bulletLive.length; i++) {
Bullet b = bullets[i];
if (!b.outOfBounds()) {
bulletLive[index] = b;
index++;
}
}
bullets = Arrays.copyOf(bulletLive, index);
}
/** 子弹与敌人的碰撞 */
int score = 0;
public void bulletBangAction() {
for (int i = 0; i < bullets.length; i++) {// 遍历所有的子弹
Bullet b = bullets[i];// 获取每一个子弹
// 遍历所有的敌人
for (int j = 0; j < flys.length; j++) {
// 获取每一个敌人
FlyingObiect f = flys[j];
// 判断碰撞
if (f.isLife() && b.isLife() && f.hit(b)) {
f.goDead();// 敌人over
b.goDead();// 子弹over
if (f instanceof Enemy) {// 如果撞上敌人
Enemy e = (Enemy) f;
score += e.getScore();
}
if (f instanceof Award) {
Award a = (Award) f;
int type = a.getAwardType();
switch (type) {
case Award.DOUBLE_FIRE:// 火力
hero.addDoubleFire();
break;
case Award.LIFE:// 生命
hero.addLife();
break;
}
}
}
}
}
}
/**英雄机与敌人发生碰撞*/
public void heroBangAction() {
/*
* 1)借助FlyingObject中的hit()方法检测碰撞
* 2)借助FlyingObject中的goDead()方法over
* 3)在Hero类中设计一个方法实现碰撞之后substractLife()减少生命,clearDoubleFire()
* 4)在run()方法中实现英雄机与敌人发生碰撞heroBangAction();
* 5)遍历每一个敌人
* 6)判断撞上了
* 7)敌人over,英雄机减少生命,清空火力
*/
for (int i = 0; i < flys.length; i++) {//遍历所有敌人
FlyingObiect f = flys[i];//获取每一个敌人
if (hero.isLife() && f.isLife() && f.hit(hero)) {
f.goDead();
hero.substractLife(); //英雄0机减命
hero.clearDoublieFire(); //英雄机清空火力值
FlyingObiect t = flys[i];
flys[i] = flys[flys.length-1];
flys[flys.length-1] = t;
//缩容(去掉最后一个元素,即被撞的敌人对象)
flys = Arrays.copyOf(flys,flys.length-1);
}
}
}
/** 判断游戏结束 */
public void checkGameOverAction(){ //10毫秒走一次
if(hero.getLife()<=0){ //游戏结束了
state = GAME_OVER;//修改当前状态为游戏结束状态
}
}
/** 测试方法 */
public void action() {
MouseAdapter ma = new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
/**重写鼠标的移动事件*/
int x = e.getX();
int y = e.getY();
System.out.println(x + "," + y);
hero.moveTo(x, y);
}
/**重写鼠标的点击事件*/
@Override
public void mouseClicked(MouseEvent e) {
//根据当前状态的不同进行处理
switch (state) {
case START:
state = RUNNING;
break;
case GAME_OVER:
score = 0;
sky = new Sky();
hero = new Hero();
flys = new FlyingObiect[0];
bullets = new Bullet[0];
state = START;//修改状态为开始状态
break;
}
}
/**重写鼠标的移入事件*/
@Override
public void mouseEntered(MouseEvent e) {
if(state==PAUSE){ //暂停状态时
state=RUNNING; //修改为运行状态
}
}
/**重写鼠标的移出事件*/
@Override
public void mouseExited(MouseEvent e) {
if(state==RUNNING){ //运行状态时
state=PAUSE; //修改为暂停状态
}
}
};
this.addMouseListener(ma);// 处理鼠标的
this.addMouseMotionListener(ma);// 处理鼠标的
// 定时器对象
Timer timer = new Timer();
int inters = 10;
timer.schedule(new TimerTask() {
@Override
public void run() {
if (state == RUNNING) {
enterAction();// 敌人入场
shootAction();// 子弹入场
stepAction();// 飞行物移动
outOfBoundsAction();// 删除越界的飞行物
bulletBangAction();// 子弹与敌人的碰撞
heroBangAction();//英雄机与敌人发生碰撞
checkGameOverAction(); //判断游戏结束
}
repaint();// 重绘,调用paint方法
}
}, inters, inters);// 计划任务
}
@Override
public void paint(Graphics g) {
super.paint(g);
sky.paintObject(g);
hero.paintObject(g);
// 画敌人
for (int i = 0; i < flys.length; i++) {
flys[i].paintObject(g);
}
for (int i = 0; i < bullets.length; i++) {
bullets[i].paintObject(g);
}
g.drawString("分数: " + score, 30, 60);
g.drawString("生命:" + hero.getLife(), 30, 80);
switch (state) {
case START:
g.drawImage(start, 0, 0, null);
break;
case PAUSE:
g.drawImage(pause, 0, 0, null);
break;
case GAME_OVER:
g.drawImage(gameover, 0, 0, null);
break;
}
}
public static void main(String[] args) {
ShootMain sm = new ShootMain();
JFrame jf = new JFrame();
jf.add(sm);// 将画布装在窗体上
jf.setSize(400, 700);// 窗体大小
jf.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);// 大小
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 关闭
jf.setLocationRelativeTo(null);// 居中显示
jf.setVisible(true);
sm.action();
}
}
public interface Enemy {
/*得分/
public int getScore();
}
public interface Award {
public int DOUBLE_FIRE = 0;
public int LIFE = 1;
/**获取奖励类型(0~1)*/
public int getAwardType();
}
OOP
射击游戏项目
需求分析
运行结果:
1.小敌机,大敌机,蜜蜂
英雄机,发射子弹
子弹可以打中敌人
2.子弹击中小敌机、、、玩家得分1
子弹击中大敌机 、、、、玩家的分3
子弹击中蜜蜂 、、、、、玩家恢复生命1 或者增加火力值
3.子弹数的变化
如果英雄机的活力值变为零时,就变为单数子弹数
4.碰撞
敌人可以与主机进行碰撞。碰撞之后主机血量减少,血量为零,游戏结束
5 设计一个父类,并且让六个对象继承父类
给父类添加构造方法,并让六个对象调用父类
谁知对象数组
在六个子类,重写
设置窗体
a:给类中添加修饰符
b:给6个派生类中添加图片属性
给六个派生类中添加static属性
再父类中添加静态方法loadimage()添加图片
六个排上类中调用static快中的loadimage()方法
将窗体的大小设置为常量
画对象:先获取图片,针对每一个对象都能狗获取到图片获取图片的行为是共有的,设计到父类中
每一个对象获取到图片的行为都是不一样的设计了一个抽象方法 getimage();
在不同状态下获取不同的图片:
设计到父类中:设计常量、:life、dead、remove、
默认状态:、state==life、
获取图片的同时,需要判断当前的状态
每一个对象都需要判断,所以可以设计到父类中;
每一个对象判断的方法是一样的,设计成普通方法就好
FlyingObject、islife()/isDead()/isRemove()/
在六个子类中重写getImage()方法;
得到不同状态的图片,进行画对象:
画对象的行为是共有的,所以设计到父类中
每一个对象的方式都是一样的
所以设计为普通方法
调用
测试·······
设计规则:将所有的子类所共有的行为和属性设计到父类中。
所有的子类,行为都是一样的。设计为普通方法;所有子类的行为不一致,设计为抽象方法
敌人的入场:
子弹入场:
主机重发黄色子弹,hero类设计方法实现子弹的发射
run(),子弹的发射shootAction();
没死百毫秒,获取到子弹数组、扩容、将自担数组添加到数组的的最后一位
飞行物的一栋:
敌人
子弹
天空
主机随着鼠标进行移动
在主机中涉及方法:movedto()实现主机移动
在shoot中建立监视机制,检测鼠标移动事件
删除月结飞行物
在FlyingObiect中检测是否越界
在run()中写方法outOfBoundsAction();删除越界飞行物
遍历数组,子弹数组。如果对象不越界。则存放到不越界的数组中。将不越界的数组复制到敌人数组中,或是子弹数组中
设计接口“
击中小敌机,得一份 Enamy
击中蜜蜂---- —随机的生命 award