EasyX见缝插针

话不多说,先上图

EasyX见缝插针

如何实现一个见缝插针游戏??

  1. 如何绘制圆盘与针
  2. 如何实现旋转
  3. 如何按下空格发射针
  4. 如何判定游戏输赢

1.绘制圆盘以及一根针

#include<graphics.h>
#include<conio.h>
#define WIDTH 800  //窗口的宽
#define HEIGHT 600  //窗口的高

int main()
{
	initgraph(WIDTH, HEIGHT);       //初始化窗口
	setbkcolor(RGB(255, 255, 255)); //设置背景色为白色
	cleardevice();    //清屏
	//画针
	setlinestyle(PS_SOLID, 3);  //实线 线宽为3
	setlinecolor(RGB(0, 0, 0)); //设置线颜色为黑色
	line(WIDTH / 2, HEIGHT / 2, WIDTH / 2 + 160, HEIGHT / 2);

	//绘制圆盘
	setlinecolor(HSVtoRGB(0,0.9,0.8));
	circle(WIDTH / 2, HEIGHT / 2, 60);
	_getch();

	closegraph();  //关闭窗口
	system("pause");
	return 0;
}

在这里插入图片描述

2.实现针的旋转

  • 实现旋转时,注意此时的二维坐标系的Y轴与我们平时使用的二维坐标系是相反的

  • 实现顺时针旋转使用sin(角度)

  • 实现逆时针旋转使用sin(-角度)
    在这里插入图片描述

  • 实现A到B为顺时针旋转
    则Y轴坐标为圆心Y坐标+Rsin(角度)

  • 实现B到A为逆时针旋转
    则Y轴坐标为圆心Y坐标+Rsin(-角度)

  • X轴cos(-角度)或者cos(角度)正负均可

  • 双缓冲绘图(批量绘图),解决循环绘图出现的闪屏现象

#include<graphics.h>
#include<conio.h>
#include<math.h>
#define WIDTH 800  //窗口的宽
#define HEIGHT 600  //窗口的高
#define PI 3.1415926

int main()
{
	initgraph(WIDTH, HEIGHT);
	float lineLength = 160;                //针的长度
	float xEnd = (WIDTH / 2) + lineLength;  //针的末端x坐标
	float yEnd = HEIGHT / 2;                 //针的末端y坐标
	float angle = 0;                      //针的旋转角度
	float rotateSpeed = PI / 360;        //旋转的速度
	setbkcolor(RGB(255, 255, 255));    //设置背景色为白色
	cleardevice();    //清屏
	while (1)
	{
		//加双缓冲绘图防止闪屏
		BeginBatchDraw();
		cleardevice();
		angle += rotateSpeed;        //增加角度
		if (angle > PI * 2)          //防止angle无限增加而导致越界
			angle -= 2 * PI;
		xEnd = lineLength * cos(-angle) + WIDTH / 2;
		yEnd = lineLength * sin(angle) + HEIGHT / 2;
		//画针
		setlinestyle(PS_SOLID, 3);  //实线 线宽为3
		setlinecolor(RGB(0, 0, 0)); //设置线颜色为黑色
		line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);

		//绘制圆盘
		setlinecolor(HSVtoRGB(0, 0.9, 0.8));
		circle(WIDTH / 2, HEIGHT / 2, 60);

		Sleep(10);
		EndBatchDraw();
	}
	
	_getch();

	closegraph();  //关闭窗口
	system("pause");
	return 0;
}

在这里插入图片描述

3.实现多个针的绘制以及旋转

  • 需要一个针的初始角度数组去保存每一根针的初始角度
  • 需要变量保存针的个数
#include<graphics.h>
#include<conio.h>
#include<math.h>
#define WIDTH 800  //窗口的宽
#define HEIGHT 600  //窗口的高
#define PI 3.1415926
#define MAXSIZE 20 //针的最大个数

