2022.1.6Java基础+简单实战:飞机大战

算法冒泡排序

没啥好说的,就是优化的时候加了一遍boolean值,判断这次循环有进行数据交换吗,没有就认为已经完结了,跳出大循环

package com.itbaizhan;

import java.util.Arrays;

public class TestBubbleSort {
    public static void main(String[] args) {
        int[] values = {3,4,1,5,9,4,2,4,5,0};
        //int[] values = {2,1,3,4,5,6,7};
        System.out.println(Arrays.toString(values));

        for (int i =0;i<values.length;i++){
            boolean flag = true;

            for (int j = 0;j<values.length-1-i;j++){
                if(values[j]>values[j+1]){
                    int t = values[j];
                    values[j]=values[j+1];
                    values[j+1]=t;
                    flag=false;
                }
            }
            //如果本次循环没有交换,那么结束排序
            if(flag){
                break;
            }
            System.out.println("第"+i+"次循环:"+Arrays.toString(values));
        }
    }
}

二分法查找

package com.itbaizhan;

public class TestBinarySearch {
    public static void main(String[] args) {
        int[] values = {1,2,3,4,5,6,7};
        int value=9;
        int index=binarySearch(values,value);
        if(index!=-1)
            System.out.println("查找数组values中是否有"+value+",下标索引为:"+index);
        else
            System.out.println("查找数组values中是否有"+value+",未找到该数");
    }
    public static int binarySearch(int[] array,int value){
        int low = 0;
        int high = array.length-1;
        while(low<=high){
            int middle=(low+high)/2;
            if(value==array[middle]){
                return middle;
            }
            if(value>array[middle]){
                low=middle+1;
            }
            if(value<array[middle]){
                high=middle-1;
            }
        }
        return -1;
    }
}


 实战项目:飞机大战

 基础类:GameObject(游戏对象类)、GameUitl(游戏工具类)、MyGameFrame(游戏界面)

游戏对象类:Plane(飞机类)、Shell(子弹类)、Explode(爆炸特效类,这个类没有继承GameObject)

GameObject类

package com.bjsxt;

import java.awt.*;

//游戏物体的根类
public class GameObject {
    Image img;      //对应的图片
    int x,y;        //坐标
    int speed;      //物体移动速度
    int width,height;//物体的宽度和高度

    //画自己
    public void drawMySelf(Graphics g){
        g.drawImage(img,x,y,width,height,null);
    }

    //返回该物体对应的矩形
    public  Rectangle getRec(){
        return new Rectangle(x,y,width,height);
    }


    public GameObject(){}

    public GameObject(Image img, int x, int 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, int x, int y, int speed) {
        this(img,x,y);
        this.x = x;
        this.y = y;
        this.speed = speed;

    }

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

    public GameObject(Image img) {
        this.img = img;
        if(this.img!=null){
            this.width=img.getWidth(null);
            this.height=img.getHeight(null);
        }
    }
}

GameUitl类

package com.bjsxt;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.net.URL;

//工具类
public class GameUitl {
    public static final int FRAME_WIDTH=500;
    public static final int FRAME_HIGHT=500;

    public static Image getTmage(String path){
        Image img=null;
        URL url = GameUitl.class.getClassLoader().getResource(path);
        try{
            img= ImageIO.read(url);
        }catch (IOException e){
            e.printStackTrace();
        }
        return img;
    }
}

MyGameFrame类

package com.bjsxt;

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

import static com.bjsxt.GameUitl.*;

public class MyGameFrame extends Frame {
    Image bgImg= GameUitl.getTmage("images/break.jpeg");
    Image planeImg= GameUitl.getTmage("images/飞机.png");

    //加载实体,飞机、子弹,爆炸
    Plane plane = new Plane(planeImg,200,200,7,40,40);
    Shell[] shells= new Shell[50];
    Explode explode;        //声明炮弹M

    //记录时间的
    Date starTime = new Date();
    Date endTime;
    int period;
    public static void main(String[] args) {
        MyGameFrame frame=new MyGameFrame();
        frame.launchFrame();
    }

