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專案總結(6)NinaPro肌電資料集(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 登入頁地址,返回給前端;
使用者在