Я новичок здесь, и мой вопрос был слишком длинным, и я принял совет Исима и сократил вопрос. Я только учусь задавать вопросы. Спасибо Исиму.
Я также новичок в C ++ и ООП, работаю над игрой, использую некоторые замечательные библиотеки (Bullet для физики, Ogre для рендеринга, RakNet для сетей и т. Д.) Хотя моя игра работает, у меня есть ощущение, что я что-то делаю не так.
У меня есть эта проблема для каждой библиотеки, которую я использую. Чтобы быть кратким и приятным, я приведу в качестве примера только использование Bullet и предположу, что у нас есть только два класса (Game и Object)
class Game
{
public:
btDiscreteDynamicsWorld *bulletWorld;
Game();
~Game();
void UpdateWorld();
};
class Object
{
public:
btRigidBody *body;
Object() { bulletWorld->addRigidBody(body); };
};
и вот главное:
int main()
{
Game myGame;
while(1)
myGame.UpdateWorld(); // this is THE GAME LOOP
return 0;
}
Слишком просто, не правда ли? Здесь моя проблема в том, что если я создаю объект и помещаю его в мир, я должен назвать это:
bulletWorld->addRigidBody(body)
Так что на данный момент я не могу создать объект с:
Object *myObj = new Object(); //the Object class cannot access the Game class' members
Я знаю, что могу передать указатель * bulletWorld в качестве аргумента:
Object(btDiscreteDynamicsWorld *bulletWorld);
и так моя игра работает как шарм. Тем не менее, я не чувствую себя настолько комфортно с тем фактом, что у меня больше библиотек, чем просто Bullet, и для каждого метода моих классов, который мне нужен, мне приходится снова и снова передавать указатели в качестве аргументов. Итак, если у меня сейчас 20 000 символов в исходном коде, 10 000 из них являются аргументами-указателями, и это беспокоит меня.
Это нормально и лучший способ или есть лучший способ сделать то, что я хочу. Я думал о создании объектов с использованием метода createObject () в классе Game, вместо создания с помощью класса Object, и это, похоже, решит мою проблему, но тогда, не нужно других классов и делать все в классе Game, похоже, что это не C ++ и ООП стиль, выглядит просто как стиль С. Так что я могу сделать?
Я думаю, вам просто нужно больше думать о том, кто за что отвечает. Объекты мира должны быть ответственны за обработку вещей мира, локальные объекты должны отвечать за обработку локальных вещей. Если бы я проектировал эту игру, main, вероятно, выглядел бы примерно так:
int main()
{
Game *myGame = new Game();
Object * enemy1 = new Object();
Object * hero1 = new Object();
myGame->addObject(enemy1); //This takes care of adding the object to the physics engine, since Game objects in your case are responsible for the world
myGame->addObject(hero1); //Same as above; Game will take care of setting up hero1 in the world context
while(1)
myGame->UpdateWorld(); // this is THE GAME LOOP
delete myGame;
return 0;
}
Ваша игра addObject
метод будет выглядеть примерно так:
void addObject(Object * obj)
{
bulletWorld->addRigidBody(obj->getBody());
...
}
Вам не нужны одиночные игры, это ваша игра, и вы не собираетесь объявлять нужные вам классы только один раз.
Просто сделайте ваши классы необходимыми везде глобальными и (i) либо сделайте все необходимые методы public
(ii) или объявить классы, доступ к которым разрешен как friend
,
В противном случае использование указателя также вполне допустимо, и какой путь лучше, как часто зависит … тем не менее, вы должны лучше использовать умные указатели (более подробно, shared_ptr
с в классах и один unique_ptr
где-то) чтобы лучше указать отношения собственности.