Shoot设计项目设计

1.需求分析

运行项目,看结果:

A:小敌机、大敌机、蜜蜂----------敌人

英雄机发射子弹

子弹打中敌人

B:

子弹击中小敌机------玩家得分 1分

子弹击中大敌机------玩家得分 5分

子弹击中小蜜蜂------玩家的生命  1命或者得火力值30

C:单倍火力,双倍火力的变化

英雄机的火力值变为0的时候,就变成了单倍活力

火力值大于0 的时候,变为双倍火力;依次减少2

D:碰撞

敌人可以与英雄机发生碰撞,碰撞之后,英雄机的生命值减少,变为0的时候,游戏结束。

2.技术分析

设计类:

A:找对象:6个对象

英雄机、小敌机、大敌机、小蜜蜂、子弹、天空。

B:抽类:

Hero/Airplane/BigAriplane/Bee/Bullet/Sky

C:设计成员变量和方法

D:测试

2.1.需求分析

A:设计一个父类、超类;并且让6个对象继承超类,测试

B:给超类添加构造方法;让6个对象分别调用超类

C:设置对象数组,进行测试

D:在6个子类、派生类重写

E:画窗体;

2.2技术分析

重写和重载:

override:发生在父子类中,方法名相同,参数列表不同,方法体不同;

	遵循“运行期绑定“,看对象的类型来调用方法;

overload:发生在一个类中,方法名相同,参数列表不同,方法体不同;

	   遵循“编译器绑定”,看参数、引用类型的绑定方法;

3.代码实现

3.1需求分析

A:给类中添加修饰符

B:给6个派生类中添

在这里插入图片描述

加图片属性

1)6个派生类中添加static属性

2)在父类中添加静态方法loadmage()加载图片

3)6个派生类中调用static块中。调用loadmage()方法

3.2技术实现

4.1.需求分析

A:将窗体的大小设置为常量

B:画对象:

想画对象先获取到图片,针对每一个对象都能够获取到图片,获取到图片的行为是共有的,设计父类中;FlyingObject

每一个对象得到图片的行为都是不一样的,设计一个抽象方法------getImage()

在不同状态下,得到不同的图片

状态:设计到父类中,设计常量:LIFE;DEAD;REMOVE

默认状态:state = LIFE

获取图片的同时,需要判断当前的状态

每一个对象都需要判断,设计到超类/父类中

而每一个对象判断的行为都是一样的,设计普通方法即可

------FlyingObject:isLife()/isDead()/isRemove()

C:在6个子类对象中重写getImage()方法;

Sky:直接返回即可

Bullet:如果是存活的,返回images即可;如果是over的,删除即可

Hero:如果是存活的,返回images[0]/images[1]

Airplane:如果是存活的,返回images[0];如果是over的,images[1]到images[4]进行切换,切换完毕,到了images[4]后进行删除;

D: 得到不同状态的图片,进行开始画出来

画对象的行为是共有的,所以设计到超类中

每一个对象画的方式都是一样的,所以设计为【普通方法】

E:测试,调用即可

设计规则:

将所有的子类所共有的行为和属性,可以设计到超类中;----抽共性

所有子类的行为如果都是一样的,设计为普通方法;所以子类的行为都是不一样的,设计为抽象方法;

5.1需求分析

A:敌人入场

产生敌人:在ShootMain类中nextOne()

需要定时加载敌人;-----enterAction()实现敌人入场

每400毫秒,获取到敌人,扩容,将敌人添加到数组的最后一位

B:子弹入场

英雄机中发射子弹,Hero类中设计一个方法用来实现子弹的发射-------shoot()

run()方法中,子弹的发射shootAction()

每400毫秒,获取子弹数组,扩容,将子弹数组添加到数组的最后一位

C:飞行物移动

敌人的移动

子弹的移动

天空的移动

D:英雄机随着鼠标进行移动

在hero类中设计方法:movedTo()实现英雄机的移动;

在ShootMain中建立监听机制,检测鼠标的移动事件

E:删除越界的飞行物

在FlyingObject中涉及另一个outOfBounds()----检测是否越界

在run()方法中,写一个方法outOfBoundsAction();----删除越界飞行物

	遍历敌人、子弹数组。如果对象不越界,那么存放到不越界的数字中,将不越界的数组复制到敌人、子		弹数组中

F:设计接口

击中小敌机+大敌机-----得1分或者3分****Enemy

击中蜜蜂-----随机得到生命或者火力****Award

6.1需求分析

A:子弹与敌人碰撞

设计到父类中,hit()方法,实现检测子弹与敌人发生碰撞

在父类中设计一个goDead()实现飞行物over

在Hero类中设计实现addLife(),addDoubleFire()

通过Airplane和BigAirplane中的接口来实现玩家得分

通过Bee中的接口实现玩家得奖励

代码实现

Airplane
import java.awt.image.BufferedImage;
import java.util.Random;

/**

  • 小敌机
  • @author 卿恋今生

*/
public class Airplane extends FlyingObject 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;
}
}
BigAriplane
import java.awt.image.BufferedImage;
import java.util.Random;

/**

  • 大敌机
  • @author 卿恋今生

*/
public class BigAriplane extends FlyingObject 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 BigAriplane () {
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;
}
}
Bee
import java.awt.image.BufferedImage;
import java.lang.reflect.AnnotatedWildcardType;
import java.util.Random;

/**

  • 小蜜蜂
  • @author 卿恋今生

*/
public class Bee extends FlyingObject 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;
}

}
Bullet
import java.awt.image.BufferedImage;

/**

  • 子弹
  • @author 卿恋今生

*/
public class Bullet extends FlyingObject{
private static BufferedImage images;
static{
images = loadImage(“bullet.png”);
}
//成员变量
private int speed;//速度
public Bullet(int x ,int y) {
super(8, 14,x , y);
speed = 2;
}
/移动/
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;
}
}
Hero
import java.awt.image.BufferedImage;

/**

  • 英雄机
  • @author 卿恋今生

*/
public class Hero extends FlyingObject{
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);
		doubleFire -= 2;
		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 subtractLife() {
	life--; //命数减1
}
public void clearDoubleFire() {
	doubleFire = 0; //火力值归零
}

}
Sky
import java.awt.Graphics;
import java.awt.image.BufferedImage;

/**

  • 天空
  • @author 卿恋今生

*/
public class Sky extends FlyingObject{
private static BufferedImage images;
static{
images = loadImage(“background.png”);
}
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);
}

}
FlyingObject
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.management.RuntimeErrorException;

/**

  • 父类:飞行物
  • @author 卿恋今生

*/
public abstract class FlyingObject {
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 FlyingObject(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 FlyingObject(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(FlyingObject.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(FlyingObject 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

}

}

接口

Enemy
/**

  • 得分接口
  • @author 卿恋今生

/
public interface Enemy {
/得分/
public int getScore();
}
Award
/

  • 奖励接口
  • @author 卿恋今生

/
public interface Award {
public int DOUBLE_FIRE = 0;
public int LIFE = 1;
/**获取奖励类型(0~1)
/
public int getAwardType();
}
ShootMain
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.Thread.State;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;

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 = FlyingObject.loadImage("start.png");
	pause = FlyingObject.loadImage("pause.png");
	gameover = FlyingObject.loadImage("gameover.png");
}
FlyingObject[] flys = new FlyingObject[0];
Sky sky = new Sky();
Hero hero = new Hero();
private Bullet[] bullets = {};
public FlyingObject nextOne() {
	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 BigAriplane();
	}
}

// 实现敌人入场
int enterIndex = 0;

public void enterAction() {
	enterIndex++;
	if (enterIndex % 40 == 0) {
		// 获取敌人
		FlyingObject f = nextOne();
		// 敌人添加到数组的最后一位;
		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;// 存放不越界数组下标,个数
	//
	FlyingObject[] flysLive = new FlyingObject[flys.length];
	for (int i = 0; i < flys.length; i++) {
		// 获取到每一个敌人
		FlyingObject 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++) {
			// 获取每一个敌人
			FlyingObject 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++) {//遍历所有敌人
		FlyingObject f = flys[i];//获取每一个敌人
		if (hero.isLife() && f.isLife() && f.hit(hero)) { 
			f.goDead();
			hero.subtractLife(); //英雄机减命
			hero.clearDoubleFire(); //英雄机清空火力值
			FlyingObject 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 FlyingObject[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);// 居bb 中显示
	jf.setVisible(true);
	sm.action();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值