飞机大战JAVA编程
来源:互联网 发布:java pdf转word 编辑:程序博客网 时间:2024/04/29 17:02
飞机大战JAVA编程
最近在学习java语言,飞机大战是其中一个练习小项目。这里记录一下写这个程序的思路。
- 首先是需求分析,这里建立项目需求的思维导图,一目了然:
- 然后是思路分析
这是写程序前列举的一个基本的思路,以此为主线,写的时候遇到具体问题再进行修改,最后得出最终程序。 - 最后是写好的程序结构图:
这里就不多写文字了,所有内容都在图中,下面是运行结果和源代码。
运行结果:
源码:
//FlyingObject类,抽象类:package com.centerm.shoot;import java.awt.image.BufferedImage;/** * 将四个主要角色的共同属性提取出来组成一个父类 * @author 89447 */public abstract class FlyingObject { //定义所有飞行器共有的属性:图片、坐标、尺寸 protected BufferedImage image; protected int x; protected int y; protected int width; protected int height; //定义所有飞行器共有的方法:移动、越界 public abstract void moveFlying(); public abstract boolean outOfBound(); //下面定义的这个方法只有Airplane和Bee使用 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; int xb1 = bullet.x; int xb2 = bullet.x + bullet.width; int yb1 = bullet.y; int yb2 = bullet.y + bullet.height; return (xb1>x1 && xb1<x2) && (yb1>y1 && yb1<y2) || (xb2>x1 && xb2<x2) && (yb1>y1 && yb1<y2) || (xb1>x1 && xb1<x2) && (yb2>y1 && yb2<y2) || (xb2>x1 && xb2<x2) && (yb2>y1 && yb2<y2); }}
package com.centerm.shoot;import java.util.Random;/** * 敌机 * @author 89447 * */public class Airplane extends FlyingObject{ //前进速度 private int speed; //构造方法 public Airplane(){ image = Stage.airplane; x = new Random().nextInt(Stage.STAGE_WIDTH - image.getWidth()); y = -image.getHeight(); width = image.getWidth(); height = image.getHeight(); speed = 3; } //移动 public void moveFlying(){ this.y += this.speed; } //出界判断 public boolean outOfBound() { return this.y > Stage.STAGE_HEIGHT; }}
package com.centerm.shoot;import java.util.Random;/** * 蜜蜂类 * @author 89447 * */public class Bee extends FlyingObject{ //奖励类型 public static final int AWARD_LIFE = 0; public static final int AWARD_FIRE = 1; //左右飞行,用于飞行方向的改变 private static final int FLY_RIGHT = 1; private static final int FLY_LEFT = -1; //飞行方向变量 private int flyingDirection = FLY_RIGHT; //X、Y方向上前进的速度 private int speedX; private int speedY; //构造函数 public Bee(){ image = Stage.bee; x = new Random().nextInt(Stage.STAGE_WIDTH - image.getWidth()); y = -image.getHeight(); width = image.getWidth(); height = image.getHeight(); speedX = 2; speedY = 1; } //移动一步 public void moveFlying(){ /** * 先确定小蜜蜂飞行的方向 */ if(this.x >= Stage.STAGE_WIDTH - this.width){ flyingDirection = FLY_LEFT; } if(this.x <= 0){ flyingDirection = FLY_RIGHT; } /** * 再根据方向进行移动 */ if(flyingDirection == FLY_RIGHT){ this.x += this.speedX; this.y += this.speedY; }else{ this.x -= this.speedX; this.y += this.speedY; } } //获取奖励类型 public int getAwardType(){ return new Random().nextInt(2)==AWARD_LIFE ? AWARD_LIFE : AWARD_FIRE; } //判断出界 public boolean outOfBound() { return this.y > Stage.STAGE_HEIGHT; }}
package com.centerm.shoot;/** * 子弹类 * @author 89447 * */public class Bullet extends FlyingObject{ //子弹运行速率 private int speed; //构造函数 public Bullet(int x, int y){ this.x = x; this.y = y; image = Stage.bullet; width = image.getWidth(); height = image.getHeight(); speed = 4; } //子弹移动一步 public void moveFlying(){ this.y -= this.speed; } //判断出界 public boolean outOfBound() { return this.y < 0; }}
package com.centerm.shoot;/** * 英雄机的类 * @author 89447 * */public class Hero extends FlyingObject{ //定义默认生命值 private static final int DEFAULT_LIFE = 3; //定义移动方向,用于键盘控制 public static final int MOVE_UP = 1; public static final int MOVE_DOWN = -1; public static final int MOVE_LEFT = 2; public static final int MOVE_RIGHT = -2; //定义一次移动的距离,用于键盘控制 public static final int STEP_DISTANCE = 10; //定义火力值、生命值 private int firePower; private int life; //构造函数 public Hero(int x, int y){ this.x = x; this.y = y; image = Stage.hero0; width = image.getWidth(); height = image.getHeight(); firePower = 0; life = DEFAULT_LIFE; } //获取生命值 public int getLife(){ return life; } //生命值减一 public void substactLife() { this.life --; } //生命值加一 public void addLife() { this.life ++; } //获取双倍火力值 public int getFirePower(){ return firePower; } //清空火力值 public void clrFirePower(){ firePower = 0; } //火力值增加固定的数值 public void addFirePower(){ firePower += 40; } //英雄机按照某个方向移动一步,用于键盘控制 public void moveDirection(int direction){ switch (direction) { case MOVE_DOWN: if(this.y >= Stage.STAGE_HEIGHT - this.height){ break; }else if(this.y >= Stage.STAGE_HEIGHT - this.height- STEP_DISTANCE && this.y <Stage.STAGE_HEIGHT - this.height){ this.y = Stage.STAGE_HEIGHT - this.height; }else{ this.y += STEP_DISTANCE; } break; case MOVE_UP: if(this.y == 0){ break; }else if(this.y > 0 && this.y <= STEP_DISTANCE){ this.y = 0; }else { this.y -= STEP_DISTANCE; } break; case MOVE_LEFT: if(this.x == 0){ break; }else if(this.x > 0 && this.x <= STEP_DISTANCE){ this.x = 0; }else { this.x -= STEP_DISTANCE; } break; case MOVE_RIGHT: if(this.x == Stage.STAGE_WIDTH - this.width){ break; }else if(this.x >= Stage.STAGE_WIDTH - this.width - STEP_DISTANCE && this.x < Stage.STAGE_WIDTH - this.width){ this.x = Stage.STAGE_WIDTH - this.width; }else { this.x += STEP_DISTANCE; } break; default: break; } } //英雄机移动,用于图片切换 private int indexOfImage = 0; public void moveFlying(){ indexOfImage = 1 - indexOfImage; if(indexOfImage == 0){ image = Stage.hero0; }else{ image = Stage.hero1; } } //直接将英雄机移动到某个确定的位置,用于鼠标控制 public void setLocation(int x, int y){ this.x = x - this.width/2; this.y = y - this.height/2; } //创建子弹,可能是一个,也可能是两个,因此这里返回数组 public Bullet[] createBullets(){ if(firePower > 0){ firePower -= 2; return new Bullet[]{new Bullet(this.x + this.width/4 - 10, this.y), new Bullet(this.x + this.width*3/4 - 10, this.y)}; }else { return new Bullet[]{new Bullet(this.x + this.width/2 - 10, this.y)}; } } //出界判断,由于英雄机无法出界,因此这里返回null public boolean outOfBound() { return false; } //英雄机撞击敌机判断 public boolean hitFlying(FlyingObject flying){ int x1 = this.x; int x2 = this.x + this.width; int y1 = this.y; int y2 = this.y + this.height; int xb1 = flying.x; int xb2 = flying.x + flying.width; int yb1 = flying.y; int yb2 = flying.y + flying.height; return (xb1>x1 && xb1<x2) && (yb1>y1 && yb1<y2) || (xb2>x1 && xb2<x2) && (yb1>y1 && yb1<y2) || (xb1>x1 && xb1<x2) && (yb2>y1 && yb2<y2) || (xb2>x1 && xb2<x2) && (yb2>y1 && yb2<y2); }}
//舞台类,关键package com.centerm.shoot;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.util.Arrays;import java.util.Random;import java.util.Timer;import java.util.TimerTask;import javax.imageio.ImageIO;import javax.swing.JFrame;import javax.swing.JPanel;/** * 舞台类 * @author 89447 * */@SuppressWarnings("serial")public class Stage extends JPanel{ public static final int STAGE_WIDTH = 400; public static final int STAGE_HEIGHT = 650; public static final String PATH = "." + File.separator + "src" + File.separator + "com" + File.separator + "centerm" + File.separator + "shoot" + File.separator; /** * 下面统一管理图片,也可以放在各个具体的类中,但是会显得比较混乱,因此这里放在一起 */ public static BufferedImage hero0; public static BufferedImage hero1; public static BufferedImage bee; public static BufferedImage bullet; public static BufferedImage airplane; public static BufferedImage background; public static BufferedImage pause; public static BufferedImage start; public static BufferedImage gameover; //定义几个状态 public static final int START = 0; public static final int RUNNING = 1; public static final int PAUSE = 2; public static final int GAMEOVER = 3; //状态变量 private int state = START; //主要的成员变量 private Hero hero = new Hero(200,300);; private Bullet[] bullets = {}; private FlyingObject[] flyings = {}; //分数 private int score = 0; //初始化图片的静态块 static{ try { hero0 = ImageIO.read(new File(PATH + "hero0.bmp")); hero1 = ImageIO.read(new File(PATH + "hero1.bmp")); bee = ImageIO.read(new File(PATH + "bee.bmp")); bullet = ImageIO.read(new File(PATH + "bullet.bmp")); airplane = ImageIO.read(new File(PATH + "airplane.bmp")); background = ImageIO.read(new File(PATH + "background.bmp")); pause = ImageIO.read(new File(PATH + "pause.bmp")); start = ImageIO.read(new File(PATH + "start.bmp")); gameover = ImageIO.read(new File(PATH + "gameover.bmp")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //绘制所有元素 public void paint(Graphics g) { // TODO Auto-generated method stub g.drawImage(background, 0, 0, null); //绘制背景图片 paintHero(g); //绘制英雄机 paintFlyings(g);//绘制敌机:包括小蜜蜂和飞行器 paintBullet(g); //绘制子弹: paintText(g); paintState(g); } //绘制英雄机,为paint()服务 public void paintHero(Graphics g){ g.drawImage(hero.image, hero.x, hero.y, null); } //绘制敌机,为paint()服务 public void paintFlyings(Graphics g){ for(FlyingObject flying : flyings){ g.drawImage(flying.image, flying.x, flying.y, null); } } //绘制子弹,为paint()服务 public void paintBullet(Graphics g){ for(Bullet bullet : bullets){ g.drawImage(bullet.image, bullet.x, bullet.y, null); } } //绘制文字信息,为paint()服务 public void paintText(Graphics g){ g.setColor(new Color(0xff0000)); g.setFont(new Font(Font.DIALOG, 20, 20)); g.drawString("生命数:"+Integer.toString(hero.getLife()), 0, 100); g.drawString("分数:"+Integer.toString(score), 0, 50); g.drawString("火力剩余:"+Integer.toString(hero.getFirePower()), 0, 75); } //绘制各个状态下的图片,为paint()服务 public void paintState(Graphics g){ switch(state){ case START: g.drawImage(start, 0, 0, null); break; case RUNNING: break; case PAUSE: g.drawImage(pause, 0, 0, null); break; case GAMEOVER: g.drawImage(gameover, 0, 0, null); break; default: break; } } //生成新的敌机,为FlyingEnter()方法服务 public FlyingObject createFlying(){ Random random = new Random(); if(random.nextInt(20) < 2){ return new Bee(); }else{ return new Airplane(); } } //敌机入场 int flyingEnterDelay = 0; public void FlyingEnter(){ if(flyingEnterDelay ++ >= 40){ flyingEnterDelay = 0; flyings = Arrays.copyOf(flyings, flyings.length + 1); flyings[flyings.length - 1] = createFlying(); } } //子弹入场 int BulletEnterDelay = 0; public void BulletEnter(){ if(BulletEnterDelay ++ >= 20){ BulletEnterDelay = 0; Bullet[] bullets_temp = hero.createBullets(); bullets = Arrays.copyOf(bullets, bullets.length + bullets_temp.length); for(int i = 0; i<bullets_temp.length; i++){ bullets[bullets.length - i - 1] = bullets_temp[i]; } } } //移动一帧 public void moveStepAction(){ //移动英雄机:切换图片 hero.moveFlying(); //移动敌机 for(FlyingObject flying: flyings){ flying.moveFlying(); } //移动子弹 for(Bullet bullet: bullets){ bullet.moveFlying(); } } //出界处理方法 public void outOfBoundAction(){ FlyingObject[] flying_temp = new FlyingObject[flyings.length]; int flying_index = 0; for(int i = 0; i<flyings.length; i++){ FlyingObject flying = flyings[i]; if(!flying.outOfBound()){ flying_temp[flying_index ++] = flying; } } flyings = Arrays.copyOf(flying_temp, flying_index); Bullet[] bullets_temp = new Bullet[bullets.length]; int bullet_index = 0; for(int i = 0; i<bullets.length; i++){ Bullet bullet = bullets[i]; if(!bullet.outOfBound()){ bullets_temp[bullet_index ++] = bullet; } } bullets = Arrays.copyOf(bullets_temp, bullet_index); } //一颗子弹射击敌机方法,为shootAction()服务 public boolean bulletShootFlyings(Bullet bullet){ int index = -1; FlyingObject flying; for(int i = 0; i<flyings.length; i++){ flying = flyings[i]; if(flying.shootBy(bullet)){ index = i; //如果有撞击到,将被撞击的元素下标取出,在外部处理这个元素,避免嵌套过深 break; } } if(index != -1){ flying = flyings[index]; if(flying instanceof Bee){ int type = ((Bee) flying).getAwardType(); if(type == Bee.AWARD_FIRE){ hero.addFirePower(); } if(type == Bee.AWARD_LIFE){ hero.addLife(); } } if(flying instanceof Airplane){ score += 5; } //省去了使用循环操作的麻烦 flyings[index] = flyings[flyings.length - 1]; flyings = Arrays.copyOf(flyings, flyings.length - 1); return true; } return false; } //子弹击落敌机方法 public void shootAction(){ Bullet[] bullets_temp = new Bullet[bullets.length]; int bullet_index = 0; for(int i = 0; i<bullets.length; i++){ Bullet bullet = bullets[i]; if(!bulletShootFlyings(bullet)){ bullets_temp[bullet_index ++] = bullet; } } bullets = Arrays.copyOf(bullets_temp, bullet_index); } //英雄机撞击敌人 public void hitAction(){ for(int i = 0; i<flyings.length; i++){ FlyingObject flying = flyings[i]; if(hero.hitFlying(flying)){ hero.substactLife(); hero.clrFirePower(); flyings[i] = flyings[flyings.length - 1]; flyings = Arrays.copyOf(flyings, flyings.length - 1); } } } public void gameOverAction(){ if(hero.getLife() <= 0){ state = GAMEOVER; } } public void action(){ Timer timer = new Timer(); /** * 用于移动的定时任务 */ timer.schedule(new TimerTask() { @Override public void run() { if(state == RUNNING){ FlyingEnter(); BulletEnter(); moveStepAction(); outOfBoundAction(); shootAction(); hitAction(); gameOverAction(); } repaint(); } }, 0, 10); /** * 键盘控制英雄机的行动 */ this.requestFocus(); this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if(state == RUNNING){ //程序没有运行时英雄机是不能动的 switch(e.getKeyCode()){ case KeyEvent.VK_UP: hero.moveDirection(Hero.MOVE_UP); repaint(); break; case KeyEvent.VK_DOWN: hero.moveDirection(Hero.MOVE_DOWN); repaint(); break; case KeyEvent.VK_LEFT: hero.moveDirection(Hero.MOVE_LEFT); repaint(); break; case KeyEvent.VK_RIGHT: hero.moveDirection(Hero.MOVE_RIGHT); repaint(); break; default: break; } } } }); /** * 鼠标控制英雄机的行动 */ MouseAdapter adapter = new MouseAdapter() { public void mouseMoved(MouseEvent arg0) { if(state == RUNNING){ //状态不是运行时候不能移动英雄机 hero.setLocation(arg0.getX(), arg0.getY()); } } public void mouseClicked(MouseEvent arg0) { if(state == START){ state = RUNNING; } if(state == GAMEOVER){ score = 0; hero = new Hero(200, 300); flyings = new FlyingObject[]{}; bullets = new Bullet[]{}; state = START; } } public void mouseExited(MouseEvent arg0) { if(state == RUNNING){ state = PAUSE; } } public void mouseEntered(MouseEvent arg0) { if(state == PAUSE){ state = RUNNING; } } }; this.addMouseListener(adapter); this.addMouseMotionListener(adapter); } public static void main(String[] args) { JFrame frame = new JFrame(); Stage panel = new Stage(); frame.add(panel); frame.setSize(STAGE_WIDTH+10, STAGE_HEIGHT+10); frame.setAlwaysOnTop(true); //将串口一直放在所有窗口之上 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置默认关闭操作为串口关闭时退出程序 frame.setLocationRelativeTo(null); //设置窗口位置居中 frame.setVisible(true); //显示窗口,尽快调用paint()方法 panel.action(); }}
0 0
- 飞机大战JAVA编程
- java飞机大战游戏
- 全民飞机大战Java
- 飞机大战-java
- java飞机大战
- java游戏-飞机大战
- java写飞机大战一
- java写飞机大战二
- java写飞机大战三
- java写飞机大战四
- java写飞机大战五
- Java程序之飞机大战
- 《飞机大战》-Java版-01
- Java飞机大战0_1
- Java飞机大战0_2
- Java飞机大战0_3
- Java飞机大战0_4
- Qt游戏编程——飞机大战
- [Android] Android 动画浅析
- 离散数学输入表达式打印真值表和主析/合取范式
- 单例demo
- C++11中的匿名函数指针(Lambda表达式)
- c++ primer记录
- 飞机大战JAVA编程
- 二级C语言复习5
- Linux c — void类型变量和指针
- 使用jms工厂连接websphere mq
- 微信公众平台开发教程第1篇-新手解惑
- 第三周项目二 建设“顺序表”算法库
- curl 实现sftp功能
- [Android] ButterKnife8.0以上 空指针错误
- 基于cocos2d-x引擎3.9版本分析之CCRef篇