⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matlab-russian.txt

📁 用MATLAB软件实现的一个经典游戏
💻 TXT
📖 第 1 页 / 共 4 页
字号:
end
   
% 按序号获得方块
switch(BlockIndex)
    case {1,2,3,4} % 方块
        BlockXArray = [0;0;1;1] * 20 - 10 ;
        BlockYArray = [0;1;1;0] * 20 - 10 ;
    case {5,6}     % 竖长条
        BlockXArray = [0;0;0;0] * 20 - 10 ;
        BlockYArray = [-1;0;1;2] * 20 - 10 ;
    case {7,8}     % 横长条
        BlockXArray = [-1;0;1;2] * 20 - 10 ;
        BlockYArray = [1;1;1;1] * 20 - 10 ;
    case {9}       % 4类T T1
        BlockXArray = [-1;0;1;0] * 20 - 10 ;
        BlockYArray = [1;1;1;0] * 20 - 10 ;
    case {10}      % T2
        BlockXArray = [0;0;1;0] * 20 - 10 ;
        BlockYArray = [2;1;1;0] * 20 - 10 ;
    case {11}      % T3
        BlockXArray = [0;0;1;-1] * 20 - 10 ;
        BlockYArray = [2;1;1;1] * 20 - 10 ;
    case {12}      % T4
        BlockXArray = [0;0;0;-1] * 20 - 10 ;
        BlockYArray = [2;1;0;1] * 20 - 10 ;
    case {13}      % 8类L L1
        BlockXArray = [0;0;0;1] * 20 - 10 ;
        BlockYArray = [1;0;-1;-1] * 20 - 10 ;
    case {14}      % L2
        BlockXArray = [-1;0;1;1] * 20 - 10 ;
        BlockYArray = [0;0;0;1] * 20 - 10 ;
    case {15}      % L3
        BlockXArray = [-1;0;0;0] * 20 - 10 ;
        BlockYArray = [1;1;0;-1] * 20 - 10 ;
    case {16}      % L4 
        BlockXArray = [-1;-1;0;1] * 20 - 10 ;
        BlockYArray = [-1;0;0;0] * 20 - 10 ;
    case {17}      % L5
        BlockXArray = [-1;0;0;0] * 20 - 10 ;
        BlockYArray = [-1;-1;0;1] * 20 - 10 ;
    case {18}      % L6
        BlockXArray = [-1;-1;0;1] * 20 - 10 ;
        BlockYArray = [1;0;0;0] * 20 - 10 ;
    case {19}      % L7
        BlockXArray = [0;0;0;1] * 20 - 10 ;
        BlockYArray = [-1;0;1;1] * 20 - 10 ;
    case {20}      % L8
        BlockXArray = [-1;0;1;1] * 20 - 10 ;
        BlockYArray = [0;0;0;-1] * 20 - 10 ;
    case {21 22}   % 4类Z Z1
        BlockXArray = [-1;0;0;1] * 20 - 10 ;
        BlockYArray = [1;1;0;0] * 20 - 10 ;
    case {23 24}   % Z2
        BlockXArray = [0;0;1;1] * 20 - 10 ;
        BlockYArray = [-1;0;0;1] * 20 - 10 ;
    case {25 26}   % Z3
        BlockXArray = [-1;0;0;1] * 20 - 10 ;
        BlockYArray = [0;0;1;1] * 20 - 10 ;
    case {27 28}   % Z4
        BlockXArray = [0;0;1;1] * 20 - 10 ;
        BlockYArray = [1;0;0;-1] * 20 - 10 ;
end

if nargin == 1
    % 产生的新方块
    NewBlockArray.BlockXArray = BlockXArray ;
    NewBlockArray.BlockYArray = BlockYArray ;
    NewBlockArray.BlockIndex = BlockIndex ;    
    % 方块先进入 下一个方块的提示窗中
    NextAxesXLim = get( handles.NextBlockAxes, 'XLim' ) ;
    NextAxesYLim = get( handles.NextBlockAxes, 'YLim' ) ;
    % 将方块置于提示窗中心
    set( handles.NextBlock, 'XData', [BlockXArray + 0.5 * diff( NextAxesXLim ) - ceil( sum( BlockXArray ) / 4 ) ],...
            'YData', [BlockYArray + 0.5 * diff( NextAxesYLim )] - ceil( sum( BlockYArray ) / 4 ) ) ;
    % 保存下提示窗中的方块
    setappdata( handles.RussiaBlock, 'BlockArray', NewBlockArray ) ;
    if isempty( BlockArray )
        % 在这个方块前,没有保存下的可以用于操作的方块,那么在随机获得一个方块(刚开始游戏时会产生这情况)
        Com_GetBlock( varargin{1} ) ;
    else
        % 将方块保存
        BlockXArray = BlockArray.BlockXArray ;
        BlockYArray = BlockArray.BlockYArray ;
        BlockIndex = BlockArray.BlockIndex ;
    end
    
end

% 获得主轴的范围
AxesXLim = getappdata( handles.RussiaBlock, 'XLim' ) ;
AxesYLim = getappdata( handles.RussiaBlock, 'YLim' ) ;

% 将方块放到主轴的正上方
BlockXArray = BlockXArray + 0.5 * diff( AxesXLim ) ; 
BlockYArray = BlockYArray + diff( AxesYLim ) ;


% -------------------------------------------------------------------------
function Status = test_MoveBlock( h, MoveMode ) 
% 方块移动

% 用于判断方块落底的状态值
Status = 1;

% 界面被关闭
if ~ishandle( h )
    return
end

% 提取所有句柄
handles = guidata( h ) ;

% 当前操作的方块
TempXData = get( handles.TempBlock, 'XData' ) ;
TempYData = get( handles.TempBlock, 'YData' ) ;
% TempFaceVertexCData = get( handles.BlockHandle, 'FaceVertexCData' ) ;
TempXData = TempXData';
TempYData = TempYData' ;

% 所有方块
TotalXData = get( handles.BlockHandle, 'XData' ) ;
TotalYData = get( handles.BlockHandle, 'YData' ) ;
% TotalFaceVertexCData = get( handles.BlockHandle, 'FaceVertexCData' ) ;
TotalXData = TotalXData' ;
TotalYData = TotalYData' ;

% 当前处理方块的位置
TempBlockPos = getappdata( handles.RussiaBlock, 'TempBlockPos' ) ;
if isempty( TempBlockPos ) 
    return
end

% 主轴的范围
AxesXLim = getappdata( handles.RussiaBlock, 'XLim' ) ;
AxesYLim = getappdata( handles.RussiaBlock, 'YLim' ) ;
 
