JAVA飞机大战 小游戏 1.1

游戏效果
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
增加了加速减速,免伤功能(1.1);

MyGameFrame类


```java
package com.wenchi666.plane;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyGameFrame extends Frame{

    Image planeImg = GameUtil.getImage("images/plane.png");
    Image bgImg = GameUtil.getImage("images/bg.jpg");
//static int count = 0;

    //初始化飞机
    Plane p1 = new Plane(planeImg,(int)(Math.random()*Constant.GAME_WIDTH),(int)(Math.random()*Constant.GAME_HEIGHT),5);
    Time t =new Time();Time unH=new Time();
    Shell []shells = new Shell[50];
    Explode explode;//explode=null;

    public  void paint(Graphics g) {
        //绘制背景
        g.drawImage(bgImg, 0, 0,Constant.GAME_WIDTH,Constant.GAME_HEIGHT, null);
//      g.drawImage(planeImg,c,100,22,33,null);
//      System.out.println("调用paint,重画窗口,次数:"+(count++));
        //绘制时间
        t.paint(p1,g);
        //绘制飞机
        p1.drawMyself(g);
        //绘制炮弹
        for(int i=0;i<shells.length;i++){
            shells[i].drawMyself(g,t.getS());
            boolean zhuang = shells[i].getRect().intersects(p1.getRect());
                    if(zhuang&&p1.unhurt==false){
                        ///System.out.println("crash!!!");
                        p1.live=false;
                        if(explode==null){
                            explode=new Explode((int)p1.x,(int)p1.y);
                            System.out.println("crash!!!");
                        }explode.drawMyself(g);//轮播一次后计数器已到达末尾,不new执行重画 也无法重画
                    }
        }
    }
    class PaintThread extends Thread{//刷新
        public  void run(){
            while(true){
                repaint();
                try{
                    Thread.sleep(40);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
    public void launchFrame(){
        this.setTitle("飞机大战-纹箎制作");
        setVisible(true);
        setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);//窗口的大小
        setLocation(400,200);

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        new PaintThread().start();//启动重画线程
        this.addKeyListener(new KeyMonitor());

        for(int i=0;i<shells.length;i++){//循环new炮弹
            shells[i]=new Shell();
        }

    }
//注释掉双缓冲可解决残影问题
    private Image offScreenImage = null;
    public void update(Graphics g){
        if(offScreenImage==null)
            offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage,0,0,null);
    }

    //监听键盘的输入输出
    class KeyMonitor extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e){
            p1.addDirection(e);
        }
        @Override
        public void keyReleased(KeyEvent e){
            p1.minusDirection(e);
            p1.changeSpeed(e);
            unH=p1.unHurt(e);
            if(unH.getS()>=5)
                p1.unhurt=false;
            System.out.println(unH.getS());
        }
    }

    public static void main(String[] args) {
        MyGameFrame gameFrame=new MyGameFrame();
        gameFrame.launchFrame();
    }
}

GameObject类

package com.wenchi666.plane;

import java.awt.*;

public class GameObject {
    
    
    Image img;
    double x,y;
    int speed;
    int width ,height;

    public GameObject(){
    
    
    }

    public void drawMyself(Graphics g){
    
    
        g.drawImage(img,(int)x,(int)y,null);
    }
    public  GameObject(Image img,double x,double y){
    
    
        this.img=img;
        this.x=x;
        this.y=y;
        if(img==null){
    
    
            this.width = img.getWidth(null);
            this.height=img.getHeight(null);
        }
    }

    public GameObject(Image img, double x, double y, int speed, int width, int height) {
    
    
        this.img = img;
        this.x = x;
        this.y = y;
        this.speed = speed;
        this.width = width;
        this.height = height;
    }

    public  GameObject(Image img,double x,double y,int speed){
    
    
        this.img=img;
        this.x=x;
        this.y=y;
        this.speed=speed;

        this.height=img.getHeight(null);
        this.width=img.getWidth(null);
    }

    //返回物体对应的矩形区域,便于后续在碰撞检测中使用
    public Rectangle getRect(){
    
    
        return new Rectangle((int)x,(int)y,width,height);
    }


}


GameUtil类

package com.wenchi666.plane;
//工具类
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.nio.Buffer;

public class GameUtil {
    
    
    private GameUtil(){
    
    

    }
    public static Image getImage(String path){
    
    
        BufferedImage img = null;
        URL u = GameUtil.class.getClassLoader().getResource(path);
        try {
    
    
            img = ImageIO.read((u));
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return img;
    }

    public static void main(String[] args) {
    
    
        Image img = GameUtil.getImage("images/plane.png");
        System.out.println(img);
    }

}

Plane类

package com.wenchi666.plane;

import java.awt.*;
import java.awt.event.KeyEvent;

//继承GameObject
public class Plane extends GameObject {
    
    

    boolean left,right,up,down;
    boolean live=true,unhurt=false;//附初始值
    Time t;
    private Graphics gr;

    public void addDirection(KeyEvent e) {
    
    
       System.out.println("anxia"+e.getKeyCode());
        switch (e.getKeyCode()){
    
    
            case KeyEvent.VK_LEFT:left=true;break;
            case KeyEvent.VK_RIGHT:right=true;break;
            case KeyEvent.VK_UP:up=true;break;
            case KeyEvent.VK_DOWN:down=true;break;
        }
    }

    public void minusDirection(KeyEvent e){
    
    
      System.out.println("taiqi"+e.getKeyCode()+speed+" "+this.unhurt);
        switch (e.getKeyCode()){
    
    
            case KeyEvent.VK_LEFT:left=false;break;
            case KeyEvent.VK_RIGHT:right=false;break;
            case KeyEvent.VK_UP:up=false;break;
            case KeyEvent.VK_DOWN:down=false;break;
        }
    }

    public void changeSpeed(KeyEvent e){
    
    
        if(e.getKeyCode()==81) speed++;//Q加速
        if(e.getKeyCode()==87) speed--;//W减速
        //不知道什么原因,不可在此用paint方法绘画
//        class tmp extends Frame {
    
    
//            public void paint(Graphics gr) {
    
    
//                Plane p2 = new Plane(GameUtil.getImage("images/plane.png"), 200, 200, 3);
//                System.out.println("!!!!!!!!!!");
//                p2.drawMyself(gr);
//            }
//        }
    }

    public Time unHurt(KeyEvent e){
    
    
        //若此时正处于无敌则不new t,new t会导致一直刷新 则 无敌时间时间一直是零
        //无敌中再次无敌也不会刷新时间(该版本无法解决此问题,刷新时间的话就会导致时间一直是0)
        if(unhurt==false)
            t=new Time();
        if(e.getKeyCode()== 32)
            unhurt=true;
        return t;
    }

    @Override
    public void drawMyself(Graphics g){
    
    
        if(live==true) {
    
    
            super.drawMyself(g);
            if (left) {
    
    
                x -= speed;
            }
            if (right) {
    
    
                x += speed;
            }
            if (up) {
    
    
                y -= speed;
            }
            if (down) {
    
    
                y += speed;
            }
        }
    }

    public Plane(Image img,double x,double y,int speed){
    
    

        super(img,x,y,speed);
        Time t=new Time();
    }

   public Plane(Image img,double x,double y,int speed,int width,int height){
    
    
        super(img,x,y,speed,width,height);
       Time t=new Time();
   }

}

Shell类


```java
package com.wenchi666.plane;


