0

質問:

while ループが終了しません。デバッグ中に、それはstateID3 に等しいと非常に具体的に述べています。しかし、std::cout << stateID;値を追加する1と、デバッガーが何を言っているかに関係なく、常にコンソールに書き込まれます。

コードでは、入力ループのに画面をレンダリングします。これは、間違いなく、期待どおりに入力ループが適切に終了することを示しています。また、それで十分でない場合は、最初に stateID を変更するために終了する必要があります。ネストされたループが問題であるというこれ以上の議論はやめてください。また、ループの後に適切にヒットするブレークポイントも使用しました。

コード:

int main()
{

    stateID = 1;

    GameState* state = new GameStateTitle();

    sf::RenderWindow window(sf::VideoMode(1000, 600), "RPG");

    //GAME LOOP//
    while (stateID != 3)
    {//INPUT//
    sf::Event event;
    while (window.pollEvent(event))
    {
        switch (event.type)
        {
        //Window closed
        case sf::Event::Closed:
            set_next_state(3);
            break;
        }
    }

        change_state(state);

    //RENDERING//
    window.clear(sf::Color::Black);

    state->render(window);

    window.display();
    }
    /////////////

    window.close();

    return 0;
}

void set_next_state(int new_state)
{
    //Set the next state to take place
    next_state = new_state;
}

void change_state(GameState *current_state)
{
    //Check if the next state is null or exit
    if (next_state != 0)
    {
        if (next_state != 3)
            delete current_state;

        //Set the new state
        switch(next_state)
                ...
        }

        stateID = next_state;
        next_state = 0;
    }
}

重要な何かを見逃した場合に備えて、以下は私の完全なコードです。

メイン.cpp

#include "GameState.hpp"

int main()
{

    stateID = STATE_TITLE;

    GameState* state = new GameStateTitle();

    sf::RenderWindow window(sf::VideoMode(1000, 600), "RPG");

    //GAME LOOP//
    while (stateID != STATE_EXIT)
    {
        //INPUT//
        sf::Event event;
        while (window.pollEvent(event))
        {
            switch (event.type)
            {
            //Window closed
            case sf::Event::Closed:
                set_next_state(STATE_EXIT);
                break;
            }
        }
        ///////////

        ////LOGIC//
        state->logic();
        ///////////

        change_state(state);

        //RENDERING//
        window.clear(sf::Color::Black);

        state->render(window);

        std::cout << stateID;

        window.display();
        /////////////
    }
    ///////////////

    window.close();

    return 0;
}

GameState.hpp

#pragma once

#include <SFML/Graphics.hpp>

//DEFINITIONS ETC//
enum GAME_STATES {
    STATE_NULL,
    STATE_TITLE,
    STATE_BATTLE,
    STATE_EXIT
};
///////////////////

//Game State Class//
class GameState
{
public:
    virtual void input(void) = 0;
    virtual void logic(void) = 0;
    virtual void render(sf::RenderWindow &window) = 0;
};
////////////////////

//FUNCTIONS//
void set_next_state(int new_state);
void change_state(GameState *current_state);
/////////////

//VARIABLES//
static int stateID;
static int next_state;
/////////////

//Title GameState Class//
class GameStateTitle : public GameState
{
private:
    sf::Texture img_title;
    sf::Sprite bgr_title;

public:
    GameStateTitle(void);
    ~GameStateTitle(void);

    void input(void);
    void logic(void);
    void render(sf::RenderWindow &window);
};
/////////////////////////

//Battle GameState Class//
class GameStateBattle : public GameState
{
private:
    sf::Image img_left;
    sf::Image img_right;

public:
    GameStateBattle(void);
    ~GameStateBattle(void);

    void input(void);
    void logic(void);
    void render(sf::RenderWindow &window);
};
//////////////////////////

GameState.cpp

#include "GameState.hpp"

//Game state general functions
void set_next_state(int new_state)
{
    //Set the next state to take place
    next_state = new_state;
}

