第九章(中)鼠标交互案例——扫雷

初始化模块

按照模块化的思路进行开发,首先在Game.h文件中,Run()函数是游戏运行主体,所以移到前面。

Initial函数下增加三个初始化函数                                   

                   

 Input函数下增加三个交互响应函数

Logic函数与Draw函数同理增加

复制一下,在Game.cpp文件中 ,为刚才新增的几个函数创建函数体,可以在类中直接添加函数,也可以在类视图中右键点击添加,添加函数。这样的添加方式是为了在代码段中指定函数的添加位置。将各自函数下新增的函数放到该函数边上。

之后就开始介绍初始化模块的设置

游戏开始时应该有一个默认的游戏难度:

Inital函数在游戏每次运行中游戏开始的时候被调用,每次都需要根据选项进行初始化,点击的位置的块的大小。也是因为这个原因初始化模块会分为两块 ,一块在构造函数中进行,一块在Initial函数中进行。

x y的坐标进行设置,让游戏的舞台处于游戏窗口的中心位置

在IniData()函数中对栅格数据进行初始化,所有块置为空且未点击

若想对皮肤和背景进行变更,需要在Game.h申明两个管理变量,因为要涉及字符转换,包含string头文件#include <sstream>

 在Game.cpp文件的构造函数中对这两个管理变量进行初始化

继续回到IniData()中初始化对象

将各个精灵对象与纹理进行绑定 

为什么没有在初始化模块中进行布雷操作?

 游戏栅格上的数值设定

 在MineSet函数(布雷)上进行设定

根据各栅格周边雷数的统计结果给非雷的各个栅格设定相应的数值

问题:如何让鼠标左键第一次点击处周边八栅格都不是雷?

图形绘制模块

本节要将之前的游戏素材进行显示,通过函数的封装,让Draw()函数的框架结构更加清晰。

下面写DrawGrid函数:

没被按下的栅格不管是什么值,一律绘制ncUNDOWN进行遮掩

#include "Game.h"
using namespace std;
Game::Game()
{
	Window_height = 600;
	Window_width = 860;

	gamelvl = 2;
	imgBGNo = 1;
	imgSkinNo = 1;
	window.create(sf::VideoMode(Window_width, Window_width), L"MindSweeper by");
}
Game::~Game()
{

}

void Game::Initial()
{
	window.setFramerateLimit(60);     //每秒设置目标帧频
	gridSize = GRIDSIZE; //点击的位置的块的大小

	switch (gamelvl)
	{
	case 1:
		stageWidth = LVL1_WIDTH;
		stageHeight = LVL1_HEIGHT;
		mMineNum = LVL1_NUM;
		break;
	case 2:
		stageWidth = LVL2_WIDTH;
		stageHeight = LVL2_HEIGHT;
		mMineNum = LVL2_NUM;
		break;
	case 3:
		stageWidth = LVL3_WIDTH;
		stageHeight = LVL3_HEIGHT;
		mMineNum = LVL3_NUM;
		break;
	default:
		break;
	}
	gameOver = false;
	gameQuit = false;
	isGameOverState = ncNo; //初始化游戏的结束状态
	mFlagCalc = 0;          //初始化旗子的数量
	isGameBegin = false;    //初始化游戏是否开始
	mTime = 0;              //初始化游戏进行的时间

	mCornPoint.x = (Window_width - stageWidth * GRIDSIZE) / 2;  //设置舞台的左上角坐标
	mCornPoint.y = (Window_height - stageHeight + GRIDSIZE) / 2;
	IniData();              //初始化数据
	LoadMediaData();        //加载素材
}
void Game::LoadMediaData()
{
	stringstream ss;
	ss << "data/images/BK0" << imgBGNo << ".jpg";  //imgBGNo是背景图涉及的变量
	if (!tBackground.loadFromFile(ss.str()))
		cout << "BK image 没有找到" << endl;

	ss.str("");//清空字符串
	ss << "data/images/Game" << imgSkinNo << ".jpg";
	if (!tTiles.loadFromFile(ss.str()))
		cout << "Game Skin image 没有找到" << endl;
	if (!tNum.loadFromFile("data/images/num.jpg"))
		cout << "num.jpg 没有找到" << endl;
	if (!tTimer.loadFromFile("data/images/jishiqi.jpg"))
		cout << "jishiqi.jpg 没有找到" << endl;
	if(!tCounter.loadFromFile("data/images/jishiqi.jpg"))
		cout << "jishiqi.jpg 没有找到" << endl;
	if (!tButtons.loadFromFile("data/images/button.jpg"))
		cout << "button.jpg 没有找到" << endl;
	if (!tGameOver.loadFromFile("data/images/gameover.jpg"))
		cout << "gameover.jpg 没有找到" << endl;

	sBackground.setTexture(tBackground);
	sTiles.setTexture(tTiles);
	sButtons.setTexture(tButtons);
	sNum.setTexture(tNum);
	sTimer.setTexture(tTimer);
	sCounter.setTexture(tCounter);
	sGameOver.setTexture(tGameOver);

		
}

