8月31写的,因为时间原因(在学YOLO),未写注释,有很多内容没写,有时间再补充,先贴vs2022项目文件和代码,自己配置环境依旧需要将“字符集”改成“多字节字符集”
9月5将球的y坐标及球y轴随机速度改为浮点型,范围为-2.5到2.5,解决bot跑出窗口的问题。
9月6添加大循环,可以重复游戏,不再修改没控制台的版本,需要自行修改,将球的y坐标及球y轴随机速度改为单精度浮点型
9月14添加注释并在显示获胜玩家时取消对鼠标消息的检测
1.vs2022文件
通过网盘分享的文件:C++游戏
链接: https://pan.baidu.com/s/1aJQb1ofMnmvrkd1sfXk8Sw?pwd=2n8w 提取码: 2n8w

2.代码,注释的printf语句是我测试用的

#include<graphics.h>//easyx的头文件
//#include<Windows.h>//Windows api的头文件,改成无cmd窗口运行需要
#include<time.h>//时间函数的头文件
#include<stdio.h>//输入输出函数的头文件
#define R 1//1表示向右,0表示向左
#define L 0//1表示向右,0表示向左

void keydown(struct Player& player);//键盘控制player1上下移动
int ballmove(struct Player& player1, struct Player& player2, struct Ball& ball);//球的移动
void bot(struct Player& player2, struct Ball& ball);//简单的机器人移动

struct Player {//玩家结构体,包含上下左右坐标
	int lx;
	int ly;
	int rx;
	int ry;
};
struct Ball {//球结构体,包含x坐标,y坐标,半径
	int x;
	float y;
	int r;
};

bool RoL = R;//球的移动方向,R表示向右,L表示向左
float random_speed;//球的垂直移动速度

