国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件

這篇具有很好參考價值的文章主要介紹了基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??它來了它來了,最后一期終于來了。理論上該講的全都講完了,只剩下那個拖了好幾期的自定義控件和一個比較沒有存在感的設置功能沒有講。所以這次就重點介紹它們倆吧。

??首先我們快速瀏覽下設置的實現(xiàn),上圖:

基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件

??然后是控制器代碼:

SettingsController.java
package controllers;

import components.GameEnum;
import javafx.animation.FadeTransition;
import javafx.animation.RotateTransition;
import javafx.animation.SequentialTransition;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.util.Duration;

import static components.Constant.*;

/**
 * @description: 設置界面控制邏輯
 * @author: 郭小柒w
 * @time: 2023/6/15
 */
public class SettingsController {
    @FXML  // 單選按鈕, 難度
    private RadioButton easy, medium, hard, custom;
    @FXML  // 文本框組, 自定義游戲數(shù)據(jù)
    private TextField numWidth, numHeight, numBomb;
    @FXML // 保存按鈕
    private Button save;
    @FXML // 輔助效果圖
    private ImageView loading;
    // 單選按鈕組
    private ToggleGroup degree;

    public void initialize() {
        // 文本框默認不可編輯
        numWidth.setEditable(false);
        numHeight.setEditable(false);
        numBomb.setEditable(false);
        // 首先嘗試使用已保存設置
        switch (GAME) {
            case MEDIUM:
                medium.setSelected(true);
                break;
            case HARD:
                hard.setSelected(true);
                break;
            case CUSTOM:
                custom.setSelected(true);
                numWidth.setEditable(true);
                numHeight.setEditable(true);
                numBomb.setEditable(true);
                numWidth.setText(GAME.width + "");
                numHeight.setText(GAME.height + "");
                numBomb.setText(GAME.bomb + "");
                break;
            default:
                easy.setSelected(true);
                break;
        }

        // 單選按鈕分組
        degree = new ToggleGroup();
        easy.setToggleGroup(degree);
        medium.setToggleGroup(degree);
        hard.setToggleGroup(degree);
        custom.setToggleGroup(degree);
        // 難度按鈕選中事件
        degree.selectedToggleProperty().addListener(((observable, oldValue, newValue) -> {
            String id = ((RadioButton) newValue).getId();
            // 只有選中自定義難度情況下可編輯文本框, 默認不可編輯
            if (id.equals("custom")) {
                GAME = GameEnum.CUSTOM;
                numWidth.setEditable(true);
                numHeight.setEditable(true);
                numBomb.setEditable(true);
            } else {
                // 清空文本框并設置為不可編輯
                numWidth.setText(null);
                numHeight.setText(null);
                numBomb.setText(null);
                numWidth.setEditable(false);
                numHeight.setEditable(false);
                numBomb.setEditable(false);
                if (id.equals("easy")) {
                    GAME = GameEnum.EASY;
                } else if (id.equals("medium")) {
                    GAME = GameEnum.MEDIUM;
                } else {
                    GAME = GameEnum.HARD;
                }
            }
        }));

        // 保存按鈕點擊事件
        save.setOnMouseClicked(event -> {
            try {
                // 如果是自定義難度, 保存輸入的值
                if (GAME == GameEnum.CUSTOM) {
                    try {
                        // 保存自定義輸入
                        GAME.setWidth(Integer.parseInt(numWidth.getText()));
                        GAME.setHeight(Integer.parseInt(numHeight.getText()));
                        GAME.setBomb(Integer.parseInt(numBomb.getText()));
                    } catch (NumberFormatException e) {
                        // 輸入問題導致的轉換失敗, 按簡單設置處理
                        GAME.setWidth(9);
                        GAME.setHeight(9);
                        GAME.setBomb(10);
                    }
                }
                // 設置用于動畫效果的圖片
                loading.setImage(new Image(LOAD_IMG));
                loading.setVisible(true);
                // 點擊保存時的動畫效果,分兩步, 1:旋轉緩沖 2:圖片淡出
                RotateTransition transition1 = new RotateTransition(Duration.seconds(1), loading);
                // 旋轉角度
                transition1.setByAngle(360);
                transition1.setOnFinished(event1 -> {
                    loading.setImage(new Image(SAVE_IMG));
                });

                FadeTransition transition2 = new FadeTransition(Duration.seconds(1), loading);
                // 不透明度變化
                transition2.setFromValue(1);
                transition2.setToValue(0);

                SequentialTransition sequence = new SequentialTransition(transition1, transition2);
                // 播放動畫
                sequence.play();
            } catch (Exception e) {
                System.out.println("Error on [Class:SettingsController, Method:initialize, Event: save]=>");
                e.printStackTrace();
            }
        });
    }
}

