自製的MATLAB拼圖游戲GUI界面版詳解(中篇)

来源:https://www.cnblogs.com/sixuwuxian/archive/2022/10/06/16758712.html
-Advertisement-
Play Games

這篇博文在早前本人寫的介紹拼圖游戲的基礎上推出帶有GUI用戶界面的增強版,這裡將通過上、中、下三篇博文詳細介紹利用MATLAB GUI設計的拼圖游戲完整實現過程,每篇都會附上相應代碼及解釋。中篇主要講解拼圖游戲中游戲難度選擇(拼圖階數設置)與拼圖塊數字提示功能的詳細實現過程。中篇的要點如下:拼圖游戲... ...


圖片展示

摘要:這篇博文在早前本人寫的介紹拼圖游戲的基礎上推出帶有GUI用戶界面的增強版,這裡將通過上、中、下三篇博文詳細介紹利用MATLAB GUI設計的拼圖游戲完整實現過程,每篇都會附上相應代碼及解釋。中篇主要講解拼圖游戲中游戲難度選擇(拼圖階數設置)與拼圖塊數字提示功能的詳細實現過程。中篇的要點如下:

點擊跳轉至拼圖游戲全部文件下載頁


1. 前言

    從網路上可以看到用Java, C++等語言編寫的拼圖小游戲多不勝數,MATLAB作為高校幾乎必設的一名基礎編程語言或工具,大多都是用在數據計算、科學研究及實驗模擬上,而網上流傳的其編寫小游戲的代碼都是那幾個老舊版本。這篇博文緊接著上篇繼續介紹MATLAB GUI拼圖游戲的詳細過程,相比於早前的基本版本增加了圖片選擇、難度設置、數字提示的功能,使其在功能上更像一個游戲的樣子。因為GUI界面版內容較多,這裡限於篇幅分成了上、中、下連續三篇依次講解。希望本文能給對MATLAB GUI界面設計或小游戲感興趣的朋友有所啟發。


2. 拼圖游戲初始圖片顯示

    簡單來說,我們這一節實現的功能是:剛運行程式後,在兩個用於顯示原始圖片和拼圖圖片的坐標軸上顯示一張預先設置的初始圖片(否則該區域空白,有失美觀),在下方任務欄和界面左上角顯示自行設置的圖標。其效果如下:

圖片展示

    要實現以上功能,需要在GUI界面中各控制項創建時,添加相應代碼使在界面初始化時顯示我們設置的圖片。每個控制項都有一個回調函數CreateFcn,該函數只有在創建該控制項的時候才會被調用。和上篇的方法一樣,我們打開之前設計好的包含GUI界面的fig文件,分別選中用於顯示初始圖片和拼圖圖片的兩個坐標軸,右擊選擇“查看回調”,點擊“CreateFcn”即可跳轉至該函數的定義編輯文件中,如下圖所示:

圖片展示

    axes_jigsaw_CreateFcn是這裡創建顯示拼圖的坐標軸(axes_jigsaw)時調用的函數,在該函數中添加下麵的代碼:

% --- Executes during object creation, after setting all properties.
function axes_jigsaw_CreateFcn(hObject, eventdata, handles)
% 創建圖形時執行,設置拼圖區坐標顯示拼圖原始圖片
image(imread('jigsawImage.jpeg'));
set(hObject,'Visible','off','Tag','axes_jigsaw')% 關閉坐標軸顯示

    代碼第4行表示先讀入事先準備好的放在同一目錄下的名為‘jigsawImage.jpeg’的圖片併在該坐標軸顯示,第5行設置該坐標軸狀態為隱藏(不影響該坐標上圖片的顯示)。同理在顯示初始圖片的坐標軸(axes_original)的CreateFcn函數下添加以下代碼:

