matlab俄罗斯方块下降,用MATLAB玩俄罗斯方块

偶然发现有人编写了用matlab玩俄罗斯方块的程序,测试了一下,果然可以用。但是我们的目的不是玩,而是学习这个编程的过程。其中各种方块的形状和颜色是用patch这个命令来完成的。方块用方向键控制,上方向键可以调整方块的形状。

function [STRUCT] = matlabtetris(varargin)

%MATLABTETRIS A MATLAB version of the classic game Tetris.

% The goal is to fill as many horizontal lines on the game board as

% possible by manipulating the pieces as they fall into place.  As more

% lines are filled, gameplay speeds up.  More points are awarded the more

% lines are filled at once, and as a function of the current level.

%

% Pushing the following keys has the listed effect:

%

% Key     Effect

% ------------------

% n       Starts a new game in the middle of any game.

% p       Pauses/Unpauses game play.

% s       Starts the new game (alternative to pushing the start button).

%

% Other tips:

%

% To move the piece, use the arrow keys.

% The up arrows rotates a piece clockwise, shift+up, counter clockwise.

% Clicking on the preview window hides/unhides the preview (next piece).

% Click on the level (1) before starting a game to choose start level.  If

% the first level is too slow, try starting out at a higher level, up to 9.

% The desired starting level may also be passed in as an argument when

% first calling the game.  For example,

%

%       matlabetetris(7)

%

% starts the game at level 7.

%

% Also, calling

%

%       A = matlabtetris;

%

% returns the handle/data structure.  Handles are lower-case, data

% uppercase.  This can be useful for troubleshooting, etc.

%

% This game changes the state of the random generator.

% This game tries to write the high score to a file named:

%

%       TETRIS_HIGH_SCORE.mat

%

% Author: Matt Fig

% Date: 1/11/2012

% Version 2.1

try

rng('shuffle');  % So each game is not the same! RNG is new in r2011a.

catch  %#ok

rand('twister',sum(100*clock));  %#ok Should work back to r2006a.

end

f_clr = [.741 .717 .42]; % Allows for easy change.  Figure color.

S.fig = figure('units','pixels',...

'name','Tetris',...

'menubar','none',...

'numbertitle','off',...

'position',[100 100 650 720],...

'color',f_clr,...

'keypressfcn',@fig_kpfcn2,...%

'closereq',@fig_clsrqfcn,...%

'busyaction','cancel',...

'renderer','opengl',...

'windowbuttondownfcn',@fig_wbdfcn,...

'resizefcn',@fig_rszfcn);

S.pbt = uicontrol('units','pix',...

'style','pushbutton',...

'position',[420 30 200 100],...

'fontweight','bold',...

'fontsize',20,...

'string','Start',...

'callback',@pbt_call,...

'enable','off',...

'busyaction','cancel');

S.axs = axes('units','pix',...

'position',[420 460 200 200],...

'ycolor',f_clr,...

'xcolor',f_clr,...

'color',f_clr,...

'xtick',[],'ytick',[],...

'xlim',[-.1 7.1],...

'ylim',[-.1 7.1],...

'visible','off'); % This axes holds the preview.

r_col = [.85 .95 1]; % The color of the rectangles.

S.rct = rectangle('pos',[0 0 7 7],...

'curvature',.3,...

'facecolor',r_col,...

'edgecolor','r',...

'linewidth',2); % This is used below the preview.

S.tmr = timer('Name','Tetris_timer',...

'Period',1,... % 1 second between moves time.

'StartDelay',1,... %

'TasksToExecute',50,... % Will be restarted many times.

'ExecutionMode','fixedrate',...

'TimerFcn',@game_step); % Function def. below.

S.axs(2) = axes('units','pix',...

'position',[410 130 220 320],...

'ycolor',f_clr,...

'xcolor',f_clr,...

'xtick',[],'ytick',[],...

'xlim',[-.1 1.1],...

'ylim',[-.1 1.1],...

'visible','off'); % Points/Lines holder

S.rct(2) = rectangle('pos',[0 0 1 1],...

'curvature',.3,...

'facecolor',r_col,...

'edgecolor','r',...

'linewidth',2); % Holds the current stats.

