美文网首页
Java+swing版飞机大战

Java+swing版飞机大战

作者: itczt | 来源:发表于2019-03-27 18:14 被阅读0次

    Java小游戏实训——飞机大战

    一、实验目的

    使用Java+swing实现飞机大战小游戏

    二、实验要求

    1.掌握Java的基本语法。
    2.掌握面向对象的编程思想。
    3.掌握利用swing布局游戏界面的方法。

    三、实验步骤

    1.创建本次实验的文件目录结构如下:

    目录结构

    2.代码清单

    4-1:FeiJiGame。java

    package com.feiji.game;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Rectangle;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import com.feiji.util.Bullet;
    import com.feiji.util.GameUtil;
    import com.feiji.util.Plane;
    
    /**
     * 这是游戏的主体类 需要继承Frame类
     * 用户 创建游戏,
     * @author Administrator
     *
     */
    public class FeiJiGame extends Frame{
    
        /**
         * 定义一些变量 画布  飞机  子弹
         *
         */
        Image bg = GameUtil.getImage("images/bg.jpg");
        Plane plane = new Plane("images/plane.png",200,200);
        List bulletList = new ArrayList();
        //计时功能
        Date starTime;
        Date endTime;
        Date countTime;
        
        // 游戏状态,游戏结束时  改为false;
        boolean gameState = true;
        
        /**
         * 加载游戏,画出窗口界面
         */
        public void loadGame(){
            //设置窗口尺寸
            setSize(700,700); 
            //设置窗口出现横纵坐标
            setLocation(200,20);
            //设置窗口可见
            setVisible(true);
            
            //启动重画线程
            new PaintThread().start();      
            
            //设置窗口可以关闭
            addWindowListener(new WindowAdapter(){
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }       
            });
        }
        
        /**
         * 加载游戏,监听按键,创建子弹数量
         */
        public void launchFrame(){
            
            loadGame();
            addKeyListener(new KeyMoniter());
            
            //启动重画线程
            new PaintThread().start();      
            
            // 集合里 放进去10个子弹
            for(int i=0;i<10;i++){
                Bullet bullet = new Bullet();
                bulletList.add(bullet);
            }
            starTime = new Date();
        }
        
        /**
         * 往画布 上画 图像
         */
        @Override
        public void paint(Graphics g) {
            
            // 画 背景图
            g.drawImage(bg, 0, 0, null);// 发现 这个图像 一直在闪。怎么解决?使用缓冲技术就可以,下边的方法就是
            // 画出来飞机,飞机画在背景上,飞机的位置就确定了。
            plane.draw(g);  // 飞机没有出来???怎么回事 live 没有 初始化
            countTime = new Date();
            //然后把子弹放进去,基本就可以了
            
            if(gameState){
                for(int i=0;i<bulletList.size();i++){
                    Bullet b=(Bullet) bulletList.get(i);
                    b.draw(g);
                    
                    // 循环判断 每一个子弹 是否 和 飞机 发生 重叠
                    // 获取子弹的 范围
                    Rectangle bulletRectangle = new Rectangle((int)b.x,(int)b.y,b.width,b.height);
                    
                    // 获取飞机的范围 
                    Rectangle planeRectangle = new Rectangle((int)plane.x,(int)plane.y,plane.width,plane.height);
                    
                    //检测是否碰撞
                    boolean collide= bulletRectangle.intersects(planeRectangle);
                    
                    // 如果中弹 就牺牲了。。。
                    if(collide){
                        plane.setLive(false);
                        endTime = new Date();
                        gameState = false;
                    }
                }
            }
            
            
            /**
             * 游戏中计时效果
             */
            if(plane.isLive()){
                int count_time = (int)(countTime.getTime()-starTime.getTime())/1000;
                printInfo(g,"你已经坚挺了"+count_time+"秒",20,510,50);
            }
            
            /**
             * 死亡时
             */
            if(!plane.isLive()){
                printInfo(g,"GAME OVER",80,160,200);
                int survivalTime = (int)(endTime.getTime()-starTime.getTime())/1000; 
                printInfo(g,"生存时间:"+survivalTime+"秒",40,220,300);
                
                switch(survivalTime/10){
                case 0: 
                    printInfo(g,"菜鸡",30,310,400);
                    break;
                case 1: 
                    printInfo(g,"菜鸟",30,310,400);
                    break;              
                case 2: 
                    printInfo(g,"不错",30,310,400);
                    break;              
                case 3: 
                    printInfo(g,"高手",30,310,400);
                    break;                  
                }
            }
            
        }
        
        /**
         * 双缓冲技术,消除图像的闪烁
         */
        Image ImageBuffer = null;  
        Graphics GraImage = null;    
        public void update(Graphics g){     //覆盖update方法,截取默认的调用过程  
            ImageBuffer = createImage(this.getWidth(), this.getHeight());   //创建图形缓冲区  
            GraImage = ImageBuffer.getGraphics();       //获取图形缓冲区的图形上下文  
            paint(GraImage);        //用paint方法中编写的绘图过程对图形缓冲区绘图  
            GraImage.dispose();     //释放图形上下文资源  
            g.drawImage(ImageBuffer, 0, 0, this);   //将图形缓冲区绘制到屏幕上  
        }  
        
        
        /**
         * 内部类,监听 飞机的按键
         * @author Administrator
         *
         */
        class KeyMoniter extends KeyAdapter{
            @Override
            public void keyPressed(KeyEvent e) {
                plane.KeyPressedControlDirection(e);
            }
            @Override
            public void keyReleased(KeyEvent e) {
                plane.KeyRelasedControlDirection(e);
            }   
        }
        
        
        /**
         * 在屏幕上打印输出内容
         * @param g
         * @param message
         * @param size
         */
        public void printInfo(Graphics g,String message,int size,int x,int y){
            g.setColor(Color.white);
            Font f = new Font("宋体",Font.BOLD,size);
            g.setFont(f);
            g.drawString(message, x,y);
        }
            
        /**
         * 重画窗口的线程类,是一个内部类。
         * @author Administrator
         *
         */
        class PaintThread extends Thread {
            @Override
            public void run() {
                while(true){
                    repaint();
                    try {
                        Thread.sleep(400);   //1秒=1000毫秒,40毫秒表示一秒钟重画25次
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }   
        }
        
        
        /**
         * 程序入口点 开始游戏
         * @param args
         */
        public static void main(String[] args) {
            
            FeiJiGame game = new FeiJiGame();
            // 加载游戏,游戏开始
            game.launchFrame();
            
        }
    }
    
    

    4-2:Bullet.java

    package com.feiji.util;
    
    
    import java.awt.Color;
    import java.awt.Graphics;
    
    /**
     * 子弹类
     * @author Administrator
     *
     */
    public class Bullet {
    
        /**
         * 子弹的速度 以及 发出的角度
         * 坐标位置,宽度 高度
         */
        double speed=10;
        double degree;
        
        public double x,y;
        public int width,height;
        
        //无参构造方法
        public Bullet(){
            degree = Math.random()*Math.PI*2;
            x=700/2;
            y=700/2;
            width = 10;
            height = 10;
        }
        
        /**
         * 画出子弹
         * @param g
         */
        public void draw(Graphics g){
            
            g.setColor(Color.green);
            g.fillOval((int)x, (int)y,width, height);
            
            x += speed*Math.cos(degree);
            y += speed*Math.sin(degree);
            
            if(x>700-width||x<width){
                degree=Math.PI-degree;
            }
            if(y>700-height||y<height+10){
                degree=-degree;
            }
        }
    }
    
    

    4-3 :GameUtil.java

    package com.feiji.util;
    
    
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    
    public class GameUtil {
    
        /**
         * 加载图片方法,传一个路径,获得路径所在的图片
         * @param path
         * @return
         */
        public static Image getImage(String path){
            URL u=GameUtil.class.getClassLoader().getResource(path);
            BufferedImage img=null;
            try {
                img = ImageIO.read(u);
            } catch (IOException e) {
                e.printStackTrace();
            }   
            return img;
        }
    }
    
    

    4-4 :Plane.java

    package com.feiji.util;
    
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyEvent;
    
    /**
     * 飞机类
     * @author Administrator
     *
     */
    public class Plane {
    
        /**
         * 基本属性 上下左右  宽高  是否活着
         * 坐标位置
         * 飞机图像
         */
        
        boolean left,right,down,up,live;
        
        public int x,y,width,height;
        
        Image img ;
        
        /*
         *  画出飞机
         */
        public void draw(Graphics g){
            if(live){
                g.drawImage(img, x, y, null);
                move();
            }
        }
        
        /**
         * 有参构造器
         * 飞机的图片地址,位置都已经确定
         * 飞机的宽高 就是图片的宽高
         */ 
        public Plane(String img_path,int x, int y){
            this.img = GameUtil.getImage(img_path);
            this.x = x;
            this.y = y;
            width = img.getWidth(null);
            height = img.getWidth(null);
            live = true;
        }
        
        /**
         * 移动飞机,坐标改变
         */
        public void move(){
            if(left){
                x -= 10;
            }       
            if(up){
                y -= 10;
            }
            if(right){
                x += 10;
            }
            if(down){
                y += 10;
            }
        }
        
        /**
         * 监听按键,如果 上下左右移动,就改变 变量,进行移动。
         * @param e
         */
        public void KeyPressedControlDirection(KeyEvent e){
            int key_code = e.getKeyCode();
            if(key_code == 37){
                left = true;
            }
            if(key_code == 38){
                up = true;
            }
            if(key_code == 39){
                right = true;
            }
            if(key_code == 40){
                down = true;
            }
        }
        /**
         * 监听是否停止按键
         * @param e
         */
        public void KeyRelasedControlDirection(KeyEvent e){
            int key_code = e.getKeyCode();
            if(key_code == 37){
                left = false;
            }
            if(key_code == 38){
                up =false;
            }
            if(key_code == 39){
                right = false;
            }
            if(key_code == 40){
                down = false;
            }
        }
        
    
        public boolean isLive() {
            return live;
        }
    
        public void setLive(boolean live) {
            this.live = live;
        }
    }
    

    五、实验结果

    运行结果.gif

    相关文章

      网友评论

          本文标题:Java+swing版飞机大战

          本文链接:https://www.haomeiwen.com/subject/lkltbqtx.html