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;
}
到此这篇关于C++入门实现十步万度游戏的文章就介绍到这了,更多相关C++十步万度游戏内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341