雷霆战机小游戏java

Shootgame类

package com.hyxy.shoot;

import java.awt.Color;

import java.awt.Font;

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.Timer;

import java.util.TimerTask;

 

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

/**

 * 游戏面板类型,需要继承Jpanel

 * @author Administrator

 *

 */

public class ShootGame extends JPanel{

    //定义两个属性,分别是游戏面板的宽高

    public static final int WIDTH=400;

    public static final int HEIGHT=654;

    //面板上需要有一个英雄机属性

    protected Hero hero=new Hero();

    protected FlyingObject[] objects={};//所有飞行物

    protected Bullet[] bullets={};//所有子弹

    protected int score;//面板上的总分

    protected int life;//面板上的命数

    protected int state;

    protected static final int startgame=0;//开始状态

    protected static final int running=1;//运行状态

    protected static final int pausegame=2;//暂停状态

    protected static final int over=3;//结束状态

    //定义所有的图片属性

    public static BufferedImage hero0;

    public static BufferedImage hero1;

    public static BufferedImage airplane;

    public static BufferedImage bee;

    public static BufferedImage bullet;

    public static BufferedImage background;

    public static BufferedImage start;

    public static BufferedImage pause;

    public static BufferedImage gameover;

    //使用静态块给图片赋值

    static{

       try {

           hero0=ImageIO.read(ShootGame.class.getResource("hero0.png"));

           hero1=ImageIO.read(ShootGame.class.getResource("hero1.png"));

           airplane=ImageIO.read(ShootGame.class.getResource("airplane.png"));

           bee=ImageIO.read(ShootGame.class.getResource("bee.png"));

           bullet=ImageIO.read(ShootGame.class.getResource("bullet.png"));

           background=ImageIO.read(ShootGame.class.getResource("background.png"));

           start=ImageIO.read(ShootGame.class.getResource("start.png"));

           pause=ImageIO.read(ShootGame.class.getResource("pause.png"));

           gameover=ImageIO.read(ShootGame.class.getResource("gameover.png"));

          

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

    /**

     * 重写面板绘制功能

     */

    public void paint(Graphics g){

       //绘制背景图片

       g.drawImage(background, 0, 0, null);

       paintHero(g);//绘制英雄机对象

       paintBullets(g);//绘制所有的子弹

       paintFlyingObject(g);//绘制敌机或蜜蜂

       paintScore(g);//绘制分数和生命

       paintState(g);//绘制游戏状态

    }

    private void paintState(Graphics g) {

       switch(state){

       case startgame:

           g.drawImage(start, 0, 0, null);

           break;

       case pausegame:

           g.drawImage(pause, 0, 0, null);

           break;

       case over:

           g.drawImage(gameover, 0, 0, null);

           break;

       }

    }

    private void paintScore(Graphics g) {

       int x=10;

       int y=20;

       g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,20));

       g.setColor(new Color(0xFF0000));

       g.drawString("分数:"+score, x, y);

       g.drawString("生命:"+hero.getLife(), x, y+20);

    }

    private void paintFlyingObject(Graphics g) {

       for(int i=0;i<objects.length;i++){

           FlyingObject obj=objects[i];

           g.drawImage(obj.image, obj.x, obj.y, null);

       }

    }

    private void paintBullets(Graphics g) {

       for(int i=0;i<bullets.length;i++){

           Bullet b=bullets[i];

           g.drawImage(b.image, b.x, b.y, null);

       }

      

    }

    /**绘制英雄机*/

    private void paintHero(Graphics g) {

       //获取英雄机图片

       BufferedImage image=hero.image;

       g.drawImage(image, hero.x, hero.y, null);

    }

   

    Timer timer;//添加定时器属性

    /**

     * 程序的所有执行逻辑功能

     */

