Анализ проблемы
class entity :public sf::CircleShape, public sf::RectangleShape
В этой декларации говорится, что каждый entity
является одновременно CircleShape
и RectangleShape
. Это не то, что вы хотите. Вы, кажется, хотите сущность, которая может быть или кругом или прямоугольником. Так что это наследство не является правильной стратегией.
Учитывая, что вы добавляете горизонтальную и вертикальную скорости, создается впечатление, что вы пытаетесь добавить базовую анимацию к элементам, которые можно нарисовать. Анимация - это абстрактное понятие, основанное на рисовании (анимация должна быть нарисована, но не все рисунки должны быть анимированными). Определенные движущиеся фигуры будут строиться поверх анимации, поэтому ваше идеальное наследование будет больше похоже на следующее:
circle -> entity -> drawable
Однако есть несколько недостатков. Один недостаток заключается в том, что это заставляет все круги быть анимированными объектами, когда некоторые круги можно просто нарисовать в одном месте. Кроме того, классы circle и drawable взяты из библиотеки, поэтому вы не можете связываться с этой конкретной схемой наследования.
Я могу придумать две разумные альтернативы на макушке. (Кстати, «сущность» - не лучшее название для вашего класса, но я буду придерживаться его для последовательности. Вам следует придумать более описательное имя для класса. Это будет хорошая практика, именование вещей иногда является одной из самых сложных частей написания кода. :))
Сущность как базовый класс
Вы можете определить entity
как базовый класс, а затем определить новый класс для каждой фигуры.
--> sf::CircleShape --> sf::Drawable
/
MyCircle --<
\
--> entity
Это может работать, но это не очень хорошо, если entity
нужно вызывать функции, определенные в Drawable
. Не является невозможным: приведение стороны может сделать возможным вызов функций Drawable
. Просто тогда вы должны учитывать случай сбоя приведения, поскольку компилятор не может это уловить.
Фигуры в качестве членов
Что бы я, вероятно, сделал, это полностью отказаться от наследства. Вместо того, чтобы пытаться сказать, что ваша сущность является кругом (наследование), я бы придерживался подхода, согласно которому ваша сущность имеет круг (членство). Одним из преимуществ этого подхода является то, что нетрудно расширить его, сказав, что ваша сущность имеет несколько фигур, все они движутся с одинаковой скоростью. Однако сейчас я буду придерживаться одной фигуры.
Сложность этого подхода заключается в том, что вы не знаете, какую форму должен иметь объект - должен ли он иметь круг или прямоугольник? К счастью, с этим полиморфизмом хорошо справляется.
class entity {
std::unique_ptr<sf::Drawable> shape; // <-- Polymorphism to the rescue!
float xspeed = 0.0, yspeed = 0.0;
public:
// Construct a circle.
entity(int radius = 0) : shape(std::make_unique<sf::CircleShape>(radius)) {}
// Construct a rectangle.
entity(sf::Vector2f size) : shape(std::make_unique<sf::RectangleShape>(size)) {}
// Something will go here to support drawing.
};
Для поддержки рисования есть (как минимум) два варианта. Если уместно иметь entity
замену для Drawable
, было бы разумно определить неявное преобразование.
operator const sf::Drawable &() const { return *shape; }
Если неявное преобразование нежелательно, можно указать его explicit
.
Если единственное время, когда вам нужно использовать entity
в качестве Drawable
, это когда вы вызываете window.draw()
, вы можете вместо этого указать entity
draw
метод, который принимает window
в качестве параметра .
void draw(sf::RenderTarget & target, sf::RenderStates states) const
{ target.draw(*shape, states); }
Это делает Drawable
доступным для RenderTarget::draw()
, оставляя его вне поля зрения (уменьшение помех) в другое время.