線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:10405
推到 Plurk!
推到 Facebook!

同是按下兩個鍵盤上的鍵...只偵測到一個?

 
myname798
一般會員


發表:2
回覆:5
積分:6
註冊:2007-01-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-01-21 15:34:42 IP:61.216.xxx.xxx 訂閱
我發覺 borland c++的 keydown事件好像只能一次讀到一個值,例如:
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
switch(Key)
{
case 38: //.........
case 40: //............
case 37: //..........
case 39: //..............
}
}

這樣子的話...也就是說如果按下''上''( 使物件向上移動 )
再按下''空白'' ( 發射子彈 ), 電腦會忽略掉按下''上''而只偵測到''空白''
造成物件的停止...
請問各位大大知不知道有什麼方法可以解決這個問題勒?

pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-01-22 08:56:31 IP:60.248.xxx.xxx 未訂閱
 既然你在delphi區詢問,我就貼上delphi碼,手上沒有bcb環境可測
Form1.KeyPreview=True
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case key of
vk_Right:Memo1.Lines.Add('右');
vk_Left:Memo1.Lines.Add('左');
vk_Up:Memo1.Lines.Add('上');
vk_Down:Memo1.Lines.Add('下');
end;
end;

g9221712
高階會員


發表:145
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-01-22 14:15:32 IP:220.134.xxx.xxx 訂閱
我也測試了一下,不過我也是用Delphi寫的,本來我是想說,可以在兩個地方寫,
但是我發現會因為鍵盤碼改變的緣故,也是會有停頓的感覺,不過我有另外一個想法
不知道可以行,就是按下"上"改變一個IS_BTN__UP=true,就是用一個變數讓只要按下
上方,就讓物件持續前進,按下下方讓物件持續向下,左右方向同理,若沒有改變方向變數
就維持原來的方向行進,而按下空白這樣就可以處理了! 不知道我這樣突發奇想,是否符合
遊戲軟體的設計,因為我比較常寫的資料庫部份,按鍵操作比較不擅長,提供給您參考,
若可行,也請回應到版上!
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case key of

vk_Right:Memo1.Lines.Add('右');
vk_Left:Memo1.Lines.Add('左');
vk_Up:Memo1.Lines.Add('上');
vk_Down:Memo1.Lines.Add('下');
end;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
Memo1.Lines.Add('FormKeyPress'); // 假設是按下空白發射子彈
end;

------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-01-22 14:21:14 IP:218.170.xxx.xxx 訂閱
他要的是按住上下左右的時候。同時按一下 space,當你放開 space 之後。還想知道剛才還按了那個方向鍵。
你的回答並沒有解答他的問題。
g9221712
高階會員


發表:145
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-01-22 15:29:43 IP:220.134.xxx.xxx 訂閱
恩!前輩確實會這樣,但是以我對鍵盤的了解,鍵盤其實也是一個Buffer機制,但是若要持續的對特定按鍵(非Ctrl 、Shift、Alt 等等按鍵)
只能用一個變數去記憶上一個按鍵狀態,因為不知道這個遊戲是,要一直按下方線鍵上才會移動,還是只要按一下方向鍵上就會使物件
一直往上跑,我不太確認這個遊戲的操作設定方式,不過這個問題,確實是一個好問題!因為我沒遇過啊!
------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-01-22 19:05:37 IP:61.216.xxx.xxx 未訂閱
暗黑大大看的仔細唷!
g9221712大大"鍵盤其實也是一個Buffer機制"恩,但是否同一時間會觸發KeyDown事件?我想要視WM_Message訊息佇列派送速度而定,通常同一時間應該只收到一個吧?
其實作法g9221712已講,設一個變數記載上次按的鍵值,或用結構陣列存放,每一鍵值標上時間註記,在比對時,可取得差異微秒最少的,即是離最近所按的鍵值.
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-01-22 23:33:36 IP:218.170.xxx.xxx 訂閱
因為程式不出十行的。我會先TRY一下,就回掉了。
這個不出十行。能回我早就回了。^^

現在還有另一個問題是 向上按著不放。你的 keydown 的 event 會一直觸發
而你按了一下 space 的話。它的 向上鍵的 keydown 的 event 就停了。
所以用你說的方法,又會。。。。。。。。