    public void action(){

       //添加鼠标监听事件

       MouseAdapter l=new MouseAdapter(){

           //鼠标的移动事件

           public void mouseMoved(MouseEvent e){

              if(state==running){

                  //获取鼠标的坐标

                  int x=e.getX();

                  int y=e.getY();

                  //英雄机与鼠标位置关联

                  hero.moveTo(x, y);

              }

           }

           /**鼠标点击即进入runnning状态*/

           @Override

           public void mouseClicked(MouseEvent e) {

              switch (state) {

              case startgame:

                  state=running;

                  break;

              case over:

                  state=startgame;

                  //所有的数据都要重置

                  hero=new Hero();

                  score=0;

                  bullets=new Bullet[0];

                  objects=new FlyingObject[0];

                  break;

             

              }

           }

           /**鼠标离开即进入pausegame状态*/

           @Override

           public void mouseExited(MouseEvent e) {

              if(state==running){

                  state=pausegame;

              }

           }

           /**鼠标进入即进入running状态*/

           @Override

           public void mouseEntered(MouseEvent e) {

              if(state==pausegame){

                  state=running;

              }

           }

          

       };

       //将监听事件绑定到面板上

       this.addMouseListener(l);

       //添加监听事件的鼠标滑动效果

       this.addMouseMotionListener(l);

        timer=new Timer();

        /**

         * 设置定时器任务,

         * 第一个为任务内容

         * 第二个参数为多少毫秒后开始执行任务,

         * 第三个是每隔多少毫秒执行任务

         * */

        timer.schedule(new TimerTask(){

            public void run(){

               if(state==running){

                   enterAction();//飞行物进场

                   stepAction();//所有飞行物开始走步

                   shootAction();//射击行为

                   boomAction();//碰撞行为

                   outOfBoundsAction();//处理飞行物越界情况

                   checkGameOver();//检查游戏是否结束

               }

               //重写绘制效果

               repaint();

            }

        }, 10, 10);

    }

    /**处理越界行为,将没有越界的装入新的数组*/

    protected void outOfBoundsAction() {

       FlyingObject[] objLives={};

        for(int i=0;i<objects.length;i++){

           FlyingObject obj=objects[i];

           if(!obj.outOfBounds()){

              objLives=Arrays.copyOf(objLives, objLives.length+1);

              objLives[objLives.length-1]=obj;

           }

       }

       objects=objLives;

       Bullet[] bsLives={};

       for(int i=0;i<bullets.length;i++){

           Bullet b=bullets[i];

           if(!b.outOfBounds()){

              bsLives=Arrays.copyOf(bsLives, bsLives.length+1);

              bsLives[bsLives.length-1]=b;

           }

       }

       bullets=bsLives;

    }

    /**检查游戏是否结束*/

    protected void checkGameOver() {

       if(isGameover()){

           state=over;//游戏结束后,更改状态

       }

    }

    /**判断游戏是否结束

     * 条件是,生命值为0

     * */

    private boolean isGameover() {

       int index=-1;

       for(int i=0;i<objects.length;i++){

           FlyingObject obj=objects[i];

           if(hero.hit(obj)){

              hero.substractLife();//减一条命

              hero.setDoubleFire(0);//重置火力值

              //让飞行物消失

              index=i;//记录敌机下标

              if(index!=-1){

                  objects[index]=objects[objects.length-1];

                  objects=Arrays.copyOf(objects, objects.length-1);

              }

              break;

           }

       }

       return hero.getLife()<=0;

    }

    /**子弹与敌机或蜜蜂进行碰撞*/

    protected void boomAction() {

       for(int i=0;i<bullets.length;i++){

           Bullet b=bullets[i];

           //判断b是否与飞行物相撞

           boom(b);

       }

    }

    /**查看子弹与飞行物相撞的情况*/