void Game::IniData()
{
	int i, j;
	for (j = 0; j < stageHeight; j++)//所有块置为空且未点击
	{
		for (i=0;i<stageWidth;i++)
		{
			mGameData[j][i].mState = ncUNDOWN;
			mGameData[j][i].isPress = false;
		}
	}
}

void Game::MineSet(int Py, int Px)   //布雷
{
	int mCount, i, j, k, l;
	mCount = 0;

	srand(time(NULL));        //用当前系统时间作为随机数生成器的种子
	//布雷
	do 
	{
		k = rand() % stageHeight;  //生成随机数
		l = rand() % stageWidth;
		if (k == Py && l == Px)
			continue;
		if (mGameData[k][l].mState == ncUNDOWN)
		{
			mGameData[k][l].mState = ncMINE;
			mGameData[k][l].mSateBackUp = ncMINE;  //备份状态
			mCount++;
		}
	} while (mCount!=mMineNum);//这样就能避免在第一下鼠标点击的位置布雷

	//方格赋值
	for (i=0;i<stageHeight;i++)
	{
		for (j = 0; j < stageWidth; j++)
		{
			if (mGameData[i][j].mState != ncMINE)
			{
				mCount = 0;
				for (k=i-1;k<i+2;k++)
				{
					for (l=j-1;l<j+2;l++)
					{
						if (k >= 0 && k < stageHeight && l >= 0 && l < stageWidth)
						{
							if (mGameData[k][l].mState == ncMINE)
								mCount++;
						}
					}
				}//计算(i,j)周围雷的数目
				switch (mCount)
				{
				case 0:
					mGameData[i][j].mState = ncNULL;
					break;
				case 1:
					mGameData[i][j].mState = ncONE;
					break;
				case 2:
					mGameData[i][j].mState = ncTWO;
					break;
				case 3:
					mGameData[i][j].mState = ncTHREE;
					break;
				case 4:
					mGameData[i][j].mState = ncFOUR;
					break;
				case 5:
					mGameData[i][j].mState = ncFIVE;
					break;
				case 6:
					mGameData[i][j].mState = ncSIX;
					break;
				case 7:
					mGameData[i][j].mState = ncSEVEN;
					break;
				case 8:
					mGameData[i][j].mState = ncEIGHT;
					break;
				default:
					break;
				}
			}
		}
	}
}   

