Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: bouncing  (Read 6000 times)

0 Members and 1 Guest are viewing this topic.

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« on: September 28, 2008, 03:24:54 pm »
well i have a problem (again):

in my pong clone the ball should bounce when it touches the top or bottom of the window, i tried it like this:


thers a class ball with a vector2f dir  for the direction the ball goes , and a float speed for the velocity;
moreover i got a function bounce_y when the ball should bounce from top or bottom:


Code: [Select]


class ball
{
vector2f dir;
float speed;
...
}

void ball::bounce_y()
{
    if(dir.y == 1)
        dir.y = -1;
    else
        dir.y = 1;
}


i try to find out wether the ball should bounce like that:


Code: [Select]

if( Ball.GetPosition().y <= 0 || Ball.GetPosition().y +10 >= WINDOW_HEIGHT)
        Ball.bounce_y();



after that i move the ball:

Code: [Select]
Ball.Move(Ball.speed * Ball.dir * App.GetFrameTime());

mostly it works fine but sometimes in my game my ball is hanging, it doesnt bounce when it should

could that be because there are no negative y-values in GetPosition?

well i cannot find any other mistake; if there are problems with understanding my question i could post the whole code;
at moment only the y-direction is important

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
bouncing
« Reply #1 on: September 28, 2008, 04:16:32 pm »
What do you think is special about when dir.y == 1 that's making you test against that?

Edit:  Also, I hope you are normalizing dir or you're going to get some weird movement calculations.

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #2 on: September 28, 2008, 05:39:36 pm »
sry quasius, ill tell u a bit more:

my vector dir can be (-1|-1) (1|-1) (-1|1) or (1|1)

i do not have to normalize the vector because only 45° appear

i think my problem is following:

let´s take the top of my window: the ball reaches a negative y-coord and then there is the order: bounce() which changes the y-value of dir , and now it seems that the ball does not reach a positive y-coord in the next frame and the ball bounces so long until it reaches a positive y-coord again

i hope my thoughts are not too far from truth, if u have a solution for this , pls tell me

thanks your raven

Beaker

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • http://corvuscorone.net/
bouncing
« Reply #3 on: September 28, 2008, 06:19:47 pm »
Can you post your code for your Ball.Move method.

Also, your bounce_y method can be simplified somewhat:

Code: [Select]
void ball::bounce_y()
{
    dir.y = -dir.y;
}

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
bouncing
« Reply #4 on: September 28, 2008, 06:34:16 pm »
Quote from: "ravenheart"
sry quasius, ill tell u a bit more:

my vector dir can be (-1|-1) (1|-1) (-1|1) or (1|1)

i do not have to normalize the vector because only 45° appear

i think my problem is following:

let´s take the top of my window: the ball reaches a negative y-coord and then there is the order: bounce() which changes the y-value of dir , and now it seems that the ball does not reach a positive y-coord in the next frame and the ball bounces so long until it reaches a positive y-coord again

i hope my thoughts are not too far from truth, if u have a solution for this , pls tell me

thanks your raven


That sounds like it could be a problem.  If that's the case, you need to test something else before calling bounce.  (Use &&)

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #5 on: September 28, 2008, 06:44:33 pm »
is there any possibilty that a certain function cannot be called in 2 following frames, i think about a bool bounce

when the ball bounced its 1
if bounce == 1, the function cannot be called

and bounce = 0 again

does it sound like a good plan?

_____________________________________________________________

i hate collisions

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #6 on: September 28, 2008, 06:48:13 pm »
sry forgot to post my ball movement:


Code: [Select]
if( Ball.GetPosition().y <= 0 || Ball.GetPosition().y +10 >= WINDOW_HEIGHT)
        Ball.bounce_y();

if(Uhr.GetElapsedTime() > 5.0)
    {
        Ball.increase_speed();
        Uhr.Reset();
    }

Ball.Move(Ball.speed * Ball.dir * App.GetFrameTime());

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
bouncing
« Reply #7 on: September 28, 2008, 07:02:01 pm »
Quote from: "ravenheart"
is there any possibilty that a certain function cannot be called in 2 following frames, i think about a bool bounce

when the ball bounced its 1
if bounce == 1, the function cannot be called

and bounce = 0 again

does it sound like a good plan?

_____________________________________________________________

i hate collisions


Something like that would work, but before you start making new variables and making your code more complicated, look at what you already have.  Is there something in the data you already have (position, speed, dir, etc.) that would tell you if you've already bounced and shouldn't do it again?

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #8 on: September 28, 2008, 07:26:48 pm »
i think its easier when i let u see the code:


Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>
#include <iomanip>
#include <sstream>

using namespace sf;
using namespace std;

////////////////////////////////////////////////////////////
/// Entry point of application
////////////////////////////////////////////////////////////

 class ball: public Shape
{
    public:
    Vector2f dir;
    float speed;
    int width;
    int height;
    ball();
    void increase_speed();
    void bounce_y();
    void bounce_x();
};

ball::ball()
{
    AddPoint(0,0);
    AddPoint(10,0);
    AddPoint(10,10);
    AddPoint(0,10);
    width = height = 10;
    dir.x = dir.y = -1;
    speed = 50;
}

void ball::increase_speed()
{
    speed = speed +50;
}

void ball::bounce_y()
{
    dir.y = -dir.y;
}

void ball::bounce_x()
{
    dir.x = -dir.x;
}

class bat : public sf::Shape
{
    public:
    bat();
    bool exist;
    int width;
    int height;
};

bat::bat()
{
    AddPoint(0, 0,  sf::Color(255, 0, 0),     sf::Color(0, 128, 128));
    AddPoint(50, 0,   sf::Color(255, 85, 85),   sf::Color(0, 128, 128));
    AddPoint(50, 50,  sf::Color(255, 170, 170), sf::Color(0, 128, 128));
    AddPoint(0, 50,  sf::Color(255, 170, 170), sf::Color(0, 128, 128));
    SetColor(Color(255, 255, 255, 255));
    Scale(1, 3);
    SetPosition(0,0);

    width = 50;
    height = 150;
    exist = 1;
}



const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;



int main()
{

// Create main window
    RenderWindow App;
    App.Create(sf::VideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,32), "SFML Window", Style::Fullscreen);
// Cursor is not being shown
    ShowCursor(0);
// create bats
    bat left;
    bat right;
    right.SetPosition(WINDOW_WIDTH - right.width,0);
//  INput
    bool left_up ;
    bool left_down ;
    bool right_up ;
    bool right_down;
// Ball
    ball Ball;
    Ball.SetPosition((WINDOW_WIDTH - Ball.width)/2, (WINDOW_HEIGHT - Ball.height)/2);
// goals
    int goal1;
    int goal2;
    goal1 = goal2 = 0;
// Uhr
    Clock Uhr;
// im spiel
    bool gameover;
    bool goal;
    gameover = goal = 0;
// TExte
    String Text;
    Text.SetFont(sf::Font::GetDefaultFont());
    Text.SetSize(20);
    Text.SetPosition(350,0);

    std::ostringstream out;
    out << setprecision(2) <<fixed;
    std::string str;


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

        // keybord-events
        if ((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::Escape))
        {
            App.Close();
        }
        if ((Event.Type == Event.KeyPressed) && (Event.Key.Code == Key::F1))
        {
            right.SetPosition(WINDOW_WIDTH - right.width,0);
            left.SetPosition(0,0);
            Ball.SetPosition((WINDOW_WIDTH - Ball.width)/2, (WINDOW_HEIGHT - Ball.height)/2);
            Ball.speed = 50;
            goal = 0;
            goal1 = goal2 = 0;
            gameover = 0;
        }


    }

out  << goal1 << " : " << goal2;
str = out.str();
out.seekp(0);
Text.SetText(str);
App.Draw(Text);


