陳兵 王雪梅
關(guān)鍵詞:C語言;EasyX;項目化教學;教學研究;彈球游戲
1 引言
C語言是大學理工科專業(yè)的必修課,是編程的入門課程,為學生的編程實踐和計算機理論打好基礎(chǔ)。在編程語言教學中,項目化教學的重要性越來越被認識到,但是由于C語言是偏底層語言,C語言開發(fā)環(huán)境不像開發(fā)Java程序那樣自帶圖形、界面等一些庫,因此用C語言編寫應(yīng)用并不非常方便,這就為在C語言教學中開展項目化教學帶來了困難[1]。
2 EasyX 圖形庫
EasyX是一個可以用C、C++語言進行編程的免費繪圖庫,可以幫助C/C++ 初學者快速上手圖形和游戲編程。如官網(wǎng)介紹的那樣,“EasyX Graphics Library 是針對Visual C++ 的免費繪圖庫,支持VC6.0 ~VC2022,簡單易用,學習成本極低,應(yīng)用領(lǐng)域廣泛。目前已有許多大學將EasyX 應(yīng)用在教學當中?!焙喲灾?,EasyX有如下特點:
1) EasyX安裝簡單,對包含VC6.0之后的VC各版本都支持。
2) EasyX使用簡單,利用簡單的繪圖函數(shù)和如顏色、坐標幾個繪圖相關(guān)的基本概念就能編寫圖形和游戲程序。
可以說,EasyX庫的繪圖功能是基礎(chǔ)且充分的,對語言初學者很友好,讓初學者可以專注在編程語言課程知識上,不被繪圖部分牽扯太多精力。利用EasyX 編寫包括游戲類的程序可以激發(fā)的學生的學習興趣。因此,利用EasyX 圖形庫編寫圖形、游戲,是C 以及C++語言進行項目化教學非常合適的工具[2]。
3 項目案例
下面,介紹一下對項目設(shè)計的總體思考。常見的游戲項目有井字棋[3]、貪吃蛇[4]、碰撞的球等,由于碰撞的球總體難度相對較低,而且在MDN(Mozilla 開發(fā)者社區(qū))等教程中也被使用,故本文就以碰撞的球項目為例。
由于一下子將項目的整個內(nèi)容呈現(xiàn)在學生面前可能加大學生的接受難度,因此可以將項目分為基礎(chǔ)項目和強化項目這樣兩階段的形式?;A(chǔ)項目難度較低,強化項目在基礎(chǔ)項目的基礎(chǔ)上增加一些功能,并增加實現(xiàn)難度。比如,基礎(chǔ)項目的形式是提供代碼片段,讓學生整合代碼,強化項目可以提高更少的代碼,讓學生自己補充部分代碼?;A(chǔ)項目和強化項目合起來基本涵蓋了C語言的主要語法,包括選擇、循環(huán)、數(shù)組、函數(shù)、指針、結(jié)構(gòu)體等?;A(chǔ)項目和強化項目可以分前后兩個階段,在學期末作為個人或者分組項目作業(yè)布置到班級中去。
比如,對于碰撞的球項目來說,基礎(chǔ)項目是實現(xiàn)碰撞的球。即多個灰度不同的球(隨機產(chǎn)生的)在窗口中以不同的速度運動(隨機產(chǎn)生水平和豎直運動速度),碰到窗口邊框就反彈,兩個球之間相互碰到則將它們的灰度都變成一樣的(隨機產(chǎn)生的)?;A(chǔ)項目應(yīng)用到了選擇、循環(huán)、數(shù)組、函數(shù)等知識點。(為了方便打印,各個球的顏色是R、G、B分量都相同的灰色,也完全可以是R、G、B不同的彩色)
而強化項目,在基礎(chǔ)項目的基礎(chǔ)上,再實現(xiàn)一個用鍵盤控制的特殊的球(下圖中白邊的小球,可以進行水平移動和豎直移動)來“吃掉”其他的球,即碰到其他的球就讓被碰到的球消失。強化項目要用鍵盤控制白色小球,因此還用到了EaysX的peekmessage函數(shù)來接收鍵盤按下事件,該函數(shù)的參數(shù)還用到了指針和結(jié)構(gòu)體。故與基礎(chǔ)項目一起,整個項目基本涵蓋了C語言的主要知識點。
由于基礎(chǔ)項目和強化項目涵蓋了C語言的大部分知識點,因此需要在期末推出項目。如果希望盡早在教學中引入項目,比如在教授完選擇和循環(huán)后就希望推出項目,那么可以另行采用其他項目,或者采用碰撞的球的簡化版本,比如,實現(xiàn)單個球的碰撞,這樣就不需要使用類似數(shù)組這樣課程偏后面的知識點。單個球的碰撞項目,仍然可以采用基礎(chǔ)項目和強化項目這樣的兩階段的形式。比如,基礎(chǔ)項目是實現(xiàn)單個球的碰撞到邊緣的反彈,任務(wù)提供代碼片段,學生只需要代碼整合;而強化項目是反彈模式發(fā)生變化,比如碰到左邊緣,從右邊緣出來,反之亦然,并且只提供部分代碼。這樣難度就有階梯。項目案例從易到繁,迭代式地引入課堂中,也是類似五星教學法所推薦的模式[5]。
3.1 碰撞的球之基礎(chǔ)項目
下面給出期末版本的基礎(chǔ)項目的各個子任務(wù)的例子,以做參考。
1) 給出代碼框架,并做出解釋。
#define BALL_NUMBER 20
#define WIDTH 640
#define HEIGHT 480
int random(int min, int max);
int main(){
int x[BALL_NUMBER] = {0}, y[BALL_
NUMBER] = {0}, radius[BALL_NUMBER] = {0}, velX
[BALL_NUMBER]={0}, velY[BALL_NUMBER] = {0};
COLORREF color[BALL_NUMBER] = {0};
int i = 0, j = 0;
//初始化動畫窗口,并設(shè)置大小
initgraph(WIDTH, HEIGHT);
//使每次的隨機數(shù)序列不同
srand((unsigned) time(NULL));
//初始化圓球
...
//核心動畫代碼
...
closegraph();
return 0;
}
int random(int min, int max){
return rand() % (max - min + 1) + min;
}
其中,BALL_NUMBER 是定義球的數(shù)量的宏,WIDTH 和HEIGHT分別是定義窗口寬和高的宏。x、y、radius、velX、velY和color數(shù)組分別保存圓球的x坐標、y坐標、半徑、x方向的速度、y方向的速度和顏色。random函數(shù)隨機產(chǎn)生在兩個參數(shù)min和max的之間的整數(shù),在后續(xù)的任務(wù)中被用到。
2) 初始化圓球處補充代碼:
for(i = 0; i < BALL_NUMBER; i++){
radius[i] = random(10, 20);
x[i] = random(0 + radius[i], WIDTH - radius[i]);
y[i] = random(0 + radius[i], HEIGHT - radius[i]);
velX[i] = random(-5, 5);
該代碼隨機產(chǎn)生一定范圍的整數(shù)值,用來初始化各個圓的半徑、x坐標、y、坐標、x方向速度、y方向速度、顏色值。其中RGB是EasyX庫的帶參數(shù)的宏,用于將紅、綠、藍顏色分量合成顏色。代碼中這3個分量都相同,產(chǎn)生的是灰色。
3) 核心動畫代碼處框架如下:
上面代碼中4個if分別判斷各個圓球是否與右、左、下、上四個邊緣發(fā)生碰撞,如果發(fā)生,則相應(yīng)修改圓球的移動速度屬性,這樣動畫中就有邊緣碰撞引起的反彈效果。
6) 繪圖代碼處繼續(xù)補充代碼,做圓球之間的碰撞檢測
雙重循環(huán)檢查任意兩個不同的圓球是否發(fā)生的碰撞,一旦發(fā)生碰撞,則將碰撞的兩個圓球都設(shè)置成一個隨機產(chǎn)生的新顏色。
以上就給出了完成基礎(chǔ)項目的6個子任務(wù)。這6 個子任務(wù)的代碼都是提供出來的,學生只要將各個任務(wù)代碼整合就可以完成這個階段。這樣項目難度就降低了??梢愿鶕?jù)實際情況增減難度,比如可以去掉部分核心語句,要求學生補充。顯然,這是與學生水平相關(guān)的。強化項目階段可以比基本項目再適當增加難度。
3.2 碰撞的球之強化項目
強化項目在基礎(chǔ)項目的基礎(chǔ)上,使用了一個獨特的白色無填充的球來“吃”其他普通的球,這個白球可以用鍵盤進行上下左右移動控制,因此比基礎(chǔ)項目在難度上有所提高。
在強化項目任務(wù)單中,可以和基礎(chǔ)項目類似地給出框架和代碼,如果要增加難度,那么部分代碼可以讓學生來補充。代碼框架如下:
相比基礎(chǔ)項目,強化項目為多個普通碰撞球添加了一個標志是否存在的數(shù)組exists[BALL_NUMBER],數(shù)組每個元素表示對應(yīng)的普通球是否已經(jīng)被白球“吃”掉,初始化為1,表示還存在,被“吃”掉后則修改為0。鍵盤w、s、a、d按下分別控制白球的上、下、左、右移動,EasyX中需要使用peekmessage函數(shù)來獲取按鍵被按下事件。下面代碼中變量m是ExMessage類型的,用來存儲鍵盤消息,處理白球移動的代碼如下:
如同基礎(chǔ)項目那樣,后面可以針對代碼框架中的代碼塊布置一些子任務(wù),這里就省略了。子任務(wù)的難度可以通過要學生補充代碼的多少來控制。
3.3 項目實施的感悟
項目化教學案例還可以用井字棋游戲、翻牌游戲等。個人在項目教學設(shè)計方面有一些感悟,就是往往在選擇案例和如何實現(xiàn)案例時顧慮較多,可能會出現(xiàn)項目出錯、不完善的情況。項目設(shè)計的時候也許不需要過于糾結(jié)它們的細節(jié)和可玩性等方面問題,邏輯清楚、實現(xiàn)較簡單的項目就可以起到引領(lǐng)學生入門的作用,因為更重要的是提高學生學習興趣,后期學生可以自行增加一些感興趣的復雜功能。例如,碰撞的球例子里面兩個球碰撞時,也許教師的第一反應(yīng)是如同現(xiàn)實那樣實現(xiàn)兩個球的反彈,但是這個實現(xiàn)難度就提高了。與其為了項目更加“完善”和“真實”,不如適當簡化項目,讓學生更易上手。
4 小結(jié)
EasyX圖形庫不但可以使用在項目化教學中,而且在C語言各章的教學中就可以用EasyX編寫一些小程序來展示C語言語法的在各章中的應(yīng)用。甚至在C++語言的教學中仍然可以使用EasyX,即接著用面向?qū)ο蠓绞絹砭帉懘a。總體來看,EasyX可以在C/C++的教學中起到較為積極的作用,性價比還是不錯的。