C++入門(mén)之實(shí)現(xiàn)十步萬(wàn)度游戲
參考
《C和C++游戲趣味編程》 童晶
十步萬(wàn)度游戲
用鼠標(biāo)點(diǎn)擊任意一個(gè)小圓圈,其指針順時(shí)針旋轉(zhuǎn)90度,后續(xù)被指向的圓圈指針也依次旋轉(zhuǎn),所有圓圈的旋轉(zhuǎn)度數(shù)累積。玩家點(diǎn)擊10次,嘗試得到盡量高的旋轉(zhuǎn)度數(shù)

繪制圓圈和指針
定義一個(gè)結(jié)構(gòu)體Round,用于保存圓圈的信息,成員變量有圓圈的圓心坐標(biāo)、半徑和角度。進(jìn)一步,定義一個(gè)Round類(lèi)型的二維數(shù)組,保存所有圓圈的信息
#include <graphics.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159
struct Round // 定義結(jié)構(gòu)體,用來(lái)表示帶角度指示的小圓圈
{
float x, y; // 圓心坐標(biāo)
float r; // 圓圈半徑
int angleNum; // 對(duì)應(yīng)的角度,取0、1、2、3。表示乘以PI/2后對(duì)應(yīng)的4個(gè)角度值
};
// 全局變量定義
Round rounds[5][5];
void startup() // 初始化函數(shù)
{
initgraph(600, 700);
setbkcolor(RGB(50, 50, 50));
setlinestyle(PS_SOLID, 3); // 設(shè)置線(xiàn)條樣式、線(xiàn)寬
cleardevice();
BeginBatchDraw();
int i, j;
for (i = 0; i < 5; i++) // 初始化5*5個(gè)圓圈
{
for (j = 0; j < 5; j++)
{
rounds[i][j].x = 100 + j * 100;
rounds[i][j].y = 200 + i * 100;
rounds[i][j].r = 30;
rounds[i][j].angleNum = 1; // 開(kāi)始都是PI/2
}
}
}
void show() // 繪制函數(shù)
{
int i, j;
float angle;
cleardevice();
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
setlinecolor(RGB(200, 200, 200));// 圓圈的顏色為白灰色
circle(rounds[i][j].x, rounds[i][j].y, rounds[i][j].r);
setlinecolor(RGB(255, 0, 0)); // 角度指示線(xiàn)顏色為紅色
angle = rounds[i][j].angleNum * PI / 2;
line(rounds[i][j].x, rounds[i][j].y, rounds[i][j].x + rounds[i][j].r * cos(-angle), rounds[i][j].y + rounds[i][j].r * sin(-angle));
}
}
FlushBatchDraw();
}
void update() // 更新函數(shù)
{
}
int main()
{
startup();
while (1)
{
show();
update();
}
return 0;
}
鼠標(biāo)互動(dòng)
和鍵盤(pán)交互代碼結(jié)構(gòu)類(lèi)似,實(shí)現(xiàn)基于鼠標(biāo)的交互處理:
void update()
{
ExMessage e; // 定義鼠標(biāo)消息
if (peekmessage(&e)) // 如果有鼠標(biāo)消息
{
if (e.message == WM_LBUTTONDOWN) // 如果點(diǎn)擊鼠標(biāo)左鍵
{
// 執(zhí)行相應(yīng)操作
// m.x為當(dāng)前鼠標(biāo)的x坐標(biāo),m.y為當(dāng)前鼠標(biāo)的y坐標(biāo)
}
}
}
被鼠標(biāo)點(diǎn)擊后旋轉(zhuǎn)
鼠標(biāo)點(diǎn)擊位置的坐標(biāo)為(m.x, m.y),被點(diǎn)擊的小圓圈在二維數(shù)組rounds中的行、列序號(hào)為:
int clicked_i = int(m.y - 150) / 100; int clicked_j = int(m.x - 50) / 100;
被點(diǎn)擊的小圓圈需要順時(shí)針旋轉(zhuǎn)90度,需要將angleNum值依次減?。?/p>
rounds[clicked_i][clicked_j].angleNum -= 1;
if (rounds[clicked_i][clicked_j].angleNum < 0)
{
rounds[clicked_i][clicked_j].angleNum = 3;
}
將小圓圈順時(shí)針旋轉(zhuǎn)的功能封裝在rotateRound()中:
void rotateRound(int i, int j)
{
rounds[i][j].angleNum -= 1;
if (rounds[i][j].angleNum < 0)
{
rounds[i][j].angleNum = 3;
}
}
void update() // 更新函數(shù)
{
ExMessage e;
if (peekmessage(&e))
{
if (e.message == WM_LBUTTONDOWN) // 如果點(diǎn)擊鼠標(biāo)左鍵
{
int clicked_i = int(e.y - 150) / 100; // 獲取當(dāng)前點(diǎn)擊圓圈的序號(hào)
int clicked_j = int(e.x - 50) / 100;
rotateRound(clicked_i, clicked_j);
show();
}
}
}
旋轉(zhuǎn)的傳播
當(dāng)鼠標(biāo)點(diǎn)擊一個(gè)小圓圈時(shí),小圓圈順時(shí)針旋轉(zhuǎn)90度,然后其指向的下一個(gè)圓圈繼續(xù)旋轉(zhuǎn)90度,如此迭代,直到不指向任何小圓圈為止
首先,定義一維數(shù)組indexes,存儲(chǔ)被鼠標(biāo)點(diǎn)中的小圓圈在二維數(shù)組rounds中的行列序號(hào):
int index[2] = {clicked_i, clicked_j};
定義函數(shù)int GetNextIndexes(int indexes[2]),根據(jù)當(dāng)前小圓圈的序號(hào)indexes[0]、indexes[1]和當(dāng)前小圓圈的角度angleNum,首先求出其指向小圓圈的序號(hào)。如果指向的小圓圈超出邊界,函數(shù)返回0;如果指向一個(gè)有效的小圓圈,就把其序號(hào)更新到數(shù)組indexes中,函數(shù)返回1
int GetNextIndexes(int indexes[2])
{
int i = indexes[0];
int j = indexes[1];
// 根據(jù)當(dāng)前圓圈的角度,獲得下一個(gè)小圓圈的序號(hào)
if (rounds[i][j].angleNum == 0) // 指向右邊的
{
j++;
}
else if (rounds[i][j].angleNum == 3) // 指向下邊
{
i++;
}
else if (rounds[i][j].angleNum == 2) // 指向左邊
{
j--;
}
else if (rounds[i][j].angleNum == 1) // 指向上邊
{
i--;
}
indexes[0] = i;
indexes[1] = j;
if (i >= 0 && i < 5 && j >= 0 && j < 5)
{
return 1;
}
else
{
return 0;
}
}
得分顯示
定義全局變量step和score記錄剩下的操作步數(shù)和一共旋轉(zhuǎn)的度數(shù):
int step; int score;
在show()函數(shù)中輸出相關(guān)的文字信息:
void show() // 繪制函數(shù)
{
TCHAR s[20]; // 要輸出的字符串
setbkmode(TRANSPARENT); // 透明顯示文字
swprintf_s(s, _T("%d 步 %d 度"), step, score); // 把整數(shù)轉(zhuǎn)換為字符串
settextstyle(50, 0, _T("宋體"));
outtextxy(150, 30, s); // 在xy位置輸出字符串文字
settextstyle(20, 0, _T("宋體"));
outtextxy(15, 100, _T("點(diǎn)擊一個(gè)圓圈 其指針順時(shí)針旋轉(zhuǎn)90度之后 指向的指針依次旋轉(zhuǎn)"));
FlushBatchDraw();
FlushBatchDraw();
}
每旋轉(zhuǎn)一次,得分增加90度:
void rotateRound(int i, int j)
{
score += 90;
}
鼠標(biāo)每操作一次,step減1:
if (e.message == WM_LBUTTONDOWN && step > 0)
{
step--;
}
完整代碼
#include <graphics.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159
struct Round // 定義結(jié)構(gòu)體,用來(lái)表示帶角度指示的小圓圈
{
float x, y; // 圓心坐標(biāo)
float r; // 圓圈半徑
int angleNum; // 對(duì)應(yīng)的角度,取0、1、2、3。表示乘以PI/2后對(duì)應(yīng)的4個(gè)角度值
};
// 全局變量定義
Round rounds[5][5];
int step;
int score;
void startup() // 初始化函數(shù)
{
initgraph(600, 700);
setbkcolor(RGB(50, 50, 50));
setlinestyle(PS_SOLID, 3); // 設(shè)置線(xiàn)條樣式、線(xiàn)寬
cleardevice();
BeginBatchDraw();
step = 10;
score = 0;
int i, j;
for (i = 0; i < 5; i++) // 初始化5*5個(gè)圓圈
{
for (j = 0; j < 5; j++)
{
rounds[i][j].x = 100 + j * 100;
rounds[i][j].y = 200 + i * 100;
rounds[i][j].r = 30;
rounds[i][j].angleNum = 1; // 開(kāi)始都是PI/2
}
}
}
void show() // 繪制函數(shù)
{
int i, j;
float angle;
cleardevice();
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
setlinecolor(RGB(200, 200, 200));// 圓圈的顏色為白灰色
circle(rounds[i][j].x, rounds[i][j].y, rounds[i][j].r);
setlinecolor(RGB(255, 0, 0)); // 角度指示線(xiàn)顏色為紅色
angle = rounds[i][j].angleNum * PI / 2;
line(rounds[i][j].x, rounds[i][j].y, rounds[i][j].x + rounds[i][j].r * cos(-angle), rounds[i][j].y + rounds[i][j].r * sin(-angle));
}
}
TCHAR s[20]; // 要輸出的字符串
setbkmode(TRANSPARENT); // 透明顯示文字
swprintf_s(s, _T("%d 步 %d 度"), step, score); // 把整數(shù)轉(zhuǎn)換為字符串
settextstyle(50, 0, _T("宋體"));
outtextxy(150, 30, s); // 在xy位置輸出字符串文字
settextstyle(20, 0, _T("宋體"));
outtextxy(15, 100, _T("點(diǎn)擊一個(gè)圓圈 其指針順時(shí)針旋轉(zhuǎn)90度之后 指向的指針依次旋轉(zhuǎn)"));
FlushBatchDraw();
}
void rotateRound(int i, int j)
{
rounds[i][j].angleNum -= 1;
if (rounds[i][j].angleNum < 0)
{
rounds[i][j].angleNum = 3;
}
score += 90;
}
int GetNextIndexes(int indexes[2])
{
int i = indexes[0];
int j = indexes[1];
// 根據(jù)當(dāng)前圓圈的角度,獲得下一個(gè)小圓圈的序號(hào)
if (rounds[i][j].angleNum == 0) // 指向右邊的
{
j++;
}
else if (rounds[i][j].angleNum == 3) // 指向下邊
{
i++;
}
else if (rounds[i][j].angleNum == 2) // 指向左邊
{
j--;
}
else if (rounds[i][j].angleNum == 1) // 指向上邊
{
i--;
}
indexes[0] = i;
indexes[1] = j;
if (i >= 0 && i < 5 && j >= 0 && j < 5)
{
return 1;
}
else
{
return 0;
}
}
void update() // 更新函數(shù)
{
ExMessage e;
if (peekmessage(&e))
{
if (e.message == WM_LBUTTONDOWN && step > 0) // 如果點(diǎn)擊鼠標(biāo)左鍵
{
int clicked_i = int(e.y - 150) / 100; // 獲取當(dāng)前點(diǎn)擊圓圈的序號(hào)
int clicked_j = int(e.x - 50) / 100;
rotateRound(clicked_i, clicked_j);
show();
Sleep(300);
int indexes[2] = { clicked_i, clicked_j }; // 存儲(chǔ)當(dāng)前點(diǎn)擊圓圈的序號(hào)
while (GetNextIndexes(indexes)) // 依次獲取指向的下一個(gè)圓圈
{
rotateRound(indexes[0], indexes[1]);
show();
Sleep(300);
}
}
}
}
int main()
{
startup();
while (1)
{
show();
update();
}
return 0;
}

到此這篇關(guān)于C++入門(mén)實(shí)現(xiàn)十步萬(wàn)度游戲的文章就介紹到這了,更多相關(guān)C++十步萬(wàn)度游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示
這篇文章主要介紹了c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
基于Qt OpenCV實(shí)現(xiàn)圖像數(shù)據(jù)采集軟件
這篇文章主要為大家詳細(xì)介紹了如何利用Qt+OpenCV實(shí)現(xiàn)圖像數(shù)據(jù)采集軟件,文中的示例代碼講解詳細(xì),對(duì)我學(xué)習(xí)或工作有一定參考價(jià)值,感興趣的可以了解一下2022-07-07
詳解C++語(yǔ)言中的加法運(yùn)算符與賦值運(yùn)算符的用法
這篇文章主要介紹了C++語(yǔ)言中的加法運(yùn)算符與賦值運(yùn)算符的用法,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01
Matlab實(shí)現(xiàn)二維散點(diǎn)主方向直方圖的繪制詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Matlab實(shí)現(xiàn)二維散點(diǎn)主方向直方圖的繪制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下2022-09-09