int main()
{
	initgraph(WIDTH, HEIGHT);
	float lineLength = 160;          //针的长度
	float xEnd = (WIDTH / 2) + lineLength;  //针的终点X坐标
	float yEnd = HEIGHT / 2;                //针的终点Y坐标
	float angle[MAXSIZE] = { 0 };        //针的旋转角度
	float rotateSpeed = PI / 360;      //旋转的速度
	//设置每一根针的偏转角度
	for (int i = 0; i < MAXSIZE; i++)
	{
		angle[i] = i * (2 * PI / MAXSIZE);
	}
	setbkcolor(RGB(255, 255, 255));    //设置背景色为白色
	cleardevice();                     //清屏
	while (1)
	{
		//加双缓冲绘图防止闪屏
		BeginBatchDraw();
		cleardevice();

		//绘制全部的针
		for (int i = 0; i < MAXSIZE; i++)
		{
			angle[i] += rotateSpeed;       //增加针的初始角度实现旋转效果
			if (angle[i] > PI * 2)
				angle[i] -= 2 * PI;
			xEnd = lineLength * cos(-angle[i]) + WIDTH / 2;
			yEnd = lineLength * sin(angle[i]) + HEIGHT / 2;
			//画针
			setlinestyle(PS_SOLID, 3);  //实线 线宽为3
			setlinecolor(RGB(0, 0, 0)); //设置线颜色为黑色
			line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);
		}
		//绘制圆盘
		setlinecolor(HSVtoRGB(0, 0.9, 0.8));
		setfillcolor(HSVtoRGB(0, 0.9, 0.8));
		fillcircle(WIDTH / 2, HEIGHT / 2, 60);

		Sleep(10);
		EndBatchDraw();
	}
	_getch();
	closegraph();  //关闭窗口
	system("pause");
	return 0;
}

在这里插入图片描述

4.实现用户插入的那根针,以及用户按键操作

  • 通过函数实现各个功能
  • 需要使用全局变量以及static全局变量
#include<graphics.h>
#include<conio.h>
#include<math.h>
#define WIDTH 800  //窗口的宽
#define HEIGHT 600  //窗口的高
#define LINELENGTH 160   //针的长度
#define PI 3.1415926

static int lineNum = 0;           //初始化针的个数为0根
float angle[180] = { 0 };        //每个针的旋转角度数组
float xEnd = 0;                  //针的终点X坐标
float yEnd = 0;                  //针的中断Y坐标
float rotateSpeed = PI / 360;      //旋转的速度

//添加针以及初始化当前针的角度
void beamNeedle()
{
	angle[lineNum++] = PI;   //新针初始角度为PI
	//初始化针的末端坐标
	xEnd = LINELENGTH * cos(-angle[lineNum - 1]) + WIDTH / 2;
	yEnd = LINELENGTH * sin(angle[lineNum - 1]) + HEIGHT / 2;
	line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);   //绘制针
}
//针的旋转
void needleRotate()
{
	for (int i = 0; i < lineNum; i++)
	{
		angle[i] += rotateSpeed;        //增加角度
		if (angle[i] > PI * 2)
			angle[i] -= 2 * PI;
		xEnd = LINELENGTH * cos(-angle[i]) + WIDTH / 2;
		yEnd = LINELENGTH * sin(angle[i]) + HEIGHT / 2;
		line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);
	}
}
//用户按键处理
void userKey()
{
	if (_kbhit())    //检测是否存在按键
	{
		char userKey = _getch();  //保存用户输入的按键
		if (userKey == ' ')       //按键为空格就发射针
		{
			beamNeedle();      //调用添加针以及初始化当前针的角度
		}
	}
}
//绘制圆盘
void drawCircle()
{
	setlinecolor(HSVtoRGB(0, 0.9, 0.8));
	setfillcolor(HSVtoRGB(0, 0.9, 0.8));
	fillcircle(WIDTH / 2, HEIGHT / 2, 60);
}
//绘制发射的针(左侧的那根针)
void stoneNeedle()
{
	//绘制一根发射的针
	setlinecolor(RGB(0, 0, 0));
	setlinestyle(PS_SOLID, 3);  //实线 线宽为3
	line(0, HEIGHT / 2, LINELENGTH, HEIGHT / 2);
}

int main()
{
	initgraph(WIDTH, HEIGHT);
	setbkcolor(RGB(255, 255, 255)); //设置背景色为白色
	cleardevice();    //清屏
	while (1)
	{
		//加双缓冲绘图防止闪屏
		BeginBatchDraw();
		cleardevice();

		stoneNeedle();    //绘制发射的针
		needleRotate();   //绘制所有的针
		userKey();        //获取用户输入
		drawCircle();      //绘制圆盘

		Sleep(10);
		EndBatchDraw();
	}

	closegraph();  //关闭窗口
	system("pause");
	return 0;
}

在这里插入图片描述

5.实现游戏结束处理,以及分数的绘制

  • 游戏结束的判断
  • 只需要遍历圆盘上的针,当它们的角度差<PI/60时,做出重玩游戏还是退出的处理
  • 头文件添加

