当前位置:首页>休闲益智>画出对象 > 阅读正文

来看看大佬用Java做的:微信打飞机小游戏(需求分析 代码 图片)

来看看大佬用Java做的:微信打飞机小游戏(需求分析 代码 图片)

更新时间:2024-04-17 08:25:34

shoot射击游戏项目一

1.需求分析:

运行项目,看结果:

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

英雄机发射子弹

B:

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

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

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

C:

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

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

D:碰撞

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

2.计数分析

设计类:

A:找对象:6个对象

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

B:抽类

Hero/Airplane/BIgAirplane/Bee/Bullet/Sky

C:设计成员变量和方法

shoot射击游戏项目二

1.需求分析:

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

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

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

D:在六个子类,派生类中重写

E:画窗体

2.技术分析:

重写和重载:

重写:(Override)

  • 发生在父子类中,方法名相同,参数列表相同,方法体不同;
  • 遵循“运行期绑定”,看对象的类型来调用方法;

重载:(Overload)

  • 发生在一个类中,方法名相同,参数列表不同,方法体不同:
  • 遵循“编译器绑定”,看参数,引用类型绑定法;
shoot射击游戏项目三

1.需求分析:

A:给类中添加修饰符

B:给6个派生类中添加图片属性

1):6个类种添加static

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

3):六个派生类中static代码块调用Loadlmage()方法

2:技术实现:

修饰符

y/n public protected default private 同一个类 y y y y 同一个包中不同类 y y y 不同包类 y y 不同胞中的类 y Shoot射击游戏四

1.需求分析

A:将窗体大小设置成常量

B:画对象:

想画对象先获取图片,针对每个对象能够获取到图片,

获取到图片的行为是共有的,设计到父类中;

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

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

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

默认状态:state=LIFE

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

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

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

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

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

  • Sky:直接返回即可
  • 子弹Bullet:如果是存活的返回images即可
    如果是over的删除即可
  • 英雄机:如果是存活,返回imgaes[0]/images[1]
  • 小敌机:如多存活,返回images[0]

如果over,images[1]—images[4]进行切换,切换完毕,到了images[4]后进行删除

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

画对象的行为是共有的,所以涉及到超类中;

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

E:测试,调用即可

设计规则:

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

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

Shoot射击游戏六

子弹与敌人碰撞:

  • 设计到父类中,hit()方法,实现检测子弹与敌人大声碰撞
  • 在父类中设计一个goDead()实现飞行物over
  • 在Hero类中设计实现addLife(),addDoubleFire()
  • 通过AirPlane和BigAirplane中的接口来实现玩家得分
  • 通过Bee中的接口来实现玩家获得奖励
代码实现

子弹:

package cn.tedu.shoot; import java.awt.image.BufferedImage; /** * 子弹 * @author Administrator * */ 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; } }

大敌机:

package cn.tedu.shoot; import java.awt.image.BufferedImage; import java.util.Random; /** * 大敌机: * * @author Administrator * */ public class BigAirplane 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"); } } int speed;// 速度 /** 构造方法 */ public BigAirplane() { super(99, 89); this.speed = 2; } public void step(){ this.y = speed; } // 得到图片 int index = 1; @Override public BufferedImage getImage() {// 10M if (isLife()) { return images[0]; } else if (isDead()) {// 图片的切换 BufferedImage img = images[index ]; if (index == images.length) { state = REMOVE; } return img; } /* * images[index ]; index = 1; 10M images[1] index = 2 返回images[1] 20M * images[2] index = 3 返回images[2] 30M images[3] index = 4 返回images[3] * 40M images[4] index = 5 返回images[4] */ return null; } /**重写得分接口*/ @Override public int getScore() { return 3; } }

小敌机:

package cn.tedu.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; /** * 小敌机: * @author Administrator * */ 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 = 5; } /**移动*/ public void step(){ this.y = speed; } //得到图片 int index = 1; @Override public BufferedImage getImage() {//10M if (isLife()) { return images[0]; }else if(isDead()){//图片的切换 BufferedImage img = images[index ]; if (index == images.length) { state = REMOVE; } return img; } /*images[index ]; * index = 1; * 10M images[1] index = 2 返回images[1] * 20M images[2] index = 3 返回images[2] * 30M images[3] index = 4 返回images[3] * 40M images[4] index = 5 返回images[4] * */ return null; } @Override public int getScore() { return 1; } }

