项目简介:
1、游戏开始可以产生:敌机/小蜜蜂/自己的飞机,随机(概率)出现
2、跟鼠标相关的:开始/结束游戏界面、移动自己的飞机、鼠标移除窗口,游戏暂停、鼠标进入窗口,游戏继续、子弹射中敌人/小蜜蜂:分数加成(或者生命值加1)
3、子弹打中小蜜蜂: 奖励加成 -> 生命+1或者双倍火力
4、子弹打中敌机: 分数+2
5、实现背景滚动卷轴
6、飞行物越界问题
项目的思维导图:
遇见问题:
边界问题:在父类构造抽象方法 isout(),分别在airplane、hero、bee类中通过控制x和y轴的位置,如果跃出边界,则在flyobject和bullet里面删除相应的物体。
背景的滚动卷轴问题:在shootgame里面通过创造y轴back _y来实现x轴不变,y轴随着绘画的调用不断重复,达到滚动的效果。
素材更换问题:在photo包里面,将其删除,并将相应的素材粘贴进来,将素材文件命名为与原来图片一样名字(注意命名空格问题),相同文件格式。这样避免了修改源代码问题。
代码没错但运行报错问题:①、这个可以再创建一个类局部调试,如果报错,那就是代码原本问题。②、可能程序零时缓存有问题,需要删除缓存out后,再进行运行。③、可以再窗口实现的paint方法里面,看看实现的先后顺序问题。④、看看方法有没有调用,如果没有调用,需要在相应的地方调用。
不同机器报错问题:①、需要更改一些文件的绝对路径为运行机器的绝对路径。
运行页面:
开始界面:
暂停界面:
死亡界面:
运行界面:
类的实现
ShootGame类:
package com.qicco.shoot;
import com.qicco.photo.Photo;
import sun.audio.AudioStream;
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.*;
import java.util.List;
import java.util.Timer;
/* 图片加载,描绘窗口之类工作都在该类中完成
1.继承JPanel类
点菜:
JPanel类(盘子)
* JFrame类是用来窗口描绘(桌子)
* */
public class ShootGame extends JPanel {
/*2.规定窗体宽高 ,定义成static,我们需要在其他地方使用、但我不想变-->大写*/
public static final int WIDHT = 650;//窗体宽度
public static final int HEIGHT = 950;//窗体高度
//标记游戏失败结束,ture为游戏结束
public boolean GAMEOVER;
//标记游戏胜利结束,ture为游戏结束
public boolean VECTORY;
/*3. 变量声明(容器)*/
public static BufferedImage background;//背景图片
public static BufferedImage airplane;//敌机图片
public static BufferedImage bee;//蜜蜂图片
public static BufferedImage bullet;//子弹图片
public static BufferedImage hero0;//英雄机0图片
public static BufferedImage hero1;//英雄机1图片
public static BufferedImage pause;//暂停
public static BufferedImage start;//开始
public static BufferedImage gameover;//结束
/*6.厨师炒菜,准备上菜(将图片准备好,并且加载到当前Shootgame类中,然后准备画面)-----------*/
/*7.将蜜蜂敌机装到一个容器里面,使用集合存储蜜蜂和敌机----------------------------------*/
private List<flyObject> flyings = new ArrayList<>();//仅仅在当前页面使用
/*8.准备容器中,并将子弹放入其中---------------------------------------------------*/
private List<Bullet> bullets = new ArrayList<>();
/*9.准备英雄机的容器-------------------------------------------------------------*/
private Hero hero = new Hero();//因为here类中已经存在一个List集合存放我们英雄机了
/*16.定时器,时间间隔*/
private Timer timer;//
private int time = 15;//时间间隔:15毫秒
/*26.定义总分*/
private int score = 0;//每调用一次,就加一分
/*================================================*/
//背景竖坐标,用于背景图片滚动
int back_y = -background.getHeight(null) + background.getHeight(null);
/*================================================*/
/*背景音乐*/
// 设置背景音乐
public static void setMusicGame() throws IOException {
FileInputStream stream = null;
try {
stream = new FileInputStream("D:\\ideafile\\TrainingCourse\\plangame\\src\\com\\qicco\\photo\\background.png");
AudioStream audioStream = new AudioStream(stream);
sun.audio.AudioPlayer.player.start(audioStream);
} catch (Exception e) {
System.out.println(e);
System.err.println("错误!");
}finally {
stream.close();
}
}
/*10初始化该类 加载图片
* 使用构造方法 获取敌机,蜜蜂,英雄机,子弹图片,装到准备好的容器中
* 10.1将蜜蜂装到容器里(flyings)
* */
public ShootGame() {
flyings.add(new Bee());//将蜜蜂存到flyings中
flyings.add(new airPlane());//将敌机存到flyings中
//bullets.add(new Bullet(200, 300));//子弹存放到bullets里,需要传参
}
/*11.开始画画 画背景图 用一个方法Paint(),该方法是由JFrame提供的
* graphics:相当于画笔
* *-------------------------------------------------------------------------------*/
@Override
public void paint(Graphics g) {
g.drawImage(background, 0, 0, null);
/*drawImage需要传入四个参数
第一个参数代表需要画的图片
第二个和第三个参数代表从哪里开始(起始位置)
第四个参数代表通知哪些对象* */
/*======================================*/
//使背景无限滚动
g.drawImage(background, 0, back_y++, null);
g.drawImage(background, 0, back_y - background.getHeight(null), null);
if (back_y == background.getHeight(null)) {
back_y = 0;
}
paintHero(g);
paintFlyingObject(g);//需要前往Bee和airplane类中将y轴改成100看见效果
painBullet(g);
/*==========================================================================*/
/*g.setFont(new Font("宋体", Font.BOLD, 20));
g.drawString("得分:",20, 60);//画文字*/
/*====================================================================*/
//g.drawString(Integer.toString(score), 80, 60);//画文字
//g.drawString("生命:", 20, 90);//画文字
// /*====================================================================*/
//g.drawString(Integer.toString(hero.getlife()), 80, 90);
g.drawImage(hero.image, hero.x, hero.y, null);
/*调用画分数方法*/
paintScore(g);
paintStatus(g);
}
/*12.画英雄机----------------------------------------------------------------*/
public void paintHero(Graphics g) {
/*可以自己设置*/
g.drawImage(hero.getImage(), hero.getX(), hero.getY(), 10, 20, null);
}
/*13.画蜜蜂和敌机 都存到了flyings中,所以需要遍历处理------------------------------------*/
public void paintFlyingObject(Graphics g) {
for (flyObject f : flyings) {
flyObject fly = f;//将遍历结果存放到fly中,方便画画
g.drawImage(fly.getImage(), fly.getX(), fly.getY(),100,80,null);//开始画敌机和蜜峰
}
}
/*14.画敌机放在bullets里面了----------------------------------------------------------*/
public void painBullet(Graphics g) {
for (Bullet b : bullets) {
Bullet bul = b;//将遍历结果存放到bul中,方便画画
g.drawImage(bul.getImage(), bul.getX(), bul.getY(), 20,20,null);
}
}
/*4.加载图片(放入容器)
* 使用静态代码块:读取
* */
static {
//方法一:先通过file,将地址放进来,然后再传给backgrund
//File file = new File("com/qicco/photo/background.png");
try {
/* background = ImageIO.read(new File("com/qicco/photo/background.png"));
不能直接传字符串,"com/qicco/photo/background.png"
这里会出现IOException,但是静态代码块不能通过throw抛出异常,只能try catch处理
方法二:使用反射机制 (通过类找到路径)
*/
background = ImageIO.read(Photo.class.getResource("background.png"));
airplane = ImageIO.read(Photo.class.getResource("airplane.png"));
bee = ImageIO.read(Photo.class.getResource("bee.png"));
bullet = ImageIO.read(Photo.class.getResource("bullet.png"));
hero0 = ImageIO.read(Photo.class.getResource("hero0.png"));
hero1 = ImageIO.read(Photo.class.getResource("hero1.png"));
pause = ImageIO.read(Photo.class.getResource("pause.png"));
start = ImageIO.read(Photo.class.getResource("start.png"));
gameover = ImageIO.read(Photo.class.getResource("gameover.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
/*5程序入口方法,画出画板(窗口)------------------------------------------------------------*/
public static void main(String[] args) throws InterruptedException {
JFrame jFrame = new JFrame("飞机大战");//title:类似于桌号(窗口名称)
ShootGame shootGame = new ShootGame();//为了告诉计算机,我要在当前类中画窗口
// 如果要在画板中绘画,进行创作,添加图片,描绘之类的,需要先将面板加载到窗口
jFrame.add(shootGame);
//jFrame.setSize(WIDTH, HEIGHT);
jFrame.setBounds(100, 100, WIDHT, HEIGHT);
//设置窗体永远在最上面显示
jFrame.setAlwaysOnTop(true);
//在窗口中可以关闭该窗口,不需要返回idea
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//调用paint方法,调用这个方法之后,就相当于在画板上去添加东西,准备画面了
jFrame.setVisible(true);
//一般出现在中间
jFrame.setLocationRelativeTo(null);
//上菜
try {
setMusicGame();
} catch (IOException e) {
System.err.println("音乐播放异常!");
e.printStackTrace();
}
//shootGame.loop();
shootGame.action();
//jFrame.setResizable(false);
}
/*15 将子类中所有飞行物体方法加载到该类中,使之移动*/
public void stepAction() {
/*15.1 让蜜蜂和敌机走一步*/
for (flyObject fo : flyings) {
flyObject f = fo;//接受遍历的结果
f.step();
//fo中有蜜蜂,有敌机,f.step方法会到每个子类中找到step方法
}
/*15.2 让子弹走一步,子弹存放集合里面------------------------------------------------*/
for (Bullet bls : bullets) {
Bullet b = bls;
b.step();
}
/*15.3英雄机走一步---------------------------------------------------------------*/
hero.step();
}
//使用循环使之一直动
//方式 1:使用循环
/* public void action() throws InterruptedException {
while (true){
stepAction();
repaint();//重绘
Thread.sleep(50);//线程,给它50毫秒
}
}*/
//方式 2:使用定时器 动作
public void action() {
/*24.添加鼠标监听事件 需要用到mouseAdapter类*/
MouseAdapter l = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if (status == RUNNING) {
int x = e.getX();//获得x轴坐标
int y = e.getY();//获得y
hero.moveT0(x, y);
}
}
/*鼠标进入监听*/
@Override
public void mouseEntered(MouseEvent e) {//监测鼠标进入事件
if (status == PAUSE) {
status = RUNNING;
}
}
/*画板移出鼠标--鼠标移出监听 */
@Override
public void mouseExited(MouseEvent e) {
if (status != GAME_OVER) {
status = PAUSE;
}
}
/*鼠标点击事件 当前状态是:start -- >running
* 当前是 gameover--->start*/
@Override
public void mouseClicked(MouseEvent e) {
switch (status) {
case START:
status = RUNNING;
break;
case GAME_OVER:
/*删档 分数 生命值 飞行物 英雄机 子弹 */
score = 0;
flyings = new ArrayList<flyObject>();
hero = new Hero();
bullets = new ArrayList<Bullet>();
status = START;
break;
}
}
};
this.addMouseListener(l);
/*============================================================================*/
this.addMouseMotionListener(l);
timer = new Timer();//util下的包
/* schedule 需要传入三个参数
第一个:代表想要定时器做什么
第二个:执行时间
第三个:时间间隔
*/
timer.schedule(new TimerTask() {
@Override
/*----------------------------------*/
public void run() {
if (status == RUNNING) {
stepAction();//调用飞行物体
entryAction();//20.调用飞行物进入
shootAction();//22.调用射击方法
isoutplane();
isoutbee();
isoutbullet();
/*调用检测子弹碰撞*/
bangAction();
/*写一个控制死亡的方法*/
// isGameOver();
checkGameOverAction();
}
repaint();//重绘方法
}
}, time, time);
}
/*敌机蜜蜂只出现一次,子弹只有一发
* 18.随机生成飞行物(敌机和蜜蜂)方法*/
public flyObject nextOne() {
Random random = new Random();
int type = random.nextInt(20);
if (type == 0) {
return new Bee();
} else {
return new airPlane();
}
}
/*19.设置飞行物进场方式*/
int flyEnterIndex = 0;
public void entryAction() {
flyEnterIndex++;
if (flyEnterIndex % 40 == 0) {//为了让我们飞行物进来,设置一个进入时间
flyObject obj = nextOne();//
flyings.add(obj);//需要传入flyobject类型的值
}
/*20.想要多发子弹
* 子弹反射分两类:单倍火力,发射点在英雄机1/2处
* 双倍火力,发射点在英雄级4/1+3/4处
* */
}
/*21.射击方法*/
int shootIndex = 0;
public void shootAction() {
shootIndex++;
if (shootIndex % 30 == 0) {
List<Bullet> bs = hero.shoot();
/*遍历将集合里面的子弹取出来*/
for (Bullet b : bs) {
bullets.add(b);
}
}
}
/*23当前项目敌机,蜜蜂,子弹都可以的,英雄机移动t,鼠标事件,去hero类中写一个计算坐标的方法*/
/*25 射击到飞行物使之消失
* 分析:
* 两张图片发生碰撞,需要一个碰撞范围 x轴坐标范围:x+飞行物宽度(width)
* y轴坐标范围:y+飞行物高度(height)
* 去flyobject中判断是否打中飞行物*/
/*27.判断碰撞方法。检查子弹和飞行物体之间的碰撞 ,当前只是一颗子弹与飞行物进行比较*/
public void bang(Bullet bullet) {
int index = -1;//定义索引
/*第一步:将集合里的飞行物取出来,再在那这颗子弹去比较*/
for (flyObject f : flyings) {//for(数据类型,flyings)
flyObject obj = f;
index++;
if (obj.shootBy(bullet)) {
/*如果为真,则判断碰撞上了,让飞行物消失*/
flyObject one = flyings.remove(index);//删除当前飞行物
/*需要判断飞行物的类型,来选择效果*/
if (one instanceof airPlane) {//敌机
//加分
airPlane ap = (airPlane) one;//强制转换 将flyobject 类型的one 转换成airplane类型
//这样才能调用方法getScore()
score = score + ap.getScore();//将两分
}
if (one instanceof Bee) {//蜜蜂
/*判断当前是什么奖励类型*/
Bee be = (Bee) one;//强制转换 将flyobject 类型的one 转换成bee类型
int type = be.getType();
switch (type) {
case 0:
hero.addDoubleFire();
break;
// 双倍火力
case 1:
hero.addlife();
// 加生命值
break;
}
}
break;
}
;//结果判断
}
}
/*28.所有子弹都去检查*/
public void bangAction() {
for (Bullet bt : bullets) {
Bullet b = bt;
bang(b);
}
}
/*============?*/
//30 画分数和生命值
public void paintScore(Graphics g){
/* Fond类作用:设置字体的一个类
* 第一个参数,相当于当前类的名字
* 第二个:设置字体
* 第三个:设置字体大小*/
Font font = new Font("分数",Font.BOLD,500);
g.setColor(new Color(0xEF122C));
g.drawString("分数:"+score,50,20);
Font font1 = new Font("生命",Font.BOLD,500);
g.setColor(new Color(0xEF122C));
g.drawString("生命:"+hero.getlife(),50,60);
g.setFont(font);
g.setFont(font1);
/*在画版上写字
* 第一个:名称
* 第二个*/
}
/*32.检测游戏结束方法
* 1.英雄机是否发生碰撞和飞行物---
* 飞行物消失---判断--
* 减命+双倍活力消失
* */
public boolean isGameOver() {
int index = -1;//
for (flyObject f : flyings) {
flyObject fl = f;
index++;
if (hero.hit(f)) {
if (index != -1) {
flyings.remove(index);
}
hero.reduceLife();
hero.setDoublefileZero();
break;//避免死循环
}
}
return hero.getlife() <= 0;//判断是否结束游戏
}
/*33.设置游戏开始 ,暂停和结束*/
private int status;//设置游戏状态
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;//游戏结束
// 判断游戏结束
public void checkGameOverAction() {
if (isGameOver()) {
status = GAME_OVER;
}
}
/*35.画开始 暂停 结束页面*/
public void paintStatus(Graphics g) {
switch (status) {
case START:
g.drawImage(start, 170, 290, 300,300,null);
break;
case PAUSE:
g.drawImage(pause, 150, 150,400,400,null);
break;
case GAME_OVER:
g.drawImage(gameover, 60, 350, null);
break;
}
}
/*
*/
/*================================================================================*/
//处理敌机出界方法
public void isoutplane() {
List<flyObject> removePlanes = new ArrayList<>();
for (int j = 0; j < flyings.size(); j++) {
flyObject F = flyings.get(j);
if (F.isOut()) {
removePlanes.add(F);
break;
}
}
flyings.removeAll(removePlanes);
}
//处理蜜蜂出界方法
public void isoutbee() {
List<flyObject> removeBees = new ArrayList<>();
for (int j = 0; j < flyings.size(); j++) {
flyObject bee = flyings.get(j);
if (bee.isOut()) {
removeBees.add(bee);
break;
}
}
flyings.removeAll(removeBees);
}
//处理子弹出界方法
public void isoutbullet() {
List<Bullet> removeBullets = new ArrayList<>();
for (int j = 0; j < bullets.size(); j++) {
Bullet bullet = bullets.get(j);
if (bullet.isOut()) {
removeBullets.add(bullet);
break;
}
}
bullets.removeAll(removeBullets);
}
}
Hero类:
package com.qicco.shoot;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Random;
public class Hero extends flyObject {
//暂时不设置英雄机的速度,它是一张图片,不是自己飞。随着鼠标而动的
private List<BufferedImage> images = new ArrayList<>();//这个用来存放英雄集合的
private int doublefile = 0;//双倍火力
private int life = 3;//生命值
// 10 减少生命值
public void reduceLife(){
life--;
}
/*11.设置双倍火力清零*/
public void setDoublefileZero(){
this.doublefile = 0;
}
public int getlife(){
return life;//调用方法时,给你返回生命数
}
/*7.设置双倍火力*/
public void addDoubleFire(){
doublefile = doublefile + 40;
}
/*8.增加生命力*/
public void addlife(){//调用方法一次就加一条命
life++;
}
/*重写飞行物体移动方法 需要无法确定英雄机移动轨迹,需要加入鼠标事件,先不写移动方法,改成英雄机喷气方法 */
/*设置发射火力*/
@Override
public void step() {
if (images.size()>0){//判断集合是否为空
//1.使用ramdon随机类,让我们随机获得一张图片
Random random = new Random();
image = images.get(random.nextInt(2));
}
}
/*==========================================================================*/
//判断是否出界
public boolean isOut(){
return false;
}
/*==========================================================================*/
// 2.构造方法初始化,加载图片
public Hero(){
this.image = ShootGame.hero0;//获取图片
this.width = image.getWidth();
this.height = image.getHeight();
// 3.获取X轴坐标/给一个暂时值
x = 150;
y = 400;
// 4. 图片加载
images.add(ShootGame.hero0);
images.add(ShootGame.hero1);
}
/*5.获得子弹方法*/
public List<Bullet> shoot(){
int xStep = width/4;// 1/4的图片
int yStep = 20;//飞机与子弹的间距
if (doublefile > 0){
//5.1双培火力 弄好子弹
Bullet bullet1= new Bullet(x + xStep,y - yStep);//第一发子弹 x轴 :图片1/4处 y轴 :图片 上面一点点
Bullet bullet2 = new Bullet(x + 3 * xStep,y - yStep);//第二发子弹,图片 3/4处
//5.2装子弹的包
List<Bullet> bullets = new ArrayList<>();
//5.3装子弹
bullets.add(bullet1);//装第一发
bullets.add(bullet2);//装第二发
doublefile = doublefile -2;//设置双倍火力发射次数
//5.4发送
return bullets;
}else {
//单倍活力
Bullet bullet1 = new Bullet(x+ 2*xStep,y - yStep);
// 因为在ShootGame中是使用集合bullets容器,专门存储子弹,
/*5.2准备容器*/
List<Bullet> bullets = new ArrayList<>();
/*5.3子弹放进包里*/
bullets.add(bullet1);
/*5.4发送*/
return bullets;
}
}
/*6.计算英雄机坐标方法 本来会加上鼠标监听事件,由于坐标不是我们想要的,我们鼠标控制图片中心移动*/
public void moveT0(int x,int y){//鼠标监听事件中的x轴坐标和y轴坐标
this.x =x - width/2;//当前的X是英雄机的,我们需要鼠标的
/*this.x谁调用,指向谁的x*/
this.y = y- height/2;
}
/*12
*x1:飞行物x - 1/2 hero的weith
* x2:飞行物 + 1/2 hero的weith
*y1:飞行物 - 1/2 hero的height
*y2 : 飞行物 + 1/2 hero的height
* 中心点x:herox+1/2hero width
* 中心点y:hero.y +1/2 hero height
* */
public boolean hit(flyObject flyObject){
int x1 = flyObject.x - this.width/2;
int x2 = flyObject.x + this.width/2;
int y1 = flyObject.y - this.height/2;
int y2 = flyObject.y + this.height/2;
int centerx = this.x + this.width/2;
int centery = this.y + this.height/2;
boolean b = x1 < centerx && centerx <x2;
boolean c = y1 < centery && centery <y2;
return b&&c;
}
}
Bullet类:
package com.qicco.shoot;
import java.util.Random;
public class Bullet extends flyObject{
//1.定义特有属性:速度
private int speed = 3;//比敌机稍快一点
/*重写飞行移动方法 step方法*/
@Override
public void step() {
y -= speed;//由下往上发射的
}
/*=====================================================================*/
@Override
public boolean isOut() {
if(y==0)
{
return true;
}
else {
return false;
}
}
/*=====================================================================*/
// 2.使用构造方法,让类初始化就加载图片
public Bullet(int x,int y){
// 2.获取图片
this.image = ShootGame.bullet;
this.width = image.getWidth();
this.height = image.getHeight();
// 3.定义y,x轴坐标,需要随鼠标的移动来发射子弹,需要随时传入。
this.x = x;
this.y = y;
}
}
flyObjet类:
package com.qicco.shoot;
import java.awt.image.BufferedImage;
//父类
public abstract class flyObject {
protected int x;
protected int y;
protected BufferedImage image;//图片
protected int width;//图片宽度
protected int height;//图片高度
/*3.检查子弹是否击中飞行物 传入子弹,去和页面中all飞行物比较*/
public boolean shootBy(Bullet bullet){
/*在范围内,则表示碰撞
* 分析:
* 两张图片发生碰撞,需要一个碰撞范围 x轴坐标范围:x+飞行物宽度(width)
* y轴坐标范围:y+飞行物高度(height)*/
int x = bullet.getX();//得到子弹x的坐标
int y= bullet.getY();//得到子弹y的坐标
// boolean b = this.x < x&&x <this.x+width ; //this.x敌机x轴
// boolean c = this.y <y&&y<this.y + height;//y轴范围
// b&&c;?
boolean b = (this.x < x&&x <this.x+width)&&(this.y <y&&y<this.y + height);
return b;//ture表明击中
/*射击到蜜蜂时,要么增加命,要么双倍火力*/
}
/*2.飞行物移动的方法(定义一个方法,让图片动起来)------------------------------*/
public abstract void step();//抽象类,使子类必须重写飞行物体的移动方法
/*-----------------------------------------------------------------------------------------*/
//添加越界方法
public abstract boolean isOut();
/*---------------------------------------------------------------------------------------*/
/*添加get set toString 有参构造和无参构造 alt+insret
constructor:构造方法
getter:get方法
setter:set方法
toString:toString 方法
*/
//无参构造
public flyObject() {
}
//按住shift选中最后----或按ctrl一个一个选
//有参构造
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public String toString() {
return "flyObject{" +
"x=" + x +
", y=" + y +
", image=" + image +
", width=" + width +
", height=" + height +
'}';
}
}
airPlane类:
package com.qicco.shoot;
import java.util.Random;
//敌机类
public class airPlane extends flyObject {
//1.定义特有属性
private int speed = 2;//定义速度
/*重写飞行移动方法 step方法*/
@Override
public void step() {
y +=speed;
}
/*========================================================================*/
@Override
public boolean isOut() {
if(y>ShootGame.HEIGHT-100||x>ShootGame.WIDHT-100)
{
return true;
}
else {
return false;
}
}
/*========================================================================*/
/*2.使用构造方法----显示图片
* */
public airPlane(){
this.image=ShootGame.airplane;//this。image父类继承而来,获取一张敌机图片
this.width = image.getWidth();
this.height = image.getHeight();
// 3.定义y轴,坐标怎么定义,因为图片从看不到的地方由上至下加载。所以起始坐标从负值开始
y = -height;
// 4.定义x轴,敌机随机出现
// 4.1 使用random
Random random = new Random();
x = random.nextInt(ShootGame.WIDHT - width);//敌机存在宽度,400-敌机
}
/*3.设置加分的方法: ,每次击中敌机,就加1分*/
public int getScore(){
return 2;
}
/*射击到蜜蜂,不知道奖励,去bee里面弄*/
}
Bee类:
package com.qicco.shoot;
import java.util.Random;
//蜜蜂类
public class Bee extends flyObject {
//1.设置速度.蜜蜂存在会弹的过程,在页面上会来回跑动
private int xspeed = 1;
private int yspeed = 3;
/*5.设置奖励类型*/
private int awardType;
/*7.设置奖励类型,产生(new Bee())一只蜜蜂决定好奖励类型*/
public int getType(){
return awardType;
}
/*重写飞行移动方法*/
@Override
public void step() {
//由于蜜蜂有一个回弹过程,所以存在两个速度,分别在x和y轴上
x += xspeed;
y += yspeed;//易出现x轴停止,但y轴未停止
if ( x> ShootGame.WIDHT-width){
xspeed = -1;
}
if (x<0){
xspeed = 1;//说明蜜蜂已经到达最左边了
}
}
/*==============================================================================*/
@Override
public boolean isOut() {
if(y>ShootGame.HEIGHT||x>ShootGame.WIDHT)
{
return true;
}
else {
return false;
}
}
/*==============================================================================*/
// 2.使用构造方法,让图片在初始化类的时候,可以调用
public Bee(){
this.image = ShootGame.bee;//获取蜜蜂图片
this.width = image.getWidth();
this.height = image.getHeight();
// 3.定义y轴坐标,从负轴开始
y = -height;
// 4.定义X轴坐标,图片本身也有宽度,随机出现
Random random = new Random();
x = random.nextInt(ShootGame.WIDHT - width);//大框 - 小框
/*6.一出生就定义好了,*/
awardType = random.nextInt(2);
}
}