switch MoveMode    
    case 'Left' % 左移动        
        if any( TempXData - 20 < AxesXLim(1) )
            % 已经到达最左
            return
        end
        % 假设将当前方块左移一格,看是否会与已存在的方块产生共同位置
        TestArray = ismember( [TempXData - 20, TempYData], [TotalXData, TotalYData], 'rows' ) ;
        
        if any( TestArray )
            % 将产生共同位置,无法进行移动
            return;
        else
            % 将方块左移
            set( handles.TempBlock, 'XData', TempXData - 20 ) ;
            TempBlockPos.LeftStep = TempBlockPos.LeftStep + 1 ;
            % 更新方块位置信息
            setappdata( handles.RussiaBlock, 'TempBlockPos', TempBlockPos ) ;
        end
    case 'Right' % 右移动
      if any( TempXData + 20 > AxesXLim(2) )
           % 已经到达最右
            return
      end
      % 假设将当前方块右移一格,看是否会与已存在的方块产生共同位置
      TestArray = ismember( [TempXData + 20, TempYData], [TotalXData, TotalYData], 'rows' ) ;
        if any( TestArray )
            % 将产生共同位置,无法进行移动
            return;
        else
            % 将方块右移
            set( handles.TempBlock, 'XData', TempXData + 20 ) ;
            TempBlockPos.LeftStep = TempBlockPos.LeftStep - 1 ;
            % 更新方块位置信息
            setappdata( handles.RussiaBlock, 'TempBlockPos', TempBlockPos ) ;
        end      
    case 'Down'     
        % 提取一个值,用于判断上次的方块落下后是否产生了满行
        ClearBlock = getappdata( handles.RussiaBlock, 'ClearBlock') ;
        if isempty(ClearBlock)
            % 空的,即上次的方块落下后没有产生满行
            ClearBlock = 0 ;
        end
        % 下落到了最低点
        if any( TempYData - 20 < AxesYLim(1) )
            % 上次并没有产生满行而现在总方块序列的最后一个与此次方块所在位置完全相同,这说明是因为重复响应键盘下移产生的重复累计,不记录
            if  ClearBlock == 0 && length(TotalXData) > 4 && isequal(TotalXData(end-3:end), TempXData) && isequal(TotalYData(end-3:end), TempYData)                 
                TotalXData = TotalXData ;
                TotalYData = TotalYData ;
            else % 是正常的落到底部,                
               TotalXData = [TotalXData; TempXData] ;
               TotalYData = [TotalYData; TempYData] ; 
               % 方块到底了,重置方块是否满行的信息
               setappdata( handles.RussiaBlock, 'ClearBlock', 0) ;
            end
            % 更新方块位置
            set( handles.BlockHandle, 'XData', TotalXData, 'YData', TotalYData );% 'FaceVertexCData', [TotalFaceVertexCData; TempFaceVertexCData] ) ;
            Status = 0 ;   
            return;
        end
        % 尝试下移一格,看是否会与已存在的方块产生共同位置
        TestArray = ismember( [TempXData, TempYData - 20], [TotalXData, TotalYData], 'rows' ) ;
        if any( TestArray ) % 将产生共同位置            
            if  ClearBlock == 0 && length(TotalXData) > 4 && isequal(TotalXData(end-3:end), TempXData) && isequal(TotalYData(end-3:end), TempYData)
                % 上次并没有产生满行而现在总方块序列的最后一个与此次方块所在位置完全相同,这说明是因为重复响应键盘下移产生的重复累计,不记录
                TotalXData = TotalXData ;
                TotalYData = TotalYData ;
            else % 是正常的落到底部
               TotalXData = [TotalXData; TempXData] ;
               TotalYData = [TotalYData; TempYData] ; 
               % 方块到底了,重置方块是否满行的信息
               setappdata( handles.RussiaBlock, 'ClearBlock', 0) ;
            end
            % 更新方块位置
            set( handles.BlockHandle, 'XData', TotalXData, 'YData', TotalYData );% 'FaceVertexCData', [TotalFaceVertexCData; TempFaceVertexCData] ) ;
            Status = 0 ;
        else
            % 方块下移
            set( handles.TempBlock, 'YData', TempYData - 20 ) ;
            TempBlockPos.DownStep = TempBlockPos.DownStep + 1 ;
            % 保存方块位置
            setappdata( handles.RussiaBlock, 'TempBlockPos', TempBlockPos ) ;
        end          
    case 'Drop'% 直接落下
        global PauseTime
        PauseTime = 0 ;
    case 'Change'
        global BlockIndex
        % 变形前方块序号
        OldBlockIndex = BlockIndex ;
        % 按方块序号得到变形后方块的序号
        switch BlockIndex
            case {1,2,3,4}
                return;
            case {5,6}
                NewIndex = 7 ;                
            case {7,8}
                NewIndex = 5 ;
            case {9,10,11,12}
                NewIndex = mod( OldBlockIndex, 4 ) + 9;
            case {13,14,15,16}
                NewIndex = mod( OldBlockIndex, 4 ) + 13;
            case {17,18,19,20}
                NewIndex = mod( OldBlockIndex, 4 ) + 17;
            case {21,22}
                NewIndex = 23;
            case {23,24}
                NewIndex = 21;
            case {25,26}
                NewIndex = 27 ;
            case {27,28}
                NewIndex = 25 ;
        end
        % 根据方块序号得到方块的位置
        [BlockXArray, BlockYArray] = Com_GetBlock( h, NewIndex ) ;
        % 方块的位置在正上方,需要按实际位置做偏移处理
        NewTempXData = BlockXArray - TempBlockPos.LeftStep * 20 ;
        NewTempYData = BlockYArray - TempBlockPos.DownStep * 20 ;
        % 变形后可能有方块跑出主轴边界
        if any( NewTempXData < AxesXLim(1) ) | any( NewTempXData > AxesXLim(2) ) |...
                any( NewTempYData < AxesYLim(1) )
            % 变形失败,中断变形
            BlockIndex = OldBlockIndex ;
            return;
        end
        % 变形后可能造成与已存方块的位置重合
        TestArray = ismember( [NewTempXData, NewTempYData], [TotalXData, TotalYData], 'rows' ) ;
        if any( TestArray )
             % 变形失败,中断变形
            BlockIndex = OldBlockIndex ;
        else
            % 变形成功,更新方块
            BlockIndex = NewIndex ;
            set( handles.TempBlock, 'XData', NewTempXData, 'YData', NewTempYData ) ;
        end        
