% 游戏名称:2048
% 实现的功能:2048基本游戏主体、分数显示、难度选择、历史记录、对应图片显示等
% 实现的功能:2048基本游戏主体、分数显示、难度选择、历史记录、对应图片显示等
% 完成时间:2018.06.24
@图片需另外下载或自己制作
function game2048() % 主函数
initialize() % 初始化
hardAndNumberProbability() % 选择初始化难度
dispdata() % 显示初始化结果
end
function initialize() % 初始化函数,生成界面以及初始化游戏
global griddata hb photo2048 score scoreHandle gameover; % 全局变量
griddata = zeros(4); % 初始化4X4矩阵数据
rand_i = randi(16);
griddata(rand_i) = 2; % 随机位置生成一个2
score = 0 ; % 初始化分数
gameover = 0; % 初始化游戏结束标志位
figHandle = figure('Name','2048','MenuBar','none',... % 生成主窗口
'ToolBar','none','NumberTitle','off',...
'Units','normalized', 'Position',[0.39 0.30 0.3 0.6],...
'KeyPressFcn',@keyevent);
for xi =0:15 % 生成4*4按钮矩阵
ix=rem(xi,4);
iy = fix((xi+0.5)/4);
uicontrol(figHandle,'Style','pushbutton',...
'Units','normalized','position',[ix*0.25 iy*0.20 0.245 0.195],'KeyPressFcn',@keyevent)
end
hb = findall(gcf, 'Style', 'pushbutton');% 获得16个方格的句柄值
photo2048 = struct('p2',{imread('2.jpg')},'p4',{imread('4.jpg')},'p8',{imread('8.jpg')},... % 读取显示的图片
'p16',{imread('16.jpg')},'p32',{imread('32.jpg')},'p64',{imread('64.jpg')},...
'p128',{imread('128.jpg')},'p256',{imread('256.jpg')},'p512',{imread('512.jpg')},...
'p1024',{imread('1024.jpg')},'p2048',{imread('2048.jpg')},'p4096',{imread('4096.jpg')},...
'p8192',{imread('8192.jpg')});
% 这里需要导入图片
uicontrol(figHandle,'Style','text','Units','normalized',... % 生成2048标志
'Position',[0.01,0.81,0.3 0.15],'String','2048@',...
'FontSize',25,'FontName','微软雅黑');
uicontrol(figHandle,'Style','text','Units','normalized',... % 生成分数标志
'Position',[0.35 0.81 0.18 0.07],'String','分数:','FontSize',18);
scoreHandle = uicontrol(figHandle,'Style','pushbutton','Units','normalized',...
'Position',[0.51,0.81,0.24 0.09],'String','0','FontSize',15,'KeyPressFcn',@keyevent); % 生成分数显示框
uicontrol(figHandle,'Style','pushbutton','Units','normalized',...
'Position',[0.75 0.9 0.245 0.09],'String','历史记录','FontSize',13,'Callback',@file,'KeyPressFcn',@keyevent) % 生成历史记录按钮
uicontrol(figHandle,'Style','pushbutton','Units','normalized',...
'Position',[0.75 0.81 0.245 0.09],'String','选择难度',...
'FontSize',13,'Callback',@hardAndNumberProbability,'KeyPressFcn',@keyevent) % 生成选择难度按钮
uicontrol(figHandle,'Style','pushbutton','Units','normalized',... % 生成重新游戏按钮
'Position',[0.51,0.9,0.24,0.09],'String','从新开始游戏',...
'FontSize',13,'Callback',@reset,'KeyPressFcn',@keyevent)
end
function hardAndNumberProbability(hObject,handles) % 难度判断及2.4.8出现的概率
global hardPop hardOption;
hardOption = dialog('Name','难度选择','Units','normalized','Position',[0.43 0.45 0.12 0.10]); % 难度选择
hardPop = uicontrol(hardOption,'Style','popupmenu','Units','normalized',... % 弹出式菜单
'Position',[0.31 0.5 0.4 0.4],'String',{'简单','中等','困难'},...
'FontSize',20);
hardPush = uicontrol(hardOption,'Style','pushbutton','Units','normalized',... % 确定按钮
'position',[0.3 0.05 0.4 0.32],'String','确定','FontSize',20,'Callback',@pushCallback);
end
function pushCallback(hObject,handles) % 难度选择 确定按钮 回调函数
global hardPop hardOption hardNum
hardNum = get(hardPop,'Value');
close(hardOption)
end
function keyevent(~, event) % 检测键盘输入和数组合并 最重要
global griddata gameover;
oldgriddata = griddata; % 判断数组是否相等,以判别存在不能移动但又不是游戏结束的情况
switch event.Key
case 'uparrow'
disp('上键')
hasBeenChangeData=standardRightSlip(rot90(griddata,-1));
griddata = rot90(hasBeenChangeData);
case 'leftarrow'
disp('左键')
hasBeenChangeData = standardRightSlip(flip(griddata,2));
griddata = flip(hasBeenChangeData,2);
case 'downarrow'
disp('下键')
hasBeenChangeData=standardRightSlip(rot90(griddata));
griddata = rot90(hasBeenChangeData,-1);
case 'rightarrow'
disp('右键')
griddata=standardRightSlip(griddata);
case 'escape'
return
otherwise
return
end
if isequal(oldgriddata,griddata) % 判断数组是否相等,以判别存在不能移动但又不是游戏结束的情况
else
randNum(); % 调用随机生成数字函数
end
dispdata() % 调用显示函数
if gameover ==0
gameoverFun() % 调用检测游戏状态函数
end
end
function griddata = standardRightSlip(griddata) % 标准右滑动,数据合并
global score
for iix = 1:4
rowData = griddata(iix,:);
rowData = rowData(rowData>0);
lenRow = length(rowData);
switch lenRow
case 0
griddata(iix,:) = [0 0 0 0];
case 1
griddata(iix,:) = cat(2,[0 0 0],rowData);
case 2
if rowData(1) == rowData(2)
rowData(2) = rowData(1)+rowData(2);
score = score + rowData(2);
rowData(1) = 0;
end
griddata(iix,:) = cat(2,[0 0],rowData);
case 3
if rowData(2) == rowData(3)
rowData(3) = rowData(2)+rowData(3);
score = score + rowData(3);
rowData(2) = [];
griddata(iix,:) = cat(2,[0 0],rowData);
continue;
elseif rowData(1) == rowData(2)
rowData(2) = rowData(1)+rowData(2);
score = score + rowData(2);
rowData(1) = 0;
griddata(iix,:) = cat(2,[0],rowData);
else
griddata(iix,:) = cat(2,[0],rowData);
end
case 4
if rowData(3) == rowData(4)
rowData(4) = rowData(3)+ rowData(4);
score = score + rowData(4);
rowData(3) = [];
if rowData(1) == rowData(2)
rowData(2) = rowData(1)+rowData(2);
score = score + rowData(2);
rowData(1) = [];
griddata(iix,:) = cat(2,[0 0],rowData);
continue
else
griddata(iix,:) = cat(2,[0],rowData);
continue
end
elseif rowData(2) == rowData(3)
rowData(3) = rowData(2)+rowData(3);
score = score + rowData(3);
rowData(2) = [];
griddata(iix,:) = cat(2,[0],rowData);
continue
elseif rowData(1) == rowData(2)
rowData(2) = rowData(1)+rowData(2);
score = score + rowData(2);
rowData(1) = [];
griddata(iix,:) = cat(2,[0],rowData);
end
otherwise
errordlg('程序存在BUG!','错误!')
end
end
end
function randNum() % 随机生成数字函数
global griddata hardNum;
yxx=[];
for ix = 1:16
if griddata(ix) < 1
yxx=[yxx;ix];
end
end
hh = randi(length(yxx));
bb = randi(100);
if hardNum == 1
griddata(yxx(hh))= 2;
elseif hardNum == 2
if bb >= 70
griddata(yxx(hh))= 4;
else
griddata(yxx(hh))= 2;
end
elseif hardNum == 3
if bb >= 80
griddata(yxx(hh))= 8;
elseif bb>=50
griddata(yxx(hh))= 4;
else
griddata(yxx(hh))= 2;
end
end
end
function gameoverFun() % 判断游戏是否结束及选择后续操作
global griddata gameover score;
for ie = 1:4
hand = griddata(ie,:);
lie = griddata(:,ie);
if ~isempty(hand(hand == 0)) || ~isempty(lie(lie == 0))
gameover = 0;
break
elseif hand(1) == hand(2) || hand(2) == hand(3) || hand(3) == hand(4)
gameover = 0;
break
elseif lie(1) == lie(2) || lie(2) == lie(3) || lie(3) == lie(4)
gameover = 0;
break
else
if ie ==4
gameover = 1;
end
end
end
if gameover == 1
player = inputdlg('请输入的你的名字:(如果不输入则随机)');
fileHandle = fopen('记录.txt','at');
a = strcat('玩家:',player,'--','分数:',num2str(score),'\n');
a = char(a);
fprintf(fileHandle,a);
fclose(fileHandle);
overSelection = questdlg('Game Over!!! 是否从新开始游戏?','游戏结束','重新开始','结束游戏','查看分数记录','重新开始');
if strcmp(overSelection,'重新开始')
reset()
elseif strcmp(overSelection,'结束游戏')
close all
elseif strcmp(overSelection,'查看分数记录')
file()
end
end
end
function dispdata() % 对应相应的数字显示图片到按钮上
global griddata hb photo2048 scoreHandle score;
dispGriddata = rot90(griddata);
set(hb,'CData',[])
set(scoreHandle,'String',num2str(score)) % 显示分数
for ix =1:16
switch dispGriddata(ix)
case 2
set(hb(ix),'CData',photo2048.p2)
case 4
set(hb(ix),'CData',photo2048.p4)
case 8
set(hb(ix),'CData',photo2048.p8)
case 16
set(hb(ix),'CData',photo2048.p16)
case 32
set(hb(ix),'CData',photo2048.p32)
case 64
set(hb(ix),'CData',photo2048.p64)
case 128
set(hb(ix),'CData',photo2048.p128)
case 256
set(hb(ix),'CData',photo2048.p256)
case 512
set(hb(ix),'CData',photo2048.p512)
case 1024
set(hb(ix),'CData',photo2048.p1024)
case 2048
set(hb(ix),'CData',photo2048.p2048)
case 4096
set(hb(ix),'CData',photo2048.p4096)
case 8192
set(hb(ix),'CData',photo2048.p8192)
end
end
end
function reset(hObject,handles) % 重置游戏
global griddata score gameover;
griddata = zeros(4); % 初始化4X4矩阵数据
rand_i = randi(16);
griddata(rand_i) = 2;
score = 0 ;
gameover = 0;
dispdata()
end
function file(hObject,handles) % 显示排行榜
fileHandle = fopen('记录.txt','rt');
b=textscan(fileHandle,'%s');
b=char(b{1});
rankingList = figure('Name','排行榜','MenuBar','none','ToolBar','none','NumberTitle','off');
axeshandle = axes(rankingList);
axis off
text(axeshandle,'String',b,'Position',[0.05 0.7],'Units','normalized')
fclose(fileHandle);
end