Hello again.
I'm trying to make a simple Entity system for a 2D bullet hell game. Each frame, I calculate the velocity and position of each entity and render it on the screen using a temporary sf::RectangleShape. All was going well untill I attempted to make an entity rotate. The first thing that came to mind was to pass the temporary
sf::RectangleShape to the draw function of the current render target (I'm refering to the parameter of the sf::Drawable::draw method, inherited by Entity) along with the transform of the entity (which of course also inherits from sf::Transformable) through the render states, and it all worked as expected... until I tyed to rotate an entity while it was moving. This made the entity suddenly change position by a drastic offset (often going offscreen) without any apparent reason. Initially, I thought that this had to do with the origin of the entity, but even by moving the origin every frame along with the position, the problem persisted.
Here is the draw function:
void Entity::draw(sf::RenderTarget& target, sf::RenderStates states) const {
sf::RectangleShape rectangle(mHitBox);
rectangle.setTexture(mTexture);
states.transform = getTransform();
target.draw(rectangle, states);
}
And here is the function where movement takes place:
void MovingEntity::handleLogic(sf::RenderWindow& window, const sf::Time& timeElapsed) {
//accelerate entity
mVelocity += mAcceleration * timeElapsed.asSeconds();
//simulate next position
auto displacement = mVelocity * timeElapsed.asSeconds();
auto futurePos = getPosition() + displacement;
//check border collisions
auto borders = sf::Vector2f(window.getSize()) - mHitBox;
if(futurePos.x < 0 || futurePos.x > borders.x) {
mVelocity.x = 0;
mAcceleration.x = 0;
if(futurePos.x < 0)
futurePos.x = 0;
else if(futurePos.x > borders.x)
futurePos.x = borders.x;
}
if(futurePos.y < 0 || futurePos.y > borders.y) {
mVelocity.y = 0;
mAcceleration.y = 0;
if(futurePos.y < 0)
futurePos.y = 0;
else if(futurePos.y > borders.y)
futurePos.y = borders.y;
}
//move entity
move(displacement);
}
And here's where I do the rotation:
void Ferri::vHandleLogic(sf::RenderWindow& window, const sf::Time& timeElapsed) {
//move Ferri
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
mAcceleration.x = 0;
mAcceleration.y = -1;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
mAcceleration.x = 1;
mAcceleration.y = 0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
mAcceleration.x = 0;
mAcceleration.y = 1;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
mAcceleration.x = -1;
mAcceleration.y = 0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::R)) {
rotate(1);
}
else {
mAcceleration.x = 0;
mAcceleration.y = 0;
}
mAcceleration *= mAccelerationIntensity;
//don't get over the limit velocity
float speed = std::sqrt(std::pow(mVelocity.x, 2) + std::pow(mVelocity.y, 2));
if(speed >= mMaxSpeed) {
mVelocity.x = mVelocity.x / speed * mMaxSpeed;
mVelocity.y = mVelocity.y / speed * mMaxSpeed;
}
}
That's all. I really hope I'm not missing a stupid bug or something...