    private void boom(Bullet b) {

       int index=-1;//用于记录被击中的飞行的下标

       for(int i=0;i<objects.length;i++){

           FlyingObject obj=objects[i];

           //查看飞行物是否被飞行物击中

           boolean f=obj.shootBy(b);

           if(f){

              index=i;

              break;

           }

       }

       //需要将被击中的飞行物删除

       if(index!=-1){

           //保存被击中的飞行物

           FlyingObject obj=objects[index];

           //将之从数组中删除

           objects[index]=objects[objects.length-1];

           //缩容一位

           objects=Arrays.copyOf(objects, objects.length-1);

           //查看被击中的是敌机还是蜜蜂

           if(obj instanceof Bee){

              //是蜜蜂

              Bee bee=(Bee)obj;

              int awardType=bee.getType();//获取奖励类型

              switch(awardType){

              case Award.DOUBLE_FIRE: //变成双倍火力

                  hero.addDoubleFire();

                  break;

              case Award.LIFT: //英雄机生命+1

                  hero.addLife();

                  break;

              }

           }else{

              //是敌机

              Airplane air=(Airplane)obj;

              score+=air.getScore();

           }

       }

    }

 

    /**英雄机发射子弹的功能*/

    int shootIndex;//定义变量,计算子弹发射频率

    protected void shootAction() {

       shootIndex++;

       /*400毫秒一发射,自定义*/

       if(shootIndex%30==0){

           Bullet[] bs=hero.shoot();//产生子弹

           //将产生的子弹存入游戏面板的子弹数组

           bullets=Arrays.copyOf(bullets, bullets.length+bs.length);

           System.arraycopy(bs, 0, bullets,bullets.length-bs.length, bs.length);

       }

    }

    /**所有飞行物开始走步*/

    protected void stepAction() {

       //敌机和蜜蜂开始走步

       for(int i=0;i<objects.length;i++){

           FlyingObject obj=objects[i];

           obj.step();

       }

       for(int i=0;i<bullets.length;i++){

           Bullet b=bullets[i];

           b.step();

       }

       hero.step();

    }

    /**让所有的飞行物即敌机和蜜蜂进场*/

    int objectIndex;//用来控制飞行物入场的频率

    protected void enterAction() {

       objectIndex++;

       /**飞行物入场:每300毫秒就进入一个*/

       if(objectIndex%90==0){

           /**

            * 随机产生一个飞行物

            */

           FlyingObject obj=randomOne();

           objects=Arrays.copyOf(objects, objects.length+1);

           objects[objects.length-1]=obj;

       }

      

    }

    /**随机一个敌机或者是蜜蜂*/

    private FlyingObject randomOne() {

       int num=(int)(Math.random()*20);

       if(num==19){

           Bee b=new Bee();

           return b;

       }else{

           Airplane air=new Airplane();

           return air;

       }

    }

    public static void main(String[] args) {

       //创建一个窗口

       JFrame frame=new JFrame("雷霆战机");

       //设置窗口大小

       frame.setSize(WIDTH, HEIGHT);

       //创建游戏面板对象

       ShootGame panel=new ShootGame();

       //将面板嵌入窗口

       frame.add(panel);

       //设置关闭即结束

       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       //设置窗口居中

       frame.setLocationRelativeTo(null);

       //设置窗口在屏幕最前端

       frame.setAlwaysOnTop(true);

   

       //设置窗口可见

       frame.setVisible(true);

       //执行程序逻辑

       panel.action();

      

    }

}

FlyingObject:

package com.hyxy.shoot;

 

import java.awt.image.BufferedImage;

 

/**

 * 定义抽象类型:飞行物

 * 将面板上的所有飞行物的共有特征及其

 * 功能封装到这个抽象类

 * @author Administrator

 *

 */

public abstract class FlyingObject {

    protected BufferedImage image//图片

    protected int x;//绘制起始横坐标

    protected int y;//绘制起始纵坐标

    protected int width;//图片的宽

    protected int height;//图片的高

    //共同功能

    public abstract void step();//走步行为

    public abstract boolean outOfBounds();//越界行为

    /**

     * 查看飞行物是否被子弹击中

     * @param b 子弹对象

     * @return  true:表示被击中

     *          false:表示没被击中

     */