    //初始化窗口
    public void launchFrame(){
        this.setTitle("飞机大战");
        this.setVisible(true);
        this.setSize(FRAME_WIDTH,FRAME_HIGHT);
        this.setLocation(300,300);
        //窗口监听 增加关闭窗口的动作
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        //启动窗口绘制线程
        new PaintThread().start();

        //启动键盘监听
        this.addKeyListener(new KeyMoniteor());

        //初始化所有炮弹
        for(int i=0;i<shells.length;i++){
            shells[i]=new Shell();
        }
    }

    //绘制窗口,绘制背景和飞机
    @Override
    public void paint(Graphics g) {
        // System.out.println("窗口绘制...");
        g.drawImage(bgImg,0,0,FRAME_WIDTH,FRAME_HIGHT,null);
        plane.drawMySelf(g);
        //子弹循环
        for(Shell shell:shells){
            //画子弹
            shell.drawMySelf(g);
            //碰撞监测,子弹和飞机是否碰撞
            boolean peng = shell.getRec().intersects(plane.getRec());
            if(peng && plane.live){
                //飞机时候,生命开关关掉,记录死亡时间
                //System.out.println("飞机死了");
                plane.live = false;
                shell.live = false;

                endTime=new Date();
                period=(int)((endTime.getTime()-starTime.getTime())/1000);
            }
        }

        //死亡画面,播放坠毁特效
        if(!plane.live){
            printInfo(g,"飞机死了!",20,plane.x,plane.y,Color.white);
            printInfo(g,"您坚持了"+period+"秒",40, FRAME_WIDTH/4,FRAME_HIGHT/2,Color.white);

            if(explode==null){
                explode=new Explode(plane.x,plane.y,plane.width,plane.height);
            }
            explode.draw(g);
        }
        // g.drawLine(100,50,400,400);
        // g.drawRect(100,50,400,400);
        // g.drawOval(100,50,400,400);
    }


    //在界面上显示字体
    public void printInfo(Graphics g,String str,int size, int x, int y,Color color){
        Font oldFont = g.getFont();
        Color oldColor = g.getColor();

        Font f= new Font("宋体",Font.BOLD,size);
        g.setFont(f);
        g.setColor(color);
        g.drawString(str,x,y);

        g.setFont(oldFont);
        g.setColor(oldColor);
    }

    //键盘监听内部类
    class KeyMoniteor extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e) {
            plane.addDirection(e);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            plane.minusDirection(e);
        }
    }

    //重画线程
    class PaintThread extends Thread{
       @Override
       public void run() {
           while(true){
               repaint(); //内部会自动调用paint方法
               try{
                   Thread.sleep(40);  //1s=1000ms
               }catch (InterruptedException e){
                   e.printStackTrace();
               }
           }
       }
   }


   //解决闪烁问题AWT技术有这个问题,他是最早的技术
    private Image offScreenImage = null;

    public void update(Graphics g){
        if(offScreenImage==null){
            offScreenImage = this.createImage(FRAME_WIDTH,FRAME_HIGHT);
        }
        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage,0,0,null);
    }
}

Plane类

package com.bjsxt;

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

//飞机类
public class Plane extends GameObject{
    boolean left,up,right,down;
    boolean live=true;

    public Plane(Image img, int x, int y, int speed) {
        super(img, x, y, speed);
    }

    public Plane(Image img, int x, int y, int speed, int width, int height) {
        super(img, x, y, speed, width, height);
    }

    //对象自带方法:画飞机判断,如果判断方向在,就对x,y进行移动
    @Override
    public void drawMySelf(Graphics g) {
        if(!live){
            return;
        }
        super.drawMySelf(g);

        if(left){
            x-=speed;
        }
        if(right){
            x+=speed;
        }
        if(up){
            y-=speed;
        }
        if(down){
            y+=speed;
        }
    }

    //两个对象自带方法:通过输入的键盘数值判断bool是否有这个方向的朝向
    public void addDirection(KeyEvent e) {
        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) {
        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;
        }
    }


}

Shell类

package com.bjsxt;

import java.awt.*;

public class Shell extends GameObject{
    double degree;
    boolean chuJie = false;
    boolean live = true;
    public Shell(){
        degree = Math.random()*Math.PI*2;
        x=20;
        y=20;
        width=10;
        height=10;
        speed=4;
    }

