學習編程的好方法——控制台遊戲
本文難度:☆☆☆☆
題圖:控制台RPG遊戲——誅仙劍 by 獃獃的碼農
一、前言
在我大知乎,有以下基本日常問題:
- 如何學習C語言?
- 如何學習C++?
- 如何學習Python?
- 如何學習XXXX語言?
用一句話形容這類問題——高默新淚。高手因為不想反覆回答這類問題而沉默……新手因為苦苦找不到入門的路而流淚。
本文想要給苦惱的新手們指明一個前進的方向。
二、控制台遊戲簡介
所謂控制台,在Windows下就是開始——運行——cmd。也叫「命令行窗口」、「Console」、「Terminal」都是同一個東西。
這個黑漆漆的東西有什麼好玩的呢?看看下面這個遊戲:
和Flash原版魔塔基本一樣:
在控制台里,我們可以通過彩色的文字、背景、空格,來表現出比較抽象的場景。掌握了這個方法,我們就可以盡情發揮想像,做出各種各樣的遊戲了。而且麻雀雖小五臟俱全,製作控制台遊戲有助於我們對遊戲整個流程有完整的掌控,自己設計邏輯、渲染循環,讓我們對真正引擎的理解能更上一層樓。
雖然畫面過於簡單是個缺點,但是勝在製作也很簡單,最重要的是,在學習階段讓我們能迅速開發自己的小遊戲~~
三、控制台遊戲鑒賞
其實知乎上有一些非常厲害的控制台遊戲的例子,但是那些作品主要是用到了一些字元渲染技術,將複雜圖形轉化為字元表示……其實複雜的東西都有一個簡單的內核,如果咱們把基本的控制台操作搞定了,就離大佬們近了一大步。畢竟遊戲是用來玩的,不是用來膜拜的。
所以這裡我們展示一些皮皮關學員作品,供大家學習參考。
1、魔塔
(有點閃爍是因為錄屏軟體正好錄到了屏幕刷新的時刻,遊戲本身閃爍並不明顯)
本遊戲採用了把關卡地圖放在txt文本里的方法,而且後期有跳關、查看怪物等功能,麻雀雖小,五臟俱全。最難能可貴的是工程代碼比較平鋪直敘,萌新也可以看懂。
2、回合制戰鬥模擬器
這個作品在技能動畫上的處理非常厲害,箭頭移動比較流暢(動圖看不出來。這是用一邊擦除、一邊畫箭頭的方法實現的)
3、霧之迷宮
開腦洞,實現帶有迷霧的地圖。
4、戰棋遊戲Demo(火焰紋章)
這個Demo不完整,只是展示了《火焰紋章》遊戲中的移動、攻擊等細節。彩色背景的效果棒極了,文字一個一個冒出來的感覺也很帥。
5、掃雷、俄羅斯方塊、2048、貪食蛇等等
一些經典的小遊戲都可以在控制台上實現,我就不再貼圖了,有興趣可以在文末的地址中下載。
四、用各種語言編寫控制台遊戲
不同的語言開發控制台遊戲的方法略有不同,主要原因是某些語言缺乏好用的控制台輸出庫。我們最需要的是控制字元輸出、窗口刷新的函數。
1、C#
在windows下,C#語言是最好用的控制台遊戲開發語言,微軟爸爸給我們提供了豐富的顯示相關函數,下面舉個例子,彩色動態的Hello world:
高級用法:可以用Console.SetCursorPosition(int left, int top)來把游標定位在某個位置,這樣就可以做到只修改某個位置的字元,而不用反覆調用Console.Clear() 讓屏幕整體閃爍。前面的「回合制戰鬥模擬器」就用這種技術實現了極其流暢的動畫效果。
2、C++ / C
C++操作控制台方案很多,比如利用system("color 03"); 但是用起來有一些問題。
如圖:直接只用DOS命令color即可改變文字和背景顏色。
相對好一些的方案是使用Windows提供的SetConsoleTextAttribute等函數來實現設置顏色。但是Windows提供的清屏我沒有找到靠譜的方法,只能暫時用system("cls")來做,效果還可以,以下代碼提供了清屏和列印彩色字元兩個函數供參考:
#include "stdafx.h"nn#include <iostream> n#include <Windows.h> n#include <stdio.h> n#include <stdarg.h> nnusing namespace std;nnvoid PrintfColor(char* str, WORD color, ...) {ntWORD colorOld;ntHANDLE handle = ::GetStdHandle(STD_OUTPUT_HANDLE);ntCONSOLE_SCREEN_BUFFER_INFO csbi;ntGetConsoleScreenBufferInfo(handle, &csbi);ntcolorOld = csbi.wAttributes;ntSetConsoleTextAttribute(handle, color);ntcout << str;ntSetConsoleTextAttribute(handle, colorOld);n}nnvoid Clear() {ntsystem("cls");n}nnint main() {ntwhile (true)nt{nttPrintfColor("H", 10);nttPrintfColor("e", 9);nttPrintfColor("l", 12);nttPrintfColor("l", 11);nttPrintfColor("o", 13);nttPrintfColor("!", 4);nt}ntsystem("PAUSE");ntntreturn 0;n}n
由於C和C++在不同平台、不同系統下套路不太一樣。網上有些方法無法直接應用,主要是因為VisualStudio版本以及WinSDK版本不同造成的。建議試驗確定一種方案,然後以該方案為準即可。
3、Python
在控制台操作方面,Python有功能強大的curses模塊,但是必須要用linux系統,可以考慮用Linux虛擬機來學習。
(Python的Windows版本缺少一些好用的庫……非常遺憾,剛才我又搜了一下,還是沒找到適合Windows下開發控制台遊戲的方案。希望朋友們在評論里補充。(或者咱們直接用Pygame來做小遊戲更簡單 :D))
五、遊戲主循環
其實,有了列印字元和清空屏幕這兩個工具,就已經可以製作各種各樣的控制台遊戲了,簡單說下思路:
using System;nusing System.Collections.Generic;nusing System.Linq;nusing System.Text;nusing System.Threading.Tasks;nn// C#控制台遊戲架構nnamespace ConsoleApp1n{n class Programn {n static void Init() {n // 初始化遊戲n }nn static void Logic() {n ConsoleKeyInfo key = Console.ReadKey();n // 針對輸入進行處理n }nn static void RealTimeLogic()n {n // 另一種輸入不卡住遊戲的方案,適用於貪食蛇、俄羅斯方塊等遊戲n ConsoleKeyInfo key;n // 如果沒有按鍵輸入,就不會執行ReadKey,遊戲就不會卡住n if (Console.KeyAvailable)n {n key = Console.ReadKey();n }n // 針對輸入進行處理n }nn private static void Refresh() {n // 清屏n Console.Clear();n // 將內容列印到屏幕上n }nn static void Main(string[] args)n {n Init();n // 遊戲主循環n while (true)n {n Logic();n Refresh();n }n }n }n}n
所有文章中提到的遊戲,我都開放了源碼下載。而這些工程萬變不離其宗,都用到了以上基本的遊戲邏輯循環,只要看懂了一個項目,其它都迎刃而解了。建議從《魔塔》項目開始學習,比較符合新手的理解力。
建議從簡單的回合制遊戲、貪食蛇、2048開始嘗試吧!
工程地址:
mayao11/ConsoleGames
推薦閱讀:
※git:一個本地分支可以對應多個遠程分支么?
※High Flexibility Remote Development
※為什麼說「函數式語言是沒有調用棧」的,所謂「函數式語言的思維」又是指什麼呢?