英雄机

package cn.tedu.shoot; import java.awt.image.BufferedImage; /** * 英雄机: * * @author Administrator * */ 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 movedTo(int x, int y){ this.x = x - this.width/2; this.y = y - this.height/2; } /**英雄机的移动*/ public void step(){ System.out.println("图片的切换"); } int index = 0; @Override public BufferedImage getImage() { // return images[0]; return images[index /10%images.length]; } /**英雄机产生子弹*/ 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 substractLife(){ life--; } /**清空火力*/ public void clearDoubleFire(){ doubleFire = 0; } }

蜜蜂:

package cn.tedu.shoot; import java.awt.image.BufferedImage; 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;// x坐标的速度 private int ySpeed;// y坐标的速度 private int awardType;// 获取奖励的类型 public Bee() { super(29, 39); xSpeed = 1; ySpeed = 2; Random rand = new Random(); awardType = rand.nextInt(2);// 0 1 } 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() {// 10M 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() { // TODO Auto-generated method stub return awardType; } }

天空:

package cn.tedu.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; /** * 天空: * * @author Administrator * */ 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); } }

飞行物的父类

package cn.tedu.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; /** * 父类:飞行物 * * @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;// over 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.width = width; this.height = height; this.x = x; this.y = y; } /** 移动的方法 */ public void step() { } /** 读取图片 */ 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(); /** 画图片 g:画笔 */ public void paintObject(Graphics g) { g.drawImage(this.getImage(), this.x, this.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; } /* 实现子弹与敌人发生碰撞 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;// 将对象状态修改为DAED } public int getScore() { // TODO Auto-generated method stub return 0; } }

得分接口

package cn.tedu.shoot; /** * 得分接口 * @author 小二郎 * */ public interface Enemy { /*得分*/ public int getScore(); }

奖励接口

package cn.tedu.shoot; /** * 得分接口 * @author 小二郎 * */ public interface Enemy { /*得分*/ public int getScore(); }

主函数类:

package cn.tedu.shoot; import java.awt.AWTError; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; import javax.swing.JPanel; /** * 主函数的类: * * @author Administrator * */ public class ShootMain extends JPanel { public static final int SCREEN_WIDTH = 400; public static final int SCREEN_HEIGHT = 700; //起始状态START/RUNNING/PAUSE/GAME_OVER //默认起始状态 /* * 鼠标点击事件: * 开始--运行 结束---开始 * 鼠标移动事件: * 启动状态:结束----启动 * 暂停状态:鼠标从屏幕里划到外 * 运行状态:从外到内的时候 * 结束状态:英雄机的生命为0 */ 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 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"); } private Sky sky = new Sky(); private Hero hero = new Hero(); private FlyingObject[] flys = {}; 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 BigAirplane(); } } /** 实现敌人入场 */ 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); //System.out.println("index == " index); index = 0; Bullet[] bulletLive = new Bullet[bullets.length]; for (int i = 0; i < bullets.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()火力清0 * 4) 在run()方法中实现英雄机与敌人发生碰撞 * heroBangAction(); * 遍历敌人获取到每一个敌人: * 判断撞上了: * 敌人over,英雄机减少生命,清空火力 */ //遍历所有的敌人 for (int i = 0; i < flys.length; i ) { //获取每一个敌人 FlyingObject f = flys[i]; if (hero.isLife() && f.isLife() && f.hit(hero)) { f.goDead(); hero.substractLife();//减少生命 hero.clearDoubleFire();//清空火力 } } } /**检测游戏是否结束*/ public void checkGameOverAction(){ //判断英雄机的生命值, //如果小于0的话,游戏结束,修改状态 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(); hero.movedTo(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);// 计划任务 /* * 7.30 20 第一次 10 第一次---第二次 */ } /** 画对象 */ @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(SCREEN_WIDTH, SCREEN_HEIGHT);// 窗体的大小 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setLocationRelativeTo(null);// 居中显示 jf.setVisible(true); sm.action(); } }改进思路

  1. 增加敌机被击中后的爆炸动画效果
  2. 抽象类实例化不同的敌机类,得分也设置为不同
  3. 设置奖励系统
  4. 设置生命系统和等级闯关系统,达到一定分数后增加难度
  5. 提供界面使玩家自选难度

如有问题,希望各位大佬指正!

图片素材: