«Концепция» оо-игры - PullRequest
       14

«Концепция» оо-игры

1 голос
/ 05 ноября 2010

В большинстве или во всех объектно-ориентированных играх каждый класс опирается не только на свои, но и на родительские классы.Как это соединение классов реализовано в C ++?Вы просто добавляете указатель для нужного вам родительского класса или есть лучший способ?

Например, футбольная игра, когда человек щелкает по ней классом, спрашивает класс сцены, пинает ли он какие-либо шары, ион тогда двигает это.Надеюсь, это понятно и не слишком абстрактно.

Ответы [ 2 ]

1 голос
/ 05 ноября 2010

Я не думаю, что передача родителя в конструкторе хорошая идея. Вместо этого вы должны использовать класс, который поддерживает список всех игровых элементов и средств взаимодействия между ними; например, класс Game, показанный ниже, будет проверять наличие столкновений между любыми двумя игроками и, если он обнаружен, сообщать каждому из них, что они пострадали и кем.

Я не уверен, принесет ли это вам хоть какую-то пользу, но я напечатал его для своего первоначального ответа, поэтому я мог бы также отправить его. Обратите внимание, что все это по-прежнему актуально, если вы говорите о текстовой игре, просто игнорируйте намеки на графику в этом случае. Дизайн игры основан на непрерывном игровом цикле, и его можно представить очень просто:

while(true)
    for each tick:
        react to user input
        update player, enemies, objects, etc.
end while

Где «тик» - это каждая итерация игровых часов, однако вы выбираете ее реализацию - на основе fps, каждую секунду, что угодно. В вашем примере пользователь нажимает на футбольный мяч, игра видит щелчок и указывает футболу двигаться. Чтобы сделать это очень просто, ведите список всех элементов игры в классе, который поддерживает состояние. Чтобы проиллюстрировать это, вот очень простой способ реализовать это:

class Game {
    vector<GameElement> elements;
Football football;
Player currentPlayer;

Game() {
    this.football = new Football();
}

    void update() {
        for e in elements:
            e.update();

        // Once every element has been updated for the current tick, redraw them on the screen  
        screen.redraw();
    }
    void addElement(GameElement e) {
        elements.add(e);
    }
}

class GameElement {
    int posx, posy;     // screen coordinates
    void paint() {};    // method to draw this element to the screen
    virtual void update();
}

class Football: public GameElement {
    bool kicked;
    int anglex, angley;
    double velocity;

    void update() {
        if(kicked){
            // update position, angle, velocity; slow it down, check for bounce, whatever
            posx = new x position;
            posy = new y position;
        if(velocity == 0)
            kicked = false;     
        }
        paint();    // call the paint method after the new position has been found
    }
}

Предположим, у вас есть другой класс, унаследованный от GameElement, Player, с методом kick (football), который приводит в движение переданный футбол - т.е. set kicked = True. Таким образом, чтобы инициализировать игру, вы должны настроить что-то вроде:

Game game = Game();
game.add(new Football());
game.add(new Player());
while(true) {
if(user_input==X)
    game.currentPlayer.kick(football);
    game.update();
    sleep(1);
}

Это можно изменить, чтобы поддерживать, например, слои вместо всей игры, тогда класс более высокого уровня мог бы вызывать обновление каждого слоя по порядку, позволяя вещам закрашиваться друг на друга, а дети взаимодействовать только с братьями и сестрами. Есть много возможностей.

1 голос
/ 05 ноября 2010

Столкнулся с похожими вопросами, работая над игрой в покер: Вот как я это сделал:

В вашем примере добавьте сцену * the_scene в конструктор person. Затем, когда человек инициализируется, передайте ему указатель на сцену. Так как вы сказали «родитель» и «потомок», если родитель «сцена», то он просто использовал бы «это» и отправил бы адрес родителя.

Опять же, похоже, именно так вы и собирались это делать. Еще одна вещь, если вам нужно, чтобы человек взаимодействовал с несколькими классами, которые не находятся непосредственно внутри него, вы можете создать некоторый контейнерный класс, который будет хранить указатели на все из них и просто передать ему тот, чтобы избежать создания слишком много параметров.

...