我是在想。他應該要用個 stack 的東東來做。
在 keydown 這個 event 發生時 把key push 進去。
在 key up 這個 event 發生時 把 key pop 出來。
目前動作中的為 stack 最上層的那個 key.
自己用資料結構寫一下。
這個動作超過十行,我就懶得試了。
也不知道要講到發問者懂 stack 要多久。就乾脆不答了。^_^
那知道有人掉進陷阱,沒把問題看清楚。。。。。kekekekekekeee
===================引 用 文 章===================
暗黑大大看的仔細唷!
g9221712大大"鍵盤其實也是一個Buffer機制"恩,但是否同一時間會觸發KeyDown事件?我想要視WM_Message訊息佇列派送速度而定,通常同一時間應該只收到一個吧?
其實作法g9221712已講,設一個變數記載上次按的鍵值,或用結構陣列存放,每一鍵值標上時間註記,在比對時,可取得差異微秒最少的,即是離最近所按的鍵值.
g9221712
高階會員


發表:145
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-01-22 23:43:14 IP:220.134.xxx.xxx 訂閱
暗黑前輩:
stack在資料結構上好像是後進先出,而Buffer好像是先進先出(符合Keyboard輸入時的時序),但是有一個問題
攔截我會,反正就是用一個陣列或者..將每個設定的功能鍵弄一組一個文字代碼,但是何時要將這個代碼Send到OS的Event中,
還有在Send的過程中,若使用者又持續的按住按鍵,這樣os會不會搞混!

這個題目真的越想難度越高!懇請前輩們,回應一下這個主題! 真是小問題大麻煩! 我也被考倒了!
------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-01-23 00:24:46 IP:203.73.xxx.xxx 未訂閱
why stack?

從第一篇的發言來考慮,
首先按了Up,觸發「上移」
再按了Space,觸發「發射」,
但這時候Up的動作沒有結束,所以我們要keep track上一個motion是作什麼事,所以是stack
suppose Up的狀態被改變了(比如說在KeyUp Event),那麼在KeyUp這個Event裡面我就要trace之前的motion是Up, Down, Left, Right or NULL
於是「可以被組合的功能」就組成了一個Stack,不可重覆性的Function被觸發時就要去找上一個要取代掉的State來作判斷(如移動方向同時間只能有一種,但發射和移動是可以組合的)

(完?)//好吧..我也上當了(?)
//不過..這種事感覺上enumerate比較簡單一點(?)
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-01-23 07:51:13 IP:61.224.xxx.xxx 未訂閱
小題大哉問?
嚴格講起來,KeyDown事件不保証會依續或完整觸發,WM_ Message會在系統負擔重時會丟失訊息,而且KeyDown事件你去回應系統接進來key值,要相關環節一起考量
假設是這樣
偵測鍵值,移動
碰撞偵測
計分
著繪
這四個環節,若花在繪製精靈時,很多時間,輪到偵測鍵值時,可能已誤失好些ms了,這幾個環節都要整體考量,看遊戲做到什麼程度,不同程度有不同程度的最佳化,計對著繪、輸入及音效輸出可考慮採用DirectX,裡面有DirectGraph、DirectInput、DirectSound,提升這幾個點的效率.
GDI在做呈現層速度是不夠的
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-01-23 10:23:41 IP:218.170.xxx.xxx 訂閱
再修正一下我說的 stack
依順序我們來看
向上鍵按下。
stack : up press
現在的動作是 up
它一直不放。會一直有 up press 的 event
這時候不要 push 進 stack,因為你的 stack 中有 up press
你按了 space
要推入 stack
stack: up press, space press
這時候你要做 space press 的事。
等 space press 放開。(key up event)
你去把 stack 倒出一個 space press 來。
這時候,剩下
stack: up press
你就要做 up press 的動作。即使沒有 event 了

寫到這裏,發現。你去維護這樣的一個 stack (當然,你可以用 link list.....etc 去做到)
可以的話。處理的程序,應可以抓 stack 中所有的 key 來做判斷。
這樣。所有的動作都可以做到你的要求。

咦。這個好像就是用 Set 來做嘛。
加油了。把我遇到問題的思考方式都一步一步推演。
應該可以解決你的問題了。

還有。你用了 Set 來處理時。你要把處理的地方移到 timer 去。而不是放在 key press down 的地方。
因為連按之後中斷就不再有 event 了。
移去 timer 然後利用時間到了再去檢查 Set 中有那些鍵。
有就做那些事,沒有就走人。
記得 timer 要用要小心。不要這個 timer event 還沒結束。又進入另一次 event 了。^^
xfile
初階會員


發表:21
回覆:80
積分:25
註冊:2004-10-02

發送簡訊給我
#12 引用回覆 回覆 發表時間:2007-03-07 11:25:39 IP:220.130.xxx.xxx 訂閱
DirectX 應該可以解決,不然就是自己改寫鍵盤偵測了
系統時間:2024-04-27 9:03:44
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!