Мнения Entity Manager - PullRequest
       0

Мнения Entity Manager

1 голос
/ 15 декабря 2011

В настоящее время я занимаюсь рефакторингом кода, и одна из вещей, которую я хочу улучшить, это мой код менеджера сущностей.Точнее, функция обновления, где обновляются сущности.Мой движок - это движок 2D на основе плиток, который я использую для игры на iphone.У меня была идея разделить обновление сущностей на несколько задач, потому что я готов перейти к сущностям на основе компонентов, когда у меня будет время.Это физическая задача, задача обнаружения столкновений, задача ИИ и т. Д. *

В течение долгого времени я использовал простую функцию update () для обновления сущности, которая была вызвана менеджером сущности впетля.Теперь я нашел другой способ сделать это (в конце концов, это то же самое), но дает мне некоторые преимущества, такие как, например, разные такты для разных задач (физика может работать с различной частотой обновления, чем столкновения и т. Д.)

Вот исходный код.Я был бы очень рад, если бы кто-нибудь мог прокомментировать, высказать свое мнение или улучшить его.Извините, это ObjC, но я думаю, что это довольно легко понять:

//Run the update process o nall entities.
for(int i=0; i< numGameObjects;++i)
{
    GameObject* go=_entities[i];

    //If this game object was marked to be delted don't do any process with it.
    //It will be released when update loop is finished.
    if(! [go isToBeDeleted])
    {
        //Player does its physics (Movement, etc...)
        //We save old position to let the onMapCollision know
        //The previous position before physics were applied.
        CGPoint oldPos=[go position];
        [go doPhysics];

        if([go collisionEnabled])
        {   
            //Check collisions against map
            CollisionMask collisionMask=[go collisionMask];
            if(collisionMask & MapEntity)
            {
                bool collision=[self checkEntityVsMapCollision:go];
                if(collision==true)
                    [go onMapCollision:oldPos];
            }

            //Check collisions against other entities (just the ones that have not been checked previously)
            for(int j=i+1; j < numGameObjects; ++j)
            {
                GameObject* otherGO= _entities[j];
                EntityType type=[go type];
                if( (collisionMask & type) && [go collidesWith:otherGO])
                {
                    [go onEntityCollision:otherGO];
                    [otherGO onEntityCollision:go];
                }
            }
        }

        //Execute AI for this game object
        [go doLogic];
    }
}

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

Заранее спасибо.

1 Ответ

1 голос
/ 15 декабря 2011

Так что это выглядит как тонкая петля.Я не вижу смысла менять его, если у вас нет проблем.Но так как вы разместили здесь, я собираюсь предположить, что у вас проблемы с производительностью.

Этот кусок:

//Check collisions against map
CollisionMask collisionMask=[player collisionMask];
if(collisionMask & MapEntity)
{
    bool collision=[self checkEntityVsMapCollision:_player];
    if(collision==true)
        [_player onMapCollision:oldPos];
}

Возможно, я что-то упускаю, это делает вас старыми, но есть ли у этогоделать с отдельным игровым объектом?Можно ли [self checkEntityVsMapCollision] просто вызвать один раз перед циклом?

Вы также можете кэшировать, если объект был перемещен.Если что-то не сдвинулось, не нужно проверять столкновение.Каждый другой объект по-прежнему будет проверять, попал ли он (поэтому ваш внутренний цикл for должен начинаться с 0), но затем вы сохраняете полную проверку столкновения для неподвижных объектов.

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

...