??和上期排行版難度按鈕類似,都是單選按鈕分組然后設置對應點擊事件。不同的是不像排行版切換那樣直觀,這里需要一個提示來讓玩家清楚保存是生效了的,所以我設置了保存按鈕和對應的動畫提示。下面介紹自定義控件的實現(xiàn)(設置真的沒有存在感,哈哈哈)。

??LedNumber,這個東西可是費了我老半天勁。我的思路是既然想在界面上顯示,他要么是布局要么是控件,經過嘗試后發(fā)現(xiàn)還是控件合理。所以這個自定義類要繼承 Control 類,然后按照要求實現(xiàn) createDefaultSkin 方法。到這里我就不會了,它要求的返回值類型為 Skin<?>,這是啥,沒見過啊。求助萬能的GPT后大概明白了它的要求(我理解的不一定準確)——控件顯示是需要有Skin的,沒有的話就類似無內容的Label,不設置背景色在界面上看起來就跟沒有一樣。所以我按GPT的提示創(chuàng)建了對應的skin類 LedNumberSkin,并在里面進行外觀設計。

??設計思路受這篇文章啟發(fā):https://blog.csdn.net/hx0_0_8/article/details/8012448

??其思想就是將數(shù)字看作由以下七個線段組合而成,不同數(shù)字使用不同的線段:

基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件

??只是這樣看起來還不夠美觀,所以可以對這些線段的拼接處進行處理,比如下面這種形式(繪制的有些簡陋,代碼中是可以控制連接處貼合的,適當留白更立體):

基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件

??那么代碼中是如何實現(xiàn)的呢?對于每一條邊,可以使用多邊形Polygon類實現(xiàn),只需要依次寫入它的坐標即可(必須是順時針或者逆時針,起始點位置不做要求),如下:

/**
 * 計算自定義多邊形各頂點坐標
 *
 * @param toward 多邊形朝向 [01234: 右下左上中]
 * @param x      起始點橫坐標
 * @param y      起始點縱坐標
 * @return 坐標數(shù)組
 */
public ArrayList<Double> getPoints(int toward, double x, double y) {
    ArrayList<Double> points = new ArrayList();
    // 添加起始點坐標
    points.add(x);
    points.add(y);
    // 按順時針方向依次添加其余坐標
    switch (toward) {
        case 0:
            points.add(x + height);
            points.add(y + height);
            points.add(x + height);
            points.add(y + height + lenShort);
            points.add(x);
            points.add(y + lenLong);
            break;
        case 1:
            points.add(x + lenLong);
            points.add(y);
            points.add(x + height + lenShort);
            points.add(y + height);
            points.add(x + height);
            points.add(y + height);
            break;
        case 2:
            points.add(x + height);
            points.add(y - height);
            points.add(x + height);
            points.add(y + height + lenShort);
            points.add(x);
            points.add(y + lenShort);
            break;
        case 3:
            points.add(x + lenShort);
            points.add(y);
            points.add(x + height + lenShort);
            points.add(y + height);
            points.add(x - height);
            points.add(y + height);
            break;
        case 4:
            points.add(x + height);
            points.add(y - height + 2);
            points.add(x + height + lenShort);
            points.add(y - height + 2);
            points.add(x + lenLong);
            points.add(y);
            points.add(x + height + lenShort);
            points.add(y + height - 2);
            points.add(x + height);
            points.add(y + height - 2);
            break;
    }
    return points;
}

??有了繪制方法,接下來就是具體數(shù)字需要的初始化方法:

/**
 * 構建點陣數(shù)字需要的邊
 */
public void init() {
    // 初始化
    for (int i = 0; i < 7; ++i) {
        polygons[i] = new Polygon();
    }
    // 計算出各多邊形的頂點坐標
    polygons[0].getPoints().addAll(getPoints(0, 1, 1));
    polygons[1].getPoints().addAll(getPoints(1, 2, 0));
    polygons[2].getPoints().addAll(getPoints(2, height + lenShort + 3, height + 1));
    polygons[3].getPoints().addAll(getPoints(2, height + lenShort + 3, height + lenLong + 3));
    polygons[4].getPoints().addAll(getPoints(3, height + 2, lenLong * 2 - 1));
    polygons[5].getPoints().addAll(getPoints(0, 1, lenLong + 3));
    polygons[6].getPoints().addAll(getPoints(4, 2, lenLong + 2));

    // 根據(jù)edges數(shù)組判斷每條邊待設置的顏色
    for (int i = 0; i < 7; ++i) {
        if(edges[index][i]) {
            polygons[i].setFill(Color.web("#FF0000"));
        } else {
            polygons[i].setFill(Color.web("#680404"));
        }
        pane.getChildren().add(polygons[i]);
    }

    getChildren().add(pane);
}