int main()
{
	//游戏程序的主体部分
	initgraph(400, 300);//创建一个400*300的窗口

	Player player1;//player1为玩家,player2为机器人
	Player player2;
	Ball ball;//ball为球
	clock_t starttime, endtime;//计时器
	ExMessage m;//easyx的消息结构体
	int temp;//用来接收ballmove函数的返回值

	srand((unsigned)time(NULL));//用当前时间作为随机数种子
	
	settextstyle(20, 10, "Consolas");//设置字体逻辑高度平均宽度和字体
	BeginBatchDraw();//开始双缓冲
	while (1)//开始游戏循环
	{
		player1 = { 0,100,5,149 };//初始化玩家和机器人的位置,球的位置
		player2 = { 395,100,399,149 };
		ball = { 5,122.0f,3 };
		temp = 0;//初始化temp为0
		while (1)//开始界面循环
		{
			cleardevice();//清屏
			outtextxy(150, 100, "Start Game");//输出开始游戏
			peekmessage(&m, EX_MOUSE | EX_KEY);//检测鼠标和键盘消息

			if (m.x > 150 && m.x < 250 && m.y>100 && m.y < 120)//当鼠标在开始游戏的位置并且点击左键时,跳出循环,开始游戏
				if (m.message == WM_LBUTTONDOWN)
				{
					break;
				}
			if (m.vkcode == 32 && m.message == WM_KEYDOWN)//空格的键码值为0x20即32,当按下空格键时,跳出循环,开始游戏
			{
				//printf("一%d\n", m.vkcode);
				m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
				break;
			}
			FlushBatchDraw();//显示绘制的内容
		}
		starttime = clock();//开始计时
		random_speed = (rand() % 51 - 25) / 10.0f;//初始化球的垂直移动速度,范围为-2.5到2.5
		while (1)
		{
			cleardevice();//清屏
			endtime = clock();//结束计时
			if (endtime - starttime > 3)//每隔3毫秒操作一次
			{
				keydown(player1);//键盘控制player1上下移动
				temp = ballmove(player1, player2, ball);//球的移动
				bot(player2, ball);//简单的机器人移动
				starttime = endtime;//重新开始计时
			}
			if (temp == 1)//当temp为1时,表示player2赢
			{
				outtextxy(150, 100, "Player2 Win");//输出player2赢
				peekmessage(&m, EX_KEY);//检测键盘消息
				if (m.vkcode == 32 && m.message == WM_KEYDOWN)//当按下空格键时,跳出循环,重新开始游戏
				{
					//printf("Player2  %d\n", m.vkcode);
					m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
					break;
				}
			}
			else if (temp == 2)//当temp为2时,表示player1赢
			{
				outtextxy(150, 100, "Player1 Win");//输出player1赢
				peekmessage(&m, EX_KEY);//检测键盘消息
				if (m.vkcode == 32 && m.message == WM_KEYDOWN)//当按下空格键时,跳出循环,重新开始游戏
				{
					//printf("Player1 %d\n", m.vkcode);
					m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
					break;
				}
			}
			else if (temp != 1 && temp != 2 && temp != 0)//当temp不为0,1,2时,表示程序出错
				printf("%d\n", temp);
			solidrectangle(player1.lx, player1.ly, player1.rx, player1.ry);//绘制玩家和机器人以及球
			solidrectangle(player2.lx, player2.ly, player2.rx, player2.ry);
			fillcircle(ball.x, ball.y, ball.r);
			FlushBatchDraw();//显示绘制的内容

		}
	}
	EndBatchDraw();//结束双缓冲
	closegraph();//关闭图形窗口
	return 0;
}
void keydown(struct Player& player)
{
	if (GetAsyncKeyState('W'))//当按下W键时,player1向上移动
	{
		if (player.ly != 0)//防止player1移出屏幕
		{
			player.ly--;
			player.ry--;
		}
	}
	if (GetAsyncKeyState('S'))//当按下S键时,player1向下移动
	{
		if (player.ly != 250)//防止player1移出屏幕
		{
			player.ly++;
			player.ry++;
		}
	}

}
int ballmove(struct Player& player1,struct Player& player2,struct Ball& ball)
{
	
	if (ball.x + ball.r < 400 && RoL == R)//当球没有移出屏幕且向右移动时
	{
		if (ball.x + ball.r >= player2.lx)//当球的右边缘到达player2的左边缘y坐标时
		{
			if (ball.y > player2.ly && ball.y < player2.ry)//当球的y坐标在player2的上下边缘之间时,表示player2接到球
			{
				//printf("%d", RoL);
				RoL = L;//改变球的移动方向
				random_speed = (rand() % 51 - 25) / 10.0f;//改变球的垂直移动速度,范围为-2.5到2.5
			}

		}
		ball.x++;//球向右移动

	}
	else if (RoL == R)//当球向右移出屏幕,表示player1赢(设定上不可能)
	{
		//printf("1继续%d\n", ball.y);
		return 2;
	}
	else if (ball.x - ball.r >= 0 && RoL == L)//当球没有移出屏幕且向左移动时
	{
		if (ball.x - ball.r <= player1.rx)//当球的左边缘到达player1的右边缘y坐标时
		{
			if (ball.y > player1.ly && ball.y < player1.ry)//当球的y坐标在player1的上下边缘之间时,表示player1接到球
			{
				RoL = R;//改变球的移动方向
				//printf("%d", RoL);
				random_speed = (rand() % 51 - 25) / 10.0f;//改变球的垂直移动速度,范围为-2.5到2.5
			}

		}
		ball.x--;//球向左移动
	}
	else if (RoL == L)//当球向左移出屏幕,表示player2赢
	{
		//printf("2继续%d\n", ball.y);
		return 1;
	}
	if (ball.y - ball.r < 1 && random_speed < 0)//当球的上边缘到达屏幕上边缘时,改变球的垂直移动方向
	{
		random_speed = -random_speed;
	}
	else if (ball.y + ball.r > 298 && random_speed > 0)//当球的下边缘到达屏幕下边缘时,改变球的垂直移动方向
	{
		random_speed = -random_speed;
	}
	ball.y = ball.y + random_speed;//球的y坐标改变
	//printf("%lf\n", ball.y);
	return 0;
}
void bot(struct Player& player2, struct Ball& ball)
{
	if (ball.y > 275)//防止player2移出屏幕
		player2.ly = 250;
	else if (ball.y < 25)
		player2.ly = 0;
	else
		player2.ly = ball.y - 25;
	player2.ry = player2.ly + 49;//player2的右下角y坐标
}

3.如果想去掉控制台,主函数改成如下,并包含Windows.h头文件,我的代码已经包含

int WinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ int nShowCmd
)
{
	return 0;
}

属性页链接器,系统,子系统里改成窗口,而非控制台
在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