欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java gui詳解貪吃蛇小游戲?qū)崿F(xiàn)流程

 更新時(shí)間:2021年11月05日 09:27:48   作者:Laurie_c  
剛開始學(xué)JAVA GUI,就練手寫了一個(gè)小時(shí)候經(jīng)常在諾基亞上玩的一個(gè)小游戲__貪吃蛇.做的比較簡單,但還是可以玩的.感興趣的朋友快來看看吧

根據(jù)狂神的視頻做的,然后自己優(yōu)化了一些bug,比如新生成食物的時(shí)候不會(huì)生成在蛇的身體上,再新增長身體的時(shí)候不會(huì)在左上角出現(xiàn)一個(gè)綠色的方塊以及增加了難度控制功能,以及可以使用WASD進(jìn)行控制,而不僅僅限于上下左右方向鍵
最后的游戲界面是這樣的:

在這里插入圖片描述

可以在上方的菜單欄里選擇不同的難度進(jìn)行游戲.難度對應(yīng)的是不同的蛇移動(dòng)的速度,點(diǎn)擊退出游戲和點(diǎn)擊右上角的X是一樣的功能,都是退出游戲.然后點(diǎn)擊重新開始就會(huì)回到最初的時(shí)候重新開始游戲.
按下空格開始游戲,隨時(shí)可以再次按下空格進(jìn)行暫停游戲.同時(shí)每吃到一個(gè)食物就會(huì)在右上角加10分.

在這里插入圖片描述

游戲代碼一共分成了三個(gè)類
一個(gè)是GameStart類,用來創(chuàng)建JFrame繪制游戲主體.
一個(gè)是GamePanel類,用來添加在JFrame中,里面加入了菜單欄以及一些鍵盤監(jiān)聽器,用來根據(jù)讀入的信息操縱蛇移動(dòng).
另一個(gè)是Data類,用來讀取statics文件夾中的圖片素材,代碼更簡潔.

在這里插入圖片描述

GameStart類代碼如下:(具體代碼后面都有注釋)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @author Laurie
 */
public class GameStart {
    public static void main(String[] args) {
        JFrame jframe = new JFrame("貪吃蛇");
        jframe.setBounds(10, 10, 900, 720);//繪制游戲主界面的范圍
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setResizable(false);//不可擴(kuò)大縮小窗口
        GamePanel gamePanel = new GamePanel();
        jframe.add(gamePanel);
        jframe.setVisible(true);//顯形
        gamePanel.setLayout(new BorderLayout());
    }
}

GamePanel類代碼是:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * @author Laurie
 */

public class GamePanel extends JPanel implements ActionListener, KeyListener {
    int length;//蛇的長度
    int[] snakeX = new int[500];//隨便定義長度,反之不出意外是不會(huì)超過的
    int[] snakeY = new int[500];
    String direction;//蛇的方向,來根據(jù)這個(gè)改變蛇頭的圖片
    Timer timer = new Timer(60, this);//計(jì)時(shí)器,來觸發(fā)蛇移動(dòng)的事件
    int score;//分?jǐn)?shù)
    Boolean isFail = false;//是否失敗判斷
    Boolean isStart = false;//是否啟動(dòng)判斷
    int foodX;//食物坐標(biāo)
    int foodY;
    Random random = new Random();//用來產(chǎn)生隨機(jī)數(shù)的Random類的實(shí)例化


