📄 matlab-russian.txt
字号:
function varargout = RussiaBlock( varargin )
if nargin == 0
OldHandle = findobj( 'Type', 'figure', 'Tag', 'RussiaBlock' ) ;
if ishandle( OldHandle )
delete( OldHandle ) ;
end
FigureHandle = figure( 'Name', '俄罗斯方块MATLAB版', 'Tag', 'RussiaBlock', 'NumberTitle', 'off',...
'Menubar', 'none', 'DoubleBuffer', 'on', 'Resize', 'off', 'visible', 'off',...
'KeyPressFcn', 'RussiaBlock( ''KeyPress_Callback'', gcbo )',...
'HelpFcn', 'helpdlg(''帮不了你- -!'',''不好意思'')',...
'CloseRequestFcn', 'RussiaBlock( ''CloseFigure_Callback'', gcbo )' ) ;
generate_FigureContent( FigureHandle ) ;
init_FigureContent( FigureHandle ) ;
set( FigureHandle, 'Visible', 'on' ) ;
elseif ischar( varargin{1} )
if nargout == 0
feval( varargin{:} ) ;
else
[varargout{1:nargout}] = feval( varargin{:} ) ;
end
end
% -------------------------------------------------------------------------
function generate_FigureContent( FigureHandle )
TabSpace = 30 ;
BlockWidth = 20 ;
BlockHeight = 20 ;
FigureWidth = BlockWidth * (12 + 1) + TabSpace * 7;
FigureHeight = 500 ;
set( FigureHandle, 'Position', [0 0 FigureWidth FigureHeight] ) ;
movegui( FigureHandle, 'center' ) ;
% 创建菜单
BeginMenu = uimenu( FigureHandle, 'Label', '开始' ) ;
StartMenu = uimenu( BeginMenu, 'Label', '开始新游戏', 'Accelerator', 'N',...
'Callback', 'RussiaBlock( ''StartNewGame_Callback'', gcbo )');
SaveMenu = uimenu( BeginMenu, 'Label', '保存', 'Accelerator', 'S', 'Enable', 'on',...
'Separator', 'on', 'Cal', 'RussiaBlock( ''SaveGame_Callback'', gcbo )' );
LoadMenu = uimenu( BeginMenu, 'Label', '读取', 'Accelerator', 'L', 'Enable', 'on',...
'Cal', 'RussiaBlock( ''LoadGame_Callback'', gcbo )' );
QuitMenu = uimenu( BeginMenu, 'Label', '退出', 'Accelerator', 'Q', 'Separator', 'on', 'Cal', 'close(gcf)');
OperationMenu = uimenu( FigureHandle, 'Label', '功能' );
BoardConfigMenu = uimenu( OperationMenu, 'label', '键盘设置', 'Enable', 'on',...
'Cal', 'RussiaBlock( ''BoardConfig_Callback'', gcbo )' );
FigureConfigMenu = uimenu( OperationMenu, 'label', '界面设置', 'Enable', 'on');
uimenu( FigureConfigMenu, 'Label', '设置窗口颜色', 'Cal', 'RussiaBlock( ''WindowColor_Callback'', gcbo )' )
uimenu( FigureConfigMenu, 'Label', '设置背景图片', 'Cal', 'RussiaBlock( ''WindowPicture_Callback'', gcbo )' )
uimenu( FigureConfigMenu, 'Label', '设置方块颜色', 'Cal', 'RussiaBlock( ''BlockColor_Callback'', gcbo )' )
uimenu( FigureConfigMenu, 'Label', '恢复默认', 'Cal', 'RussiaBlock( ''Default_Callback'', gcbo )' )
HighScoreMenu = uimenu( OperationMenu, 'label', '最高记录', 'Separator', 'on',...
'Cal', 'RussiaBlock( ''HighScore_Callback'', gcbo )', 'Enable', 'on' );
GameLevelMenu = uimenu( OperationMenu, 'Label', '游戏难度',...
'Cal','RussiaBlock( ''GameLevel_Callback'', gcbo )' );
HelpMenu = uimenu( FigureHandle, 'Label', '帮助' );
AboutMenu = uimenu( HelpMenu, 'Label', '关于此软件', 'Cal', 'helpdlg(''俄罗斯方块MATLAB版------冰风漫天(制作)(2006/11/21)'',''关于此软件……'')');
HelpDlgMenu = uimenu( HelpMenu, 'Label', '游戏帮助', 'Separator', 'on', 'Cal', 'helpdlg(''帮不了你- -!'',''不好意思'')' );
% 创建工具条,图标可以用imread从图片读取,但图片不要太大
BeginTool = uipushtool( 'ToolTipString', '开始', 'CData', rand(16,16,3), 'Tag', 'BeginTool',...
'ClickedCallback', 'RussiaBlock( ''StartNewGame_Callback'', gcbo )' ) ;
PauseTool = uitoggletool( 'ToolTipString', '暂停', 'Tag', 'PauseTool', 'Tag', 'PauseTool',...
'CData', reshape( repmat( [1 1 0], 16, 16), [16,16,3] ),...
'ClickedCallback', 'RussiaBlock( ''PauseGame_Callback'', gcbo )' ) ;
% 创建游戏窗口
MainWindowXPos = TabSpace;
MainWindowYPos = TabSpace;
MainWindowWidth = BlockWidth * 12 ;
MainWindowHeight = BlockHeight * 22 ;
MainWindowPosition = [MainWindowXPos MainWindowYPos MainWindowWidth MainWindowHeight] ;
% 定义游戏窗口的右键菜单
AxesContextMenu = uicontextmenu( 'Tag', 'uicontextmenu' ) ;
uimenu( AxesContextMenu, 'Label', '设置窗口颜色', 'Cal', 'RussiaBlock( ''WindowColor_Callback'', gcbo )' )
uimenu( AxesContextMenu, 'Label', '设置背景图片', 'Cal', 'RussiaBlock( ''WindowPicture_Callback'', gcbo )' )
uimenu( AxesContextMenu, 'Label', '设置方块颜色', 'Cal', 'RussiaBlock( ''BlockColor_Callback'', gcbo )' )
uimenu( AxesContextMenu, 'Label', '恢复默认', 'Cal', 'RussiaBlock( ''Default_Callback'', gcbo )' )
MainAxes = axes( 'Units', 'pixels', 'Pos', MainWindowPosition, 'XTick', [], 'YTick',[], 'XTickLabel', [],...
'YTickLabel', [], 'Box', 'on', 'Tag', 'MainAxes', 'UicontextMenu', AxesContextMenu,...
'XLim', [0 MainWindowWidth], 'YLim', [0 MainWindowHeight] ) ;
hold on;
% 创建一个窗口用于显示下一个方块的图形
NextBlockWndXPos = MainWindowXPos + MainWindowWidth + TabSpace ;
NextBlockWndHeight = 4 * TabSpace + BlockHeight ;
NextBlockWndYPos = MainWindowYPos + MainWindowHeight - NextBlockWndHeight ;
NextBlockWndWidth = TabSpace * 4 + BlockWidth ;
NextBlockWndPosition = [NextBlockWndXPos NextBlockWndYPos NextBlockWndWidth NextBlockWndHeight] ;
NextBlockAxes = axes( 'Units', 'pixels', 'Pos', NextBlockWndPosition, 'XTick', [], 'YTick',[],...
'XTickLabel', [], 'YTickLabel', [], 'XLim', [0 NextBlockWndWidth],...
'YLim', [0 NextBlockWndHeight], ...
'Box', 'on', 'Tag', 'NextBlockAxes', 'Color', [0.85 0.85 0.85] ) ;
% 创建一组控件,包括(两个文本框用于显示当前方块数和成绩,两个按钮用于暂停和退出)
ButtonTag = { 'QuitButton', 'PauseButton', 'BlockNumText', 'ScoreText' } ;
ButtonStyle = { 'pushbutton', 'togglebutton', 'text', 'text' } ;
FontColor = { [0 0 0], [1 0 0], [0 0 1], [1 0 1] } ;
ButtonColor = { [0.7 0.8 0.9], [0.3 1 0.3], [0.5 1 1], [0.5 1 1] } ;
ButtonString = { '退出', '暂停', '方块数', '积分' };
ButtonCallback = { 'close(gcf)', 'RussiaBlock( ''ButtonPauseGame_Callback'', gcbo )', '', '' } ;
ButtonNumber = length( ButtonTag ) ;
ButtonWidth = NextBlockWndWidth ;
ButtonHeight = 50 ;
ButtonXPos = NextBlockWndXPos ;
ButtonYPos = MainWindowYPos + TabSpace ;
ButtonPosition = [ButtonXPos ButtonYPos ButtonWidth ButtonHeight] ;
ButtonTabSpace = (NextBlockWndYPos - 2 * TabSpace - ButtonHeight * ButtonNumber) / ButtonNumber ;
for num = 1: ButtonNumber
TempButtonPosition = ButtonPosition ;
TempButtonPosition(2) = ButtonPosition(2) + (num - 1) * (ButtonTabSpace + ButtonHeight);
if findstr( ButtonStyle{num}, 'button' )
TempButtonPosition(1) = TempButtonPosition(1) + 10 ;
TempButtonPosition(2) = TempButtonPosition(2) + 5 ;
TempButtonPosition(3) = TempButtonPosition(3) - 10 * 2 ;
TempButtonPosition(4) = TempButtonPosition(4) - 5 * 2 ;
else
TempButtonPosition(1) = TempButtonPosition(1) - 10 ;
TempButtonPosition(2) = TempButtonPosition(2) - 5 ;
TempButtonPosition(3) = TempButtonPosition(3) + 10 * 2;
TempButtonPosition(4) = TempButtonPosition(4) + 5 * 2 ;
end
ButtonHandle = uicontrol( 'Tag', ButtonTag{num}, 'Style', ButtonStyle{num}, 'Pos', TempButtonPosition,...
'Foregroundcolor', FontColor{num}, 'Backgroundcolor', ButtonColor{num},...
'Fontsize', 16, 'String', ButtonString{num}, 'Cal', ButtonCallback{num} ) ;
if findstr( ButtonStyle{num}, 'text' )
set( ButtonHandle, 'Max', 2 ) ;
end
if findstr( ButtonTag{num}, 'PauseButton' )
set( ButtonHandle, 'Enable', 'inactive', 'ButtonDownFcn', ButtonCallback{num}, 'Cal', '' ) ;
end
end
MainBlockAxes = axes( 'Units', 'pixels', 'Pos', MainWindowPosition, 'XTick', [], 'YTick',[], 'XTickLabel', [],...
'YTickLabel', [], 'Box', 'on', 'Tag', 'MainBlockAxes', 'Hittest', 'off',...
'XLim', [0 MainWindowWidth], 'YLim', [0 MainWindowHeight], 'Color', 'none' ) ;
% 线句柄,用于画所有方块
line( 'Visible', 'on', 'Tag', 'BlockHandle', 'Markersize', 18, 'Parent', MainBlockAxes, 'HitTest', 'off',...
'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', nan, 'YData', nan, 'LineStyle', 'none' ) ;
% 线句柄,用于画运动中的方块
line( 'Visible', 'off', 'Tag', 'TempBlock', 'Markersize', 18, 'Parent', MainBlockAxes, 'HitTest', 'off',...
'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', 130, 'YData', 30, 'LineStyle', 'none' ) ;
% 线句柄,用于绘制下一个将要落下的方块
line( 'Visible', 'off', 'Tag', 'NextBlock', 'Markersize', 18, 'Parent', NextBlockAxes, 'HitTest', 'off',...
'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', 30, 'YData', 30, 'LineStyle', 'none' ) ;
% patch( 'Visible', 'on', 'Tag', 'BlockHandle', 'Markersize', 18, 'Parent', MainBlockAxes, 'HitTest', 'off',...
% 'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', [nan nan nan nan], 'YData', [nan nan nan nan],...
% 'LineStyle', 'none', 'MarkerFaceColor', 'flat',...
% 'facecolor','none','FaceVertexCData', [1 0 0; 0 1 0; 0 0 1; 1 1 0] ) ;
% patch( 'Visible', 'off', 'Tag', 'TempBlock', 'Markersize', 18, 'Parent', MainBlockAxes, 'HitTest', 'off',...
% 'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', [nan nan nan nan], 'YData', [nan nan nan nan],...
% 'LineStyle', 'none', 'MarkerFaceColor', 'flat',...
% 'Facecolor','none' ,'FaceVertexCData', [1 0 0; 0 1 0; 0 0 1; 1 1 0] ) ;
% patch( 'Visible', 'off', 'Tag', 'NextBlock', 'Markersize', 18, 'Parent', NextBlockAxes, 'HitTest', 'off',...
% 'Marker', 's', 'MarkerEdgeColor', 'k', 'XData', [nan nan nan nan], 'YData', [nan nan nan nan],...
% 'LineStyle', 'none','MarkerFaceColor', 'flat',...
% 'Facecolor','none', 'FaceVertexCData', [1 0 0; 0 1 0; 0 0 1; 1 1 0] ) ;
% 设置坐标轴范围
setappdata( FigureHandle, 'XLim', [0 MainWindowWidth] )
setappdata( FigureHandle, 'YLim', [0 MainWindowHeight] )
% 保存句柄
handles = guihandles( FigureHandle ) ;
guidata( FigureHandle, handles ) ;
% -------------------------------------------------------------------------
function init_FigureContent( FigureHandle )
% 初始化界面
handles = guidata( FigureHandle ) ;
% 键盘设置
BoardConfig = [] ;
try
% 载入
BoardConfig = load('BoardConfig.mat') ;
catch
end
% 载入失败,重新生成
if isempty( BoardConfig )
% 键盘设置
BoardConfig = GetDefaultBoardConfig ;
else
BoardConfig = BoardConfig.BoardConfig;
end
% 用户设置的前后左右和直接下落键
setappdata( handles.RussiaBlock, 'BoardConfig', BoardConfig ) ;
% 颜色信息
ColorInfo = [] ;
try
% 载入
ColorInfo = load('ColorInfo.mat') ;
catch
end
% 载入失败,重新生成
if isempty( ColorInfo )
% 方块颜色
ColorInfo.BlockColor = GetDefaultBlockColor ;
% 背景颜色
ColorInfo.MainAxesColor = GetDefaultMainAxesColor ;
% 图片
ColorInfo.MainAxesImage.ImageData = [] ;
end
% 背景颜色设置
set( handles.MainAxes, 'Color', ColorInfo.MainAxesColor ) ;
if ~isempty( ColorInfo.MainAxesImage.ImageData )
% 画图片
ImageHandle = image( ColorInfo.MainAxesImage.ImageData, 'Parent', handles.MainAxes ) ;
set( ImageHandle, ColorInfo.MainAxesImage.Property ) ;
setappdata( FigureHandle, 'ImageData', ColorInfo.MainAxesImage.ImageData ) ;
end
% 方块颜色
set( handles.BlockHandle, 'MarkerFaceColor', ColorInfo.BlockColor ) ;
set( handles.TempBlock, 'MarkerFaceColor', ColorInfo.BlockColor ) ;
set( handles.NextBlock, 'MarkerFaceColor', ColorInfo.BlockColor ) ;
setappdata( FigureHandle, 'BlockColor', ColorInfo.BlockColor ) ;
% 颜色信息
ScoreInfo = [] ;
try
% 载入
ScoreInfo = load('ScoreInfo.mat') ;
catch
end
% 载入失败,重新生成
if isempty( ScoreInfo )
% 名称
ScoreInfo(1).Name = '无名' ;
% 分数
ScoreInfo(1).Score = 0 ;
% 前三名
ScoreInfo(2:3) = ScoreInfo(1) ;
else
ScoreInfo = ScoreInfo.ScoreInfo;
end
setappdata( FigureHandle, 'ScoreInfo', ScoreInfo ) ;
% ------------------------------------------------------------
function StartNewGame_Callback( h, StartType )
% 开始新游戏
% 得到所有句柄
handles = guidata( h ) ;
global PauseTime
if nargin == 1
% 初始化一些变量
StartType = 'NewStart' ;
setappdata( handles.RussiaBlock, 'BlockNumber', 0 ) ;
set( handles.BlockNumText, 'String', {'方块数','0'} ) ;
setappdata( handles.RussiaBlock, 'CurrentScore', 0 ) ;
set( handles.ScoreText, 'String', {'积分','0'} ) ;
set( handles.BlockHandle, 'XData', [nan nan nan nan], 'YData', [nan nan nan nan] ) ;
set( handles.TempBlock, 'XData', [nan nan nan nan], 'YData', [nan nan nan nan] ) ;
else
end
% 有条文本需要擦除(就是那条 GameOver 的 - -)
TextHandle = findobj( 'Parent', handles.MainBlockAxes, 'Type', 'text' ) ;
delete( TextHandle ) ;
% 重新开始游戏时,难度应该恢复为用户设置的难度
UseSetGameLevel = getappdata( handles.RussiaBlock, 'UseSetGameLevel' ) ;
if ~isempty(UseSetGameLevel)
setappdata( handles.RussiaBlock, 'GameLevel', UseSetGameLevel ) ;
end
set( handles.NextBlock, 'Visible', 'on' ) ;
set( handles.TempBlock, 'Visible', 'on' ) ;
% 既然开始了,快截工具条上的"暂停"按钮和界面上的"暂停"按钮都改弹起来了
set( handles.PauseTool, 'State', 'off' ) ;
set( handles.PauseButton, 'Value', 0 ) ;
% Y轴范围
YLim = get( handles.MainAxes, 'YLim' ) ;
% 只要界面没关,代码就一直在这循环内
while( ishandle( h ) )
if strcmp(StartType, 'NewStart')
% 所有目前存在的方块的Y值
TotalYData = get( handles.BlockHandle, 'YData' ) ;
% 有Y值太高,超过顶了,那么失败
if any( TotalYData >= YLim(2) )
% Game over
text( 20, 200, 'GameOver', 'Parent', handles.MainBlockAxes,...
'FontSize', 30, 'Color', 'r', 'FontAngle', 'italic' ) ;
% 排名
ScoreIndex = getappdata( handles.RussiaBlock, 'ScoreIndex' ) ;
if ~isempty(ScoreIndex)
% 提示输入姓名
PlayerName = inputdlg('名列前三,请输入大名:', '信息') ;
if ~isempty(PlayerName)
% 更新信息
SetHighScorePlayerName( handles.RussiaBlock, PlayerName{1} )
% 排名清除
setappdata( handles.RussiaBlock, 'ScoreIndex', [] ) ;
end
end
break;
end
% 至少有一个方块下落了以后
if length( TotalYData ) >= 4
% 得到所有存在方块的X值
TotalXData = get( handles.BlockHandle, 'XData' ) ;
% 最后一组(4个)方块,的Y值,这些Y值所在的行可能产生了满行,需要清楚并加分
LastBlockYData = TotalYData( end - 3: end ) ;
% 过滤重复Y值
LastBlockYData = unique( LastBlockYData ) ;
% 完成行的行号
CompleteLine = [] ;
% 完成行的那些方块在所有方块中的序号
UsefulIndex = [] ;
% 循环这些行
for num = 1: length( LastBlockYData )
% 在所有方块中找Y值与此行相同的
[YData, Index] = find( TotalYData == LastBlockYData(num) ) ;
% 满行是12个
if length( YData ) == 12
% 行号增加
CompleteLine = [CompleteLine, LastBlockYData(num)] ;
% 序号增加
UsefulIndex = [UsefulIndex, Index] ;
end
end
% 找到了满行的
if ~isempty( CompleteLine )
% 所有方块的数组中清除这些方块
TotalXData( UsefulIndex ) = [] ;
TotalYData( UsefulIndex ) = [] ;
% 这次清除的行数
LineNumber = length( CompleteLine ) ;
% 分数
ScoreArray = [100 300 600 1000] ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -