C++小游戏/井字棋/基于EasyX图形渲染/仅个人笔记


#include<graphics.h>
#include<iostream>

char board_data[3][3] =
{
	{'-','-','-'},
	{'-','-','-'},
	{'-','-','-'}
};
char current_piece = 'O';

bool CheckWin(char c)//检测谁获胜
{
	if (board_data[0][0] == c && board_data[0][1] == c && board_data[0][2] == c)//横线
		return true;
	if (board_data[1][0] == c && board_data[1][1] == c && board_data[1][2] == c)
		return true;
	if (board_data[2][0] == c && board_data[2][1] == c && board_data[2][2] == c)
		return true;
	if (board_data[0][0] == c && board_data[1][0] == c && board_data[2][0] == c)//竖线
		return true;
	if (board_data[0][1] == c && board_data[1][1] == c && board_data[2][1] == c)
		return true;
	if (board_data[0][2] == c && board_data[1][2] == c && board_data[2][2] == c)
		return true;
	if (board_data[0][0] == c && board_data[1][1] == c && board_data[2][2] == c)//斜线
		return true;
	if (board_data[0][2] == c && board_data[1][1] == c && board_data[2][0] == c)
		return true;

	return false;
}
bool CheckDraw()//检测是否为平局
{
	for(size_t i=0;i<3;i++)
		for (size_t j = 0; j < 3; j++)
		{
			if (board_data[i][j] == '-');
			return false;
		}
	return true;
}

void DrawBoard()//绘制棋盘
{
	line(0, 200, 600, 200);
	line(0, 400, 600, 400);
	line(200, 0, 200, 600);
	line(400, 0, 400, 600);
}

void DrawPiece()//绘制棋子
{
	for(size_t i=0;i<3;i++)
		for (size_t j = 0; j < 3; j++)
		{
			switch (board_data[i][j])
			{
			case 'O':
				circle(j* 200 + 100, i * 200 + 100, 67);
				break;
			case 'X':
				line(j * 200+50, i * 200+50, (j + 1) * 200-50, (i + 1) * 200-50);
				line((j+1)*200-50, 200*i+50,j*200+50, (i+1)*200-50);
				break;
			case'-':
				break;
			}


		}

}

void DrawTipText()//绘制提示信息
{ 
	static TCHAR str[64];
	_stprintf_s(str, _T("当前棋子类型:%c"), current_piece);//和printf(“%c”,c)很像


	settextcolor(RGB(225, 175, 45));
	outtextxy(0, 0, str);

}

int main()
{
	DWORD start_time = GetTickCount();
	initgraph(600, 600);
	bool  Running = true;


	BeginBatchDraw();

	while(Running)
	{
		//读取信息
		ExMessage msg;


		//处理信息
		while (peekmessage(&msg))
		{


			if (msg.message == WM_LBUTTONDOWN)
			{
				int x = msg.x;
				int y = msg.y;

				int index_x = x / 200;
				int index_y = y / 200;//将棋盘网格跟图形界面构建索引

				//尝试落子
				if (board_data[index_y][index_x] == '-')
				{
					board_data[index_y][index_x] = current_piece;
					if (current_piece == 'O')
					{
						current_piece = 'X';
					}
					else current_piece = 'O';//实现棋子的轮换

				}



			}
		}
		//绘制图像
		cleardevice();

		DrawBoard();
		DrawPiece();
		DrawTipText();


		FlushBatchDraw();


		if (CheckWin('X'))//检测到游戏结束,进行弹窗
		{
			MessageBox(GetHWnd(), _T("X玩家获胜"), _T("游戏结束"), MB_OK);
			//MEssageBox()
			//Hwnd,   父窗口句柄,用于找到当前窗口
			//Text,  提示内容
			//caption  弹窗标题
			//type    弹窗样式
			Running = false;
		}
		else if (CheckWin('O'))
		{
			MessageBox(GetHWnd(), _T("O玩家获胜"), _T("游戏结束"), MB_OK);
			Running = false;
		}
		else if (CheckDraw())
		{
			MessageBox(GetHWnd(), _T("平局"), _T("游戏结束"), MB_OK);
		}

		DWORD end_time = GetTickCount();
		DWORD delta_time = end_time - start_time;//计算循环单次时间落差

		if (delta_time < 1000 / 60)
		{
			Sleep(1000 / 60 - delta_time);//要点:使用GetTickCount()来计算循环开始和一次循环结束所需要的时间落差,如果要确保画面以60hz刷新,那每次循环的总时间就是1000/60
			//如果实际循环小于1000/60,那么我们通过Sleep()函数延时剩下的时间,以达到优化CPU占用的作用
		}

		
	
	}

	EndBatchDraw();
	//释放数据
	return 0;

}

实现步骤

基本框架:

  1. 读取信息
  2. 处理信息
  3. 绘制图像
  4. 释放数据
int main()
{
	DWORD start_time = GetTickCount();
	initgraph(600, 600);//绘制600*600窗口
	bool  Running = true;


	BeginBatchDraw();

	while(Running)//主循环
	{
		//读取信息
		ExMessage msg;


		//处理信息
		while (peekmessage(&msg))
		{


			if (msg.message == WM_LBUTTONDOWN)
			{
				int x = msg.x;
				int y = msg.y;

				int index_x = x / 200;
				int index_y = y / 200;//将棋盘网格跟图形界面构建索引

				//尝试落子
				if (board_data[index_y][index_x] == '-')
				{
					board_data[index_y][index_x] = current_piece;
					if (current_piece == 'O')
					{
						current_piece = 'X';
					}
					else current_piece = 'O';//实现棋子的轮换

				}



			}
		}
		//绘制图像
		cleardevice();

		DrawBoard();
		DrawPiece();
		DrawTipText();


		FlushBatchDraw();


		if (CheckWin('X'))//检测到游戏结束,进行弹窗
		{
			MessageBox(GetHWnd(), _T("X玩家获胜"), _T("游戏结束"), MB_OK);
			//MEssageBox()
			//Hwnd,   父窗口句柄,用于找到当前窗口
			//Text,  提示内容
			//caption  弹窗标题
			//type    弹窗样式
			Running = false;
		}
		else if (CheckWin('O'))
		{
			MessageBox(GetHWnd(), _T("O玩家获胜"), _T("游戏结束"), MB_OK);
			Running = false;
		}
		else if (CheckDraw())
		{
			MessageBox(GetHWnd(), _T("平局"), _T("游戏结束"), MB_OK);
		}

		DWORD end_time = GetTickCount();
		DWORD delta_time = end_time - start_time;//计算循环单次时间落差

		if (delta_time < 1000 / 60)
		{
			Sleep(1000 / 60 - delta_time);//要点:使用GetTickCount()来计算循环开始和一次循环结束所需要的时间落差,如果要确保画面以60hz刷新,那每次循环的总时间就是1000/60
			//如果实际循环小于1000/60,那么我们通过Sleep()函数延时剩下的时间,以达到优化CPU占用的作用
		}

		
	
	}

	EndBatchDraw();
	//释放数据
	return 0;

}

要点知识

BeginBatchDraw();//双缓冲


FlushBatchDraw();


EndBatchDraw();

//对CPU占用进行优化:

//函数Sleep() 

//由于while循环速度很快,但是我们不需要这么快速的刷新速度,那么使用Sleep函数进行休眠


//具体实现如下:


//利用GetTickCount()函数计算一次循环需要的时间

DWORD begin_time = GetTickCount();


DWORD end_time=GetTickCount();

DWORD delta_time= end_time-begin_time;

//如果循环所需要的时间小于60hz刷新所需要的时间也就是1000/60ms,那么休眠1000/60-delta_time 的时间
if(delta_time  <  1000/60)
{
    Sleep(1000/60-delta_time);
}





    void DrawTipText()//绘制提示信息
{ 
	static TCHAR str[64];
	_stprintf_s(str, _T("当前棋子类型:%c"), current_piece);//和printf(“%c”,c)很像


	settextcolor(RGB(225, 175, 45));
	outtextxy(0, 0, str);

} 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值