    public boolean shootBy(Bullet b) {

       /**计算飞行物中心到子弹中心的距*/

       //x轴的中心距离

       int x1=this.x+width/2; //飞行物的中心x坐标

       int y1=this.y+height/2; //飞行物的中心y坐标

       int x2=b.x+b.width /2;

       int y2=b.y+b.height/2;

       /**满足碰撞的条件:

        * 1.两个中心的x轴小于子弹与飞行物一半宽度之和的一半

        * 2.两个中心的y轴小于子弹与飞行物一半高度的之和一半

        * */

       //x轴两个中心的距离

       double xdis=Math.abs((x1-x2));

       double ydis=Math.abs((y1-y2));

       //y轴两个中心的距离

       return xdis<(width+b.width)/2&&ydis<(height+b.height)/2;

    }

}

Award类

package com.hyxy.shoot;

/**

 * 定义奖励接口

 * @author Administrator

 *如果从蜜蜂身上获取0,就表示双倍火力

 *如果从蜜蜂身上获取0,就表示生命值

 */

public interface Award {

    int DOUBLE_FIRE=0;//双倍火力

    int LIFT=1;//生命

    /**

     *获取奖励类型的方法

     * @return

     */

    public int getType();

}

Enemy类

package com.hyxy.shoot;

/**

 * 定义敌人接口:

 * 敌人被击中后,只需要提供分数

 * @author Administrator

 *

 */

public interface Enemy {

    /**提供获取分数的方法*/

    public int getScore();

}

 

Hero类:

package com.hyxy.shoot;

 

import java.awt.image.BufferedImage;

 

/**

 * 定义定义英雄机类型继承FlyingObject

 * 英雄机需要添加自己的独有属性

 * @author Administrator

 *

 */

public class Hero extends FlyingObject{

    protected BufferedImage[] images;//图片数组

    protected int double_fire;//火力值

    protected int life;//生命值

    /**

     * 添加构造器,给属性初始化

     */

    public Hero(){

       image=ShootGame.hero0;//设置英雄机的初始图片

       x=140;//在面板x轴上的初始位置

       y=440;//在面板y轴上的初始位置

       width=image.getWidth();

       height=image.getHeight();

       images=new BufferedImage[]{

              ShootGame.hero0,ShootGame.hero1//两张图片

       };

       double_fire=0;//默认单倍火力

       life=3;//默认3条命

    }

  

    /**

     * 英雄机的走步行为即两张图片的交换

     *设计 每四百毫秒交换一次

     *    每十毫秒调用一次step()方法

     *   

     * */

    protected int index;//用来统计图片的交换频率

    @Override

    public void step() {

       index++;

       /**

        * 每10毫秒 index都会自动加一

        * */

       image=images[index/10%images.length];

    }

   

    /**英雄机设置成永不越界,即返回flase*/

    @Override

    public boolean outOfBounds() {

       // TODO Auto-generated method stub

       return false;

    }

    /**

     * 随着鼠标移动而移动

     * @param鼠标的横坐标

     * @param鼠标的纵坐标

     */

    public void moveTo(int x,int y){

       /**通过鼠标的位置计算英雄机的位置

            * 鼠标位于英雄机的中心位置

            * */

         this.x=x-width/2;

         this.y=y-height/2;

    }

    /**

     * 英雄机的射击功能

     * @return

     */

    public Bullet[] shoot(){

       if(double_fire==0){

           Bullet[] bs=new Bullet[1];

           //子弹的横坐标

           int x=this.x+width/2;

           //子弹的纵坐标

           int y=this.y-ShootGame.bullet.getHeight();

           bs[0]=new Bullet(x,y);

           return bs;

       }else{

           //双倍火力

           Bullet[] bs=new Bullet[2];

           int x1=width/4;

           int y1=ShootGame.bullet.getHeight();

           bs[0]=new Bullet(this.x+x1,this.y-y1);

           bs[1]=new Bullet(this.x+x1*3,this.y-y1);

           return bs;

       }

      

    }