S.DSPDIG(1) = digits(35,5,-50,'Lines');

set(S.DSPDIG(1).ax,'pos',[500 170 0 0]+get(S.DSPDIG(1).ax,'pos'));

S.DSPDIG(2) = digits(35,8,10,'Points');

set(S.DSPDIG(2).ax,'pos',[438 260 0 0]+get(S.DSPDIG(2).ax,'pos'));

S.DSPDIG(3) = digits(35,3,-90,'Level');

set(S.DSPDIG(3).ax,'pos',[540 350 0 0]+get(S.DSPDIG(3).ax,'pos'));

set(S.DSPDIG(3).ax,'visible','on')

digits(S.DSPDIG(3),sprintf('%i',1))

S.axs(3) = axes('units','pix',...

'position',[30 30 360 630],...

'ycolor',f_clr,...

'xcolor',f_clr,...

'xtick',[],'ytick',[],...

'xlim',[-1 11],...

'ylim',[-1 20],...

'color',f_clr,...

'visible','off'); % The main board

% Template positions for the patch objects (bricks) in both axes.

X = [0 .2 0;.2 .8 .2;.2 .8 .8;.8 .2 .8;1 .2 1;0 .2 1;0 .2 0];

Y = [0 .2 0;.2 .2 .2;.8 .8 .2;.8 .8 .8;1 .2 1;1 .2 0;0 .2 0];

g1 = repmat([.9 .65 .4],[1,1,3]); % Grey color used throughout.

S.PRVPOS{1} = [1.5 2.5 3.5 4.5;3 3 3 3]; % Positions of the previews.

S.PRVPOS{2} = [2 3 3 4;2.5 2.5 3.5 2.5]; % 1-I,2-T,3-L,4-J,5-Z,6-S,7-O

S.PRVPOS{3} = [2 3 4 4;2.5 2.5 2.5 3.5];

S.PRVPOS{4} = [2 2 3 4;3.5 2.5 2.5 2.5];

S.PRVPOS{5} = [2 3 3 4;3.5 3.5 2.5 2.5];

S.PRVPOS{6} = [2 3 3 4;2.5 2.5 3.5 3.5];

S.PRVPOS{7} = [2.5 2.5 3.5 3.5;3.5 2.5 3.5 2.5];

% Make the board boarders.

for jj = [-1 10]

Xi = X + jj;

for ii = -1:19

patch(Xi,Y+ii,g1,...

'edgecolor','none',...

'handlevis','callback') % Don't need these handles.

end

end

for ii = 0:9

patch(X+ii,Y-1,g1,'edgecolor','none','handlevis','callback')

end

S.pch = zeros(10,20); % These hold the handles to the patches.

for jj = 0:19 % Make the board squares.

for ii = 0:9

if rand<.05 this simply puts random squares on the board.>

% If you have an older version without BSXFUN, use the second

% line below and comment out the first line below - IF ERROR.

R = bsxfun(@minus,.5 + rand(1,1,3)*.5,[0,.25,.5]); % See note!

% R = repmat(.5 + rand(1,1,3)*.5,[1,3,1])-repmat([0,.25,.5],[1,1,3]);

S.pch(ii+1,jj+1) = patch(X+ii,Y+jj,R,'edgecolor','none');

% drawnow   % On faster systems this can look neat.

else

S.pch(ii+1,jj+1) = patch(X+ii,Y+jj,'w','edgecolor','w');

end

end

end

% Hold the colors of the pieces, and board index where each first appears.

S.PCHCLR = {reshape([1 .75 .5 0 0 0 0 0 0],1,3,3),...

reshape([0 0 0 1 .75 .5 0 0 0],1,3,3),...

reshape([0 0 0 0 0 0 1 .75 .5],1,3,3),...

reshape([1 .75 .5 1 .75 .5 0 0 0],1,3,3),...

reshape([1 .75 .5 0 0 0 1 .75 .5],1,3,3),...

reshape([0 0 0 1 .75 .5 1 .75 .5],1,3,3),...

reshape([.5 .25 0 .5 .25 0 .5 .25 0],1,3,3)}; % Piece colors.