    public void init(){
        length = 3;//一開始蛇的三節(jié)
        snakeX[0] = 100;//蛇頭為下標(biāo)0
        snakeY[0] = 100;
        snakeX[1] = 75;
        snakeY[1] = 100;
        snakeX[2] = 50;
        snakeY[2] = 100;
        direction = "R";//初始化方向朝右邊
        score = 0;
        foodX = getFoodX();//通過方法獲取食物的坐標(biāo)
        foodY = getFoodY();
    }
    public GamePanel(){
        //構(gòu)造函數(shù)
        init();//進(jìn)行初始化
        this.setFocusable(true);//設(shè)置可以被賦予焦點(diǎn)
        this.setForeground(Color.pink);//設(shè)置為粉色
        this.addKeyListener(this);//添加鍵盤的監(jiān)聽
        timer.start();//開始計(jì)時(shí)器
        JMenuBar menuBar = new JMenuBar();//選項(xiàng)欄
        JButton jb1 = new JButton("退出游戲");
        JButton jb3 = new JButton("新手難度");
        JButton jb4 = new JButton("高手難度");
        JButton jb5 = new JButton("地獄難度");
        menuBar.add(jb1);
        menuBar.add(jb3);
        menuBar.add(jb4);
        menuBar.add(jb5);
        jb1.addActionListener(e -> {//添加jb1的監(jiān)聽
            System.exit(0);//退出
        });
        jb3.addActionListener(e -> {
            this.requestFocus();//不獲取焦點(diǎn)后面操作鍵盤都會(huì)在菜單欄里,就無法操作蛇了
            timer.stop();//把原來的timer停止
            timer = new Timer(80, this);//使蛇的速度變慢
            timer.start();//重新開始timer
        });
        jb4.addActionListener(e -> {
            this.requestFocus();
            timer.stop();
            timer = new Timer(40, this);
            timer.start();
        });
        jb5.addActionListener(e -> {
            this.requestFocus();
            timer.stop();
            timer = new Timer(20, this);
            timer.start();
        });
        this.add(menuBar);
        JButton jb2 =  new JButton("重新開始");
        jb2.addActionListener(e -> {
            init();//重新開始所以重新初始化一下
            repaint();//重畫
            this.requestFocus();
        });
        this.add(jb2);
    }
    public int getFoodX(){
        //如果沒有判斷的話會(huì)出現(xiàn)bug,也就是食物可能出現(xiàn)在蛇的身體里,所以要進(jìn)行判斷優(yōu)化
        boolean flag = true;
        int x = 25 + 25 * random.nextInt(34);//因?yàn)橐桓駷?5,所以要乘一個(gè)25
        while(flag){
            for(int i = 0; i < length; i++){
                if(snakeX[i] == x) {
                    x = 25 + 25 * random.nextInt(34);//如果和身體重合就重新隨機(jī)一個(gè)數(shù)
                }else{
                    flag = false;
                }
            }
        }
        return x;
    }
    public int getFoodY(){
        boolean flag = true;
        int y = 75 + 25 * random.nextInt(24);//24是計(jì)算出來的,總panel的大小除以25
        while(flag){
            for(int i = 0; i < length; i++){
                if(snakeY[i] == y) {
                    y = 75 + 25 * random.nextInt(34);
                }else{
                    flag = false;
                }
            }
        }
        return y;
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponents(g);//這個(gè)不加可能會(huì)出問題
        this.setBackground(Color.white);
        g.fillRect(0,0,90,30);
        g.setColor(Color.black);
        g.drawString("貪吃蛇大挑戰(zhàn)",10,20);

        g.setColor(Color.LIGHT_GRAY);//分?jǐn)?shù)提示框
        g.fillRect( 25, 36, 850, 40);

        g.setColor(Color.pink);//游戲主界面
        g.fillRect(25,75, 850, 600);

        if ("R".equals(direction)) {//判斷是什么蛇頭朝向,選擇不同的蛇頭圖片
            Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("L".equals(direction)) {
            Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("U".equals(direction)) {
            Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("D".equals(direction)) {
            Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
        }

        for (int i = 1; i < length; i++) {//通過for循環(huán)繪制蛇的身體
            Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
        }
        g.setColor(Color.WHITE);
        g.setFont(new Font("微軟雅黑", Font.BOLD, 18));
        g.drawString("長度:"+length,650,54);
        g.drawString("分?jǐn)?shù):"+score,750,54);//分?jǐn)?shù)長度等的繪制
        Data.food.paintIcon(this, g, foodX, foodY);//繪制食物
        if (!isStart) {//如果還沒開始就提示按下空格開始
            g.setColor(Color.WHITE);
            g.setFont(new Font("微軟雅黑", Font.BOLD, 40));
            g.drawString("按下空格來開始游戲", 300, 300);
        }

        if (isFail) {//如果失敗了就提示按下空格重新開始
            g.setColor(Color.red);
            g.setFont(new Font("微軟雅黑", Font.BOLD, 40));
            g.drawString("蛇死了哦,按下空格重新開始吧", 200, 300);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (isStart && !isFail) {//如果已經(jīng)開始并且沒有失敗
            for (int i = length - 1; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];
                //就把每節(jié)身體的位置都變成上一個(gè)身體的位置來模擬移動(dòng)
                snakeY[i] = snakeY[i - 1];
            }

            if ("R".equals(direction)) {
                //動(dòng)完了身體,這里動(dòng)蛇頭,根據(jù)不同的方向來動(dòng)到位置
                snakeX[0] = snakeX[0] + 25;
                if (snakeX[0] > 850) {
                    snakeX[0] = 25;
                }
            } else if ("L".equals(direction)) {
                snakeX[0] = snakeX[0] - 25;
                if (snakeX[0] < 25) {
                    snakeX[0] = 850;
                }
            } else if ("U".equals(direction)) {
                snakeY[0] = snakeY[0] - 25;
                if (snakeY[0] < 75) {
                    snakeY[0] = 650;
                }
            } else if ("D".equals(direction)) {
                snakeY[0] = snakeY[0] + 25;
                if (snakeY[0] > 650) {
                    snakeY[0] = 75;
                }
            }

            if (snakeX[0] == foodX && snakeY[0] == foodY) {//判斷是否吃到食物
                //如果兩者的xy坐標(biāo)重合了就說明吃到了
                length++;//吃到了長度加一
                snakeX[length - 1] = foodX - 1;//這里是避免出現(xiàn)一個(gè)bug,沒有這兩行就會(huì)在吃吃到以后左上角出現(xiàn)一個(gè)綠方塊
                //這是因?yàn)樾略黾拥纳眢w沒有賦值坐標(biāo),所以就默認(rèn)在00的位置
                snakeY[length - 1] = foodY - 1;
                score = score + 10;
                foodX = getFoodX();//重新生成新的食物
                foodY = getFoodY();
            }
            for(int i = 1; i < length; i++){//進(jìn)行判斷是否死亡,當(dāng)蛇頭和身體重合就是死亡
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                    isFail = true;
                    break;
                }
            }
            repaint();//蛇移動(dòng)了所以需要重新畫一遍
        }
        timer.start();//計(jì)時(shí)器重新開始,蛇再進(jìn)行下一步移動(dòng)
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();//這個(gè)為接受的鍵盤的按鍵對應(yīng)的代碼
        if(keyCode == KeyEvent.VK_SPACE){//如果是空格的話激素hi進(jìn)行判斷
            if(!isFail){//如果沒有失敗就進(jìn)行暫停與重新游戲的功能實(shí)現(xiàn)
                isStart = !isStart;
            }else{//如果已經(jīng)死了就重新開始
                isFail = false;
                init();
            }
            repaint();//重新繪制
        }
        if (keyCode == KeyEvent.VK_LEFT && !"R".equals(direction)) {//檢查獲取的是上下左右的哪個(gè)進(jìn)行蛇頭轉(zhuǎn)向
            direction = "L";
        } else if (keyCode == KeyEvent.VK_RIGHT && !"L".equals(direction)) {
            direction = "R";
        } else if (keyCode == KeyEvent.VK_UP && !"D".equals(direction)) {
            direction = "U";
        } else if (keyCode == KeyEvent.VK_DOWN && !"U".equals(direction)) {
            direction = "D";
        }
        if (keyCode == KeyEvent.VK_A && !"R".equals(direction)) {//檢查獲取的是wasd的哪個(gè)進(jìn)行蛇頭轉(zhuǎn)向
            //注意當(dāng)是與蛇頭反方向的不可以進(jìn)行轉(zhuǎn)動(dòng),畢竟也不能180度轉(zhuǎn)脖子把
            direction = "L";
        } else if (keyCode == KeyEvent.VK_D && !"L".equals(direction)) {
            direction = "R";
        } else if (keyCode == KeyEvent.VK_W && !"D".equals(direction)) {
            direction = "U";
        } else if (keyCode == KeyEvent.VK_S && !"U".equals(direction)) {
            direction = "D";
        }
    }




    //這兩個(gè)沒有用,所以不用寫了
    @Override
    public void keyTyped(KeyEvent e) {

    }
    @Override
    public void keyReleased(KeyEvent e) {

    }
}

Data類代碼是:

import javax.swing.*;
import java.awt.*;
import java.net.URL;

/**
 * @author Laurie
 */
public class Data {
    //讀取statics文件夾里的圖片,加載成圖片
    public static URL bodyURL = Data.class.getResource("/statics/body.png");
    public static URL foodURL = Data.class.getResource("/statics/food.png");
    public static URL downURL = Data.class.getResource("/statics/down.png");
    public static URL upURL = Data.class.getResource("/statics/up.png");
    public static URL rightURL = Data.class.getResource("/statics/right.png");
    public static URL leftURL = Data.class.getResource("/statics/left.png");
    public static ImageIcon body = new ImageIcon(bodyURL);
    public static ImageIcon food = new ImageIcon(foodURL);
    public static ImageIcon down = new ImageIcon(downURL);
    public static ImageIcon up = new ImageIcon(upURL);
    public static ImageIcon right = new ImageIcon(rightURL);
    public static ImageIcon left = new ImageIcon(leftURL);
}

整個(gè)項(xiàng)目文件可以在github上自取,點(diǎn)擊藍(lán)字
github
上不去的也可以在gitee上自取,點(diǎn)擊藍(lán)字
gitee

💕
真的不下一個(gè)自己玩一玩嗎[手動(dòng)滑稽]

到此這篇關(guān)于java gui詳解貪吃蛇小游戲?qū)崿F(xiàn)流程的文章就介紹到這了,更多相關(guān)java 貪吃蛇內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot內(nèi)置的工具類之CollectionUtils示例講解

