游戏无法从菜单启动
Game does not launch from Menu
我是游戏开发新手。我设法使用 C++ 和 SFML 创建了一个简单的游戏(如 Space Invaders)以及一个简单的开始菜单。 但是,在主菜单上按“Enter”后,游戏没有启动。如何正确link?我感谢您的帮助。这不是作业。
main.cpp 代码
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "GameObjectManager.h"
#include "Menu.h"
using namespace std;
int main()
{
sf::Texture galaxyBackgroundTexture;
sf::Sprite galaxyBackground;
if (!galaxyBackgroundTexture.loadFromFile("Textures/galaxybackground.png")) {
cout << "Failed to load Image" << endl;
}
galaxyBackground.setTexture(galaxyBackgroundTexture);
sf::RenderWindow window(sf::VideoMode(1200, 800), "Space Invader Test");
Menu menu(window.getSize().x, window.getSize().y);
window.setFramerateLimit(144);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Return)
{
menu.GetPressedItem();
cout << "Play button has been pressed." << endl;
GameObjectManager* gameObjectManagerManager = new GameObjectManager(&window);
gameObjectManager->update();
gameObjectManager->render(window);
}
else if (event.type == sf::Event::Closed)
{
window.close();
}
else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
{
window.close();
}
}
window.clear();
window.draw(galaxyBackground);
menu.draw(window);
window.display();
}
return 0;
}
Menu.h
#pragma once
#include "SFML/Graphics.hpp"
#define MAX_NUMBER_OF_ITEMS 2
class Menu
{
public:
Menu(float width, float height);
~Menu();
void draw(sf::RenderWindow& window);
int GetPressedItem() { return selectedItemIndex; }
private:
int selectedItemIndex;
sf::Font font;
sf::Text menu[MAX_NUMBER_OF_ITEMS];
};
Menu.cpp
#include "Menu.h"
Menu::Menu(float width, float height)
{
if (!font.loadFromFile("arial.ttf"))
{
cout << "can't load font" << endl;
}
// initialise Menu items
menu[0].setFont(font);
menu[0].setColor(sf::Color::Red);
menu[0].setString("Play");
menu[0].setPosition(sf::Vector2f(width / 2, height / (MAX_NUMBER_OF_ITEMS + 1) * 1));
// EXIT
menu[1].setFont(font);
menu[1].setColor(sf::Color::White);
menu[1].setString("Exit");
menu[1].setPosition(sf::Vector2f(width / 2, height / (MAX_NUMBER_OF_ITEMS + 1) * 2));
}
selectedItemIndex = 0;
Menu::~Menu()
{
}
void Menu::draw(sf::RenderWindow &window)
{
for (int i = 0; i < MAX_NUMBER_OF_ITEMS; i++)
{
window.draw(menu[i]);
}
}
控制台 window 将打印:
"Play button has been pressed"
但它并没有继续进行游戏。没有其他事情发生。
"window 重新定义" 错误发生是因为您的 RenderWindow 对象具有相同的标识符(即 window)。您可能想更改第二个 window 的名称或更好地使用相同的 window.
第二个错误,sf::Text::setColor()
is deprecated 意味着它不再“可用”或“不建议使用”。 SFML 为此有两个更好的新功能:
sf::Text::setFillColor()
: 设置文本的填充。
sf::Text::setOutlineColor()
: 给你的文本一个轮廓(你还需要使用 setOutlineThickness()
改变粗细)。
此外,我建议您针对不同的场景使用一个状态机,而不是两个单独的 windows。它真的没有那么难,而且会帮助你学到更多东西。您已经通过 gameObjectManager 实现了这一目标。您只需要抽象它并为您的菜单 class 实现它。由于您只有两个场景,因此您可以简单地使用整数或布尔值在这两个场景之间切换。
编辑:了解您需要对 main.cpp 文件做什么
int main()
{
sf::RenderWindow window(sf::VideoMode(1200, 800), "Space Invader Test");
GameObjectManager* gameObjectManagerManager = nullptr;
bool inGame = false; //true = game has started, false = menu screen
while (window.isOpen())//this is the main loop
{
sf::Event event;
while (window.pollEvent(event)) //this is the event loop
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Return)
{
if(!inGame)
{
if(menu.GetPressedItem() == PlayButton) //assuming your function returns which button in the menu has been pressed
{
cout << "Play button has been pressed." << endl;
inGame = true;
gameObjectManagerManager = new GameObjectManager(&window);
}
else
{
window.close(); //since the other button is exit
}
}
}
if (event.type == sf::Event::Closed) window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) window.close();
}
//this is the place where you call your updates
if(inGame) gameObjectManagerManager->update();
window.clear();
window.draw(galaxyBackground);
if(!inGame)menu.draw(window);
if(inGame) gameObjectManagerManager->render();
window.display();
}
return 0;
}
我是游戏开发新手。我设法使用 C++ 和 SFML 创建了一个简单的游戏(如 Space Invaders)以及一个简单的开始菜单。 但是,在主菜单上按“Enter”后,游戏没有启动。如何正确link?我感谢您的帮助。这不是作业。
main.cpp 代码
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "GameObjectManager.h"
#include "Menu.h"
using namespace std;
int main()
{
sf::Texture galaxyBackgroundTexture;
sf::Sprite galaxyBackground;
if (!galaxyBackgroundTexture.loadFromFile("Textures/galaxybackground.png")) {
cout << "Failed to load Image" << endl;
}
galaxyBackground.setTexture(galaxyBackgroundTexture);
sf::RenderWindow window(sf::VideoMode(1200, 800), "Space Invader Test");
Menu menu(window.getSize().x, window.getSize().y);
window.setFramerateLimit(144);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Return)
{
menu.GetPressedItem();
cout << "Play button has been pressed." << endl;
GameObjectManager* gameObjectManagerManager = new GameObjectManager(&window);
gameObjectManager->update();
gameObjectManager->render(window);
}
else if (event.type == sf::Event::Closed)
{
window.close();
}
else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
{
window.close();
}
}
window.clear();
window.draw(galaxyBackground);
menu.draw(window);
window.display();
}
return 0;
}
Menu.h
#pragma once
#include "SFML/Graphics.hpp"
#define MAX_NUMBER_OF_ITEMS 2
class Menu
{
public:
Menu(float width, float height);
~Menu();
void draw(sf::RenderWindow& window);
int GetPressedItem() { return selectedItemIndex; }
private:
int selectedItemIndex;
sf::Font font;
sf::Text menu[MAX_NUMBER_OF_ITEMS];
};
Menu.cpp
#include "Menu.h"
Menu::Menu(float width, float height)
{
if (!font.loadFromFile("arial.ttf"))
{
cout << "can't load font" << endl;
}
// initialise Menu items
menu[0].setFont(font);
menu[0].setColor(sf::Color::Red);
menu[0].setString("Play");
menu[0].setPosition(sf::Vector2f(width / 2, height / (MAX_NUMBER_OF_ITEMS + 1) * 1));
// EXIT
menu[1].setFont(font);
menu[1].setColor(sf::Color::White);
menu[1].setString("Exit");
menu[1].setPosition(sf::Vector2f(width / 2, height / (MAX_NUMBER_OF_ITEMS + 1) * 2));
}
selectedItemIndex = 0;
Menu::~Menu()
{
}
void Menu::draw(sf::RenderWindow &window)
{
for (int i = 0; i < MAX_NUMBER_OF_ITEMS; i++)
{
window.draw(menu[i]);
}
}
控制台 window 将打印:
"Play button has been pressed"
但它并没有继续进行游戏。没有其他事情发生。
"window 重新定义" 错误发生是因为您的 RenderWindow 对象具有相同的标识符(即 window)。您可能想更改第二个 window 的名称或更好地使用相同的 window.
第二个错误,sf::Text::setColor()
is deprecated 意味着它不再“可用”或“不建议使用”。 SFML 为此有两个更好的新功能:
sf::Text::setFillColor()
: 设置文本的填充。
sf::Text::setOutlineColor()
: 给你的文本一个轮廓(你还需要使用 setOutlineThickness()
改变粗细)。
此外,我建议您针对不同的场景使用一个状态机,而不是两个单独的 windows。它真的没有那么难,而且会帮助你学到更多东西。您已经通过 gameObjectManager 实现了这一目标。您只需要抽象它并为您的菜单 class 实现它。由于您只有两个场景,因此您可以简单地使用整数或布尔值在这两个场景之间切换。
编辑:了解您需要对 main.cpp 文件做什么
int main()
{
sf::RenderWindow window(sf::VideoMode(1200, 800), "Space Invader Test");
GameObjectManager* gameObjectManagerManager = nullptr;
bool inGame = false; //true = game has started, false = menu screen
while (window.isOpen())//this is the main loop
{
sf::Event event;
while (window.pollEvent(event)) //this is the event loop
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Return)
{
if(!inGame)
{
if(menu.GetPressedItem() == PlayButton) //assuming your function returns which button in the menu has been pressed
{
cout << "Play button has been pressed." << endl;
inGame = true;
gameObjectManagerManager = new GameObjectManager(&window);
}
else
{
window.close(); //since the other button is exit
}
}
}
if (event.type == sf::Event::Closed) window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) window.close();
}
//this is the place where you call your updates
if(inGame) gameObjectManagerManager->update();
window.clear();
window.draw(galaxyBackground);
if(!inGame)menu.draw(window);
if(inGame) gameObjectManagerManager->render();
window.display();
}
return 0;
}