% S.PCHIDX holds the location where each piece first appears on the board.

S.PCHIDX = {194:197,[184 185 186 195],[184 185 186 196],...

[184 185 186 194],[194 195 185 186],[184 195 185 196],...

[185 186 195 196]};

S.MAKPRV = true;  % Make a preview or not.

S.CURPRV = []; % Holds current preview patches.

S.PRVNUM = []; % Holds the preview piece number, 1-7.

make_preview;  % Call the function which chooses the piece to go next.

S.BRDMAT = false(10,20); % The matrix game board.

S.CURROT = 1; % Holds the current rotation of the current piece.

S.PNTVCT = [40 100 300 800]; % Holds the points per number of lines.

S.CURLVL = 1; % The current level.

S.CURLNS = 0; % The current number of lines

S.STPTMR = 0; % Kills timer when user is pushing keyboard buttons.

S.SOUNDS = load('splat'); % Used for landing/line sound effect.

S.plr = audioplayer(S.SOUNDS.y,S.SOUNDS.Fs); % player for sounds.

S.CURSCR = 0; % Holds the current score during play.

S.PLRLVL = 1; % The level the player chooses to start...

% These next two dictate how fast the game increases its speed and also how

% many lines the player must score to go up a level, respectively.  The

% first value shoould be on (0,1].  Smaller values increase speed faster.

% No error handling is provided if you use bad values!

S.LVLFAC = .825;  % Percent of previous timerdelay.

S.CHGLVL = 5; % Increment level every S.CHGLVL lines.

if nargin && isnumeric(varargin{1})

S.PLRLVL = min(round(max(varargin{1},1)),9);  % Starting level.

digits(S.DSPDIG(3),sprintf('%i',S.PLRLVL))

end

try

SCR = load('TETRIS_HIGH_SCORE.mat');

S.CURHSC = SCR.SCR; % The user has a previous High Score.

catch  %#ok

S.CURHSC = 0;

end

set(S.fig,'name',['Tetris',' High Score - ', sprintf('%i',S.CURHSC)])

