栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++入门——实现十步万度游戏

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++入门——实现十步万度游戏

参考
  1. 《C和C++游戏趣味编程》 童晶
十步万度游戏

用鼠标点击任意一个小圆圈,其指针顺时针旋转90度,后续被指向的圆圈指针也依次旋转,所有圆圈的旋转度数累积。玩家点击10次,尝试得到尽量高的旋转度数

绘制圆圈和指针

定义一个结构体Round,用于保存圆圈的信息,成员变量有圆圈的圆心坐标、半径和角度。进一步,定义一个Round类型的二维数组,保存所有圆圈的信息

#include 
#include 
#include 
#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 
#include 
#include 
#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;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/296796.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号