I just can't seem to figure out what is wrong with my logic. It works fine when it bounces off the bottom or top but when it hits a side it flips out.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
#include <SFML/Graphics.hpp> //sf::RenderWindow
#include <SFML/Window.hpp> //sf::VideoMode, sf::Event
#include <cmath> //sinf
#include <chrono>
#include <random>
int main()
{
const int ScreenWidth = 640 , ScreenHeight = 400 , BPP = 32;
const std::string Title = "Bouncing Square";
sf::RenderWindow Window( sf::VideoMode( ScreenWidth , ScreenHeight , BPP ) , Title );
sf::Event Event;
const int Width = 15;
sf::RectangleShape Square( {Width , Width} );
Square.setOrigin( Width/2.0f , Width/2.0f ); //centered
Square.setPosition( ScreenWidth/2.0f , ScreenHeight/2.0f );
sf::FloatRect Rect;
sf::Clock Clock;
float DeltaTime;
float Velocity = 100.0f;
auto Seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 RandomGen( Seed );
float Angle = static_cast<float>( RandomGen() % 360 );
float UnitsToMoveX , UnitsToMoveY;
const float Pi = 3.14159f;
const float Radian = Pi / 180.0f;
while( Window.isOpen() )
{
Window.clear();
DeltaTime = Clock.restart().asSeconds();
UnitsToMoveY = sinf( Angle * Radian ) * DeltaTime * Velocity;
UnitsToMoveX = cosf( Angle * Radian ) * DeltaTime * Velocity;
Rect = Square.getGlobalBounds();
//Hit wall
if( Rect.top + UnitsToMoveY <= 0.0f || Rect.top + Rect.height + UnitsToMoveY >= ScreenHeight )
{
Angle = 360 - Angle;
UnitsToMoveY = -UnitsToMoveY; //Flip the movement (bounce)
Velocity += 5.0f; //increase velocity
}
else if( Rect.left + UnitsToMoveX <= 0.0f || Rect.left + Rect.width + UnitsToMoveX >= ScreenWidth )
{
Angle = 360 - Angle;
UnitsToMoveX = -UnitsToMoveX; //Flip the movement (bounce)
Velocity += 5.0f; //increase velocity
}
Square.move( UnitsToMoveX , UnitsToMoveY );
Window.draw( Square );
Window.display();
while( Window.pollEvent( Event ) )
{
if( Event.type == sf::Event::Closed )
Window.close();
}
}
}
|
The logic that seems to be completely messed up is this part:
1 2 3 4 5 6 7
|
//if it doesn't hit top/bottom check sides
else if( Rect.left + UnitsToMoveX <= 0.0f || Rect.left + Rect.width + UnitsToMoveX >= ScreenWidth )
{
Angle = 360 - Angle;
UnitsToMoveX = -UnitsToMoveX; //Flip the movement (bounce)
Velocity += 5.0f; //increase velocity
}
|
The logic seems right to me.
The Rect is made of the Left , Top , Width , and Height of the Square
The Origin is the center of the Square so x = left - width / 2 , y = top - height / 2
And my if statement says:
if the Left edge of the box moves left X units and is less than or equal to 0 ( left wall ) or if the right edge ( left + width ) + X Units is greater than or equal to the Width of the window ( right wall ) then flip the angle and movement ( x axis ) and increase the velocity of the object.
But I must have messed up somewhere so if a second pair of eyes could help me out I would appreciate it greatly.
PS sorry if the code is pretty messy I was trying to quickly throw together an example of what my problem was in one file.
*edit I also tried:
if( Square.getPosition().x + UnitsToMoveX - Width / 2.0 <= 0.0 || Square.getPosition().x + UnitsToMoveX + Width / 2.0 >= ScreenWidth )
Same exact problem though
One more thing I am using floats instead of doubles because the precision isn't very important or at least I didn't think it was with these variables.