% --- Executes during object creation, after setting all properties.
function axes_original_CreateFcn(hObject, eventdata, handles)
% 創建圖形時執行,設置原始圖片顯示
image(imread('jigsawImage.jpeg'));
set(hObject,'Visible','off','Tag','axes_original');

    以上代碼添加後再次運行程式則會在開始時顯示圖片,那麼如何設置圖標呢?在MATLAB 2016的視窗屬性中可直接設置圖標,而在之前的版本中則需要調用javax設置。採用上述相同的方式,在視窗(figure1)中右擊選擇“查看回調”選擇“CreateFcn”,並跳轉至該回調函數中,添加如下代碼:

% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)

javaFrame=get(hObject,'javaFrame'); % 獲取圖形句柄
% 為視窗設置圖標
set(javaFrame,'FigureIcon',javax.swing.ImageIcon('Puzzle_icon.png'))  % Puzzle_icon.png為指定的圖標
warning off all; % 忽略警告

    以上代碼中,第4行為獲取坐標軸中javaFrame對象的句柄,第6行設置視窗圖標為文件名為“Puzzle_icon.png”的圖片(文件需與m文件在同一文件夾下),第7行忽略警告。至此本節初始圖片和圖標功能完成,需要註意的是在“CreateFcn”中的代碼只在創建時執行一次,因此若需修改效果需按上面的方法再次修改代碼並生效。


3. 拼圖游戲階數選擇功能

    為了能夠調整拼圖難度,這裡選擇一個彈出式菜單控制項供用戶選擇拼圖階數,其效果簡單演示如下:

圖片展示

    在上篇中就以及在設計GUI時,為這個彈出式菜單控制項(popupmenu_rank)添加了供選擇的菜單項。這裡只需為其添加回調函數,對此這裡再次通過上面的方法跳轉至該控制項的“Callback”函數中,或者在fig對應的m文件中直接找到這個函數,在其中添加如下代碼:

% --- 下拉選擇框popupmenu_rank被點擊時執行.
function popupmenu_rank_Callback(hObject, eventdata, handles)

global flag; % 是否可點擊拼圖塊標識
flag=false; % 下拉框改變,點擊開始前不能點擊

file_name=get(handles.edit_path,'String');% 文件名
% 讀取圖片
if exist(file_name,'file')==0
   pic_data=imread('jigsawImage.jpeg');
else
   pic_data=imread(file_name);
end
% 獲取並計算拼圖階數
n=get(handles.popupmenu_rank,'value');
rank_Tag=n+2;
% 計算拼圖塊長寬
len=min([size(pic_data,1),size(pic_data,2)]);
len_col=round(len/rank_Tag);
len_row=round(len/rank_Tag);
% 統一拼圖尺寸
pic_data=imresize(pic_data,[rank_Tag*len_col rank_Tag*len_row]);

% 數字標識
Tag=[1:1:rank_Tag^2-1,0];
Tag=reshape(Tag,rank_Tag,rank_Tag);
Tag=Tag';
% 顯示拼圖
axes(handles.axes_jigsaw) 
image(pic_data);
axis off;

% 根據選擇情況決定是否顯示數字標識
ismask=get(handles.checkbox_num,'Value');
axes(handles.axes_jigsaw);
for i=1:size(Tag,1)
    for j=1:size(Tag,2)
        text(len_col/2*(2*j-1)-10,len_row/2*(2*i-1),num2str(Tag(i,j)),'FontSize',55-rank_Tag*5,'Color','c')
    end
end
if ~ismask
    h=findall(gca,'type','text');
    delete(h);
end

    在以上代碼中,第4-5行使用了一個全局變數flag這個變數與上篇中提到的是相同的變數,MATLAB中全局變數是可以在不同函數、文件中使用的,只要有所聲明。這裡flag的作用在作為一個標誌決定是否能夠點擊拼圖區的拼圖使其移動,需要遵循的一條是即便上次游戲還在運行只要點擊了難度選擇菜單,立即將標誌置為false表示重新設置重新開始游戲了,在開始游戲前點擊無效了(涉及點擊事件響應,下篇介紹)。

    這部分思路是首先讀取用於顯示文件路徑的標簽上的顯示的路徑,並讀取該路徑下上的圖片並顯示,然後讀取當前菜單欄選中項並據此計算出拼圖階數,根據階數將拼圖分成對應的拼圖塊並調整圖片尺寸。由於需要考慮到點擊菜單欄選擇難度時可能已勾選“顯示提示數字”的勾選框,因此需添加一段代碼判斷勾選狀態並根據勾選狀態決定是否顯示數字。代碼中許多代碼與上篇中實現圖片選擇功能部分的代碼一致,其中的代碼註釋也比較完善這裡就不多介紹了。