set([S.DSPDIG(:).ax,S.axs(:).',S.pbt,S.DSPDIG(:).tx],...

'units','norm','fontunits','norm')  % So we can resize the figure.

set(S.pbt,'enable','on') % Turn the game on now that we are ready...

if nargout

STRUCT = S; % Returns the structure if user requests.

end

function [] = make_preview(varargin)

% This function chooses which piece is going next and displays it.

if nargin

S.PRVNUM = varargin{1};

else

S.PRVNUM = ceil(rand*7); % Randomly choose one of the pieces.

end

if ~isempty(S.CURPRV)

delete(S.CURPRV) % Delete previous preview.

end

if S.MAKPRV

C = S.PCHCLR{S.PRVNUM};  % User wants to show the preview.

else

C = r_col;

end

for kk = 1:4  % Create a new preview.

S.CURPRV(kk) = patch(X+S.PRVPOS{S.PRVNUM}(1,kk),...

Y+S.PRVPOS{S.PRVNUM}(2,kk),...

C,'edgecolor','none',...

'parent',S.axs(1));

end

end

function [] = pbt_call(varargin)

% Callback for the 'Start' ('Pause', 'Continue') button.

switch get(S.pbt,'string')

case 'Start'

set(S.pch(:),'facecol','w','edgecol','w'); % Clear board.

set(S.pbt,'string','Pause'); % Changle pushbutton label.

digits(S.DSPDIG(3),sprintf('%i',S.PLRLVL)) % Show Level.

ND = round(1000*S.LVLFAC^(S.PLRLVL-1))/1000;% Update Timer.

set(S.tmr,'startdelay',ND,'period',ND);

digits(S.DSPDIG(2),sprintf('%i',0)) % Score and Lines

digits(S.DSPDIG(1),sprintf('%i',0))

S.CURLNS = 0; % New Game -> start at zero.

S.CURLVL = S.PLRLVL; % Set the level to players choice.

S.CURSCR = 0; % New Game -> start at zero.

play_tet; % Initiate Gameplay.

case 'Pause'

stop_tet;  % Stop the timer, set the callbacks

set([S.fig,S.pbt],'keypressfcn',@fig_kpfcn2)

set(S.pbt,'string','Continue')

case 'Continue'

set(S.pbt,'string','Pause')

start_tet;  % Restart the timer.

otherwise

end

end

function [] = play_tet()

% Picks a next piece and puts the preview in correct axes.

S.PNM = S.PRVNUM; % Hold this for keypresfcn.

S.CUR = S.PCHIDX{S.PRVNUM}; % Current loc. of current piece.

S.COL = S.PCHCLR{S.PRVNUM}; % Transfer correct color.

S.CURROT = 1; % And initial rotation number.

set(S.pch(S.CUR),'facec','flat','cdata',S.COL,'edgecol','none')

if any(S.BRDMAT(S.CUR))

disp('....Game over....')

clean_tet;  % Clean up the board.

set([S.fig,S.pbt],'keypressfcn',@fig_kpfcn2)

return

else

S.BRDMAT(S.CUR) = true; % Now update the matrix...

end

make_preview;  % Set up the next piece.

start_tet;     % Start the timer.

end

function [] = game_step(varargin)

% Timerfcn, advances the current piece down the board

if S.STPTMR && nargin  % Only timer calls with args...

return  % So that timer can't interrupt FIG_KPFCN!

end

col = ceil(S.CUR/10); % S.CUR defined in play_tet.

row = rem(S.CUR-1,10) + 1;  % These are for the board matrix.

if any(col==1)  % Piece is at the bottom of the board.

stop_tet;

check_rows;

play_tet;

else

ur = unique(row);  % Check to see if we can drop it down

for kk = 1:length(ur)

if (S.BRDMAT(ur(kk),min(col(row==ur(kk)))-1))

stop_tet;

check_rows;

play_tet;

return

end

end

mover(-10)  % O.k. to drop the piece... do it.

end

end

function [] = fig_kpfcn(varargin)

% Figure (and pushbutton) keypressfcn

S.STPTMR = 1;  % Stop timer interrupts.  See GAME_STEP

if strcmp(varargin{2}.Key,'downarrow')

game_step; % Just call another step.

S.STPTMR = 0;  % Unblock the timer.

return

end

col = ceil(S.CUR/10); % S.CUR defined in play_tet.

row = rem(S.CUR-1,10) + 1;  % These index into board matrix.

switch varargin{2}.Key

case 'rightarrow'

% Without this IF, the piece will wrap around!

if max(row)<=9

uc = unique(col);  % Check if object to the right.

for kk = 1:length(uc)

if (S.BRDMAT(max(row(col==uc(kk)))+1,uc(kk)))

S.STPTMR = 0;

return

end

end

mover(1)   % O.k. to move.

end

case 'leftarrow'

if min(row)>=2

uc = unique(col);  % Check if object to the left

for kk = 1:length(uc)

if (S.BRDMAT(min(row(col==uc(kk)))-1,uc(kk)))

S.STPTMR = 0;

return

end

end

mover(-1)  % O.k. to move.

end

case 'uparrow'

if strcmp(varargin{2}.Modifier,'shift')

arg = 1;  % User wants counter-clockwise turn.

else

arg = 0;

end

turner(row,col,arg);  % Turn the piece.

case 'p'

pbt_call;  % This will set to pause. Next set new ...

set([S.fig,S.pbt],'keypressfcn',@fig_kpfcn2)% Keypressfcn

case 'n'

quit_check;  % User might want to quit the game.

otherwise

end

S.STPTMR = 0;  % Unblock the timer.

end

function [] = fig_kpfcn2(varargin)

% Callback handles the case when 's' or 'p' is pressed if

% the game is paused or at game start.

tmp = strcmp(get(S.pbt,'string'),{'Start','Continue'});

if tmp(1)

if strcmp(varargin{2}.Key,'s')

pbt_call;  % User wants to start a game.

end

else

if tmp(2)

if any(strcmp(varargin{2}.Key,...

{'1','2','3','4','5','6','7'}))

make_preview(str2double(varargin{2}.Key));

return

end

end

if strcmp(varargin{2}.Key,'p')

pbt_call;  % User wants to pause/unpause.

end

if strcmp(varargin{2}.Key,'n')

quit_check;  % Perhaps user wants to quit.

end

end

end

function [] = mover(N)

% Common task. Moves a piece on the board.

S.BRDMAT(S.CUR) = false; % S.CUR, S.COL defined in play_tet.

S.BRDMAT(S.CUR+N) = true; % All checks should be done already.

S.CUR = S.CUR + N;

set([S.pch(S.CUR-N),S.pch(S.CUR)],...

{'facecolor'},{'w';'w';'w';'w';'flat';'flat';'flat';'flat'},...

{'edgecolor'},{'w';'w';'w';'w';'none';'none';'none';'none'},...

{'cdata'},{[];[];[];[];S.COL;S.COL;S.COL;S.COL})

end

function [] = turner(row,col,arg)

% Common task. Rotates the pieces once at a time.

% r is reading left/right, c is reading up/down.

% For the switch:  1-I,2-T,3-L,4-J,5-Z,6-S,7-O

switch S.PNM % Defined in play_tet.  Turn depends on shape.

case 1

if any(col>19) || all(col<=2)

return

else

if S.CURROT == 1;

r = [row(2),row(2),row(2),row(2)];

c = [col(2)-2,col(2)-1,col(2),col(2)+1];

S.CURROT = 2;

elseif all(row>=9)

r = 7:10;

c = [col(2),col(2),col(2),col(2)];

S.CURROT = 1;

elseif all(row==1)

r = 1:4;

c = [col(2),col(2),col(2),col(2)];

S.CURROT = 1;

else

r = [row(2)-1,row(2),row(2)+1,row(2)+2];

c = [col(2),col(2),col(2),col(2)];

S.CURROT = 1;

end

end

case 2

if sum(col==1)==3

return

end

if arg

S.CURROT = mod(S.CURROT+1,4)+1;

end

switch S.CURROT

case 1

r = [row(2),row(2),row(2),row(2)+1];

c = [col(2)-1,col(2),col(2)+1,col(2)];

case 2

if sum(row==1)==3

r = [1 2 3 2];

c = [col(2),col(2),col(2),col(2)-1];

else

r = [row(2)-1,row(2),row(2),row(2)+1];

c = [col(2),col(2),col(2)-1,col(2)];

end

case 3

r = [row(2)-1,row(2),row(2),row(2)];

c = [col(2),col(2),col(2)-1,col(2)+1];

case 4

if sum(row==10)==3

r = [9 9 8 10];

c = [col(2)+1,col(2),col(2),col(2)];

else

r = [row(2)-1,row(2),row(2),row(2)+1];

c = [col(2),col(2),col(2)+1,col(2)];

end

end

S.CURROT = mod(S.CURROT,4) + 1;

case 3

if sum(col==1)==3

return

end

if arg

S.CURROT = mod(S.CURROT+1,4)+1;

end

switch S.CURROT

case 1

r = [row(2),row(2),row(2),row(2)+1];

c = [col(2)+1,col(2),col(2)-1,col(2)-1];

case 2

if sum(row==1)==3

r = [1:3 1];

c = [col(2),col(2),col(2),col(2)-1];

else

r = [row(2)-1,row(2),row(2)-1,row(2)+1];

c = [col(2),col(2),col(2)-1,col(2)];

end

case 3

r = [row(2)-1,row(2),row(2),row(2)];

c = [col(2)+1,col(2),col(2)+1,col(2)-1];

case 4

if sum(row==10)==3

r = [10 9 10 8];

c = [col(2)+1,col(2),col(2),col(2)];

else

r = [row(2)-1,row(2),row(2)+1,row(2)+1];

c = [col(2),col(2),col(2),col(2)+1];

end

end

S.CURROT = mod(S.CURROT,4) + 1;

case 4

if sum(col==1)==3

return

end

if arg

S.CURROT = mod(S.CURROT+1,4)+1;

end

switch S.CURROT

case 1

r = [row(2),row(2),row(2),row(2)+1];

c = [col(2)-1,col(2),col(2)+1,col(2)+1];

case 2

if sum(row==1)==3

r = [1 2 3 3];

c = [col(2),col(2),col(2),col(2)-1];

else

r = [row(2)-1,row(2),row(2)+1,row(2)+1];

c = [col(2),col(2),col(2),col(2)-1];

end

case 3

r = [row(2)-1,row(2),row(2),row(2)];

c = [col(2)-1,col(2),col(2)-1,col(2)+1];

case 4

if sum(row==10)==3

r = [8 9 8 10];

c = [col(2)+1,col(2),col(2),col(2)];

else

r = [row(2)-1,row(2),row(2)-1,row(2)+1];

c = [col(2),col(2),col(2)+1,col(2)];

end

end

S.CURROT = mod(S.CURROT,4) + 1;

case 5

if any(col(2)>19) || sum(col==1)==2

return

elseif S.CURROT==1;

r = [row(2),row(2),row(2)-1,row(2)-1];

c = [col(2)+1,col(2),col(2),col(2)-1];

S.CURROT = 2;

else

if sum(row==10)==2

r = [10 9 9 8];

c = [col(2)-1,col(2)-1,col(2),col(2)];

else

r = [row(2)-1,row(2),row(2),row(2)+1];

c = [col(2),col(2),col(2)-1,col(2)-1];

end

S.CURROT = 1;

end

case 6

if any(col(2)>19)|| sum(col==1)==2

return

elseif S.CURROT==1;

r = [row(2)+1,row(2),row(2)+1,row(2)];

c = [col(2)-1,col(2),col(2),col(2)+1];

S.CURROT = 2;

else

if sum(row==1)==2

r = [1 2 2 3];

c = [col(2)-1,col(2)-1,col(2),col(2)];

else

r = [row(2)-1,row(2),row(2),row(2)+1];

c = [col(2)-1,col(2),col(2)-1,col(2)];

end

S.CURROT = 1;

end

otherwise

return % The O piece.

end

ind = r + (c-1)*10; % Holds new piece locations.

tmp = S.CUR; % Want to call SET last! S.CUR defined in play_tet.

S.BRDMAT(S.CUR) = false;

if any(S.BRDMAT(ind)) % Check if any pieces are in the way.

S.BRDMAT(S.CUR) = true;

return

end

S.BRDMAT(ind) = true;

S.CUR = ind; % S.CUR, S.COL defined in play_tet.

set([S.pch(tmp),S.pch(ind)],...

{'facecolor'},{'w';'w';'w';'w';'flat';'flat';'flat';'flat'},...

{'edgecolor'},{'w';'w';'w';'w';'none';'none';'none';'none'},...

{'cdata'},{[];[];[];[];S.COL;S.COL;S.COL;S.COL});

end

function [] = check_rows()

% Checks if any row(s) needs clearing and clears it (them).

TF = all(S.BRDMAT); % Finds the rows that are full.

if any(TF)  % There is a row that needs clearing.

set(S.pbt,'enable','off')  % Don't allow user to mess it up.

sm = sum(TF); % How many rows are there?

B = false(size(S.BRDMAT));  % Temp store to switcheroo.

B(:,1:20-sm) = S.BRDMAT(:,~TF);

S.BRDMAT = B;

TF1 = find(TF); % We only need to drop those rows above.

L = length(TF1);

TF = TF1-(0:L-1);

S.CURLNS = S.CURLNS + L;

digits(S.DSPDIG(1),sprintf('%i',S.CURLNS))  % Lines display

S.CURSCR = S.CURSCR+S.PNTVCT(L)*S.CURLVL;

digits(S.DSPDIG(2),sprintf('%i',S.CURSCR))  % Points display

play(S.plr,[6000 length(S.SOUNDS.y)])

for kk = 1:L % Make these rows to flash for effect.

set(S.pch(:,TF1(:)),'facecolor','r');

pause(.1)

set(S.pch(:,TF1(:)),'facecolor','g');

pause(.1)

end

for kk = 1:L % 'Delete' these rows.

set(S.pch(:,TF(kk):19),...

{'facecolor';'edgecolor';'cdata'},...

get(S.pch(:,TF(kk)+1:20),...

{'facecolor';'edgecolor';'cdata'}));

end

if (floor(S.CURLNS/S.CHGLVL)+1)>S.CURLVL % Level display check.

S.CURLVL = S.CURLVL + 1;

digits(S.DSPDIG(3),sprintf('%i',S.CURLVL))

ND = round(get(S.tmr,'startdelay')*S.LVLFAC*1000)/1000;

ND = max(ND,.001);

set(S.tmr,'startdelay',ND,'period',ND) % Update timer

end

if S.CURSCR>=S.CURHSC  % So that figure name is current.

S.CURHSC = S.CURSCR;

set(S.fig,'name',...

sprintf('Tetris High Score - %i',S.CURHSC))

end

set(S.pbt,'enable','on')  % Now user is o.k. to go.

else

if ~isplaying(S.plr)

play(S.plr,[7500 8500])  % Play our plunk sound.

end

end

end

function [] = clean_tet()

% Cleans up the board and board matrix after Game Over.

stop_tet;  % Stop the timer.

for kk = 1:20

set(S.pch(:,kk),'cdata',g1,'edgecol','none')

drawnow % Gives the nice effect of grey climbing up.

end

set(S.pbt,'string','Start')

S.BRDMAT(:) = false; % Reset the board matrix.

end

function [] = start_tet()

% Sets the correct callbacks and timer for a new game

set([S.fig,S.pbt],'keypressfcn',@fig_kpfcn)

start(S.tmr)

end

function [] = stop_tet()

% Sets the correct callbacks and timer to stop game

stop(S.tmr)

set([S.fig,S.pbt],'keypressfcn','fprintf('''')')

end

function [] = fig_clsrqfcn(varargin)

% Clean-up if user closes figure while timer is running.

try  % Try here so user can close after error in creation of GUI.

warning('off','MATLAB:timer:deleterunning')

delete(S.tmr)  % We always want the timer destroyed first.

warning('on','MATLAB:timer:deleterunning')

SCR = S.CURHSC;

try

save('TETRIS_HIGH_SCORE.mat','SCR')

catch  %#ok

disp('Unable to save high score. Check permissions.')

end

catch %#ok

end

delete(varargin{1})  % Now we can close it down.

end

function [] = fig_wbdfcn(varargin)

% The WindowButtonDownFcn for the figure.

if any(gco==[S.rct(1);S.CURPRV(:)]) % Clicked in preview window.

S.MAKPRV = ~S.MAKPRV;  % Change from current state.

if S.MAKPRV

set(S.CURPRV,'cdata',S.PCHCLR{S.PRVNUM},'facecolor','flat')

else

set(S.CURPRV,'facecolor',r_col)

end

elseif any(gco==[S.DSPDIG(3).ax [S.DSPDIG(3).P{:}]])

% In here user wants to select a starting level.

if strcmp(get(S.pbt,'string'),'Start')

tmp = inputdlg('Enter Starting Level',...

'Level',1,{sprintf('%i',S.PLRLVL)});

if ~isempty(tmp)  % User might have closed dialog.

S.PLRLVL = min(round(max(str2double(tmp),1)),9);

digits(S.DSPDIG(3),sprintf('%i',S.PLRLVL))

end

end

end

end

function [] = fig_rszfcn(varargin)

% The figure's resizefcn

pos = get(S.fig,'pos');  % Don't allow distorted shapes...

rat = 720/650; % This ratio will be hard-coded. Original pix size.

set(S.fig,'pos',[pos(1) pos(2) pos(4)/rat, pos(4)]);

end

function [] = quit_check()

% Creates a dialog box to check if the user wants to quit.

QG = questdlg('Are you sure you want to start over?',...

'End current game?', ...

'Yes', 'No', 'Yes');

if strcmp(QG,'Yes')

clean_tet;

% The call to UICONTROL is necessary if a line has

% just been scored and the user hits n to start a new

% game but not otherwise ... mysterious...

uicontrol(S.pbt)

pbt_call;

end

end

function [X] = digits(varargin)

% To create a display, pass in the pixel height desired, the number of

% digits to create, the offset of the text and string. To update the

% display, pass in a string representation of the number to display...

%

% Example:

% X = digits(80,2,0,'Points'); % 80 pix tall, 2 digits, 0 offset.

% for ii = 1:100,digits(X,sprintf('%i',ii)),pause(.1),end

if isstruct(varargin{1})

transcriber(varargin{1},varargin{2});  % Change display.

return

else

X.N = varargin{1}; % The pixel height of the numbers.

X.M = varargin{2}; % The number of numbers.

X.D = varargin{3}; % The offset of the text, in pixels.

X.T = varargin{4}; % The display label.

end

X.ax = axes('units','pix',...

'pos',[0,0,X.N/1.7*X.M,X.N],...

'xtick',[],'ytick',[],...

'xlim',[0,X.M],'ylim',[0,1.7],...

'color',r_col,...

'xcolor',r_col,...

'ycolor',r_col,...

'visible','off');  % Digits displayed on this axes.

X.tx = text('units','pixels',...

'pos',[X.D,X.N+10],...

'string',X.T,...

'backgroundc','none',...

'vertical','baselin',...

'fontw','bold',...

'fontname','fixedwidth',...

'fontsize',20,...

'color',[0.39216 .27059 .07451]);  % Create label.

% X.P holds the basic patch pattern as a template.

X.P{1}(1) = patch([.175 .275 .725 .825 .725 .275 .175],...

[.150 .050 .050 .150 .250 .250 .150],'k');

X.P{1}(2) = patch([.175 .275 .725 .825 .725 .275 .175],...

[.150 .050 .050 .150 .250 .250 .150]+.7,'k');

X.P{1}(3) = patch([.175 .275 .725 .825 .725 .275 .175],...

[.150 .050 .050 .150 .250 .250 .150]+1.4,'k');

X.P{1}(4) = patch([.150 .050 .050 .150 .250 .250 .150],...

[.175 .275 .725 .825 .725 .275 .175],'k');

X.P{1}(5) = patch([.150 .050 .050 .150 .250 .250 .150],...

[.175 .275 .725 .825 .725 .275 .175]+.7,'k');

X.P{1}(6) = patch([.150 .050 .050 .150 .250 .250 .150]+.70,...

[.175 .275 .725 .825 .725 .275 .175],'k');

X.P{1}(7) = patch([.150 .050 .050 .150 .250 .250 .150]+.70,...

[.175 .275 .725 .825 .725 .275 .175]+.70,'k');

set(X.P{1},'edgecolor','none')

for ww = 2:X.M

for yy = 1:7

X.P{ww}(yy) = patch('xdata',...

get(X.P{1}(yy),'xdata')+(ww-1),...

'ydata',get(X.P{1}(yy),'ydata'),...

'facecolor','k',...

'edgecolor','none');% Making digits!

end

end

X.PAT = {[1 3 4 5 6 7],... % 0.. Hold the pattern to each digit...

[6 7],...         % used as an index into X.P

[1 2 3 4 7],...   % 2

[1 2 3 6 7],...   % 3

[2 5 6 7],...     % 4

[1 2 3 5 6],...   % 5

[1 2 4 5 6],...   % 6

[3 6 7],...       % 7

1:7,...           % 8

[2 3 5 6 7]};     % 9

transcriber(X,'0')

function [] = transcriber(X,C)

% This deals with making the numbers. Nested to DIGITS.

if length(C)>X.M  % Display more digits than available!

C = repmat('9',1,X.M);

else

C = [repmat('!',1,X.M-length(C)),C];  % Pad them to left.

end

for xx = 1:X.M

set(X.P{xx}(:),'facecolor','none') % Clean it up first.

if ~strcmp('!',C(xx))

set(X.P{xx}(X.PAT{str2double(C(xx))+1}),...

'facecolor',[.1 .4 .1])  % Set correct display.

end

end

end

end

end

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值