欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

matlab GUI制作拼图小游戏

程序员文章站 2022-05-21 17:50:29
...

matlab GUI制作拼图小游戏

最近帮同学的忙制作一个拼图贴上代码和效果图,以后再详细说明。之前一般找到的拼图游戏都是“推格子”形式的,由于具体的要求,不能应用这种模板。
本人这次做的拼图是这样的:从左边图点击,选择拼图,拼图位置变空,点击右边格子,相应位置补上刚刚选择的拼图。以下是效果图:

matlab GUI制作拼图小游戏




全部代码

function varargout =page_final(varargin)
% PAGE_FINAL MATLAB code for page_final.fig
%      PAGE_FINAL, by itself, creates a new PAGE_FINAL or raises the existing
%      singleton*.
%
%      H = PAGE_FINAL returns the handle to a new PAGE_FINAL or the handle to
%      the existing singleton*.
%
%      PAGE_FINAL('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PAGE_FINAL.M with the given input arguments.
%
%      PAGE_FINAL('Property','Value',...) creates a new PAGE_FINAL or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before page_final_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to page_final_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help page_final

% Last Modified by GUIDE v2.5 31-May-2019 03:54:26

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @page_final_OpeningFcn, ...
                   'gui_OutputFcn',  @page_final_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before page_final is made visible.
function page_final_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to page_final (see VARARGIN)

% Choose default command line output for page_final
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes page_final wait for user response (see UIRESUME)
% uiwait(handles.figure1);
global pic_data;
global rank_Tag;
global blank_pic;
global Tag;
global Tag1_changing;
global Tag2_changing;
global origin;
global redo;
redo=0;
%%tperiod是时间,redo是重做次数;
%pic_data=imread('dog.jpg');

%n=get(handles.popupmenu_rank,'value'); % 获取下拉选择框的值

rank_Tag=3;% 计算选择的拼图阶数
global h_time;
h_time=timer;   %定时器
 %将定时器放到全局变量中
%set(handles.he,'ExecutionMode','singleShot');  %定时器只执行一次,定一次时。
set(h_time,'ExecutionMode','fixedRate');   %定时器,循环执行,循环定时。
set(h_time,'Period',1);    %定时器,定时间隔 1秒
set(h_time,'TimerFcn',{@disptime,handles});    %定时器,定时会触发 TimerFcn 函数,定时函数(TimerFcn)触发用户自定义的函数(disptime函数)


function disptime(hObject, eventdata, handles)
set(handles.edit2,'String',datestr(now));   % 将edit控件的内容改成当前时间







function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% --- Executes during object creation, after setting all properties.
global count;
count=0;
global pic_data;
global rank_Tag;
global blank_pic;
global Tag;
global Tag1_changing;
global Tag2_changing;
global origin;
global redo;
redo=redo+1;
global h_time;
global t1;
global t2;

%这里初始化Tag2_changing,下面会初始化Tag和Tag1_changing;
Tag2_changing=zeros(rank_Tag,rank_Tag);

%每次点击都重新读图片
file_name=get(handles.edit1,'String');
if exist(file_name,'file')==0%如果没选图
    pic_data=imread('dog.jpg');%这个或许要改
else
    pic_data=imread(file_name);
end
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]);%imresize(A,行长,列长)
origin=pic_data;

%每次点击都重新读空图片
blank_pic=imread('blank_pic.jpg');

%变成和目标图一样大小
blank_pic=imresize(blank_pic,[rank_Tag*len_col rank_Tag*len_row]);
axes(handles.axes2); % 选定坐标轴
image(blank_pic) % 显示拼图



y=randperm(rank_Tag^2);
Tag=reshape(y,rank_Tag,rank_Tag);%这是乱序序tag_A
Tag1_changing=Tag;

%%%打乱原图
drawmap(Tag,handles.axes1,pic_data,origin,rank_Tag);

if(redo==1)
   start(h_time);%开启定时器 
   t1=clock;
   %time_record=datestr(now)
end
%%开始在右侧图点击
set(gcf,'windowButtonDownFcn',{@ButtonDownFcn,handles,rank_Tag}); % 点击鼠标时调用ButtonDownFcn函数,这里是figure监听




function ButtonDownFcn(src,event,handles,rank_Tag)
%% 回调函数,鼠标点击事件发生时调用

global Tag; % 全局变量声明
global Tag1_changing;
global dTag;
global blank_pic;
global origin;
global pic_data;

pt=get(handles.axes1,'CurrentPoint'); % 获取axes1中鼠标点击位置坐标,axes1的坐标大小是图片大小,实现下面col和row计算准确
xpos=pt(1,1); % 鼠标点击处的横坐标实际值
ypos=pt(1,2); % 鼠标点击处的纵坐标实际值

len_row=size(pic_data,1)/rank_Tag; % 每块拼图的宽度
len_col=size(pic_data,2)/rank_Tag; % 每块拼图的高度

%当前选择的是图片块Tag(row,col)
col = ceil(xpos/len_row); % 将横坐标值转换为列数,朝大方向取整
row = ceil(ypos/len_col); % 将纵坐标值转换为行数

