項目是彈跳小球,其遊戲規則是:小球在牆壁間運動,若碰到牆壁或擋板則反彈,擊中磚塊可得分。玩家控制一個擋板,如果小球越過擋板,遊戲結束。
本文將以循序漸進的方法引導讀者完成項目。先實現一個會跳的小球,關於控制擋板、計分、畫牆壁等內容將在以後發佈。對於所需語法知識的學習請多查閱課本。製作本項目前所需知識:集成開發環境CodeBlock的初步用法(如新建項目、調試)
1、 顯示一個靜止的小球
所需語法知識:標識符、變量、常量、運算符與表達式、cout、for語句的用法。
目的:在控制檯的第5行第10個字符位畫出小球“o”。
思路:先輸出4個換行符,再輸出9個空格,再輸出“o”,最後輸出換行符(爲什麼?)。
代碼:自己想。。。。。。
2、 顯示一個下落的小球
所需語法知識:1所需的、清屏函數
清屏函數:實現清屏功能,包含在頭文件stdlib.h下,使用時寫下語句system(“cls”)即可。
目的:讓一個小球從控制檯的第10個字符位,從第1行掉到第9行。
思路:先清屏後重畫,在每次重畫前讓小球出現行數加1。
#include
#include <stdlib.h>
using namespace std;
int main()
{
int y,x = 5;
int high = 20;
int i,j;
for(y=1;y<10;y++)//從第1行掉到第9行
{
system(“cls”);
for(i=0;i<y;i++)
cout<<endl;//輸出到球那一行之前的行
for(j=0;j<x-1;j++)
cout<<’ ';//輸出空格
cout<<‘o’<<endl; //輸出一顆球
while(i<10000000) //減慢速度
i++;
}
return 0;
}
3、 顯示一個上下彈跳的小球
所需語法知識:2所需的
目的:讓一個小球在控制檯的第10個字符位的第1行到第9行間來回移動。
思路:先清屏後重畫。在每次重畫前,計算小球位置。若小球下落,在每次重畫前讓小球出現行數加1;若小球上升,在每次重畫前讓小球出現行數減1。
4、 顯示一個斜着彈跳的小球
所需語法知識:2所需的
目的:讓一個小球在一定的區域內來回移動,當小球到達一個矩形邊界後反彈。
思路:先清屏後重畫。在每次重畫前,計算小球位置。將斜向運動分解爲橫向運動和縱向運動,由3可類比出計算原理。
以上便在控制檯實現一個會跳的小球。3、4及完整版的代碼可以在百度網盤上下載:https://pan.baidu.com/s/1dE7OKal
5、用函數重構程序
所需語法知識:函數
目的:用函數進行邏輯模塊化
思路:將main函數改爲
int main()
{
startup();
while(1)
{
show();
updateWithoutInput();
updateWithInput();
}
return 0;
}
現在正式開始介紹遊戲算法。描述算法的方式是程序框圖和僞代碼。程序框圖高中已經學習,因此先介紹僞代碼。
僞代碼
僞代碼是程序框圖與實際代碼的中間體,它有類似代碼的格式,但爲了方便不會按如C++的具體語言的語法來組織。如上篇的2就可以寫成下列的僞代碼。
x=10,y=1
for y from 1 to y
清屏 //用縮進表示循環體
for I from 1 to y
cout<<endl
for j from 1 to x
cout<<‘ ‘
cout<< ‘o’<<endl
wait for a minute
僞代碼的作用是描述算法,不考慮實現所有細節,只考慮部分細節,所以出現了“wait for a minute”“清屏”等語句。同時因爲大家在學C++,所以用了些C++中的語句來表意,如輸出換行用“cout<<endl”而不用C語言裏的“printf("\n")”
一言蔽之,僞代碼寫得別人看得懂,能表述自己的算法就行了。
彈跳小球算法
我們的任務是在控制檯的某個位置輸出已決定的字符,然後從整體上看起來是個遊戲的畫圖及決定輸出字符的位置,使畫的圖能按照遊戲規則與玩家交互。
程序開始先定義些參數,如遊戲區域、球、磚頭、擋板的位置、球的速度、分數、擊球數。然後便進入畫圖和更新的循環,如果滿足遊戲失敗條件則結束程序。我們的遊戲計算機並不理解,它只是一個能進行邏輯運算和四則運算的計算器而已。要在計算機上實現遊戲程序,必然是把遊戲轉換成計算題去實現。
程序開始後的初始化過程如果用僞代碼來表示,即是:
Startup()
ballX=5,ballY=10 球的初始位置
ballvx=1,ballvy=1 速度,分運動思想
high=20,width=25 遊戲區域
score=0 分數
ballNumber=0 擊球數
blockX=10,blockY=1 磚塊的位置
positionX=width/2,positionY=high
ridus=5
left=positionX-ridus
right=positionX+ridus 擋板
Show()
清屏
for I from 1 to high+1
for j from 1 to width
If(i=ballX&&j=ballY)
cout<<’o’
else if(I=width)
cout<<’|’
else if(j=high+1)
cout<<’_’
else if(i=positionY&&
j>=left&&
j<=right)
cout<<’*’
else if(i=blockY&&
j=blockX)
cout<<‘B’
else cout<<’ ’
更新可分爲與玩家輸入無關的更新及與玩家輸入有關的更新,若用僞代碼表示,即是:
updateWithoutInput()
if(ballY=high-1)
if (ballX>=left&&ballX<=right)
ballNumber++ //擊中擋板
else cout<<”GameOver”
<<endl
按一下鍵
exit
if(ballX=blockX&&ballY=blockY)
score++ //擊中磚塊
blockX=0~width-1的隨機數
ballX +=ballvx //球移動
ballY+=ballvy
if(ballX =0||ballX=width-1)
ballvx = -ballvx 球反彈
if(ballY=0||ballY=high-1)
ballvy=-ballvy
wait for a minute 降低難度
下面介紹有輸入的更新
updateWithInput()
if(按鍵)
input=按鍵
if (input=”a”)
positionX-- 向左移動擋板
left=positionX-ridus
right=positionX+ridus
if(input=’d’) 向右移動擋板
positionX++
left=positionX-ridus
right=positionX+ridus