end

% ------------------------------------------------------------
function PauseTime = GetPauseTimeByGameLevel( GameLevel )
% 根据游戏等级等到暂停时间

if isempty( GameLevel )
    PauseTime = 0.3 ;
else
    % 游戏等级的难易通过暂停时间的长短来决定
    PauseTime = ceil( 20 / GameLevel ) / 100 ;
end

% -------------------------------------------------------------------------
function UpdateGameLevel( FigureHandle, Score ) ;
% 更新游戏难度

% 简单的处理为每1万分加1级
GameLevel = ceil( Score / 10000 ) ;

% 旧难度
OldGameLevel = getappdata( FigureHandle, 'GameLevel' ) ;

% 积分还不够超过用户设置的难度
if GameLevel < OldGameLevel
    return ;
end

% 最高9级
if GameLevel > 9 
    GameLevel = 9 ;
end

setappdata( FigureHandle, 'GameLevel', GameLevel ) ;


% -------------------------------------------------------------------------
function UpdateHighScore( FigureHandle, Score ) ;
% 更新最高记录

% 记录
ScoreInfo = getappdata( FigureHandle, 'ScoreInfo') ;

% 这次游戏中所在名次
ScoreIndex = getappdata( FigureHandle, 'ScoreIndex' ) ;

if isempty(ScoreIndex)
    ScoreIndex = 4 ;
end
    
% 超过第三名,而且是第一次超过第三名
if Score > ScoreInfo(3).Score && ScoreIndex >= 3
    % 设置第三名
    ScoreInfo(3).Name = '游戏中';
    ScoreInfo(3).Score = Score;
    % 保存当前名次
    setappdata( FigureHandle, 'ScoreIndex', 3 ) ;
end

% 超过第二名,而且是第一次超过第二名
if Score > ScoreInfo(2).Score && ScoreIndex >= 2
    % 这个第二名不是这次创造的
    if ScoreIndex ~= 2
        % 第二名退到第三名
        ScoreInfo(3).Name = ScoreInfo(2).Name;
        ScoreInfo(3).Score = ScoreInfo(2).Score;
    end
    % 设置第二名
    ScoreInfo(2).Name = '游戏中';
    ScoreInfo(2).Score = Score;
    % 保存当前名次
    setappdata( FigureHandle, 'ScoreIndex', 2 ) ;
end

% 超过第一名
if Score > ScoreInfo(1).Score
    % 这个第一名不是这次创造的
    if ScoreIndex ~= 1
        % 第一名退到第二名
        ScoreInfo(2).Name = ScoreInfo(1).Name;
        ScoreInfo(2).Score = ScoreInfo(1).Score;
    end
    % 设置第一名
    ScoreInfo(1).Name = '游戏中';
    ScoreInfo(1).Score = Score;    
    % 保存当前名次
    setappdata( FigureHandle, 'ScoreIndex', 1 ) ;
end

% 保存
setappdata( FigureHandle, 'ScoreInfo', ScoreInfo ) ;


% ------------------------------------------------------------------------
function SetHighScorePlayerName( h, PlayerName ) 
% 修改最高记录的玩家名称

handles = guidata( h ) ;

if nargin == 1 
    PlayerName = '无名';
end

% 得到名次
ScoreIndex = getappdata( handles.RussiaBlock, 'ScoreIndex' ) ;

if isempty(ScoreIndex)
    return ;
end

% 记录
ScoreInfo = getappdata( handles.RussiaBlock, 'ScoreInfo') ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -