Sign in to follow this  
Mr C

I feel really dumb, but I am stuck on this (changing direction of a sprite)

Recommended Posts

Mr C    137
Hey, I am currently working on making a pong clone (for learning purposes). I have it to the point where both paddles and the ball are onscreen, both paddles can be controlled, and there are checks in place to make sure nothing goes off screen. However when I added the ball, I ran into problems. I can get it to move at the start fine (as the code below shows), and it stops where its supposed to (well, close enough anyways). The problem is I cannot for the life of me figure out how to get it to change direction. I know its going to be something stupid but I have been working on this for awhile now and I feel I have gotten to the point where I should ask for help. Note: This project is being done with SFML in Code::Blocks, if that information makes any difference.
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    // Create the main rendering window
   sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Pong");
   App.SetFramerateLimit(60); // Limits framerate

   // Next 3 lines display window size in console
   std::cout << App.GetHeight();
   std::cout << "\n";
   std::cout << App.GetWidth();

   sf::Image bluePaddle;
   sf::Image redPaddle;
   sf::Image ball;


// next 3 (currently 2) if's load images and displays error message if there is a problem
   if (!bluePaddle.LoadFromFile("bluePaddle.png"))
    {
    std::cout << "Error, bluePaddle.png failed to load";
    }
   if (!redPaddle.LoadFromFile("redPaddle.png"))
    {
    std::cout << "Error,redPaddle.png failed to load";
    }
   if (!ball.LoadFromFile("ball.png"))
    {
    std::cout << "Error, ball.png failed to load";
    }

// set blue paddle sprite and values
sf::Sprite bluePaddleSprite(bluePaddle);
bluePaddleSprite.SetY(200);

// set red paddle sprite and values
sf::Sprite redPaddleSprite(redPaddle);
redPaddleSprite.SetX(784);
redPaddleSprite.SetY(200);

// set the ball's sprite and values
sf::Sprite ballSprite(ball);
ballSprite.SetX(250);
ballSprite.SetY(250);

    // Start game loop
    while (App.IsOpened())
    {

        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();

            // A key has been pressed
            if (Event.Type == sf::Event::KeyPressed)
            {
                // Escape key : exit
                if (Event.Key.Code == sf::Key::Escape)
                    App.Close();
            }
        }
        // Clear the screen
        App.Clear(sf::Color(0, 0, 0));

//next 2 if's for bluePaddles border gaurds (collision detection, makes sure it stays in bounds)
      if (bluePaddleSprite.GetPosition().y < 0)
        {
        bluePaddleSprite.SetY(0.5);
        }

      if(bluePaddleSprite.GetPosition().y > App.GetHeight()-bluePaddle.GetHeight())
        {
        bluePaddleSprite.SetY(455);
        }

//nest 2 ifs are for redPaddles vorder gaurds (same as blue)

      if (redPaddleSprite.GetPosition().y < 0)
        {
        redPaddleSprite.SetY(0.5);
        }

      if(redPaddleSprite.GetPosition().y > App.GetHeight()-redPaddle.GetHeight())
        {
        redPaddleSprite.SetY(455);
        }


//-> start of code dealing with ball. This bit will deal with ball movement/collision/etc

     ballSprite.Move(150 * App.GetFrameTime() * -1, 0);

     if (ballSprite.GetPosition().y < 0)
        {
        ballSprite.SetY(0.5);
        }

      if(ballSprite.GetPosition().y > App.GetHeight()-ball.GetHeight())
        {
        ballSprite.SetY(582);
        }

      if(ballSprite.GetPosition().x < bluePaddleSprite.GetPosition().x + 16)
      {
        ballSprite.Move(150 * App.GetFrameTime() * 1, 0);
      }

//<- end of all the work with ball



//this chunk provides the code for player control (movement)

      if (App.GetInput().IsKeyDown(sf::Key::W))  {
         bluePaddleSprite.Move(0, 150 * App.GetFrameTime() * -1);
      } else if (App.GetInput().IsKeyDown(sf::Key::S)) {
        bluePaddleSprite.Move(0, 150 * App.GetFrameTime() * 1);
      }

//this bit is a tester for red before I put in AI, to make sure movement works. (tested working)

      if (App.GetInput().IsKeyDown(sf::Key::Up))  {
         redPaddleSprite.Move(0, 150 * App.GetFrameTime() * -1);
      } else if (App.GetInput().IsKeyDown(sf::Key::Down)) {
        redPaddleSprite.Move(0, 150 * App.GetFrameTime() * 1);
      }


    //Draws the blue Paddle
      App.Draw(bluePaddleSprite);
    //Draws the red paddle
      App.Draw(redPaddleSprite);
    //Draws the ball
      App.Draw(ballSprite);

        // Display window contents on screen
        App.Display();
    }


    return EXIT_SUCCESS;
}

Is my full code. The piece of code in question is:
     ballSprite.Move(150 * App.GetFrameTime() * -1, 0);

     if (ballSprite.GetPosition().y < 0)
        {
        ballSprite.SetY(0.5);
        }

      if(ballSprite.GetPosition().y > App.GetHeight()-ball.GetHeight())
        {
        ballSprite.SetY(582);
        }

      if(ballSprite.GetPosition().x < bluePaddleSprite.GetPosition().x + 16)
      {
        ballSprite.Move(150 * App.GetFrameTime() * 1, 0);
      }


There are a few other bugs, such as that although the ball stops, it stops at the point even if the paddle is not there (leading me to think I made it so its checking the y value of the area the paddle is on, instead of just the paddle). However my biggest problem right now is just getting the ball to change directions on contact. Thank you, and sorry for the trouble.

Share this post


Link to post
Share on other sites
rsalazar    100
what the other poster is getting at is that you should imagine the direction of anything as being a vector .. a vector in 2d is just an x and a y.

if D is your direction vector , then -2*D means that your x and y are multiplied by -2.

the formula that is written on that link he posted is

Vect2 = Vect1 - 2 * WallN * (WallN DOT Vect1)
... you can use this formula, i wont confirm it correct.

but lets say you are using a vector style direction ..

if you hit a vertical wall you multiply your X by -1, if you hit a horizontal wall you multiply y by -1.

if you want to change how paddle ENDS react on the ball ..make the distance the ball hits the paddle from the center as a multiplier on the Y so its more like the pong game.

PS. i think this works only if in settings like in pong where the walls are straight vertical and straight horizontal ... i believe its just a transformation matrix { {-1,0},{0,1} }

[Edited by - rsalazar on April 25, 2010 3:58:53 AM]

Share this post


Link to post
Share on other sites
Mr C    137
Turns out my base issue was having may variables for certain things in the wrong place. Now it works, at least as far as back and fourth bouncing (other issues present but I can deal)

I had re-written the code with
float v_x = 5;
float v_y = 0;

but had put them before the part dealing with the movement, thus putting them inside of a loop, so they where constantly being made and redefined. I moved them to outside of the loop and things work now.

I did learn a lot doing this though, and thanks for pointing me in the right direction as far as the math itself.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this