void Game::Input()
{
	sf::Event event;//event type 包括Window、Keyboard、Mouse、Joystick, 4类消息
	//通过 bool Window::pollEvent (sf::Event & event) 从窗口顺序询问(polled) 事件。
	// 如果有一个事件等待处理,该函数将返回false,同样重要的是要注意,一次可能有多个事件,因此我们必须确保捕获每个
	//
	//
	while (window.pollEvent(event))
	{
		if (event.type == sf::Event::Closed)
		{
			window.close();  //窗口可以移动,调整大小和最小化,但是如果要关闭,需要自己去调用close()函数
			gameQuit = true;

		}
		if (event.type == sf::Event::EventType::KeyReleased && event.key.code == sf::Keyboard::Escape)
		{
			window.close();  //窗口可以移动,调整大小和最小化,但是如果要关闭,需要自己去调用close()函数
			gameQuit = true;
		}
		if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left)
		{
			if (mouseClickTimer.getElapsedTime().asMilliseconds() > 1000)
				std::cout << "Mouse::Left Pressed" << std::endl;
			else
			{
				std::cout << "Mouse::Left Double Clicked" << std::endl;
			}
		}
		if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left)
		{
			std::cout << "Mouse::Left Released" << std::endl;
		}
		if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Right)
		{
			std::cout << "Mouse::Right Pressed" << std::endl;
		}
		if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Right)
		{
			std::cout << "Mouse::Left Released" << std::endl;
		}
	}
}
void Game::RButtonDown(Vector2i nPoint)     //鼠标右击
{

}
void Game::LButtonDown(Vector2i nPoint)    //鼠标左击
{

}
void Game::LButtonDblClk(Vector2i mPoint)   //鼠标左键双击
{

}
void Game::Logic()
{

}
void Game::isWin()
{

}
void Game::unCover()
{

}
void Game::Draw()
{
	window.clear();  //清屏

	sBackground.setPosition(0, 0);
	window.draw(sBackground);

	//绘制舞台
	DrawGrid();
	DrawButton();
	DrawScore();
	DrawTimer();

	if (isGameOverState)
		DrawGameEnd();
	
	window.display();//把显示缓冲区的内容,显示在屏幕上,SFML采用的是双缓冲机制。
}
void Game::DrawGrid()
{
	int i, j;
	for(j=0;j<stageHeight;j++)
		for (i=0;i<stageWidth;i++)
		{
			if (mGameData[j][i].isPress == true)
			{
				sTiles.setTextureRect(IntRect(mGameData[j][i].mState * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
				sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
			}
			else
			{
				sTiles.setTextureRect(IntRect(ncUNDOWN * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
				sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
			}
			window.draw(sTiles);
		}
}
void Game::DrawButton()
{

}
void Game::DrawScore()
{

}
void Game::DrawTimer()
{

}
void Game::DrawGameEnd()
{

}
void Game::Run()
{
	do
	{
		Initial();
		while (window.isOpen() && gameOver == false)
		{
			Input();

			Logic();

			Draw();
		}
	} while (!gameQuit);
}





//void RButtonDown(Vector2i nPoint);     //鼠标右击
//void LButtonDown(Vector2i nPoint);     //鼠标左击
//void LbuttonDbClk(Vector2i mPoint);    //鼠标左键双击
//
//
//void isWin();
//void unCover();
//
//
//void DrawGrid();
//void DrawButton();
//void DrawScore();
//void DrawTimer();
//void DrawGameEnd();

接下来是DrawButton()函数

之前在定义成员变量的时候定义了intRect变量,现在要借助它们来记住各个按钮的坐标位置

EASY难度按钮的坐标区域就被存储起来

同理对其他按钮进行绘制并记录它们的坐标区域,以方便后续鼠标点击交互

此处若正常运行会发现代码有一点点不和谐

检查一下,对Hard难度左顶点坐标进行一下修正,后面按钮也做相应修正

运行按钮位置会和谐 

aaaaaaaaaaaa,突然发现了一个大bug,怪不得窗口总是不对(之前是window_width,window_height)

然后是第二个bug (把第二行+改为*)

接下来实现DrawScore()函数

先绘制计数器背景贴图,计数器纹理的贴图位置,计算数字图形在计数器上的位置坐标

然后是DrawTimer()函数,这里借鉴一下DrawScore()函数,将计数器的信息替换为计时器的信息,其中计时应该从哪里开始

给LButtonDown()增加一行代码,为啥这里我没写这个函数的内容(下一节输入模块会讲到)

接着修改DrawTimer()函数中代码

运行呈现后又发现前面一个bug

 修改后运行,出现一下效果

Game.h

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <windows.h>
#include <iostream>
#include <sstream>
#define GRIDSIZE 25
#define LVL1_WIDTH 9
#define LVL1_HEIGHT 9
#define LVL1_NUM 10
#define LVL2_WIDTH 16
#define LVL2_HEIGHT 16
#define LVL2_NUM 40
#define LVL3_WIDTH 30
#define LVL3_HEIGHT 16
#define LVL3_NUM 99
//枚举定义网格状态
typedef enum GRIDSTAT
{
	ncNULL,       //空地
	ncUNDOWN,     //背景方块
	ncMINE,       //地雷
	ncONE,        //数字
	ncTWO,
	ncTHREE,
	ncFOUR,
	ncFIVE,
	ncSIX,
	ncSEVEN,
	ncEIGHT,     
	ncFLAG,       //标记
	ncQ,          //问号
	ncX,          //备用
	ncBOMBING,    //爆炸的雷
	ncUNFOUND     //未检测出来的雷
};

typedef enum GAMEOVERSTATE
{
	ncNo,         //游戏未结束
	ncWIN,        //游戏胜利
	ncLOSE,       //游戏失败
};
using namespace sf;

class LEI
{
public:
	int mState;        //栅格的状态(栅格——雷
	int mStateBackUp;   //栅格原始状态备份
	bool isPress;      //栅格是否被点击
};

class Game
{
public:
	sf::RenderWindow window;
	Game();
	~Game();
	bool gameOver, gameQuit;
	int Window_width, Window_height, stageWidth, stageHeight, mMineNum, mFlagCalc;
	int gamelvl, mTime; //游戏难度,游戏计时
	LEI mGameData[LVL3_HEIGHT][LVL3_WIDTH];    //数组取最高难度舞台尺寸
	bool isGameBegin;       //游戏是否开始
	int isGameOverState;    //游戏结束的状态
	sf::Vector2i mCornPoint;    //舞台的左顶点坐标
	int gridSize;           //块的大小
	int imgBGNo, imgSkinNo;   

	Texture tBackground, tTiles, tButtons, tNum, tTimer, tCounter, tGameOver;   //创建精灵对象
	Sprite  sBackground, sTiles, sButtons, sNum, sTimer, sCounter, sGameOver;   //创建纹理对象
	sf::IntRect ButtonRectEasy, ButtonRectNormal, ButtonRectHard, ButtonRectBG, ButtonRectSkin, ButtonRectRestart, ButtonRectQuit;

	SoundBuffer sbWin, sbBoom;
	Sound soundWin, soundBoom;
	Music bkMusic;


	//A Clock starts conuting as soon as it's created
	sf::Clock gameClock, mouseClickTimer;

	void Run();

	void Initial();
	void IniData();
	void LoadMediaData();
	void MineSet(int Py, int Px);     //布雷


	void Input();
	void RButtonDown(Vector2i mPoint);     //鼠标右击
	void LButtonDown(Vector2i mPoint);     //鼠标左击
	void LButtonDblClk(Vector2i mPoint);    //鼠标左键双击

	void Logic();
	void isWin();
	void unCover();

	void Draw();
	void DrawGrid();
	void DrawButton();
	void DrawScore();
	void DrawTimer();
	void DrawGameEnd();

};

Game.cpp

#include "Game.h"
using namespace std;
Game::Game()
{
	Window_width = 860;
	Window_height = 600;

	imgBGNo = 1;
	imgSkinNo = 1;
	gamelvl = 2;
	window.create(sf::VideoMode(Window_width, Window_height), L"MindSweeper by");
}
Game::~Game()
{

}

void Game::Initial()
{
	window.setFramerateLimit(10);     //每秒设置目标帧频
	gridSize = GRIDSIZE; //点击的位置的块的大小

	switch (gamelvl)
	{
	case 1:
		stageWidth = LVL1_WIDTH;
		stageHeight = LVL1_HEIGHT;
		mMineNum = LVL1_NUM;
		break;
	case 2:
		stageWidth = LVL2_WIDTH;
		stageHeight = LVL2_HEIGHT;
		mMineNum = LVL2_NUM;
		break;
	case 3:
		stageWidth = LVL3_WIDTH;
		stageHeight = LVL3_HEIGHT;
		mMineNum = LVL3_NUM;
		break;
	default:
		break;
	}
	gameOver = false;
	gameQuit = false;
	isGameOverState = ncNo; //初始化游戏的结束状态
	mFlagCalc = 0;          //初始化旗子的数量
	isGameBegin = false;    //初始化游戏是否开始
	mTime = 0;              //初始化游戏进行的时间

	mCornPoint.x = (Window_width - stageWidth * GRIDSIZE) / 2;  //设置舞台的左上角坐标
	mCornPoint.y = (Window_height - stageHeight * GRIDSIZE) / 2;
	IniData();              //初始化数据
	LoadMediaData();        //加载素材
}
void Game::LoadMediaData()
{
	stringstream ss;
	ss << "data/images/BK0" << imgBGNo << ".jpg";  //imgBGNo是背景图涉及的变量
	if (!tBackground.loadFromFile(ss.str()))
		cout << "BK image 没有找到" << endl;

	ss.str("");//清空字符串
	ss << "data/images/Game" << imgSkinNo << ".jpg";
	if (!tTiles.loadFromFile(ss.str()))
		cout << "Game Skin image 没有找到" << endl;
	if (!tNum.loadFromFile("data/images/num.jpg"))
		cout << "num.jpg 没有找到" << endl;
	if (!tTimer.loadFromFile("data/images/jishiqi.jpg"))
		cout << "jishiqi.jpg 没有找到" << endl;
	if(!tCounter.loadFromFile("data/images/jishuqi.jpg"))
		cout << "jishiqi.jpg 没有找到" << endl;
	if (!tButtons.loadFromFile("data/images/button.jpg"))
		cout << "button.jpg 没有找到" << endl;
	if (!tGameOver.loadFromFile("data/images/gameover.jpg"))
		cout << "gameover.jpg 没有找到" << endl;

	sBackground.setTexture(tBackground);
	sTiles.setTexture(tTiles);
	sButtons.setTexture(tButtons);
	sNum.setTexture(tNum);
	sTimer.setTexture(tTimer);
	sCounter.setTexture(tCounter);
	sGameOver.setTexture(tGameOver);

		
}

void Game::IniData()
{
	int i, j;
	for (j = 0; j < stageHeight; j++)//所有块置为空且未点击
	{
		for (i=0;i<stageWidth;i++)
		{
			mGameData[j][i].mState = ncUNDOWN;
			mGameData[j][i].isPress = false;
		}
	}
}

void Game::MineSet(int Py, int Px)   //布雷
{
	int mCount, i, j, k, l;
	mCount = 0;

	srand(time(NULL));        //用当前系统时间作为随机数生成器的种子
	//布雷
	do 
	{
		k = rand() % stageHeight;  //生成随机数
		l = rand() % stageWidth;
		if (k == Py && l == Px)
			continue;
		if (mGameData[k][l].mState == ncUNDOWN)
		{
			mGameData[k][l].mState = ncMINE;
			mGameData[k][l].mStateBackUp = ncMINE;  //备份状态
			mCount++;
		}
	} while (mCount!=mMineNum);//这样就能避免在第一下鼠标点击的位置布雷

	//方格赋值
	for (i=0;i<stageHeight;i++)
	{
		for (j = 0; j < stageWidth; j++)
		{
			if (mGameData[i][j].mState != ncMINE)
			{
				mCount = 0;
				for (k=i-1;k<i+2;k++)
				{
					for (l=j-1;l<j+2;l++)
					{
						if (k >= 0 && k < stageHeight && l >= 0 && l < stageWidth)
						{
							if (mGameData[k][l].mState == ncMINE)
								mCount++;
						}
					}
				}//计算(i,j)周围雷的数目
				switch (mCount)
				{
				case 0:
					mGameData[i][j].mState = ncNULL;
					break;
				case 1:
					mGameData[i][j].mState = ncONE;
					break;
				case 2:
					mGameData[i][j].mState = ncTWO;
					break;
				case 3:
					mGameData[i][j].mState = ncTHREE;
					break;
				case 4:
					mGameData[i][j].mState = ncFOUR;
					break;
				case 5:
					mGameData[i][j].mState = ncFIVE;
					break;
				case 6:
					mGameData[i][j].mState = ncSIX;
					break;
				case 7:
					mGameData[i][j].mState = ncSEVEN;
					break;
				case 8:
					mGameData[i][j].mState = ncEIGHT;
					break;
				default:
					break;
				}
			}
		}
	}
}   

void Game::Input()
{
	sf::Event event;//event type 包括Window、Keyboard、Mouse、Joystick, 4类消息
	//通过 bool Window::pollEvent (sf::Event & event) 从窗口顺序询问(polled) 事件。
	// 如果有一个事件等待处理,该函数将返回false,同样重要的是要注意,一次可能有多个事件,因此我们必须确保捕获每个
	//
	//
	while (window.pollEvent(event))
	{
		if (event.type == sf::Event::Closed)
		{
			window.close();  //窗口可以移动,调整大小和最小化,但是如果要关闭,需要自己去调用close()函数
			gameQuit = true;

		}
		if (event.type == sf::Event::EventType::KeyReleased && event.key.code == sf::Keyboard::Escape)
		{
			window.close();  //窗口可以移动,调整大小和最小化,但是如果要关闭,需要自己去调用close()函数
			gameQuit = true;
		}
		if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left)
		{
			if (mouseClickTimer.getElapsedTime().asMilliseconds() > 1000)
				std::cout << "Mouse::Left Pressed" << std::endl;
			else
			{
				std::cout << "Mouse::Left Double Clicked" << std::endl;
			}
		}
		if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left)
		{
			std::cout << "Mouse::Left Released" << std::endl;
		}
		if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Right)
		{
			std::cout << "Mouse::Right Pressed" << std::endl;
		}
		if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Right)
		{
			std::cout << "Mouse::Left Released" << std::endl;
		}
	}
}
void Game::RButtonDown(Vector2i mPoint)     //鼠标右击
{

}
void Game::LButtonDown(Vector2i mPoint)    //鼠标左击
{

}
void Game::LButtonDblClk(Vector2i mPoint)   //鼠标左键双击
{

}
void Game::Logic()
{

}
void Game::isWin()
{

}
void Game::unCover()
{

}
void Game::Draw()
{
	window.clear();  //清屏

	//绘制背景
	sBackground.setPosition(0, 0);
	window.draw(sBackground);

	//绘制舞台
	DrawGrid();
	DrawButton();
	DrawScore();
	DrawTimer();

	if (isGameOverState)
		DrawGameEnd();
	
	window.display();//把显示缓冲区的内容,显示在屏幕上,SFML采用的是双缓冲机制。
}
void Game::DrawGrid()
{
	int i, j;
	for(j=0;j<stageHeight;j++)
		for (i=0;i<stageWidth;i++)
		{
			if (mGameData[j][i].isPress == true)
			{
				sTiles.setTextureRect(IntRect(mGameData[j][i].mState * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
				sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
			}
			else
			{
				sTiles.setTextureRect(IntRect(ncUNDOWN * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
				sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
			}
			window.draw(sTiles);
		}
}
void Game::DrawButton()
{
	Vector2i LeftCorner;
	int ButtonWidth = 60;
	int ButtonHeight = 36;
	int detaX;
	detaX = (Window_width - ButtonWidth * 7) / 8; //7个按钮在界面上等分宽度
	LeftCorner.y = Window_height - GRIDSIZE * 3;   //指定高度

	//ButtonRectEasy, 
	LeftCorner.x = detaX;
	sButtons.setTextureRect(IntRect(0 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectEasy.left = LeftCorner.x;
	ButtonRectEasy.top = LeftCorner.y;
	ButtonRectEasy.width = ButtonWidth;
	ButtonRectEasy.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectNormal
	LeftCorner.x = detaX * 2 + ButtonWidth;
	sButtons.setTextureRect(IntRect(1 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectNormal.left = LeftCorner.x;
	ButtonRectNormal.top = LeftCorner.y;
	ButtonRectNormal.width = ButtonWidth;
	ButtonRectNormal.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectHard, 
	LeftCorner.x = detaX *  3 + ButtonWidth * 2;
	sButtons.setTextureRect(IntRect(2 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectHard.left = LeftCorner.x;
	ButtonRectHard.top = LeftCorner.y;
	ButtonRectHard.width = ButtonWidth;
	ButtonRectHard.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectBG, 
	LeftCorner.x = detaX * 4 + ButtonWidth * 3;
	sButtons.setTextureRect(IntRect(3 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectBG.left = LeftCorner.x;
	ButtonRectBG.top = LeftCorner.y;
	ButtonRectBG.width = ButtonWidth;
	ButtonRectBG.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectSkin
	LeftCorner.x = detaX * 5 + ButtonWidth * 4;
	sButtons.setTextureRect(IntRect(4 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectSkin.left = LeftCorner.x;
	ButtonRectSkin.top = LeftCorner.y;
	ButtonRectSkin.width = ButtonWidth;
	ButtonRectSkin.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectRestart, 
	LeftCorner.x = detaX * 6 + ButtonWidth * 5;
	sButtons.setTextureRect(IntRect(5 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectRestart.left = LeftCorner.x;
	ButtonRectRestart.top = LeftCorner.y;
	ButtonRectRestart.width = ButtonWidth;
	ButtonRectRestart.height = ButtonHeight;
	window.draw(sButtons);
	//ButtonRectQuit
	LeftCorner.x = detaX * 7 + ButtonWidth * 6;
	sButtons.setTextureRect(IntRect(6 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	sButtons.setPosition(LeftCorner.x, LeftCorner.y); //设置按钮的位置坐标
	ButtonRectQuit.left = LeftCorner.x;
	ButtonRectQuit.top = LeftCorner.y;
	ButtonRectQuit.width = ButtonWidth;
	ButtonRectQuit.height = ButtonHeight;
	window.draw(sButtons);
}
void Game::DrawScore()
{
	Vector2i LeftCorner;
	LeftCorner.x = Window_width - sCounter.getLocalBounds().width * 1.25;
	LeftCorner.y = sCounter.getLocalBounds().height * 0.5;
	sCounter.setPosition(LeftCorner.x, LeftCorner.y);   //计数器纹理的贴图位置
	window.draw(sCounter);  //计算数字图形在计数器上的位置坐标

	int NumSize = sNum.getLocalBounds().height;
	LeftCorner.x = LeftCorner.x + sCounter.getLocalBounds().width - NumSize;
	LeftCorner.y = LeftCorner.y + sCounter.getGlobalBounds().height * 0.5 - NumSize * 0.5;

	int mScore = mMineNum - mFlagCalc;
	//绘制个位数的数字
	int a = mScore % 10;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
   //在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);
	//绘制十位数的数字
	mScore = mScore / 10;
	a = mScore % 10;
	LeftCorner.x = LeftCorner.x - NumSize;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
	//在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);
	//绘制百位数的数字
	mScore = mScore / 10;
	a = mScore % 10;
	LeftCorner.x = LeftCorner.x - NumSize;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
	//在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);


}
void Game::DrawTimer()
{
	Vector2i LeftCorner;
	LeftCorner.x = sTimer.getLocalBounds().width * 0.25;
	LeftCorner.y = sTimer.getLocalBounds().height * 0.5;
	sTimer.setPosition(LeftCorner.x, LeftCorner.y);   //计时器纹理的贴图位置
	window.draw(sTimer);  //计算数字图形在计数器上的位置坐标

	if (isGameBegin)
		mTime = gameClock.getElapsedTime().asSeconds();

	int NumSize = sNum.getLocalBounds().height;
	LeftCorner.x = LeftCorner.x + sTimer.getLocalBounds().width - NumSize * 1.5;
	LeftCorner.y = LeftCorner.y + sTimer.getGlobalBounds().height * 0.5 - NumSize * 0.5;

	int mScore = mTime;
	if (mScore > 999) //若觉得不够可以自行增加更多位
		mScore = 999;


	//绘制个位数的数字
	int a = mScore % 10;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
	//在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);
	//绘制十位数的数字
	mScore = mScore / 10;
	a = mScore % 10;
	LeftCorner.x = LeftCorner.x - NumSize;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
	//在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);
	//绘制百位数的数字
	mScore = mScore / 10;
	a = mScore % 10;
	LeftCorner.x = LeftCorner.x - NumSize;
	sNum.setTextureRect(IntRect(a * NumSize, 0, NumSize, NumSize));
	//在贴图上取对应数字字符的纹理贴图
	sNum.setPosition(LeftCorner.x, LeftCorner.y);
	window.draw(sNum);
}
void Game::DrawGameEnd()
{
	Vector2i LeftCorner;
	int ButtonWidth = 200;
	int ButtonHeight = sGameOver.getLocalBounds().height;
	LeftCorner.x = (Window_width - ButtonWidth) / 2;
	LeftCorner.y = (Window_height - ButtonHeight) / 2;

	sGameOver.setPosition(LeftCorner.x, LeftCorner.y);

	if (isGameOverState == ncWIN)
	{
		sGameOver.setTextureRect(IntRect(0 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	}
	if (isGameOverState == ncLOSE)
	{
		sGameOver.setTextureRect(IntRect(1 * ButtonWidth, 0, ButtonWidth, ButtonHeight));//读取按钮的纹理区域
	}
	window.draw(sGameOver);
}
void Game::Run()
{
	do
	{
		Initial();
		while (window.isOpen() && gameOver == false)
		{
			Input();

			Logic();

			Draw();
		}
	} while (!gameQuit);
}





//void RButtonDown(Vector2i nPoint);     //鼠标右击
//void LButtonDown(Vector2i nPoint);     //鼠标左击
//void LButtonDblClk(Vector2i mPoint);    //鼠标左键双击
//
//
//void isWin();
//void unCover();
//
//
//void DrawGrid();
//void DrawButton();
//void DrawScore();
//void DrawTimer();
//void DrawGameEnd();

MineSweeper.cpp

#include "Game.h"
int main()
{
	Game Mine;
	while (Mine.window.isOpen())
	{
		Mine.Run();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值