    Springboot內(nèi)置的工具類之CollectionUtils示例講解

    這篇文章主要介紹了Springboot內(nèi)置的工具類之CollectionUtils,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 淺談springBean的作用域

    淺談springBean的作用域

    本文主要介紹了淺談springBean的作用域,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Java中I/O流讀取數(shù)據(jù)不完整的問題解決

    Java中I/O流讀取數(shù)據(jù)不完整的問題解決

    本文主要介紹了ava中I/O流讀取數(shù)據(jù)不完整的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 如何在Java中判斷兩個(gè)Long類型是否相等

    如何在Java中判斷兩個(gè)Long類型是否相等

    這篇文章主要介紹了如何在Java中判斷兩個(gè)Long類型是否相等,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的?參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • java隨機(jī)驗(yàn)證碼生成實(shí)現(xiàn)實(shí)例代碼

    java隨機(jī)驗(yàn)證碼生成實(shí)現(xiàn)實(shí)例代碼

    這篇文章主要介紹了java隨機(jī)驗(yàn)證碼生成實(shí)現(xiàn)實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 深入淺析Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊

    深入淺析Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊

    這篇文章主要介紹了Java中普通代碼塊、構(gòu)造代碼塊與靜態(tài)代碼塊的相關(guān)資料,靜態(tài)代碼塊>Main()>構(gòu)造代碼塊 。非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • Java純代碼實(shí)現(xiàn)導(dǎo)出PDF功能

