TransformableとDrawableをSFMLで継承しようとしています。私は簡単なブレークアウトゲームを作っていますが、おそらく私はこれについて間違った方法をとっています。私のコードは次のとおりです:SFMLのTransformableとDrawableから継承
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
class Player : public sf::Transformable, public sf::Drawable {
public:
Player(int x, int y);
~Player() {};
sf::RectangleShape p_rect;
void doMovement(const sf::RenderWindow& window);
sf::FloatRect getGlobalBounds() const;
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
states.transform *= getTransform();
target.draw(p_rect, states);
}
};
class Ball : public sf::Transformable, public sf::Drawable {
public:
Ball(int r, int x, int y);
~Ball() {};
sf::CircleShape b_circle;
void doXMovement();
void doYMovement();
bool doXCollisions(const Player& player);
bool doYCollisions(const Player& player);
sf::FloatRect getGlobalBounds() const;
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
states.transform *= getTransform();
target.draw(b_circle, states);
}
bool right;
bool up;
};
Player::Player(int x, int y) {
p_rect = sf::RectangleShape(sf::Vector2f(x, y));
}
void Player::doMovement(const sf::RenderWindow& window) {
setPosition(sf::Mouse::getPosition(window).x, 500);
if (getPosition().x < 0)
setPosition(0, 500);
else if (getPosition().x > 720)
setPosition(720, 500);
}
sf::FloatRect Player::getGlobalBounds() const {
return getTransform().transformRect(p_rect.getGlobalBounds());
}
Ball::Ball(int r, int x, int y) {
b_circle = sf::CircleShape(r);
b_circle.setPosition(x, y);
right = true;
up = false;
}
void Ball::doXMovement() {
if (right)
move(1, 0);
else
move(-1, 0);
}
void Ball::doYMovement() {
if (up)
move(0, -1);
else
move(0, 1);
}
bool Ball::doXCollisions(const Player& player) {
bool coll;
if (getGlobalBounds().intersects(player.getGlobalBounds())) {
right = !right;
coll = true;
} else
coll = false;
if (getPosition().x >= 800 - b_circle.getRadius())
right = false;
else if (getPosition().x <= 0)
right = true;
return coll;
}
bool Ball::doYCollisions(const Player& player) {
bool coll;
if (getGlobalBounds().intersects(player.getGlobalBounds())) {
up = !up;
coll = true;
} else
coll = false;
if (getPosition().x <= 0)
up = false;
return coll;
}
sf::FloatRect Ball::getGlobalBounds() const {
return getTransform().transformRect(b_circle.getGlobalBounds());
}
int main() {
sf::RenderWindow window(sf::VideoMode(800, 600), "Breakout");
window.setMouseCursorVisible(false);
Player player(80, 10);
Ball ball(3, 100, 100);
sf::Clock clock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
player.doMovement(window);
if (clock.getElapsedTime().asMilliseconds() >= 3) {
clock.restart();
if (!ball.doYCollisions(player))
ball.doXCollisions(player);
ball.doYMovement();
ball.doXMovement();
}
window.clear(sf::Color::Black);
window.draw(player);
window.draw(ball);
window.display();
}
return 0;
}
期待通りに動き回っていますが、衝突はちょっと怪しいです。最初に私の衝突の問題:
- 私はやったようにgetGlobalBounds関数を実装する必要がありますか?あるいは、TransformableとDrawableに含まれているものを使ってより良い方法を実現できますか?
- シェイプの変形を直接実行するか、現在のように描画関数に変換を渡す必要がありますか?
おそらく速い修正であるかもしれない何か変わったことが起こっています。現在、getPositionメソッドは、私のボールオブジェクトに不正な値を返します。それが返す領域は右に少しシフトしているようです。何らかの理由がありますか?
ご協力いただきありがとうございます!
編集:また、一般的なC++のヒントも歓迎します。私はまだ初心者です。あなたは、一般的にあなたの変形および描画可能なクラスが必要とするすべてのメンバーを定義する必要があり、このクラスでは
class TransformableAndDrawable : public sf::Transformable, public sf::Drawable {
// Your code here
}
:私があなただったら、私は新しいクラスを定義します
私は本当に同じコードを2回書くのが嫌なので、クールな、これらのクラスのスーパークラスを作ることを考えていました。うまくいけば、これで私の奇妙な問題を図面で修正できます。 – mrobinson7627
getRadius関数を使用するときにShapeポインタをキャストすることをお勧めしますか?それはうまくいくだろうが、それは悪い習慣であるかもしれないように感じる。私は個人的にそうは思わない。それは、クラスがサークル型の形状を持たなければならないからだ。 編集します: '(getPosition()。x> = 800 - dynamic_cast(形) - > getRadius())' –
mrobinson7627
あなたはそれを変換することができますが、スーパークラスでもその機能を利用することができます。そこにはテンプレートを使用して任意のクラスをサポートすることができます。 –