%set(gcf, 'WindowButtonDownFcn', ''); %停止监听
if(col<=rank_Tag && col>0)&&(row<=rank_Tag && row>0) 
    set(handles.pushbutton1,'String','点击重来','ForegroundColor','r');
    dTag=Tag1_changing(row,col);%保留这里选择的块
    Tag1_changing(row,col)=0;    
    drawmap(Tag1_changing,handles.axes1,pic_data,origin,rank_Tag)
    set(gcf,'windowButtonDownFcn',{@ButtonDownFcn2,handles,rank_Tag});
else
    msgbox('点击位置异常,请选择右边拼图!!!'); % 提示完成信息
    return;
end


function ButtonDownFcn2(src,event,handles,rank_Tag)
%% 回调函数,鼠标点击事件发生时调用
global Tag; % 全局变量声明
global Tag1_changing;
global Tag2_changing;
global dTag;
global origin;
global count;
global pic_data;
global blank_pic;
global redo;
global time_record;
global h_time;
global t1;
global t2;
global tperiod;

pt=get(handles.axes2,'CurrentPoint'); % 获取axes1中鼠标点击位置坐标,axes1的坐标大小是图片大小,实现下面col和row计算准确
xpos=pt(1,1); % 鼠标点击处的横坐标实际值
ypos=pt(1,2); % 鼠标点击处的纵坐标实际值

len_row=size(blank_pic,1)/rank_Tag; % 每块拼图的宽度
len_col=size(blank_pic,2)/rank_Tag; % 每块拼图的高度

%当前选择的是图片块Tag(row,col)
col1 = ceil(xpos/len_row); % 将横坐标值转换为列数,朝大方向取整
row1= ceil(ypos/len_col); % 将纵坐标值转换为行数

% 判断鼠标点击位置是否在有效范围内 
if(col1<=rank_Tag && col1>0)&&(row1<=rank_Tag && row1>0)  
    Tag2_changing(row1,col1)=dTag;
    blank_pic=drawmap2(row1,col1,dTag,handles.axes2,blank_pic,origin,rank_Tag);
    count=count+1;
    
    if(count<9)
        set(gcf,'windowButtonDownFcn',{@ButtonDownFcn,handles,rank_Tag});
    else
        order=[1:1:rank_Tag^2];
        order=reshape(order,rank_Tag,rank_Tag);
        order=order';%[1 2 3;4 5 6;7 8 9]
        zt = abs(Tag2_changing-order); % 比较两个矩阵
        if sum(zt(:))==0 % 顺序已经完全吻合
            axes(handles.axes2)
            % 游戏完成,补全拼图
            image(origin) % 显示全图
            axes(handles.axes1)
            image(origin)
            stop(h_time);
            %time_record=datestr(now)
            t2=clock;
            tperiod=etime(t2,t1)
            a=['恭喜完成!!!您做了',num2str(redo),'次游戏'];
            msgbox(a) % 提示完成信息
            disp('****保存数据*******');
            %保存
            fid=fopen('C:\Users\user\Documents\pin_tu.csv','a+');
            fprintf(fid,'%s\n','拼图游戏');
            str=[string('游戏次数'),string('使用时间')];
            data=[redo,tperiod];
            for i=1:2
                 fprintf(fid,'%s,%f\n',str(i),data(i));
            end
            fprintf(fid,'%s\n',' ');
            fclose(fid);
            pause(5);
            close;
        else
            msgbox('很遗憾没成功,下次加油!!!') % 提示完成信息
            pause(3);
            set(gcf,'windowButtonDownFcn','');%重新游戏
            set(handles.pushbutton1,'String','点击重来','ForegroundColor','r'); 
        end
    end
else
    msgbox('点击位置异常,请把拼图放到左边适合的位置!!!');
    return %return是返回ButtonDownFcn2第一行
end



% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global pic_data; % 全局变量声明,flag决定是否能点击拼图 
global origin;
global rank_Tag;
% 弹出文件选择框,选择一张图片
[file,path] = uigetfile({'*.jpg;*.jpeg;*.png;*.bmp;*.tif',...
    '图片文件 (*.jpg,*.jpeg,*.png,*.bmp,*.tif)'},'选择一张图片');

if isequal(file,0) % 若文件不存在
   set(handles.edit1,'String','请选择一张图片');
else
   fileName= fullfile(path,file); % 选择的图片绝对路径,fullfile构成地址字符串;
   set(handles.edit1,'String',fileName); % 显示选择的图片路径
   pic_data=imread(fileName);
   % 确定每块拼图长宽
   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]);%imresize(A,行长,列长)
   origin=pic_data;

end


% --- Executes on button press in radiobutton1.
function radiobutton1_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of radiobutton1
% 根据选择情况决定是否显示数字标识
global pic_data; 
global rank_Tag;
global origin;

file_name=get(handles.edit1,'String');
if exist(file_name,'file')==0%如果没选图
    pic_data=imread('dog.jpg');%这个或许要改
else
    pic_data=imread(file_name);
end
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]);%imresize(A,行长,列长)
origin=pic_data;

ismask=get(handles.radiobutton1,'Value');%0是不选,不看原图
if(ismask)
    axes(handles.axes3);
    image(pic_data);
    %set(handles.axes3,'handlevisibility','off','visible','off');%坐标会自动调整为图片大小
else
    whole_col=size(pic_data,2);
    whole_row=size(pic_data,1);
    x=uint8(255*ones(whole_row,whole_col,3));% 拼图块0矩阵数据
    axes(handles.axes3);
    image(x);
    %set(handles.axes3,'handlevisibility','off','visible','off');
end