    Java純代碼實(shí)現(xiàn)導(dǎo)出PDF功能

    在項(xiàng)目開發(fā)中,產(chǎn)品的需求越來越奇葩啦,開始文件下載都是下載為excel的,做著做著需求竟然變了,要求能導(dǎo)出pdf,本文就來和大家分享一下Java實(shí)現(xiàn)導(dǎo)出PDF的常用方法吧
    2023-07-07
  • JavaWEB項(xiàng)目之如何配置動(dòng)態(tài)數(shù)據(jù)源

    JavaWEB項(xiàng)目之如何配置動(dòng)態(tài)數(shù)據(jù)源

    這篇文章主要介紹了JavaWEB項(xiàng)目之如何配置動(dòng)態(tài)數(shù)據(jù)源問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java軟件設(shè)計(jì)模式之適配器模式詳解

    Java軟件設(shè)計(jì)模式之適配器模式詳解

    這篇文章主要介紹了Java軟件設(shè)計(jì)模式之適配器模式詳解,適配器模式可分為對象適配器和類適配器兩種,在對象適配器模式中,適配器與適配者之間是關(guān)聯(lián)關(guān)系;在類適配器模式中,適配器與適配者之間是繼承(或?qū)崿F(xiàn))關(guān)系,需要的朋友可以參考下
    2023-07-07
  • Spring源碼剖析之Spring處理循環(huán)依賴的問題

    Spring源碼剖析之Spring處理循環(huán)依賴的問題

    大家都知道循環(huán)依賴依賴指的是Bean與Bean之間的依賴關(guān)系,循環(huán)依賴指的是兩個(gè)或者多個(gè)Bean相互依賴,本文通過代碼示例給大家講解Spring處理循環(huán)依賴的問題,感興趣的朋友一起看看吧
    2021-06-06

最新評論