Чому ви хочете цього уникнути? Кругових залежностей слід уникати, якщо ви хочете зробити клас багаторазового використання. Але програвач - це не той клас, який взагалі потребує багаторазового використання. Чи хотіли б ви використати програвач без світу? Напевно, ні.
Пам'ятайте, що класи - це не що інше, як набір функціональних можливостей. Питання лише в тому, як можна розділити функціонал. Робіть все, що вам потрібно зробити. Якщо вам потрібна кругова декаденція, то так і буде. (Те саме стосується будь-яких функцій OOP. До речі, кодуйте речі таким чином, щоб вони слугували цілі, а не просто сліпо слідувати парадигмам.)
Відредагуйте
Гаразд, щоб відповісти на запитання: ви можете уникнути того, що гравцю потрібно знати світ для перевірки зіткнення, використовуючи зворотні дзвінки:
World::checkForCollisions()
{
[...]
foreach(entityA in entityList)
foreach(entityB in entityList)
if([... entityA and entityB have collided ...])
entityA.onCollision(entityB);
}
Player::onCollision(other)
{
[... react on the collision ...]
}
Вигляд фізики, який ви описали у запитанні, може обробляти світ, якщо ви піддаєте швидкість сутностей:
World::calculatePhysics()
{
foreach(entityA in entityList)
foreach(entityB in entityList)
{
[... move entityA according to its velocity as far as possible ...]
if([... entityA has collided with the world ...])
entityA.onWorldCollision();
[... calculate the movement of entityB in order to know if A has collided with B ...]
if([... entityA and entityB have collided ...])
entityA.onCollision(entityB);
}
}
Однак зауважте, що вам, напевно, потрібна залежність від світу рано чи пізно, тобто коли вам потрібна функціональність Світу: ви хочете знати, де знаходиться найближчий ворог? Хочете знати, як далеко знаходиться наступний виступ? Залежність вона є.