// handle bat-movements
    const Input& Input = App.GetInput();
    left_up = Input.IsKeyDown(Key::W);
    left_down = Input.IsKeyDown(Key::S);
    right_up = Input.IsKeyDown(Key::Up);
    right_down = Input.IsKeyDown(Key::Down);


    if( right_down)
    {
        right.Move(0, 400* App.GetFrameTime());
    }
    if(right_up)
    {
        right.Move(0, - 400 * App.GetFrameTime());
    }
    if(left_down)
    {
        left.Move(0, 400* App.GetFrameTime());
    }
    if(left_up)
    {
        left.Move(0, -400* App.GetFrameTime());
    }

    if(Uhr.GetElapsedTime() > 5.0)
    {
        Ball.increase_speed();
        Uhr.Reset();
    }

//  tor
    if( Ball.GetPosition().x < 0 && gameover == 0)
    {
        goal2 = goal2 +1;
        goal = 1;
    }
    if( Ball.GetPosition().x > WINDOW_WIDTH  && gameover == 0)
    {
        goal1 = goal1+1;
        goal = 1;
    }

    if( goal1 >4 || goal2 >4)
        gameover =1 ;


    if(!gameover)
    {

    if(goal)
    {
        Ball.SetPosition((WINDOW_WIDTH - Ball.width)/2, (WINDOW_HEIGHT - Ball.height)/2);
        Ball.speed = 50;
        goal = 0;
    }



// check bounce
    if( Ball.GetPosition().y <= 0 || Ball.GetPosition().y +10 >= WINDOW_HEIGHT)
        Ball.bounce_y();

    if((Ball.GetPosition().x <= left.width) && Ball.GetPosition().y +10 >= left.GetPosition().y && Ball.GetPosition().y <= left.GetPosition().y + left.height)
        Ball.bounce_x();

    if((Ball.GetPosition().x +10 >= WINDOW_WIDTH - right.width) && Ball.GetPosition().y +10 >= right.GetPosition().y && Ball.GetPosition().y <= right.GetPosition().y + right.height)
        Ball.bounce_x();



    }

    out  << goal1 << " : " << goal2;
    str = out.str();
    out.seekp(0);
    Text.SetText(str);
    App.Draw(Text);

// move Ball
    Ball.Move(Ball.speed * Ball.dir * App.GetFrameTime());
// Draw
    App.Draw(left);
    App.Draw(right);
    App.Draw(Ball);

// Finally, display the rendered frame on screen
    App.Display();

}

    return 0;

}

Beaker

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • http://corvuscorone.net/
bouncing
« Reply #9 on: September 28, 2008, 09:07:17 pm »
Try checking to see if the ball will be off the screen coordinates on its next move, rather than once it has moved.

Code: [Select]
Vector2f checkPosition(Ball.speed * Ball.dir * App.GetFrameTime());
if( checkPosition.y <= 0 || checkPosition.y +10 >= WINDOW_HEIGHT)
    Ball.bounce_y();
Ball.Move(Ball.speed * Ball.dir * App.GetFrameTime());

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #10 on: September 28, 2008, 09:39:31 pm »
yes in my last version i did it like that, but i didnt know how to manage collision with x-ccords then

ravenheart

  • Full Member
  • ***
  • Posts: 148
    • View Profile
bouncing
« Reply #11 on: September 29, 2008, 08:10:50 pm »
my problem is:

when i test if the balls x-position would be smaller than 50 in the next movement , the loop will test it every frame, so i would need a second condition, something like

Code: [Select]

if ( Ball.GetPosition().x + speed*dir*App.GetFrameTime() <= 50 &&  Ball.GetPosition().x + speed*dir*App.GetFrameTime() >= 45 )
bounce_x();


so there is a 5 pixel big zone where it may bounce;

but i want that the ball does exactly what it is supposed to do

# has anyone done a similiar project and could post me the code?

Beaker

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • http://corvuscorone.net/
bouncing
« Reply #12 on: October 07, 2008, 05:38:16 am »
Hi dude, did you get this solved in the end? If not, I can check it out tomorrow.

 

anything