有游戏窗口了,接下来就为游戏添加一个启动界面吧!!!
我们将以SplashScreen.png跟MainMenu.png两幅图做为启动界面,资源可以点击这里下载。
下载后请在项目文件夹里新建一个名为images的文件夹,然后把两幅图拷贝进去。
接下来就需要为两幅图分别创建一个类,以及进行相关设置,首先是SplashScreen,代码如下:
SplashScreen.h
1 #pragma once 2 class SplashScreen 3 { 4 public: 5 void Show(sf::RenderWindow& window); 6 };
SplashScreen.cpp
1 #include "StdAfx.h" 2 #include "SplashScreen.h" 3 4 void SplashScreen::Show(sf::RenderWindow& renderWindow) 5 { 6 //创建texture对象来读取图片 7 sf::Texture image; 8 if(image.loadFromFile("images/SplashScreen.png") != true) 9 { 10 return; 11 } 12 13 //创建sprite对象来存储图片 14 sf::Sprite sprite(image); 15 16 //如果图片成功创建则将其显示到游戏窗口里 17 renderWindow.draw(sprite); 18 renderWindow.display(); 19 20 sf::Event event; 21 while(true) 22 { 23 //跟上一part一样,用renderWindow对象来监听鼠标动作事件 24 while(renderWindow.pollEvent(event)) 25 { 26 if(event.type == sf::Event::EventType::KeyPressed 27 || event.type == sf::Event::EventType::MouseButtonPressed 28 || event.type == sf::Event::EventType::Closed ) 29 { 30 return; 31 } 32 } 33 } 34 }
然后是MainMenu,代码如下:
MainMenu.h
1 #pragma once 2 #include "SFML\Window.hpp" 3 #include "SFML\Graphics.hpp" 4 #include <list> 5 6 class MainMenu 7 { 8 9 public: 10 enum MenuResult { Nothing, Exit, Play }; 11 12 //用结构体来存储矩形点击区域的属性参数信息 13 struct MenuItem 14 { 15 public: 16 //用来存储矩形区域范围的点的模板对象 17 //一个点包含两个坐标值,两点形成一矩形区域 18 sf::Rect<int> rect; 19 MenuResult action; 20 }; 21 22 MenuResult Show(sf::RenderWindow& window); 23 24 private: 25 MenuResult GetMenuResponse(sf::RenderWindow& window); 26 MenuResult HandleClick(int x, int y); 27 28 //用来存储点击区域的容器 29 std::list<MenuItem> _menuItems; 30 };
MainMenu.cpp
1 #include "stdafx.h" 2 #include "MainMenu.h" 3 4 5 MainMenu::MenuResult MainMenu::Show(sf::RenderWindow& window) 6 { 7 sf::Texture image; 8 image.loadFromFile("images/mainmenu.png"); 9 sf::Sprite sprite(image); 10 11 //设置鼠标点击矩形区域范围 12 13 //play的点击范围 14 MenuItem playButton; 15 playButton.rect.top= 145; 16 playButton.rect.left = 0; 17 playButton.rect.width = 380; 18 playButton.rect.height = 1023; 19 playButton.action = Play; 20 21 //Exit的点击范围 22 MenuItem exitButton; 23 exitButton.rect.top = 383; 24 exitButton.rect.left = 0; 25 exitButton.rect.height = 1023; 26 exitButton.rect.width = 560; 27 exitButton.action = Exit; 28 29 //把点击范围放进容器里面 30 _menuItems.push_back(playButton); 31 _menuItems.push_back(exitButton); 32 33 window.draw(sprite); 34 window.display(); 35 36 return GetMenuResponse(window); 37 } 38 39 //判断鼠标点击位置是否在矩形区域里面从而返回状态参数 40 MainMenu::MenuResult MainMenu::HandleClick(int x, int y) 41 { 42 //迭代器遍历list容器里面存放的点击区域以供判断 43 std::list<MenuItem>::iterator it; 44 45 for ( it = _menuItems.begin(); it != _menuItems.end(); it++) 46 { 47 sf::Rect<int> menuItemRect = (*it).rect; 48 if( menuItemRect.width > y 49 && menuItemRect.top < y 50 && menuItemRect.left < x 51 && menuItemRect.height > x) 52 { 53 return (*it).action; 54 } 55 } 56 57 return Nothing; 58 } 59 60 //根据鼠标动作来做出相应的响应 61 MainMenu::MenuResult MainMenu::GetMenuResponse(sf::RenderWindow& window) 62 { 63 sf::Event menuEvent; 64 65 //这里的42!=43可以理解为true 66 while(42 != 43) 67 { 68 69 while(window.pollEvent(menuEvent)) 70 { 71 if(menuEvent.type == sf::Event::MouseButtonPressed) 72 { 73 return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y); 74 } 75 if(menuEvent.type == sf::Event::Closed) 76 { 77 return Exit; 78 } 79 } 80 } 81 }
补充点:如果是用添加类的方式创建类的话,在添加MainMenu的时候会被禁止,因为MainMenu是被MFC保留的类名,所以还是乖乖地先添加.h再添加.cpp吧。
值得一提的是,MainMenu.h中的容器list应该是被include在stdafx.h里面的,原文解释说包含在MainMenu.h里是方便起见而已.
最后要回到Game.h里面添加两个函数与private下面:
static void ShowSplashScreen(); static void ShowMenu();
当然还要实现它们,在Game.cpp里面添加(记得要include MainMenu.h 和 SplashScreen.h):
1 void Game::ShowSplashScreen() 2 { 3 SplashScreen splashScreen; 4 splashScreen.Show(_mainWindow); 5 _gameState = Game::ShowingMenu; 6 } 7 8 void Game::ShowMenu() 9 { 10 MainMenu mainMenu; 11 MainMenu::MenuResult result = mainMenu.Show(_mainWindow); 12 switch(result) 13 { 14 case MainMenu::Exit: 15 _gameState = Exiting; 16 break; 17 case MainMenu::Play: 18 _gameState = Playing; 19 break; 20 } 21 }
再把Start方法里面的_gameState 改为 Game::ShowingSplash;
让GameLoop方法变成如下样子就大功告成了:
1 void Game::GameLoop() 2 { 3 sf::Event currentEvent; 4 //从消息队列里面拿出消息 5 _mainWindow.pollEvent(currentEvent); 6 7 switch(_gameState) 8 { 9 case Game::ShowingSplash: 10 { 11 ShowSplashScreen(); 12 break; 13 } 14 case Game::ShowingMenu: 15 { 16 ShowMenu(); 17 break; 18 } 19 case Game::Playing: 20 { 21 //用黑色填充游戏画面 22 _mainWindow.clear(sf::Color(0,0,0)); 23 _mainWindow.display(); 24 25 if(currentEvent.type == sf::Event::Closed) 26 { 27 _gameState = Game::Exiting; 28 } 29 if(currentEvent.type == sf::Event::KeyPressed) 30 { 31 if(currentEvent.key.code == sf::Keyboard::Escape) ShowMenu(); 32 } 33 break; 34 } 35 } 36 }
现在按F5试试吧~~~~