4. 拼圖塊數字提示功能

    這節要實現的功能是:游戲開始前或進行中,可以對對應的拼圖塊標識相應的數字作為提示信息,提示的數字應能夠適應相應的拼圖階數。效果如下:

圖片展示

    其實這部分實現在上篇也有所提及,採用上面的方法跳轉至數字提示勾選框的回調函數“Callback”的代碼編輯中,在該函數中添加如下代碼:

% --- checkbox_num按鈕被點擊時執行.
function checkbox_num_Callback(hObject, eventdata, handles)
global Tag;% 拼圖塊的數字標識

% 讀取圖片文件
file_name=get(handles.edit_path,'String');
if exist(file_name,'file')==0
    pic_data=imread('jigsawImage.jpeg');
else
    pic_data=imread(file_name);
end

% 獲取並計算拼圖階數
n=get(handles.popupmenu_rank,'value');
rank_Tag=n+2;
% 如果拼圖塊標識Tag與當前的拼圖階數不符,根據當前階數重置
if size(Tag,1)~=rank_Tag||size(Tag,2)~=rank_Tag
    Tag=[1:1:rank_Tag^2-1,0];
    Tag=reshape(Tag,rank_Tag,rank_Tag);
    Tag=Tag';
end

% 計算每個拼圖塊的長寬
len=min([size(pic_data,1),size(pic_data,2)]);
len_col=round(len/rank_Tag);
len_row=round(len/rank_Tag);

% 根據選擇情況決定是否顯示數字標識
ismask=get(handles.checkbox_num,'Value');
axes(handles.axes_jigsaw);
for i=1:size(Tag,1)
    for j=1:size(Tag,2)
        % 在每塊拼圖的中心位置添加對應數字顯示
        text(len_col/2*(2*j-1)-10,len_row/2*(2*i-1),num2str(Tag(i,j)),'FontSize',55-rank_Tag*5,'Color','c')
    end
end
if ~ismask % 選擇不顯示,則刪除所有text圖形
    h=findall(gca,'type','text');
    delete(h);
end

【代碼解釋】

    代碼第3行首先申明瞭一個全局變數Tag,它保存有當前拼圖塊的標號矩陣,通過對Tag的操作將圖片與其對應起來,因為其他函數中也需要用到這裡乾脆設置為全局變數。代碼第28-40行,理由text函數在坐標軸中顯示文本,而顯示的文本內容是每塊拼圖塊對應的數字,通過遍歷Tag能夠得到,而要顯示的位置可通過每塊拼圖的長寬計算得到,長寬除以2即要顯示數字的中心位置。如第34行所示,利用text函數顯示文本,第37-40行,根據獲取的勾選的結果決定是否顯示text文本,第39行表示刪除所有text對象。


【下載鏈接】
    若您想提前獲得博文中涉及的實現完整拼圖功能的全部程式文件(包括圖片、fig, m文件等),這裡已打包上傳至博主的CSDN下載資源中,下載後運行jigsawGUI.m文件即可運行(實現完整功能)。同時已將文件打包編程成exe的可執行文件,可在我的百度網盤中下載後直接運行。文件下載鏈接如下:

下載鏈接1:博文中涉及的完整程式文件
在這裡插入圖片描述
下載鏈接2:拼圖游戲打包的可執行EXE文件(已裝MATLAB的用戶下載)
鏈接:https://pan.baidu.com/s/1m0qLu3Un4jDT-NyQwFZs1g
提取碼:j906

