1. 程式人生 > >sEMG專案總結(4)康復手上位機系統

sEMG專案總結(4)康復手上位機系統

康復手上位機系統

目錄

1串列埠通訊

這裡寫圖片描述

%%主函式:註釋說明和視窗初始化
function varargout = serial_communication2(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @serial_communication2_OpeningFcn, ...
                   'gui_OutputFcn'
, @serial_communication2_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 %%子函式OpeningFcn開啟視窗時的初始化程式 function serial_communication2_OpeningFcn(hObject, eventdata, handles, varargin) handles.output = hObject; warning('off'); javaFrame = get(hObject, 'JavaFrame'); javaFrame.setFigureIcon(javax.swing.ImageIcon('mll.png')); %% 初始化引數 hasData = false
; %表徵串列埠是否接收到資料 isShow = false; %表徵是否正在進行數顯示,即是否正在執行函式dataDisp isStopDisp = false; %表徵是否按下了【停止顯示】按鈕 isHexDisp = false; %表徵是否勾選了【十六進位制顯示】 isHexSend = false; %表徵是否勾選了【十六進位制傳送】 numRec = 0; %接收字元計數 numSend = 0; %傳送字元計數 strRec = ''; %已接收的字串 %% 將上述引數作為應用資料,存入視窗物件內 setappdata(hObject, 'hasData', hasData); setappdata(hObject, 'strRec', strRec); setappdata(hObject, 'numRec', numRec); setappdata(hObject, 'numSend', numSend); setappdata(hObject, 'isShow', isShow); setappdata(hObject, 'isStopDisp', isStopDisp); setappdata(hObject, 'isHexDisp', isHexDisp); setappdata(hObject, 'isHexSend', isHexSend); guidata(hObject, handles); %%OutputFcn函式是視窗的輸出子函式 function varargout = serial_communication2_OutputFcn(hObject, eventdata, handles) varargout{1} = handles.output; %%串列埠回撥函式 function com_Callback(hObject,~, handles) %%在com物件產生過程中執行的回撥函式 function com_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %%波特率回撥函式 function rate_Callback(hObject, eventdata, handles) function rate_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %%校驗位回撥函式 function jiaoyan_Callback(hObject, eventdata, handles) function jiaoyan_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %%資料位回撥函式 function data_bits_Callback(hObject, eventdata, handles) function data_bits_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %%停止位回撥函式 function stop_bits_Callback(hObject, eventdata, handles) function stop_bits_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %% (1) 【開啟/關閉串列埠】按鈕的回撥函式 %% 開啟串列埠,並初始化相關引數 function start_serial_Callback(hObject, eventdata, handles) %% 若按下【開啟串列埠】按鈕,開啟串列埠 if get(hObject, 'value') com_n = sprintf('com%d', get(handles.com, 'value')); %% 獲取串列埠的埠名 rates = [300 600 1200 2400 4800 9600 19200 38400 43000 56000 57600 115200]; baud_rate = rates(get(handles.rate, 'value')); %% 獲取波特率 %% 獲取校驗位設定 switch get(handles.jiaoyan, 'value') case 1 jiaoyan = 'none'; case 2 jiaoyan = 'odd'; case 3 jiaoyan = 'even'; end data_bits = 5 + get(handles.data_bits, 'value'); %% 獲取資料位個數 stop_bits = get(handles.stop_bits, 'value'); %% 獲取停止位個數 %% 建立串列埠物件 scom = serial(com_n); scom %% 配置串列埠屬性,指定其回撥函式 配置串列埠屬性,指定其回撥函式 set(scom, 'BaudRate', baud_rate, 'Parity', jiaoyan, 'DataBits',... %BytesAvailableFcnCount:位元組計數 data_bits, 'StopBits', stop_bits, 'BytesAvailableFcnCount', 10,... %BytesAvailableFcn:位元組計數回撥函式 'BytesAvailableFcnMode', 'byte', 'BytesAvailableFcn', {@bytes, handles},...%BytesAvailableFcnMode:位元組模式,一般byte 'TimerPeriod', 0.05, 'TimerFcn', {@dataDisp, handles}); %TimerFcn:定時回撥函式,TimerPeriod:定時週期,串列埠資料通訊 %% 將串列埠物件的控制代碼作為使用者資料,存入視窗物件 set(handles.figure1, 'UserData', scom); %% 嘗試開啟串列埠 try %執行過程中如果出錯,執行catch下的語句 fopen(scom); %開啟串列埠 catch % 若串列埠開啟失敗,提示“串列埠不可獲得!” msgbox('串列埠不可獲得,未連線外設!'); set(hObject, 'value', 0); %彈起本按鈕 return; end %% 開啟串列埠後,允許串列埠傳送資料,清空接收顯示區,點亮串列埠狀態指示燈 %% 並更改本按鈕文字為“關閉串列埠” set(handles.period_send, 'Enable', 'on'); %啟用【自動傳送】按鈕 set(handles.manual_send, 'Enable', 'on'); %啟用【手動傳送】按鈕 set(handles.xianshi, 'string', ''); %清空接收顯示區 % set(handles.activex1, 'value', 1); %點亮串列埠狀態指示燈 set(hObject, 'String', '關閉串列埠'); %設定本按鈕文字為“關閉串列埠” else %若關閉串列埠 %% 停止並刪除定時器 t = timerfind; %查詢定時器 if ~isempty(t) stop(t); delete(t); end %% 停止並刪除串列埠物件 scoms = instrfind; %在記憶體查詢串列埠物件 stopasync(scoms); %停止非同步讀寫 fclose(scoms); delete(scoms); %% 禁用【自動傳送】和【手動傳送】按鈕,熄滅串列埠狀態指示燈 set(handles.period_send, 'Enable', 'off', 'value', 0); %禁用【自動傳送】按鈕 set(handles.manual_send, 'Enable', 'off'); %禁用【手動傳送】按鈕 set(hObject, 'value', 0); %彈起本按鈕 set(hObject, 'String', '開啟串列埠'); %設定本按鈕文字為“關閉串列埠” % set(handles.activex1, 'value', 0); %熄滅串列埠狀態指示燈 end %%(2) 串列埠資料顯示,串列埠的TimerFcn回撥函式 function dataDisp(obj, event, handles) %% 獲取引數 hasData = getappdata(handles.figure1, 'hasData'); %串列埠是否收到資料 strRec = getappdata(handles.figure1, 'strRec'); %串列埠接收的字串,定時顯示該資料 numRec = getappdata(handles.figure1, 'numRec'); %串列埠接收到的資料個數 %% 若串列埠沒有接收到資料,先嚐試接收串列埠資料 if ~hasData bytes(obj, event, handles); end %% 若串列埠有資料,顯示串列埠資料 if hasData %% 給資料顯示模組加互斥鎖 %% 在執行顯示資料模組時,不接受串列埠資料,即不執行BytesAvailableFcn回撥函式 setappdata(handles.figure1, 'isShow', true); %% 若要顯示的字串長度超過10000,清空顯示區 if length(strRec) > 10000 strRec = ''; setappdata(handles.figure1, 'strRec', strRec); end %% 顯示資料 set(handles.xianshi, 'string', strRec); %% 更新接收計數 set(handles.rec,'string', numRec); %% 更新hasData標誌,表明串列埠資料已經顯示 setappdata(handles.figure1, 'hasData', false); %% 給資料顯示模組解鎖 setappdata(handles.figure1, 'isShow', false); end %% (3) 串列埠接收資料,串列埠的BytesAvailableFcn回撥函式(位元組計數回撥函式) function bytes(obj, ~, handles) %% 獲取引數 strRec = getappdata(handles.figure1, 'strRec'); %獲取串列埠要顯示的資料 numRec = getappdata(handles.figure1, 'numRec'); %獲取串列埠已接收資料的個數 isStopDisp = getappdata(handles.figure1, 'isStopDisp'); %是否按下了【停止顯示】按鈕 isHexDisp = getappdata(handles.figure1, 'isHexDisp'); %是否十六進位制顯示 isShow = getappdata(handles.figure1, 'isShow'); %是否正在執行顯示資料操作 %% 若正在執行資料顯示操作,暫不接收串列埠資料 if isShow return; end %% 獲取串列埠可獲取的資料個數 n = get(obj, 'BytesAvailable'); %% 若串列埠有資料,接收所有資料 if n %% 更新hasData引數,表明串列埠有資料需要顯示 setappdata(handles.figure1, 'hasData', true); %% 讀取串列埠資料 a = fread(obj, n, 'uchar'); %從obj中讀出n個數據,8位無符號讀出 %% 若沒有停止顯示,將接收到的資料解算出來,準備顯示 if ~isStopDisp %% 根據進位制顯示的狀態,解析資料為要顯示的字串 if ~isHexDisp c = char(a'); else strHex = dec2hex(a')'; strHex2 = [strHex; blanks(size(a, 1))]; c = strHex2(:)'; end %% 更新已接收的資料個數 numRec = numRec + size(a, 1); %size(a,1)返回矩陣 a 的行數 %% 更新要顯示的字串 strRec = [strRec c]; end %% 更新引數 setappdata(handles.figure1, 'numRec', numRec); %更新已接收的資料個數 setappdata(handles.figure1, 'strRec', strRec); %更新要顯示的字串 end %% (4)清空要顯示的字串 function qingkong_Callback(hObject, eventdata, handles) setappdata(handles.figure1, 'strRec', ''); set(handles.xianshi, 'String', '');%% 清空顯示 %% (5)根據【停止顯示】按鈕的狀態,更新isStopDisp引數 function stop_disp_Callback(hObject, eventdata, handles) if get(hObject, 'Value') isStopDisp = true; else isStopDisp = false; end setappdata(handles.figure1, 'isStopDisp', isStopDisp); %function radiobutton1_Callback(hObject, eventdata, handles) %function radiobutton2_Callback(hObject, eventdata, handles) %function togglebutton4_Callback(hObject, eventdata, handles) %%(6) 根據【十六進位制顯示】複選框的狀態,更新isHexDisp引數 function hex_disp_Callback(hObject, eventdata, handles) if get(hObject, 'Value') isHexDisp = true; else isHexDisp = false; end setappdata(handles.figure1, 'isHexDisp', isHexDisp); %% (7)手動傳送回撥函式 function manual_send_Callback(hObject, eventdata, handles) scom = get(handles.figure1, 'UserData'); numSend = getappdata(handles.figure1, 'numSend'); val = get(handles.sends, 'UserData'); numSend = numSend + length(val); set(handles.trans, 'string', num2str(numSend)); setappdata(handles.figure1, 'numSend', numSend); %% 若要傳送的資料不為空,傳送資料 if ~isempty(val) %% 設定倒計數的初值 n = 1000; while n %% 獲取串列埠的傳輸狀態,若串列埠沒有正在寫資料,寫入資料 str = get(scom, 'TransferStatus'); if ~(strcmp(str, 'write') || strcmp(str, 'read&write')) %strcmp比較兩個字串是否相等 fwrite(scom, val, 'uint8', 'async'); %資料寫入串列埠 val break; end n = n - 1; %倒計數 end end %% (8)清空傳送區 function clear_send_Callback(hObject, eventdata, handles) set(handles.sends, 'string', '') set(handles.sends, 'UserData', []); %% 更新要傳送的資料 %function checkbox2_Callback(hObject, eventdata, handles) %% (9) 【自動傳送】按鈕的Callback回撥函式 function period_send_Callback(hObject, eventdata, handles) %% 若按下【自動傳送】按鈕,啟動定時器;否則,停止並刪除定時器 if get(hObject, 'value') t1 = 0.001 * str2double(get(handles.period1, 'string'));%獲取定時器週期 t = timer('ExecutionMode','fixedrate', 'Period', t1, 'TimerFcn',... {@manual_send_Callback, handles}); %建立定時器 set(handles.period1, 'Enable', 'off'); %禁用設定定時器週期的Edit Text物件 set(handles.sends, 'Enable', 'inactive'); %禁用資料傳送編輯區 start(t); %啟動定時器 else set(handles.period1, 'Enable', 'on'); %啟用設定定時器週期的Edit Text物件 set(handles.sends, 'Enable', 'on'); %啟用資料傳送編輯區 t = timerfind; %查詢定時器 stop(t); %停止定時器 delete(t); %刪除定時器 end %% (10)設定傳送週期文字框 function period1_Callback(hObject, eventdata, handles) function period1_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end %% (11)計數清零,並更新引數numRec和numSend function clear_count_Callback(hObject, eventdata, handles) set([handles.rec, handles.trans], 'string', '0') setappdata(handles.figure1, 'numRec', 0); setappdata(handles.figure1, 'numSend', 0); %% (12)設定是否允許複製接收資料顯示區內的資料 function copy_data_Callback(hObject, eventdata, handles) if get(hObject,'value') set(handles.xianshi, 'enable', 'on'); else set(handles.xianshi, 'enable', 'inactive'); end %% (13)關閉視窗時,檢查定時器和串列埠是否已關閉 ,若沒有關閉,則先關閉 function figure1_CloseRequestFcn(hObject, eventdata, handles) t = timerfind; %% 查詢定時器 %% 若存在定時器物件,停止並關閉 if ~isempty(t) stop(t); %若定時器沒有停止,則停止定時器 delete(t); end scoms = instrfind; %% 查詢串列埠物件 %% 嘗試停止、關閉刪除串列埠物件 try stopasync(scoms); fclose(scoms); delete(scoms); end delete(hObject); %% 關閉視窗 %% (14)根據【十六進位制傳送】複選框的狀態,更新isHexSend引數 function hex_send_Callback(hObject, eventdata, handles) if get(hObject,'value') isHexSend = true; else isHexSend = false; end setappdata(handles.figure1, 'isHexSend', isHexSend); %% 更新要傳送的資料 sends_Callback(handles.sends, eventdata, handles); %% (15) 資料傳送編輯區的Callback回撥函式,更新要傳送的資料 function sends_Callback(hObject, eventdata, handles) %% 獲取資料傳送編輯區的字串 str = get(hObject, 'string'); %% 獲取引數isHexSend的值 isHexSend = getappdata(handles.figure1, 'isHexSend'); if ~isHexSend %若為ASCII值形式傳送,直接將字串轉化為對應的數值 val = double(str); else %若為十六進位制傳送,獲取要傳送的資料 n = find(str == ' '); %查詢空格,返回所有空格的位置 n =[0 n length(str)+1]; %空格的索引值 n行向量 %% 每兩個相鄰空格之間的字串為數值的十六進位制形式,將其轉化為數值 for i = 1 : length(n)-1 temp = str(n(i)+1 : n(i+1)-1); %獲得每段資料的長度,為資料轉換為十進位制做準備 if ~rem(length(temp), 2) b{i} = reshape(temp, 2, [])'; %將每段十六進位制字串轉化為單元陣列 else break; end end val = hex2dec(b)'; %將十六進位制字串轉化為十進位制數,等待寫入串列埠 end %% 更新要顯示的資料 set(hObject, 'UserData', val);

2患者資訊記錄

3患者主被動康復

4遊戲

4.1打地鼠

這裡寫圖片描述

function varargout = gamedishu(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @gamedishu_OpeningFcn, ...
                   'gui_OutputFcn',  @gamedishu_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
function gamedishu_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = gamedishu_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;

%%(1)開始遊戲
function start_game_Callback(hObject, eventdata, handles)
tic                              %開始計時
I0=imread('background.jpg');     %讀取背景圖   %% imread 讀取影象得到三維矩陣,前兩維是空間座標,第三維取值1/2/3代表三基色紅、綠、藍
I1=imread('mouse.jpg');          %讀取地鼠

background_size = size(I0);
mouse_size = size(I1);

I1_Alpha = double((I1(:,:,1)<230 & I1(:,:,2) <230 & I1(:,:,3) <230));   %% 將地鼠圖片中的白色區域置1,(隱藏)

hitCount=0;                              %定義一個變數並取0
ratHole_location=load('ratHole.txt');    %取出鼠洞文字文件中的值 ,已經從背景圖片中獲得(應該是鼠洞的左上角座標值)
ratHole_num=size(ratHole_location,1);    %確定鼠洞的個數並賦值給N           

ratHole_location(:,1) = ratHole_location(:,1) + mouse_size(2)./2;    % 求得鼠洞出口的中心位置 
ratHole_location(:,2) = ratHole_location(:,2) + mouse_size(1)./2;    % 為什麼是:X+y,Y+x

rand_ratLocation=floor(rand*ratHole_num)+1;                          % 對N中的元素隨機取整(隨機取1-12),floor取比它小的整數,rand取0-1的隨機小數
set(handles.end_game,'UserData',0);             %終止程式isStop=0

imshow(I0);                                     %顯示Image1的內容   
set(gca, 'NextPlot', 'Add');   %gca返回當前axes物件的控制代碼值,nextplot重繪模式,add使用當前的座標軸,把新的圖形物件加到此座標軸中

ratImage_changed = image(-1000,-1000,I1);        % image(x,y,C), x,y指定座標軸的範圍,顯示相同的圖片
set(ratImage_changed,'AlphaData', I1_Alpha);     % 改變 I1_Alpha 值,可以改變明暗(透明程度)
pos_clickedShow = text(0, -8, '');               % text(x,y,'string')在圖形指定位置顯示字串

for k=1:100000                  
    x_rat=ratHole_location(rand_ratLocation,1);  
    y_rat=ratHole_location(rand_ratLocation,2);  % 定義地鼠的橫縱座標
    rat_rescale_factor = (y_rat+200)./(background_size(1)+200); %%地鼠縮放因子,有不同的方法設定rescale_factor,100 是隨便取的數字

    %將地鼠貼圖到背景圖的範圍內,YData有點疑問
    set(ratImage_changed ,'XData', [x_rat-mouse_size(2)*rat_rescale_factor./2, x_rat+mouse_size(2)*rat_rescale_factor./2],...
        'YData', [y_rat-mouse_size(1)*rat_rescale_factor+10.* rat_rescale_factor, y_rat+10.*rat_rescale_factor]);

    pos_clicked=get(gca,'currentpoint');  %確定滑鼠的座標 ,獲取最近一次點選的位置,返回一個2*3矩陣,axes是3D的,每行代表一個點的座標
    x_clicked=pos_clicked(1,1);
    y_clicked=pos_clicked(1,2);
    set(pos_clickedShow, 'String', sprintf('%d %d',x_clicked,y_clicked));   % 顯示當下滑鼠點選的位置
    drawnow;

    %判斷滑鼠是否點選在地鼠的範圍內
    if ((x_clicked>=x_rat-mouse_size(2)*rat_rescale_factor./2)...
            &&(x_clicked<=(x_rat+x_rat+mouse_size(2)*rat_rescale_factor./2))...
            &&(y_clicked>=y_rat-mouse_size(1)*rat_rescale_factor)...
            &&(y_clicked<=y_rat))  
        hitCount=hitCount+1;                                                     % 對變數DJ進行累加
        set(handles.correct_hit,'String',sprintf('正確打擊:%3.0f次',hitCount));  % 在text2中顯示DJ的值
        rand_ratLocation=floor(rand*ratHole_num)+1;                              % 隨機取整N中的元素
    end;

    isStop=get(handles.end_game,'UserData');   % 把pushbutton2的內容賦值給isStop
    if (isStop==1);                            % 判斷isStop==1
        break;              
    end;
end;
set(handles.game_time, 'String', sprintf('遊戲時間:%3.0f秒',toc));  %計時結束,並在text1中顯示時間

%%(2)結束遊戲
function end_game_Callback(hObject, eventdata, handles)
set(handles.end_game,'UserData',1);        % isStop=1

4.2flappy bird

這裡寫圖片描述

function varargout = flappy_point(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @flappy_point_OpeningFcn, ...
                   'gui_OutputFcn',  @flappy_point_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


function flappy_point_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;

global g y1 y2 y3 Fs1 Fs2 Fs3 picMbg picMbd flysound vwall cond record 
record=0;
flysound=0;
g=5;    %%重力加速度              %%============================================================================
vwall=4;  %%類似於鳥的水平速度       %%============================================================================
cond=0;   %%條件數

[y1,Fs1] = audioread('fb_music\die.wav');
[y2,Fs2] = audioread('fb_music\jump.wav');
[y3,Fs3] = audioread('fb_music\fly.wav');

axes(handles.axes1);
cla reset;      %%清除當前的 axes
picbg=imread('fb_pic\BG.bmp');
imshow(picbg,'xdata',[1,80],'ydata',[1,110]);
set(handles.axes1,'unit','normalized','visible','on');
axis([0 80 0 110]);  %%表示座標軸的最小最大值
axis off;  %%關閉所用座標軸上的標記、格柵、單位標記

set(handles.kaishi,'enable','on');
set(handles.qingchu,'enable','on');

picMbg=picbg;
size1=size(picbg(:,1,1));
for i=1:size1(1)
    picMbg(i,:,:)=picbg(size1(1)+1-i,:,:); %%橫座標,逆序
end

picbd=imread('fb_pic\bird.png');
picMbd=picbd;
size1=size(picbd(:,1,1));
for i=1:size1(1)
    picMbd(i,:,:)=picbd(size1(1)+1-i,:,:);   
end

guidata(hObject, handles);
function varargout = flappy_point_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;

%%(1)【清除】按鈕
function qingchu_Callback(hObject, eventdata, handles)
global record
record=0;
set(handles.gaofen,'string',num2str(record));     %%高分清除掉

%%(2)【按鍵按下】回撥函式
function figure1_KeyPressFcn(hObject, eventdata, handles)
global v cond
press=get(hObject,'currentkey');     %%獲取當下按下的按鍵的值
if strcmp(press,'downarrow')  %%向下鍵,開始
    if (cond==0)
        kaishi_Callback(hObject, eventdata, handles);
        return;
    end
end
switch press
    case {'space','uparrow'}   %% 空格鍵、向上鍵,向上跳
        v=5;           %%=================================================================================================
        game_level=get(handles.selecte_level,'value');
        switch game_level
            case 2
                 v=2;
            case 3
                 v=5;
            case 4
                 v=8;
        end
end

%%(3)【開始】按鈕
function kaishi_Callback(hObject, eventdata, handles)
global v record g vwall cond y1 y2 Fs1 Fs2 flysound picMbg picMbd
%dt=str2num(get(handles.shijian,'string')); %時間 0.05秒    
dt=0.05;               %%================================================================================================

%%選擇遊戲難度
game_level=get(handles.selecte_level,'value');
switch game_level
    case 2
        g=2;
        dt=0.02;
        vwall=3;
    case 3
        g=5;
        dt=0.05;
        vwall=11;
    case 4
        g=8;
        dt=0.07;
        vwall=13;
end

cond=1;
flysound=1;
v=0.0;     %%鳥的初始垂直高度
h=70;      %%鳥的初始高度

xx1=110;   %%每張圖兩個障礙物,橫座標
xx2=155;

s=0;     %%鳥橫向飛過的路程
dx=0;

hh1=round(20+40*rand);  %%障礙物,隨機高度 (20+40*rand) 20-60之間       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
hh2=round(20+40*rand);                     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

axes(handles.axes1);
cla reset;   %%清除當前axes
hold on;     %%使當前軸與圖形保持而不被重新整理,準備接受此後將繪製,  (新圖與舊圖共存)
a1=imshow(picMbg,'xdata',[1,80],'ydata',[1,110]);      %顯示第一張背景
a2=imshow(picMbg,'xdata',[80,159],'ydata',[1,110]);    %顯示第二張背景
bd=imshow(picMbd,'xdata',[27,33],'ydata',[68.5,73.5]); %顯示鳥
hold off;    %%使當前軸與圖形不在具備被重新整理的性質  (原圖被新圖代替)
axis xy;     %%使用笛卡爾座標系,原點在左下角
axis([0 80 0 110]);

set(handles.kaishi,'enable','off');
set(handles.qingchu,'enable','off');

%%設定障礙物,用粗線表示
L1=line([xx1,xx1],[hh1+40,110],'color','g','linewidth',42,'erasemode','normal');    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
L2=line([xx1,xx1],[0,hh1-10],'color','g','linewidth',42,'erasemode','normal');      %%%%%%%%%%%%%%%%%%%%%%%%%%
L3=line([xx2,xx2],[hh2+40,110],'color','g','linewidth',42,'erasemode','normal');    %%%%%%%%%%%%%%%%%%%%%
L4=line([xx2,xx2],[0,hh2-10],'color','g','linewidth',42,'erasemode','normal');      %%%%%%%%%%%%%%%%%%%%%%%%%%%

%%障礙物的前端區域
L5=line([xx1,xx1],[hh1+30,hh1+40],'color',[0 1 0.5],'linewidth',48,'erasemode','normal');  %%%%%%%%%%
L6=line([xx1,xx1],[hh1-10,hh1],'color',[0 1 0.5],'linewidth',48,'erasemode','normal');      %%%%%%%%
L7=line([xx2,xx2],[hh2+30,hh2+40],'color',[0 1 0.5],'linewidth',48,'erasemode','normal');   %%%%%%%%%%%%
L8=line([xx2,xx2],[hh2-10,hh2],'color',[0 1 0.5],'linewidth',48,'erasemode','normal');     %%%%%%%%%%%%%%%%%

while(cond==1)     %%死迴圈
    dx=dx+1;
    count=fix(dx/3.5);   %% fix取整函式,朝零向取整
    if(count>80)         %%圖片寬度 80
        count=0;
        dx=0;
    end

    picx1=1-count;
    picx2=80-count;
    set(a1,'xdata',[picx1,picx1+79]);    %%顯示背景圖片
    set(a2,'xdata',[picx2,picx2+79]);

    h=h+v*dt-0.5*g*dt^2;  %%鳥的高度,只受重力作用   
    v=v-g*dt;             %%鳥的速度,垂直方向上的  

    xx1=xx1-vwall*dt;     %%飛過 dt 時間之後的,水平位置   8*0.05=0.4,水平每次減少 0.4
    xx2=xx2-vwall*dt;

    prescore=fix((s-40)/45.0);  %%之前得分  s=84,prescore=0;
    if(prescore<0)
        prescore=0;
    end

    s=s+vwall*dt;    %%鳥的飛行長度   s=85,score=1
    score=fix((s-40)/45.0);
    if(score<0)
        score=0;
    end

    if(score>prescore)   %%當前得分大於之前得分
        switch game_level
            case 1
                sound(y2,Fs2);   %%前兩個遊戲等級有聲音提示,後兩個沒有,有聲音提示遊戲較卡
            case 2
                sound(y2,Fs2);
        end
    end

    set(bd,'ydata',[h-2,h+2]);   %%設定每次迴圈鳥的高度

    set(L1,'xdata',[xx1,xx1]);   %%設定每次迴圈,障礙物的水平位置
    set(L2,'xdata',[xx1,xx1]);
    set(L5,'xdata',[xx1,xx1]);
    set(L6,'xdata',[xx1,xx1]);
    set(L3,'xdata',[xx2,xx2]);
    set(L4,'xdata',[xx2,xx2]);
    set(L7,'xdata',[xx2,xx2]);
    set(L8,'xdata',[xx2,xx2]);

    if(xx1<(-5))                  %%每次迴圈 xx1減少一點
        hh1=round(20+40*rand);    %%設定隨機高度             %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        xx1=85;
        set(L1,'xdata',[xx1,xx1],'ydata',[hh1+40,110]);     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        set(L2,'xdata',[xx1,xx1],'ydata',[0,hh1-10]);       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        set(L5,'xdata',[xx1,xx1],'ydata',[hh1+30,hh1+40]);  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        set(L6,'xdata',[xx1,xx1],'ydata',[hh1-10,hh1]);     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
    end

    if(xx2<(-5))
        hh2=round(20+40*rand);                              %%%%%%%%%%%%%%%%%%%%%
            
           

相關推薦

sEMG專案總結4康復手上系統

康復手上位機系統 目錄 1串列埠通訊 %%主函式:註釋說明和視窗初始化 function varargout = serial_communication2(varargin) gui_Singleton = 1; gui_State

Django 專案總結4- 使用者中心個人資訊

使用者中心個人資訊 在該頁面會展示使用者名稱,手機號,郵箱,郵箱驗證狀態 修改使用者模型類,增加郵箱是否驗證狀態 進入該頁面時,前端向後端請求資料; 後端進行序列化把資料返回; 在檢視加上 permission_classes 許

sEMG專案總結6NinaPro肌電資料集52類動作

NinaPro肌電資料集(52類動作) 目錄 1sEMG Data subjucts : 67 intact subjects & 11 trans-radial amputated subjects Sensors : 10 Ot

Maven學習總結4-使用Maven構建多模組專案

我用的IDE是eclipse,以下是多模組專案構建步驟。 一、新建Maven Project 1.New-Maven Project-Next 2.操作如下 3.如下填寫,然後Finish 說明:maven中jar、war、pom的區別

商城專案ssm+dubbo+nginx+mysql統合專案總結4

我不會在這裡貼程式碼和詳細步驟什麼的,我覺得就算我把它貼出來,你們照著步驟做還是會出很多問題,我推薦你們去看一下黑馬的這個視訊,我個人感覺很不錯,一步一步走下來可以學到很多東西。另外,視訊和相關文件的話,關注微信公眾號“Java面試通關手冊”回覆“資源分享第一波

MEF學習總結4---Container層

ret nba enum https ive src lib nco 註入 通過AttributeedModelPrograming,我們可以聲明暴露組件,依賴組件,發現組件,但是所有這些需要有一個觸發點。即需要把所有這些組合在一起來協同工作,最終實現依賴註入。這就是Con

OpenCV學習總結4- 目標跟蹤

opened 背景 key font sin mic 目標 mil cap 視覺算法原理:背景提取  1. 打開視頻(文件或攝像頭)  2. 從視頻中提取當前幀  3. 計算背景:以前多幀求取平均  4. 根據背景得到運動目標(當前幀 - 背景)  5. 返回2,程序不斷循

產品方法論總結4——痛點、癢點、爽點

發送 比較 電影 社交 提高 bsp 需求 畫像 照片 產品的抓手,主要在於痛點和爽點。前面也提到了痛點即為恐懼,對於用戶而言是剛需,爽點為即時滿足,對用戶而言是興奮點,能讓用戶達到體驗值的高潮,而這裏也提到的癢點是滿足虛擬自我,例如,網紅產品,靠的就不是痛點和爽

設計模式總結4

設計模式總結(4) 多例模式 單例模式限制了只能使用一個例項,有時候為了提高效率需要有限個相同的例項以供使用 public class Emperor { /** * 可以產生例項個數 */ private static int maxNu

JQuery 總結4 jQuery 篩選查詢 等

1. hasClass(“class”) 判斷是否有這個class2. addClass(“class”)增加, removeClass(“class”)刪除,toggleClass(“cc”)有就刪cc,沒有增加cc。 $("li").click(function () { $(this).togg

JQuery 總結4 jQuery 篩選查找 等

cti span ttr ddc pan this attr font dcl 1. hasClass(“class”) 判斷是否有這個class2. addClass(“class”)增加, removeClass(“class”)刪除,toggleClass(“cc”)

用Vue開發仿旅遊站webapp專案總結

寫著寫著發現會寫不少內容... 全部寫在一篇文章裡感覺太多了不方便看,所以分為上下篇吧... 溫馨提示 此文章,僅是做完專案後的個人覺得可以總結下來的操作/思路,接觸vue不久的朋友應該會有收穫。此專案也才是萌新做的第二個Vue專案,使用了腳手架工具( vue-cli 2.x 非 3 ),前輩老

用Vue開發仿旅遊站webapp專案總結

用Vue開發仿旅遊站webapp專案總結 (上) 該說的話,該表明的上篇已經表明了。謝謝上篇評論區一些同學~ 很鼓勵我,不過下下篇估計沒了,這篇總結完,下下篇可能就是之後學習路的總結記錄啦。 有些話還是要說的 接觸vue不久的朋友應該會有收穫。此專案也才是萌新做的第二個Vue專案,使

SpringBoot專案總結--1校驗與加密

一、多欄位校驗 提供Validator的實現類,並且實現Validator介面的supports和validate方法。supports方法用於判斷當前類是不是需要校驗的類。只有當supports方法返回的結果為true時,validate方法才會執行進行校驗。 p

vue入門總結4

1.路由的模式: 前文中我們建立VueRouter例項時用了mode:history的引數,這個值的意思是使用history模式,這種模式充分利用了history.pushState API來完成URL的跳轉而無須重新載入頁面。 如果不使用history模式,當訪問home的時候地址就會變為

Django 專案總結7- 頁面靜態化

程式碼 GitHub 地址 頁面靜態化 首頁被訪問的比較頻繁,為了提升訪問速度,可以使用頁面靜態化技術。 頁面靜態化即將動態渲染生成的介面儲存成 html 檔案,放到靜態伺服器中,使用者訪問的時候訪問的直接是處理好之後的 html 靜態檔案。 對於頁

Django 專案總結8- 使用者瀏覽歷史記錄

使用者瀏覽歷史記錄 儲存瀏覽歷史 使用者在訪問每個商品詳情頁面時,都要記錄瀏覽歷史記錄 歷史記錄中只需要儲存多個商品的 sku_id 即可,而且需要保持新增 sku_id 的順序,採用 redis 中列表來儲存 'history_使用者id': [sku_id列表

Django 專案總結6-商品部分

商品部分 程式碼 GitHub 地址 基本功能:首頁展示、商品列表、商品詳情、商品搜尋 資料庫表設計 資料庫表設計: 電商中對於商品,有兩個重要的概念: SPU 和 SKU SPU = Standard Product Un

Django 專案總結5- 地址管理

地址管理 實現使用者地址的管理,主要業務邏輯: 省市區地址的資料庫的建立與查詢 使用者地址的增刪改查處理 設定預設地址 設定地址標題 在使用者錄入地址時,需要進行省市區的選擇。在頁面載入時,向後端請求省份資料,當用戶選擇確定省份後,向後端請

Django 專案總結3- 第三方登入QQ登入

第三方登入(QQ 登入) 根據 qq 開發文件 oauth2.0 QQ 登入流程: 前端頁面點選 QQ 登入,需要跳轉到 QQ 的登入頁面,但是前端不知道 QQ 的登入連結,所以先想後端傳送請求,由伺服器生成 QQ 登入頁地址,返回給前端; 使用者在