摘要:在 windows 中使用 c 語言製作控制台小遊戲可用的控制台雙緩衝技術,此技術可以防止畫面重新整理時螢幕閃爍的現象,使畫面過渡較為流暢。
參考樣例檔案見
在使用 c 語言製作控制台小遊戲時,為了在畫面更新的時候重新整理顯示內容,乙個容易想到的方法是在每一幀重新整理畫面,windows 下可以使用控制台命令重新整理畫面,形如:
// 分配一塊記憶體當作二維陣列,儲存螢幕顯示的資訊
char** new_screen(int screen_width, int screen_height)
// ...
int main(void)
// ...
}
在上述例子中使用 cls 命令清屏,而這將造成嚴重的螢幕閃爍。通過移動游標位置區域性擦除寫入的方式可以一部分改善這個問題,但如果需要重繪的部分過多,這個辦法依然不好用。
使用雙緩衝方法雖然不會一勞永逸地解決閃屏,但多半能一勞很久逸。所謂雙緩衝即是為控制台顯示增加一塊緩衝區域,每一幀的顯示在緩衝區域進行,寫入完成後直接放到在活動的控制台顯示區域。現代計算機處理資料的速度已經很快,相對而言慢的部分在輸出文字到顯示器這一步,所以在每一幀將字元放置到緩衝區域再一起顯示完全來得及。一開始為了找到合適的方法我在網路上尋找了很久但只有一些只言片語留在一些技術部落格裡,在這裡我會放上較為完善的版本。
雙緩衝的基礎是兩塊控制台顯示,表現為兩個控制台顯示控制代碼。由於標準輸出流對應的控制台顯示可以便利地呼叫 putchar() 等函式列印字元,所以將原來的顯示區域也就是標準輸出流對應的控制台顯示作為緩衝區比較合適。
/*
雙緩衝核心,兩個控制台顯示控制代碼
_std 對應標準輸出流,用作緩衝區
_buffer 對應活動的控制台顯示
*/struct hud
;typedef struct hud hud;
hud handle; // 乙個全域性的結構體
/* 獲取標準輸出流控制代碼
建立新的控制台輸出控制代碼
設定新的控制台輸出控制代碼為在活動的控制台輸出控制代碼
在 main() 裡先呼叫這個函式,控制台顯示將切換為 _buffer 中顯示的內容
*/void init() /*
mono 類結構和方法
雖然 c 語言語法沒有類的概念,但依然可以製作乙個類似類的
*/struct mono
;typedef struct mono* mono;
/* 基礎建構函式,傳入圖示寬高資訊。
*/mono new_mono(int width, int height)
return self;
}/*析構函式,按動態申請資源的相反順序釋放記憶體*/
void del_mono(mono self)
free(self->su***ce);
self->su***ce = null;
free(self);
self = null;
return;}/*
向標準輸出流傳入 self 內的資訊
*/void _show(mono self)
putchar('\n');
}return;}/*
傳入 su***ce 螢幕,對應標準輸出流和在活動的控制台顯示
self 與螢幕顯示之間以緩衝區作為媒介
將 self 的內容顯示到控制台
*/void show(mono self, mono buffer)
; dword bytes = 0;
// 這個函式定位 handle._std 中的游標位置
setconsolecursorposition(handle._std, coord);
for (int i = 0; i < self->height; i++)
coord output_coord = ;
dword output_bytes = 0;
setconsolecursorposition(handle._buffer, output_coord);
for (int i = 0; i < self->height; i++)
return;
}/*將 su***ce 物件的內容置為特定字元*/
void clean_mono(mono self, char c)
return;
}
在主函式中,建立上例中的 mono 物件作為顯示區域 (由於 mono 類的特性,它也可以用來盛放如可動的遊戲角色或者靜止元素的圖示,你可以將乙個 mono 物件疊放在另乙個 mono 物件上,並控制其中的位置屬性),並啟動雙緩衝。
int main(void)
// 做一些收尾工作如釋放記憶體,如果設計的程式會走到這裡的話
return 0;
}
已知的問題:
有時候控制台的顯示會出現多餘的空行,右鍵控制台標題欄設定控制台屬性中的布局,取消「調整大小時對輸出的文字換行」的勾選即可。
C 控制台專案小遊戲
判斷按鍵改變方向是否有效,向上的時候,向下操作失靈,向右時按向左或向右失靈57 5859 60 moveplayers 左右位置 或 6162 63bool firstplayerloses doesplayerlose firstplayerrow,firstplayercolumn 64bool...
C 控制台 公升級打怪小遊戲
小遊戲介紹 輸入 勇士 生日,判斷 勇士 星座,給出 勇士 的初始化屬性 體力 智力和敏捷 選單欄有2個功能 檢視狀態 和 任務選擇 檢視狀態 可以顯示 勇士 的基本屬性。任務選擇 可以選擇 勇士 要做的任務,提公升屬性。int main string constells 12 2 一月 二月 三月...
C 實現掃雷小遊戲(控制台版)
程式功能 提供三種模式 初級 中級 高階 操作模式 wsad控制游標移動,空格鍵開啟方塊 提供掃雷地圖的類 map.h ifndef map h define map h define max length 32 可以提供的地圖最大長度 define max width 18 可以提供的地圖最大寬度...