文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

参考

《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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