因为使用了求绝对值的函数,因此需要加 math.h

#include<math.h>
void dieGame()
{
	for (int i = 0; i < lineNum - 1; i++)  //当前针与之前所有针比较
	{
		if (lineNum == 0)
		{
			printf("没有针啊!\n");
			break;
		}
		if (fabs(angle[lineNum - 1] - angle[i]) < PI / 60)
		{
			int isok = MessageBox(GetHWnd(), "Low B you Die! 是否退出?",
			 "游戏结束", MB_YESNO | MB_ICONWARNING); //显示警告
			if (MouseHit())    //监听鼠标消息
			{
				MOUSEMSG msg = GetMouseMsg();
				if (isok == IDYES)
				{
					exit(666);   //退出
				}
				else      //重新玩
				{
					lineNum = 0;  //将针的个数置为0
					cleardevice();
				}
			}
		}
	}
}
  • 分数的绘制
  • 加处理安全检查的宏定义
  • 由于需要使用sprintf()函数因此需要做上一步安全性检查的处理
#define _CRT_SECURE_NO_WARNINGS
  • 添加一个全局变量用于保存分数
int score = 0;   //分数
  • 实现分数的变化
  • 实现分数变化只需要在游戏判断输赢中做处理即可
void dieGame()
{
	for (int i = 0; i < lineNum - 1; i++)  //当前针与之前所有针比较
	{
		if (lineNum == 0)
		{
			printf("没有针啊!\n");
			break;
		}
		if (fabs(angle[lineNum - 1] - angle[i]) < PI / 60)
		{
			int isok = MessageBox(GetHWnd(), "Low B you Die! 是否退出?", "游戏结束", MB_YESNO | MB_ICONWARNING); //显示警告
			if (MouseHit())    //监听鼠标消息
			{
				MOUSEMSG msg = GetMouseMsg();
				if (isok == IDYES)
				{
					exit(666);   //退出
				}
				else
				{
					lineNum = 0;  //将针的个数置为0
					cleardevice();
				}
			}
		}
	}
	score = lineNum * 10;
}
  • 实现分数的绘制
//绘制分数
void printScore()
{
	char buffer[20] = "";
	sprintf(buffer, "分数: %d", score);
	settextcolor(RGB(255, 0, 255));
	settextstyle(50, 0, "宋体");
	outtextxy(20, 20, buffer);
}

在这里插入图片描述

6.增加游戏的趣味性

  • 随机针的颜色
    只需要不断随机改变绘制针的颜色即可
    头文件引入
#include<time.h>
//针的旋转
void needleRotate()
{
	//*********************************************************
	srand((unsigned int)time(NULL));   //随机数随时间变化
	//*********************************************************
	for (int i = 0; i < lineNum; i++)
	{
		angle[i] += rotateSpeed;        //增加角度
		if (angle[i] > PI * 2)
			angle[i] -= 2 * PI;
		xEnd = LINELENGTH * cos(-angle[i]) + WIDTH / 2;
		yEnd = LINELENGTH * sin(angle[i]) + HEIGHT / 2;
		//*********************************************************
		setlinecolor(RGB(rand()%256, rand()%256, rand()%256));  //随机改变颜色
		//*********************************************************
		line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);
	}
}
  • 圆盘上有一定针的时候,加快旋转速度
//针的旋转
void needleRotate()
{
	srand((unsigned int)time(NULL));   //随机数随时间变化
	//*********************************************************
		if (lineNum >= 10 && lineNum < 20)   //随针变多,速度增加
	{
		rotateSpeed = 2 * PI / 360;    //旋转速度变为原来的两倍
	}
	else if (lineNum >= 20)
	{
		rotateSpeed = 3 * PI / 360;   //旋转速度变为原来的三倍
	}
	//*********************************************************
	for (int i = 0; i < lineNum; i++)
	{
		angle[i] += rotateSpeed;        //增加角度
		if (angle[i] > PI * 2)
			angle[i] -= 2 * PI;
		xEnd = LINELENGTH * cos(-angle[i]) + WIDTH / 2;
		yEnd = LINELENGTH * sin(angle[i]) + HEIGHT / 2;
		setlinecolor(RGB(rand()%256, rand()%256, rand()%256));
		line(WIDTH / 2, HEIGHT / 2, xEnd, yEnd);
	}
}

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石小浪♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值