初始化模块
按照模块化的思路进行开发,首先在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();
}
}