下載鏈接3:拼圖游戲打包的可執行EXE文件(未裝MATLAB的用戶下載)
鏈接:https://pan.baidu.com/s/1uCMJI5O0FsnJKyoK4Lcvmw
提取碼:a1kb

公眾號獲取
    本人微信公眾號已創建,掃描以下二維碼並關註公眾號“AI技術研究與分享”,後臺回覆“JG20190508”即可獲取全部資源文件。


5. 結束語

    中篇的講述就是這麼多了,拼圖的更多功能的實現會在後面的博文中講述,大家也可以參考博主前面的一篇博文:基於MATLAB的拼圖游戲設計。由於博主能力有限,博文中提及的方法與代碼即使經過測試,也難免會有疏漏之處。希望您能熱心指出其中的錯誤,以便下次修改時能以一個更完美更嚴謹的樣子,呈現在大家面前。同時如果有更好的實現方法也請您不吝賜教。

    大家的點贊和關註是博主最大的動力,如果您想要獲取博文中的完整代碼文件,可通過C幣或積分下載,沒有C幣或積分的朋友可在關註、點贊博文後在評論區留下郵箱,我會在第一時間發送給您。

人工智慧博士,機器學習及機器視覺愛好者,公眾號主及B站UP主,專註專業知識整理與項目總結約稿、軟體項目開發、原理指導請聯繫微信:sixuwuxian(備註來意),郵箱:[email protected],微信公眾號:“AI技術研究與分享”。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、前情回顧 在討論迴流與重繪之前,我們要知道: 瀏覽器使用流式佈局模型 (Flow Based Layout)。 瀏覽器會把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合併就產生了Render Tree。 有了RenderTree,我們就知道了所有節點的樣式,然後計算他們在頁 ...
  • 今天我們來聊一個老生常談的話題,跨域!又是跨域,煩不煩 ?網上跨域的文章那麼多,跨的我眼睛都疲勞了,不看了不看了
  • 一篇文章帶你掌握主流服務層框架——SpringMVC 在之前的文章中我們已經學習了Spring的基本內容,SpringMVC隸屬於Spring的一部分內容 但由於SpringMVC完全針對於服務層使用,所以我們在介紹時常常把SpringMVC單獨當作一個大章節來學習 溫馨提醒:在學習SpringMV ...
  • 介紹了布隆過濾器的原理,結合分析guava框架如何實現JVM層面的布隆過濾器,參照guava編寫Redis實現的分散式布隆過濾器 ...
  • 本文詳細介紹Kmeans聚類演算法的原理和程式實現。首先介紹利用該演算法的原理及理解,詳細介紹基於MATLAB設計一個自定義的Kmeans函數過程,然後利用該函數對UCI的數據集進行聚類以測試聚類結果。代碼見文末介紹,後續章節將介紹的主要部分有:Kmeans演算法的原理與理解、基本原理、演算法流程、編程實現... ...
  • 什麼是API API (Application Programming Interface) :應用程式編程介面 java中的API 指的就是 JDK 中提供的各種功能的 Java類,這些類將底層的實現封裝了起來,我們不需要關心這些類是如何實現的,只需要學習這些類如何使用即可,我們可以通過幫助文檔來 ...
  • admin後臺管理 django給您提供了一個可視化圖形界面,來方便您來對資料庫里的表進行增刪改查的管理 但是!使用admin後臺管理你自己註冊的模型表時,需要自行進行先註冊該表! 在應用下的admin.py里進行註冊: from django.contrib import admin from a ...
  • Google翻譯大概是目前機器翻譯中翻譯最為準確的了,本文分別使用了兩種可行的方式編寫了簡易的谷歌翻譯軟體。將詳細介紹調用谷歌翻譯API和自行定義谷歌翻譯介面的方式,最後講解如何通過pyqt5實現軟體UI界面並附上全部程式文件。要點如下:調用Google翻譯API方式、自行定義谷歌翻譯介面方式、谷歌... ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...