import java.awt.*;

public class Shell extends GameObject{
    
    

    double degree;
    int basicSpeed=4;
    public Shell(){
    
    
//        x=(int)(Math.random()*Constant.GAME_WIDTH*0.8+100);
//        y=(int)(Math.random()*Constant.GAME_HEIGHT*0.8+100);

        x = 333;
        y = 333;

        degree = Math.random()*Math.PI*2;
//      此处degree我们规范为 箭头方向和x正半轴夹角,需要用到degree时,我们按此运算
        width=8;
        height=8;

        speed = basicSpeed;

}
    public void drawMyself(Graphics g,int time){
    
    

        Color c = Color.yellow;
        speed = 3 + time/6;
        if(time>=30) {
    
    
            c=new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
            speed =  5 + time/10;//变彩球后加速
        }

        Color t=g.getColor();
        g.setColor(c);
        g.fillOval((int)x,(int)y,width,height);

        x += speed*Math.cos(degree);//用cos时因为定义死了夹角degree,此种定义下的degree,x需要*cos;
        y += speed*Math.sin(degree);//y与上面x同理

        int bian=10;//测试与理论不符,引入bian变量,经测试10是最好的;
        if(y>=Constant.GAME_HEIGHT-height-bian||y<=40)
            degree = -degree;//
        if(x<=0+bian||x>=Constant.GAME_WIDTH-width-bian)
            degree = Math.PI-degree;//根据入射角与反射角相等可得原degree与反弹后的degree互为补角.
        g.setColor(t);
    }
}

