C++控制台实现滚动字幕
? ? ? ? 這是大二的面向對象程序設計(C)這門課的期末大作業,老師的基本要求是:形成16*16漢字的字幕,并實現字體選擇;有多種動畫效果。
? ? ? ? 以下是我做完設計后提交的作業文檔,對主要技術進行了詳盡的解釋:
字幕滾動思路流程與代碼分析
預期效果
使用C++語言編寫程序,在字符界面上模擬滾動字幕。
基本功能包括:
1.讓用戶輸入漢字,然后在字符界面上實現16*16(每個漢字)的字幕。
2.具有三種不同的動畫效果。
3.有10*9種背景顏色和字體顏色可供選擇。
4.5種不同的字體可供選擇。
4.界面友好,操作簡便。
?
功能實現分析
????????對于這道“字幕顯示”作業要求,我們遇到的第一個知識盲區就是如何將漢字用點陣的方式在控制臺顯示出來,甚至需要更改漢字的字體。博主“帶她去流浪”(https://blog.twofei.com/embedded/hzk.html)為我們詳細介紹了HZK庫的用法和C++代碼實現方式,這個問題迎刃而解!
步驟一:實現單字矩陣的顯示
為便讀者閱讀,這里先附上博客內原文代碼:
這里仍有兩個地方需要解釋:
?解決了單字矩陣,多字如何同時顯示呢?
步驟二:多字矩陣的顯示
我們采用字符數組儲存需要輸出的字,并計算字符串長度:
?(C++也可以使用string儲存字符串,且有計算長度函數,但當時并沒想到使用string,而是使用了字符數組,后來作業太多也沒精力再進行嘗試)
上述博客采取了printf(“\n”)實現矩陣多行顯示,換行時自動出現在下一行第一列的位置。在已經打印了第一個字的基礎上,要怎么讓第二個字矩陣出現在第17~32列的位置呢(由于控制臺不便使用像素為單位的坐標系,所以直接采取了以行和列為單位的坐標系定位)?我們采用了SetConsoleCursorPosition()函數來定義光標位置,這里以最簡單的逐字輸出為例:
?其中,Y坐標只與字符行位置有關,X坐標與字符處于第幾列、正在輸出第幾個字(CharNo)有關。SetConsoleCursorPosition()只對下一行代碼修改坐標,因此事實上每一個符號都使用這個函數修改了坐標。
(有的組使用了一個大二維數組,比如16*160,先計算出要輸出的字符在這個二維數組中的位置,再逐行輸出整個二維數組,這個方法卡頓比我采用的方法小很多)
步驟三:設計動畫顯示
對于逐字顯示、滾動出現、翻轉出現三種動畫,我們寫了三個函數來分別完成單字的動畫,然后在Play()函數中根據字符串長度決定調用動畫函數次數。
?這里需要說明的是,起初,為了使得時鐘移動(TimeElapsed)前后打印的內容不沖突、輸出的字不“拖尾”,我們在sleep()函數之后使用了system(“cls”)清屏函數,但是這個方法最大的缺點是屏幕閃爍情況嚴重,于是我們改用了另一個方法。我們用直接覆蓋的方式解決了沖突問題,然后在屏幕空余的部分打印空格覆蓋原來的字符,如下圖:
?基于上面逐字輸出,滾動出現和翻轉滾動的實現如下:
滾動出現:(核心部分)
?解釋:Width是屏幕顯示滾動的列數,move隨之時間變化字符的移動量,字符X坐標隨move一直在減少,使用CycleTime = move / Width記錄字符走過一個Width的次數,從而修正pos.X,使得字符實現在左邊緣消失后在右邊緣出現的效果。if (pos.X <= Width)語句表示在非顯示區域的字符不打印,這一步主要是為了程序剛剛運行時字符不會溢出顯示區域(因為該程序根本原理是在每一個Sleep()函數前都要完整打印一次16*16*字數矩陣和空白矩陣,不使用這個檢驗會導致程序剛運行時發生錯亂),事實上CycleTime>0時并不需要這一檢驗步驟。
翻轉滾動出現:(核心部分)
實現了滾動顯示,實現矩陣翻轉、鏡像、縮放等功能實質只需要修改部分參數即可完成。
步驟四:菜單設計
菜單函數menu()的存在就是為了減少main()函數的代碼,使得mian()函數看起來更加“清爽”。Menu()中包含四個選擇函數,包括選擇字體函數SelectType()、選擇背景色函數SelectBGColor(),選擇字體顏色函數SelectWordColor(),選擇字體動畫方式函數SelectShow()。其中大部分是使用了switch函數,根據用戶輸入的按鍵,返回一個string,最終傳到play()函數中。下面是選擇函數之一的代碼:
?總之,這是一個平平無奇的菜單小函數,main()函數將不停的調用它。它的存在是為了簡化main()函數的代碼,體現式布局更加美觀。
不足和改進建議:
1.在不同的動畫函數里面都包含了大量重復的代碼,但是又有細微的不同。我們想改進方式也許可以將其中相同的部分抽象出一個類,用繼承的方法來減少代碼工作量。
2.網絡上的大佬實現了鼠標點擊操作菜單,但數次嘗試均未成功,且在老師說控制臺還是不要使用鼠標后成功勸退。我想控制臺也許不適合鼠標,但應仍是可實現的(將控制臺由行列坐標轉換為像素坐標,獲取鼠標位置),所以如有時間不妨一試。
本人小白,首篇博客試水,不妥之處請多指正鴨
總結
以上是生活随笔為你收集整理的C++控制台实现滚动字幕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深信服上网行为管理——仅用户访问某个特定
- 下一篇: QT设置默认最大化窗口