C++十步万度游戏 C++入门之实现十步万度游戏
cqu_shuai 人气:1想了解C++入门之实现十步万度游戏的相关内容吗,cqu_shuai在本文为您仔细讲解C++十步万度游戏的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:C++十步万度游戏,C++游戏,下面大家一起来学习吧。
参考
《C和C++游戏趣味编程》 童晶
十步万度游戏
用鼠标点击任意一个小圆圈,其指针顺时针旋转90度,后续被指向的圆圈指针也依次旋转,所有圆圈的旋转度数累积。玩家点击10次,尝试得到尽量高的旋转度数
绘制圆圈和指针
定义一个结构体Round,用于保存圆圈的信息,成员变量有圆圈的圆心坐标、半径和角度。进一步,定义一个Round类型的二维数组,保存所有圆圈的信息
#include <graphics.h> #include <conio.h> #include <math.h> #define PI 3.14159 struct Round // 定义结构体,用来表示带角度指示的小圆圈 { float x, y; // 圆心坐标 float r; // 圆圈半径 int angleNum; // 对应的角度,取0、1、2、3。表示乘以PI/2后对应的4个角度值 }; // 全局变量定义 Round rounds[5][5]; void startup() // 初始化函数 { initgraph(600, 700); setbkcolor(RGB(50, 50, 50)); setlinestyle(PS_SOLID, 3); // 设置线条样式、线宽 cleardevice(); BeginBatchDraw(); int i, j; for (i = 0; i < 5; i++) // 初始化5*5个圆圈 { 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; // 开始都是PI/2 } } } void show() // 绘制函数 { 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)); // 角度指示线颜色为红色 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() // 更新函数 { } int main() { startup(); while (1) { show(); update(); } return 0; }
鼠标互动
和键盘交互代码结构类似,实现基于鼠标的交互处理:
void update() { ExMessage e; // 定义鼠标消息 if (peekmessage(&e)) // 如果有鼠标消息 { if (e.message == WM_LBUTTONDOWN) // 如果点击鼠标左键 { // 执行相应操作 // m.x为当前鼠标的x坐标,m.y为当前鼠标的y坐标 } } }
被鼠标点击后旋转
鼠标点击位置的坐标为(m.x, m.y),被点击的小圆圈在二维数组rounds中的行、列序号为:
int clicked_i = int(m.y - 150) / 100; int clicked_j = int(m.x - 50) / 100;
被点击的小圆圈需要顺时针旋转90度,需要将angleNum值依次减小:
rounds[clicked_i][clicked_j].angleNum -= 1; if (rounds[clicked_i][clicked_j].angleNum < 0) { rounds[clicked_i][clicked_j].angleNum = 3; }
将小圆圈顺时针旋转的功能封装在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() // 更新函数 { ExMessage e; if (peekmessage(&e)) { if (e.message == WM_LBUTTONDOWN) // 如果点击鼠标左键 { int clicked_i = int(e.y - 150) / 100; // 获取当前点击圆圈的序号 int clicked_j = int(e.x - 50) / 100; rotateRound(clicked_i, clicked_j); show(); } } }
旋转的传播
当鼠标点击一个小圆圈时,小圆圈顺时针旋转90度,然后其指向的下一个圆圈继续旋转90度,如此迭代,直到不指向任何小圆圈为止
首先,定义一维数组indexes,存储被鼠标点中的小圆圈在二维数组rounds中的行列序号:
int index[2] = {clicked_i, clicked_j};
定义函数int GetNextIndexes(int indexes[2]),根据当前小圆圈的序号indexes[0]、indexes[1]和当前小圆圈的角度angleNum,首先求出其指向小圆圈的序号。如果指向的小圆圈超出边界,函数返回0;如果指向一个有效的小圆圈,就把其序号更新到数组indexes中,函数返回1
int GetNextIndexes(int indexes[2]) { int i = indexes[0]; int j = indexes[1]; // 根据当前圆圈的角度,获得下一个小圆圈的序号 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记录剩下的操作步数和一共旋转的度数:
int step; int score;
在show()函数中输出相关的文字信息:
void show() // 绘制函数 { TCHAR s[20]; // 要输出的字符串 setbkmode(TRANSPARENT); // 透明显示文字 swprintf_s(s, _T("%d 步 %d 度"), step, score); // 把整数转换为字符串 settextstyle(50, 0, _T("宋体")); outtextxy(150, 30, s); // 在xy位置输出字符串文字 settextstyle(20, 0, _T("宋体")); outtextxy(15, 100, _T("点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转")); FlushBatchDraw(); FlushBatchDraw(); }
每旋转一次,得分增加90度:
void rotateRound(int i, int j) { score += 90; }
鼠标每操作一次,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 // 定义结构体,用来表示带角度指示的小圆圈 { float x, y; // 圆心坐标 float r; // 圆圈半径 int angleNum; // 对应的角度,取0、1、2、3。表示乘以PI/2后对应的4个角度值 }; // 全局变量定义 Round rounds[5][5]; int step; int score; void startup() // 初始化函数 { initgraph(600, 700); setbkcolor(RGB(50, 50, 50)); setlinestyle(PS_SOLID, 3); // 设置线条样式、线宽 cleardevice(); BeginBatchDraw(); step = 10; score = 0; int i, j; for (i = 0; i < 5; i++) // 初始化5*5个圆圈 { 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; // 开始都是PI/2 } } } void show() // 绘制函数 { 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)); // 角度指示线颜色为红色 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); // 把整数转换为字符串 settextstyle(50, 0, _T("宋体")); outtextxy(150, 30, s); // 在xy位置输出字符串文字 settextstyle(20, 0, _T("宋体")); outtextxy(15, 100, _T("点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转")); 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]; // 根据当前圆圈的角度,获得下一个小圆圈的序号 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() // 更新函数 { ExMessage e; if (peekmessage(&e)) { if (e.message == WM_LBUTTONDOWN && step > 0) // 如果点击鼠标左键 { int clicked_i = int(e.y - 150) / 100; // 获取当前点击圆圈的序号 int clicked_j = int(e.x - 50) / 100; rotateRound(clicked_i, clicked_j); show(); Sleep(300); int indexes[2] = { clicked_i, clicked_j }; // 存储当前点击圆圈的序号 while (GetNextIndexes(indexes)) // 依次获取指向的下一个圆圈 { rotateRound(indexes[0], indexes[1]); show(); Sleep(300); } } } } int main() { startup(); while (1) { show(); update(); } return 0; }
加载全部内容