# Explod类

```java
package com.wenchi666.plane;

import java.awt.*;

public class Explode {
    int x,y;

    static Image [] imgs = new Image[16];

    static {
        for(int i=0;i<16;i++){
            imgs[i]=GameUtil.getImage("images/explode/e"+(i+1)+".gif");
            imgs[i].getWidth(null);//防止懒加载 的问题
        }
    }
    int c=0;
    public void drawMyself(Graphics g){
        if(c<16){
            g.drawImage(imgs[c],x,y,null);
            c++;

            //炸的慢一点
//            try {
//                Thread.sleep(50);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
        }
    }

    public Explode(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Time类

package com.wenchi666.plane;

import java.awt.*;
import java.util.Date;

public class Time {
    
    
    Date start = new Date();
    Date end;
    long  period = 0;
    public int getS(){
    
    
        return (int)(System.currentTimeMillis() - start.getTime())/1000;
    }
    public void paint (Plane p,Graphics g){
    
    
        Color c = g.getColor();//临时颜色c
        g.setColor(Color.GREEN);//设置要用到的颜色
        if(p.live){
    
    
            period = (System.currentTimeMillis() - start.getTime())/1000;
            g.drawString("坚持 "+period,55,55);
        }
        else{
    
    
            if(end==null){
    
    
                end = new Date();
                period = (end.getTime() - start.getTime());
            }
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            if(period/1000<=10)
                g.drawString("共坚持了 "+period/1000+" 秒  \"实在是菜(评级1)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=10&&period/1000<=20)
                g.drawString("共坚持了 "+period/1000+" 秒  \"一般般吧(评级2)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=20&&period/1000<=25)
                g.drawString("共坚持了 "+period/1000+" 秒  \"还行?(评级3)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=25&&period/1000<=30)
                g.drawString("共坚持了 "+period/1000+" 秒\"哎呦不错呦(评级4)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=30&&period/1000<=35)
                g.drawString("共坚持了 "+period/1000+" 秒\"哇塞,这么强?(评级5)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=35&&period/1000<=60)
                g.drawString("共坚持了 "+period/1000+" 秒\"?????你是神仙吧!!简直不要太强!(评级6)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);
            else if(period/1000>=60)
                g.drawString("共坚持了 "+period/1000+" 秒\"已达到最高评级!!!!!!(评级7)\"",Constant.GAME_HEIGHT/3,Constant.GAME_WIDTH/3);

            g.setColor(c);//还原其颜色
        }
    }
    public Time(){
    
    

    }

}


Constant类

package com.wenchi666.plane;

public class Constant {
    
    
    //窗口大小.可以随意调,背景图片会跟着变化
    //静态常量
public static final int GAME_WIDTH = 1200;
public static final int GAME_HEIGHT = 800;


}

在这里插入图片描述在这里插入图片描述在这里插入图片描述
关于角度的解释
在这里插入图片描述
免伤状态下的飞机,此版本还未添加此功能

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是十六张爆炸的图片

图片文件关系如下
在这里插入图片描述
整体的关系如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_45311187/article/details/106403494