看板 C_and_CPP 關於我們 聯絡資訊
< 原文恕刪 >
EdisonX: 為什麼我覺得最大的問題是在 getch() @@ 08/13 23:22
EdisonX: 不知道 linux 有沒有像 windows 類似 GetKeyState 的東西 08/13 23:22
Feis: 看你怎麼想. getch 感覺沒甚麼錯啊. 只是他亂用 08/13 23:25
EdisonX: @Feis : 但 getch 不是 Blocking 嗎 ?08/13 23:26
Feis: nodelay08/13 23:27
EdisonX: 試了一下, 原來是我誤會了 @@08/13 23:35
嗯,為了慶祝原來我以前誤會了一些東西,所以 reply , ( 雖然 reply 的東西和 getch 沒有什麼太大關聯 ... ) 然後原 po 抱歉,我沒仔細看你的 code , 提一個 "我覺得可行" , 但還勉強用不到 Timer , Thread 的方案 。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 首先,小弟以前發過這篇, #1EuwQVAG (C_and_CPP) , 在 wins 下跑的 , 附 Code , http://codepad.org/qV4nZln0 , 一些 functions porting 後應該是可以在 linux 底下 run。 架構和程式碼說明應該算清楚 , 有提到 Single Thread 流暢度 (Flex) 概念, 只是當時的範例不太好 , 當時是一個 * , 按方向鍵一下就跟著跑一下 , 對於動態遊戲而言大概不會是 "動一下才跑一下" ,而是畫面一直在更新 , 所以我們原本的架構直接拿來改 , 改成按了某個方向 , 這個點就會一直往 這個方向跑,這種情況下,流暢度設多少就不是很重要,甚至不要有流暢度 都無所謂,然後請先閱過上面這篇文章。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 在原文閱過之後,只有二個地方要注意 (1) 原本的 key_control 裡,是做 "取方向鍵" 、"依方向鍵執行 Func" 這裡的 key_control 改成非常簡單的 "狀態改變" 什麼是狀態改變?簡單的說,目前移動的方向用一個變數去紀錄,移動方向 就是狀態,但不做畫面更新 , code 如下所示。 void key_control() { switch( int ch = getch() ) { case VK_UP_X : g_dir = DIR_UP ; break; case VK_DOWN_X : g_dir = DIR_DOWN ; break; case VK_LEFT_X : g_dir = DIR_LEFT ; break; case VK_RIGHT_X : g_dir = DIR_RIGHT ; break; } } (2) 畫面更新放到主循環 ( code 裡面的 while(!Exit) ) , 也就是主循環變成這樣 clock_t t = clock(); while(!Exit){ for(int i=0; i<Flex; ++i){ if(kbhit()) { // 有按鍵時再判斷 t = clock(); // 計時器重數 key_control(); } MoveDraw(); Sleep(Delay); } // 3 秒沒動自動退出 // if( (clock()-t) > CLK_TCK * SECS ) Exit=true; } 然後注意的是,因為這遊戲的畫面是一直更新的,所以必須在每個 Frame 都要更新一次狀態 (這遊戲來說也就是 position ) 於是 MoveDraw() 變這樣 void MoveDraw() { last_x = x , last_y = y; switch(g_dir) { case DIR_UP : y = (y ? y-1 : H-1); break; case DIR_DOWN : y = (y < H ? y+1 : 0 ); break; case DIR_LEFT : x = (x ? x-1 : W-1 ); break; case DIR_RIGHT : x = (x < W ? x+1 : 0 ); break; } Cls(); DRAW(); } 以上兩點修改後,完整的 code 如下 http://codepad.org/gvG1ZhSI 變數弄得很亂 , global 到處飛 , 見諒。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 整個架構有一個大重點:while(!Exit) 一次循環的時間不能太長 , 不然會抓不到鍵盤輸入 , 或是會覺得非常卡! 大多花時間的地方是在於 DRAW() 裡面,由於這範例簡單 , DRAW 沒花到什麼時間。如果 DRAW 花時間的話那還是開 Thread 吧。 再來是貪食蛇重繪的方式可能較複雜,但為了避免閃爍,一定不會用 類似 clear_all_screen() 的方式,一定都是用 "擦掉" 的概念, 所以我的例子裡加了 last_x , last_y ,就是為了 "擦掉" 。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 以上,若有意見的話,歡迎補充。 -- 「自從我學了 C# , 人都變聰明 , 考試都考一百分」 「自從我學了 VB , 皮膚都變好 , 人也變漂亮了 」 「自從我學了 Java , 明顯變壯 , 個子也變高了 」 「自從我學了 C++ , 內分泌失調 , 頭都禿了... 」 < Kuso 星爺語錄 > -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.169.158 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1439483773.A.8CD.html
andrew771027: 謝謝你的意見,晚點拜讀,用手機看很崩潰 08/14 13:27