void change_state(GameState *current_state)
{
    //Check if the next state is null or exit
    if (next_state != STATE_NULL)
    {
        if (next_state != STATE_EXIT)
            delete current_state;

        //Set the new state
        switch(next_state)
        {
        case STATE_TITLE:
            current_state = new GameStateTitle;
            break;
        case STATE_BATTLE:
            current_state = new GameStateBattle;
            break;
        }

        stateID = next_state;
        next_state = STATE_NULL;
    }
}

//The functions of the title state
GameStateTitle::GameStateTitle(void)
{
    //Load texture
    img_title.loadFromFile("title_screen.png");

    //Set texture to background
    bgr_title.setTexture(img_title);
}

GameStateTitle::~GameStateTitle(void)
{
}

void GameStateTitle::input(void)
{
}

void GameStateTitle::logic(void)
{
}

void GameStateTitle::render(sf::RenderWindow &window)
{
    window.draw(bgr_title);
}

//The functions of the battle state
GameStateBattle::GameStateBattle(void)
{
}

GameStateBattle::~GameStateBattle(void)
{
}

void GameStateBattle::input(void)
{
}

void GameStateBattle::logic(void)
{
}

void GameStateBattle::render(sf::RenderWindow &window)
{
}
4

3 に答える 3

5

2 つのwhileループがあります。外側の while の条件は、内側のループが終了するまでテストされません。

条件が 1 つのループを 1 つだけ使用することを検討してください。

sf::Event event;
while ( (stateID != 3) && window.pollEvent(event)) {

}
于 2013-05-31T18:05:05.770 に答える
1

あなたは から抜け出しているのであって から抜け出しているわけではswitchありませんwhile

以下のプログラムは、コードを複製 (しようと) します。期待どおりに機能し、両方のループが想定どおりに終了します。

ところで、これは私たちが短い、封じられた、正しい例と呼んでいるものです。コンパイル可能なように正しく、 in などのグローバルや in などのマジック ナンバーを使用するstateIDのは悪い形式であり、専門家の印ではありません。3while (stateID != 3)

あなたのプログラムは以下のものからどのように逸脱していますか?

#define STATE_TITLE 2
#define STATE_BATTLE 3
#define STATE_NULL 0

int stateID;
int next_state;

struct Event
{
    Event(int Num) : type(Num){}

    Event() : type( 5 ){} // random number grater than 1

    enum Type
    {
        Closed = 1 // equivalent to sf::Event::Closed
    };

    int type;
};

class Window
{
public:

    int pollEvent( Event& Ev )
    {
        return --Ev.type;
    }
};

void set_next_state(int new_state)
{
    next_state = new_state;
}

void change_state()
{
    if (next_state != STATE_NULL)
    {
        stateID = next_state;
        next_state = STATE_NULL;
    }
}

int _tmain()
{
    stateID = STATE_TITLE;

    Window window;

    //GAME LOOP//
    while (stateID != 3)
    {//INPUT//
        Event event;
        // note that there is at least one event with a Closed type before window.pollEvent(event) return false (0)
        while (window.pollEvent(event))
        {
            switch (event.type)
            {
                //Window closed
            case Event::Closed:
                set_next_state(3);
                break;
            }
        }

        change_state();
    }

    return 0;
}
于 2013-05-31T18:01:09.167 に答える
0

関数change_stateを次のように変更しました。

void change_state(GameState *current_state, int &ID)
{
    //Check if the next state is null or exit
    if (next_state != STATE_NULL)
    {
        if (next_state != STATE_EXIT)
            delete current_state;

        //Set the new state
        switch(next_state)
        {
        case STATE_TITLE:
            current_state = new GameStateTitle;
            break;
        case STATE_BATTLE:
            current_state = new GameStateBattle;
            break;
        }

        ID = next_state;
        next_state = STATE_NULL;
    }
}

stateIDこの問題は、この関数で変更されていないため、 の宣言内にあったに違いありません。

于 2013-05-31T19:20:18.667 に答える