??注:edges為二維boolean數(shù)組,控制每條邊的顏色顯示 [true:亮紅色, false:暗紅色]

??這樣就有了每個數(shù)字對應的外觀,由于我使用的jdk版本較早,所以不支持 LedNumber 類運行中修改 Skin,所以采用以下方式實現(xiàn)數(shù)字顯示切換:

/**
 * 切換數(shù)字顯示
 * @param index 要轉化成的數(shù)字
 */
public void switchSkin(int index) {
    // 清空當前控件的子節(jié)點, 重新添加
    getChildren().clear();
    LedNumber newLedNumber = new LedNumber(index);
    getChildren().add(newLedNumber);
}

??這樣就完成了LED數(shù)字的顯示,感覺這個想法還是很不錯的。而且在這個基礎上你甚至還可以自己實現(xiàn)電子萬年歷之類的程序,有興趣的伙伴可以嘗試下。到此本次掃雷項目已經介紹差不多了,如果您還有疑問歡迎在評論區(qū)留言,有緣明年再見(開鴿!

——————————————我———是———分———割———線—————————————

??稀里糊涂地講完啦,不知道大家能理解多少??。過一陣子應該會去上海吧,找朋友聚聚,散散心開啟新生活,如正文結尾所說,我們有緣的話明年博客園再會啦,886??!文章來源地址http://www.zghlxwxcb.cn/news/detail-549310.html

到了這里,關于基于JavaFX的掃雷游戲實現(xiàn)(五)——設置和自定義控件的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Java調用ChatGPT(基于SpringBoot和Vue)實現(xiàn)連續(xù)對話、流式輸出和自定義baseUrl

    Java調用ChatGPT(基于SpringBoot和Vue)實現(xiàn)連續(xù)對話、流式輸出和自定義baseUrl

    源碼及更詳細的介紹說明參見Git上的 README.md 文檔 https://github.com/asleepyfish/chatgpt 本文Demo(SpringBoot和Main方法Demo均包括)的Git地址:https://github.com/asleepyfish/chatgpt-demo 流式輸出結合Vue前端的Demo的Git地址:https://github.com/asleepyfish/chatgpt-vue 后續(xù)使用方法和api版本更新均在Github的READM

    2024年02月16日
    瀏覽(51)
  • QT自定義優(yōu)雅的表單控件,簡單實現(xiàn)設置界面布局

    QT自定義優(yōu)雅的表單控件,簡單實現(xiàn)設置界面布局

    FormView.h FormView.cpp 核心函數(shù) 函數(shù) 變量 功能 addEditableItem title: 輸入框前面的提示文字,同時作為該控件的標識符 place_holder: 輸入框中的提示文字 在表單中插入一個可填寫項 addCheckableItem title: 不顯示在UI中,僅作為該控件的標識符 content: 勾選框后面的內容 init_status: 勾選框的初

    2024年02月11日
    瀏覽(29)
  • VScode函數(shù)跳轉,再返回,快捷鍵設置和自定義

    VScode函數(shù)跳轉,再返回,快捷鍵設置和自定義

    Win10: ctrl + 鼠標左鍵 Ubuntu:同上操作 win10: alt + leftarrow ← leftarrow ← ubuntu下: ctrl + alt + - 注意ubuntu下的, - 使用數(shù)字小鍵盤好像不咋好使,使用主鍵盤區(qū)的 - 才可以! ???♂?因此,在ubuntu下進行自定義設置返回原處按鍵,設置成和win10下面的操作一致,即 alt + leftarr

    2024年02月11日
    瀏覽(20)
  • 安卓開發(fā)——控件AlertDialog實現(xiàn)方式,設置下部三個按鈕,自定義布局設置.setView(dialogView)樣式,控件PopupWindow1常用方法,showAsDropDown構造方法

    安卓開發(fā)——控件AlertDialog實現(xiàn)方式,設置下部三個按鈕,自定義布局設置.setView(dialogView)樣式,控件PopupWindow1常用方法,showAsDropDown構造方法

    ?AlertDialog?.?Builder?builder?=?new?AlertDialog?.?Builder?(?context?); 構建?Dialog?的各種參數(shù) ?Builder?.?setlcon?(?int?iconld?); 添加?ICON? ?Builder?.?setTitle?(?CharSequence?title?); 添加標題 ?Builder?.?setMessage?(?CharSequence?message?); 添加消息 ?Builder?.?setView?(?View?view?); 設置自定義布

    2024年02月03日
    瀏覽(24)
  • Ubuntu 22.04網絡配置指南:如何設置靜態(tài)IP和自定義DNS服務器

    找到并打開Netplan配置文件 : 在Ubuntu終端中,輸入以下命令來編輯Netplan的配置文件: 請確保文件名與您系統(tǒng)中實際的文件名匹配。 更新配置文件 : 使用以下內容替換文件中的內容(根據(jù)實際情況調整接口名稱 enp0s3 、IP地址、網關和DNS服務器): 在這個配置中: enp0s3 是網

    2024年04月11日
    瀏覽(27)
  • 【C語言】實現(xiàn)掃雷游戲

    【C語言】實現(xiàn)掃雷游戲

    詳細介紹掃雷游戲的思路和實現(xiàn)過程,并用隨機數(shù)實現(xiàn)埋雷。 ? 使用控制臺實現(xiàn)經典的掃雷游戲 ? 游戲可以通過菜單實現(xiàn)繼續(xù)玩或者退出游戲 ? 掃雷的棋盤是9*9的格? ? 默認隨機布置10個雷 ? 可以排查雷 ? 如果位置不是雷,就顯示周圍有幾個雷 ? 如果位置是雷,就炸

    2024年02月04日
    瀏覽(26)
  • 掃雷游戲的實現(xiàn)(C語言)

    對于掃雷游戲,大家應該都很熟悉吧,下面讓我們來看看它是如何實現(xiàn)的。 目錄 一、游戲規(guī)則及設計思想 二、各功能的代碼實現(xiàn) 1.創(chuàng)建菜單 2、主函數(shù)的實現(xiàn)? 3、創(chuàng)建棋盤并初始化 4、打印棋盤? 5、布置雷的位置 (埋雷) 6、排查雷? ?三、代碼匯總 1、game.h文件 2、game.c文

    2024年02月03日
    瀏覽(26)
  • 小游戲掃雷實現(xiàn)教學(詳解)

    小游戲掃雷實現(xiàn)教學(詳解)

    目錄 ?【前言】 一、模塊化程序設計(多文件編程)介紹 1.概述 2.傳統(tǒng)編程的方式 3.模塊化程序設計的方法 二、掃雷代碼設計思路 三、掃雷代碼設計 1.創(chuàng)建菜單函數(shù) ?2.實現(xiàn)9x9掃雷 3.初始化棋盤 ?4.打印棋盤 ?5.隨機布置雷的位置 6.排查雷的信息 ?7.回到步驟1,重新選擇進入

    2024年02月12日
    瀏覽(23)
  • “純C”實現(xiàn)——掃雷游戲(遞歸實現(xiàn)展開功能)

    “純C”實現(xiàn)——掃雷游戲(遞歸實現(xiàn)展開功能)

    ??游戲動畫演示 ??掃雷實現(xiàn)思路 ??棋盤實現(xiàn) ??布置雷實現(xiàn) ??玩家掃雷實現(xiàn) ??帶展開功能的掃雷 ??小結語 ??text.c文件 ??game.h文件 ??game.c文件 游戲實現(xiàn)完成的模樣: 實現(xiàn)掃雷游戲的前提是要知道: 掃雷游戲的玩法 (會玩的跳過這步) 掃雷游戲也就是排雷,讓玩家點

    2024年02月03日
    瀏覽(24)
  • C語言之掃雷游戲實現(xiàn)篇

    C語言之掃雷游戲實現(xiàn)篇

    目錄 主函數(shù)test.c 菜單函數(shù) 選擇循環(huán) 掃雷游戲實現(xiàn)分析 整體思路? 問題1 問題2? 問題3 問題4? 游戲函數(shù)(函數(shù)調用)? 創(chuàng)建游戲盤數(shù)組mine 創(chuàng)建游戲盤數(shù)組show 初始化游戲盤數(shù)組InitBoard 展示游戲盤DisplayBoard 游戲盤置雷SetMine 游戲盤排雷FindMine test.c總代碼 頭文件函數(shù)聲明game

    2024年02月11日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包