    /**设置双倍火力,让属性double_fire大于0就行*/

    public void addDoubleFire() {

       double_fire+=40;

    }

    /**设置加命*/

    public void addLife() {

       life++;

    } 

    /**设置减命*/

    public void substractLife() {

       life--;

    }

    /**设置获取英雄机的总命数*/

    public int getLife(){

       return life;

    }

    /**用来设置火力值:英雄机被撞,重置火力值*/

    public void setDoubleFire(int fire){

       this.double_fire=fire;

    }

    /**判断英雄机是否与飞行物碰撞*/

    public boolean hit(FlyingObject obj) {

       //飞行物的中心坐标

       int x1=obj.x +obj.width/2;

       int y1=obj.y+obj.height/2;

       //英雄机的坐标

       int x2=this.x+this.width/2;

       int y2=this.y+this.height/2;

       int xdis=Math.abs(x1-x2);

       int ydis=Math.abs(y1-y2);

       return xdis<(this.width+obj.width)/2

              &&

              ydis<(this.height+obj.height)/2;

    }

}

Bullet类

package com.hyxy.shoot;

/**

 * 定义子弹类型:Bullet

 * @author Administrator

 *

 */

public class Bullet extends FlyingObject{

    protected int speed=3;//每次移动3像素

    /**提供构造器,给属性初始化*/

    public Bullet(int x,int y){

       this.x=x;

       this.y=y;//子弹的位置与英雄机的位置有关系

       image=ShootGame.bullet;

       width=image.getWidth();

       height=image.getHeight();

    }

    @Override

    public void step() {

       y-=speed;

    }

    @Override

    public boolean outOfBounds() {

       //纵坐标在-height以上就是true表示越界

       return this.y<-height;

    }

 

}

Airplane类:

package com.hyxy.shoot;

/**

 * 定义敌机类型:Airplane

 * 继承FlyingObject,实现Enemy

 * @author Administrator

 *

 */

public class Airplane extends FlyingObject implements Enemy {

    protected int speed=2;//每次移动2像素

    /**提供构造器,给属性初始化*/

    public Airplane(){

       image=ShootGame.airplane;

       width=image.getWidth();

       height=image.getHeight();

       this.x=(int)(Math.random()*(ShootGame.WIDTH-width));

       this.y=-height;

    }

    /**每个敌机5分*/

    @Override

    public int getScore() {

       return 5;

    }

    @Override

    public void step() {

       this.y+=speed;

    }

    @Override

    public boolean outOfBounds() {

       //敌机整个消失在面板内时才算越界

       return this.y>ShootGame.HEIGHT;

    }

 

}

Bee类:

package com.hyxy.shoot;

/**

 * 定义蜜蜂类型 Bee

 * 继承FlyingObject,实现Award接口

 * @author Administrator

 *

 */

public class Bee extends FlyingObject implements Award{

    protected int xSpeed=1;//x轴上的移动像素

    protected int ySpeed=2;//y轴上的移动像素

    protected int awardType;//蜜蜂对象的奖励类型

    /**提供构造器,给属性初始化*/

    public Bee(){

       image=ShootGame.bee;

       width=image.getWidth();

       height=image.getHeight();

       this.x=(int)(Math.random()*(ShootGame.WIDTH-width));

       this.y=-height;

       //随机一种奖励类型

       int num=(int)(Math.random()*2);

       awardType=num;//奖励类型已确定

    }

    /**蜜蜂被击中时,需要知道是哪种奖励*/

    @Override

    public int getType() {

       return awardType;

    }

 

    @Override

    public void step() {

       this.y+=ySpeed;

       if(x<0){

           xSpeed=-2;

       }

       if(x>ShootGame.WIDTH-width){

           xSpeed=-2;

       }

       this.x+=xSpeed;

    }

    @Override

    public boolean outOfBounds() {

       return  this.y>ShootGame.HEIGHT;

    }

}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值