    @Override
    public void drawMySelf(Graphics g) {
        if(!live){
            return;
        }
        Color c = g.getColor();
        g.setColor(Color.yellow);
        g.drawOval(x,y,width,height);

        //炮弹沿任意角度飞行
        x += speed*Math.cos(degree);
        y += speed*Math.sin(degree);

        //边界碰撞回弹
        if(y>GameUitl.FRAME_HIGHT || y<30 && chuJie == false){
            degree = -degree+Math.random();
            chuJie=true;
        }

        if(x<GameUitl.FRAME_WIDTH && x>0 && y<GameUitl.FRAME_HIGHT && y>30){
            chuJie=false;
            //System.out.println("x="+x+",y="+y);
            //System.out.println("在界内");
        }

        if(x>GameUitl.FRAME_WIDTH || x<0 && chuJie == false){
            degree = Math.PI-degree+Math.random();
            chuJie=true;
        }
        g.setColor(c);
    }
}

Explode类

package com.bjsxt;

import java.awt.*;

public class Explode {
    double x,y;
    static Image[] imags=new Image[21];
    int width,height;

    //静态加载图片
    static {
        for (int i = 0; i < imags.length; i++) {
            imags[i]=GameUitl.getTmage("images/boob/爆炸"+(i+1)+".png");
            //java可能懒加载,就是不加载图片,调个方法让他加载

            imags[i].getWidth(null);

        }
    }

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

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

    //依次渲染图
    int count;
    boolean live=true;
    public void draw(Graphics g){
        if(!live){
            return;
        }
        if(count<imags.length){
            g.drawImage(imags[count],(int)x,(int)y,width,height,null);
            count++;
        }else {
            live=false;
        }
    }
}

所有代码都在同一包下,游戏开始,50颗子弹随机移动,飞机躲避子弹,直到被撞到,游戏结束

  • 子弹和飞机都继承于游戏对象类,游戏对象类有非常基础的信息(位置x,y,采用那张图片,在窗口上绘画自己的方法,返回自身矩形的方法-碰撞监测需要用)
  • 游戏工具类中有如何导入图片存储到Image对象的方法,以及窗口的长宽常量
  • MyGameFrame类非常复杂,大部分运行机制都在这个类中,里面有加载的背景、飞机图片、 飞机对象、50发子弹对象、炮弹爆炸特效类、记录时间
    • 初始化窗口:窗口标题、显示窗口、设置窗口大小、出现在屏幕的位置,窗口监听-增加开关闭窗口的动作,窗口绘制线程(一秒执行大概25次这个paint方法),批量初始化所有子弹
    • paint方法:绘制背景、飞机对象自我绘制、遍历子弹数组{子弹自我绘制,碰撞监测,看是否碰到飞机了,碰到了游戏结束,飞机生命false,记录结束时间,计算坚持了多长时间}、如果飞机生命false了{写两句话:一句飞机死了,一句坚持了几秒,播放爆炸特效}
    • printInfo方法:在指定位置写一句话
    • 键盘监听内部类:里面两个方法,判断按下、判断抬起
      • 按下方法执行飞机对象中按下方向方法
      • 抬起方法执行飞机对象中抬起方向方法
    • 重画线程(也是一个内部类):只做了一件事:就是每秒多次执行paint方法
    • update方法:解决了早期AWT技术画面闪烁问题
  • 飞机类只有简单三个方法,俩构造方法--初始化飞机的用那张图片,位置,速度,大小
    • 画飞机,每次位置随着四个方向bool值改变,实现移动
    • 剩余两个方法则是 通过输入键盘值(上下左右)判断四个方向bool值的正负,从而决定打开或者关闭四个方向的bool值
  • 子弹类定义了一个随机方向degree和判断是否出界
    • 初始化随机给一个方向,其他的出生点位置、大小、速度都是定死的
    • 绘画黄色圆圈,xy轴按给定随机方向移动,判断是否碰到边界,碰到回弹
  • 爆炸类,只声明,只有飞机死亡的时候才new出来,出来就绘制爆炸,一共21张图片,依次渲染,形成爆炸画面

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值