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

Author Topic: C++ SFML, Circular Movement - Help!  (Read 45034 times)

0 Members and 1 Guest are viewing this topic.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #15 on: September 19, 2013, 06:12:42 pm »
but .... I ask again, Jycerian, shouldn t there be goal lines?

There is no "goal lines" in pong. The way you score points is when the ball gets past the opponent's paddle and there is no way to return the ball. So with a circular pong the score would happen when the ball gets outside the arc that the paddle can move in.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11043
    • View Profile
    • development blog
    • Email
AW: C++ SFML, Circular Movement - Help!
« Reply #16 on: September 19, 2013, 07:27:58 pm »
Which will be rather interesting yo program the AI for, because it should be possible to play the ball towards yourself again, thus you can really make it the way a normal Pong AI works. :D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #17 on: September 19, 2013, 07:56:52 pm »
but .... I ask again, Jycerian, shouldn t there be goal lines?

Oh my idea was to create a BOOL that changes depending on what paddle last touched the ball. like:

Player1     = true;
Computer = false;

And then do like a collision/score if statement so that when the bool is true, player1 can only score points in the enemy's field and if it's true it has no effect if he hits his own field first .. then it would just bounce instead of adding points to the bot. vica versa for the computer paddle.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #18 on: September 19, 2013, 07:59:04 pm »
Oh my idea was to create a BOOL that changes depending on what paddle last touched the ball. like:

Player1     = true;
Computer = false;

And then do like a collision/score if statement so that when the bool is true, player1 can only score points in the enemy's field and if it's true it has no effect if he hits his own field first .. then it would just bounce instead of adding points to the bot. vica versa for the computer paddle.

That would be the idea, but instead of a bool why don't you get more expressive and use an enum?
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #19 on: September 19, 2013, 10:10:18 pm »
private bool DetectCircunpherenceCollision(int ballX, int ballY)
{
    int posY, posX;
    posX = ballX - 320;
   
    if (posX > radius) posX = radius;           
    else if (posX < -radius) posX = -radius;
   
    posY = Math.Sqrt( radius * radius - posX * posX );    // now the arg >= 0

    if (ballY <= 240 - posY || bally >= 240 + posY) return true;
    return false;
}

Thanks!, But this also gets me stuck in the walls haha. pff so hard, this is like my second game ever haha did not expect it to be this hard :D but yeah I am learning so that is good.

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #20 on: September 20, 2013, 03:44:30 am »
Hello,
yeah, now i understand why the ball gets stuck ... (the collision test traps it, changing its angle indefinitely)
well, please try this, we ll make a little change
(i m assuming that now the ball, though it gets stuck, at least it does on the circle border line)

private bool DetectCircunpherenceCollision(ref int ballX, ref int ballY)
{
    int posX, posY;
    posX = ballX - 320;    // here 320 is screenWidth/2, or Xcenter

    if (posX > radius) posX = radius;
    else if (posX < -radius) posX = -radius;

    ballX = posX + 320;   // this fixes if the ball overpassed the X limit   
                                    // perhaps in C++ you d have to write *ballX = ... (indirection)
    posY = Math.Sqrt( radius * radius - posX * posX );

    // here 240 is screenHeight/2 or yCenter
    // the assignments prevents the ball to overpass the Y limit at the collision point
    if (ballY <= 240 - posY) { ballY = 240 - posY; return true; }
    else if (bally >= 240 + posY) { ballY = 240 + posY; return true; }
   
    return false;
}

now the function prevents the ball overpasses the border line, then i supose it shouldn t get stuck any more
Note you must pass to the function the X and Y values of the ball BY REFERENCE (or the address), in order it can change their values in the very probable case that they overpass the circle line (it occurs because the pixels you add to the ball trajectory may not match just on the circle line, but a little before or after)

then, your main loop could include:

.........
// here increase the ball x, y ... that is, it moves
for example:
ballX += cos (ballAngle) * 5.0;
ballY += sin (ballAngle) * 5.0;    suposing it runs 5 px per frame

if (DetectCircunpherenceCollision(ref ballX, ref ballY) == true)     // don t know if in C++ you use & not ref
{                                                                                             // and *var = ... to access the value
    ballAngle = AngleCirc();      // the new ball angle when it bounces on the circle line
}                                           // i wrote this function before, i don t remember how i called it
........

Let me know if it works now

And, i tried to run this program, and i couldn t, appears a letter that says the file MSVCP110.DLL is not in my system ... i downloaded the DLL file, copied it to C:\Windows\System32, reboot my PC, and it still says the DLL is not in my system, so i cant run the Pong.exe ...

Can someone help me with this?



Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #21 on: September 20, 2013, 01:36:05 pm »
Hey guys, I am now making a couple of small programs to help me understand things better. Like one program rotates balls (like the paddle) the other program detects collision between 2 circles etc. But now I want to make a Collision/Angle program to help me understand the bouncing of walls etc. (in my original program I tried some stuff from the pong example without completely understanding it)

So how would I go about calculating the ball angle with the following picture.

« Last Edit: September 20, 2013, 06:25:10 pm by Jycerian »

danijmn

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #22 on: September 20, 2013, 02:11:30 pm »
I saw this post and I immediately recalled one of my academic projects not so long ago in which I had to develop a pinball game in Java for Android.
Circular physics are a pain in the a**.

Fortunately, I managed to find a fantastic reference which explained how to handle collisions betweens different types of objects (but I still had to figure out how to make the flippers work ;D). It includes an explanation of the physics in collisions of balls within circular containers, which is precisely what you want. A fully working example is also provided as well as the source code (in Java, though).

Here is the link (scroll down to example 6a):
http://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #23 on: September 20, 2013, 05:34:43 pm »
I saw this post and I immediately recalled one of my academic projects not so long ago in which I had to develop a pinball game in Java for Android.
Circular physics are a pain in the a**.

Fortunately, I managed to find a fantastic reference which explained how to handle collisions betweens different types of objects (but I still had to figure out how to make the flippers work ;D). It includes an explanation of the physics in collisions of balls within circular containers, which is precisely what you want. A fully working example is also provided as well as the source code (in Java, though).

Here is the link (scroll down to example 6a):
http://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

Thanks!, looks cool but there is so much code haha and I don't know any java either pff.

If anyone is bored I created this simple program that I just wanna use to get the collision and ball bounce correct. but that is the problem :p a lot of you people gave me tips and code snippets but I do not really know how to implement those so that is why I post this simple program now so instead of giving random snippets maby tell me what I need to change / add to this code:



#include <SFML/Graphics.hpp>
#include <iostream>

const int SCREEN_WIDTH  = 640;
const int SCREEN_HEIGHT = 480;

int main()
{
    sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "SFML works!", sf::Style::Close);

        // Big circle
        float bigCircleRadius  = 200.f;
        float bigCircleCorners = 32.f;
        sf::CircleShape bigCircle    (bigCircleRadius, bigCircleCorners);
        bigCircle.setOrigin          (bigCircle.getLocalBounds().width / 2, bigCircle.getLocalBounds().height / 2);
        bigCircle.setPosition        (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
        bigCircle.setOutlineThickness(2);
        bigCircle.setOutlineColor    (sf::Color::White);
        bigCircle.setFillColor       (sf::Color::Transparent);

        // Small circle
        float smallCircleAngle   = 0.f;
        float smallCircleRadius  = 20.f;
        float smallCircleCorners = 16.f;
        sf::CircleShape smallCircle    (smallCircleRadius, smallCircleCorners);
        smallCircle.setOrigin          (smallCircle.getLocalBounds().width / 2, smallCircle.getLocalBounds().height / 2);
        smallCircle.setPosition        (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
        smallCircle.setOutlineThickness(2);
        smallCircle.setOutlineColor    (sf::Color::White);
        smallCircle.setFillColor       (sf::Color::Transparent);

        // Line representing smallCircle angle
        float lineAngle = 0.f;
        sf::RectangleShape line(sf::Vector2f(80, 1));
        line.setPosition(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
       
        // Testing variables
        float moveSpeed = 100.f;

        sf::Clock clock;
    while (window.isOpen())
    {
                float deltaTime = clock.restart().asSeconds();

        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

                // Set lineAngle to smallCircleAngle
                lineAngle = smallCircleAngle;

                // Set line position to smallCircle position
                line.setPosition(smallCircle.getPosition().x, smallCircle.getPosition().y);

                // Move the smallCircle
                smallCircle.move(moveSpeed * deltaTime, 0.f);

                // Collision
                if (sqrt(pow(smallCircle.getPosition().x - bigCircle.getPosition().x, 2) +
                             pow(smallCircle.getPosition().y - bigCircle.getPosition().y, 2)) >
                                 bigCircle.getRadius() - smallCircle.getRadius())
                {
                        moveSpeed = -moveSpeed;
                        smallCircle.rotate(180);
                        line.rotate(180);
                        std::cout << "Collision!\n";
                }

        window.clear(sf::Color::Black);
                window.draw(bigCircle);
                window.draw(smallCircle);
                window.draw(line);
        window.display();
    }

    return 0;
}

The rotation of smallCircle and line is just a placeholder to test, at the moment smallCircleAngle is not used yet.

And thank guys for all the help so far. I am learning a lot!
« Last Edit: September 20, 2013, 05:42:55 pm by Jycerian »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #24 on: September 20, 2013, 08:50:18 pm »
Quote
The rotation of smallCircle and line is just a placeholder to test, at the moment smallCircleAngle is not used yet.

Unfortunately I think that's where all the interesting parts of the collision algorithm would be, so I'm not sure I can really suggest what to add or improve to this tech demo other than the obvious: fill those parts in.

Though I guess I can point out that doing so will involve making your speed variable 2D instead of 1D, and when a collision occurs instead of simply speed = -speed you'd have to take into account the angle of impact and figure out what direction it should bounce away toward.  There's probably more steps but maybe that'll help.

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #25 on: September 20, 2013, 08:58:20 pm »
Hello, Jycerian, zsbzsb, and all Ladies and Guys from SFML

let s see, first i ll try to draw the main loop and then to detail the heavy functions, that i already wrote before
if needed, please someone translate from my code to C++, thank you (i don t know why don t you all use C# ... it s easier and more legible)
i saw you were asking in the last reply for the ball s angle when it hits the border line, here it is all

while (true)
{
    PlayerInput();     // however it is, events, etc
   
    ComputerPaddleControl()    // has it been thought or programmed?
 
    DrawGraphics();    // however it is

    BallMove();          // i ll give an idea, but perhaps it s already done

    if (DetectCircunpherenceCollision( ref ballX, ref ballY ) == true)
    {
        ballAngle = AngleCircle();
    }
    else if (DetectPaddleCollision( ballX, ballY ) == true)
    {
        ballAngle = AnglePaddle()
    }

    // it would be missing the score issue, i m sorry but i insist with the goal lines, cos the ball will never be 
    // impeded to return, as you said, zsbzsb, it will bounce once and again on different points on the circle
    // lines, even if it never hits the paddles, it can t escape from the circle

    // anyway, Jycerian, you could try first if the schema and functions i wrote make the program works fine,
    // weather there are or not goal lines
}

// returns true if the ball bounces on the circunpherence
private bool DetectCircunpherenceCollision( ref int ballX, ref int ballY )
{
// already written and optimized, see last version
}

// returns true if the ball bounces on the paddle
// convert paddleAngle to radians before passing it to the Sin or Cos
private bool DetectPaddleCollision( int ballX, int ballY )
{
    int a, SideX;
   
    Paddle.Radius = paddleTexture.Width / 2;   // however it is   
    Paddle.Height = paddleTexture.Height;       // however it is

    SideX = Math.Cos (paddleAngle) * Paddle.Radius;
    for (a = Paddle.Origin.X - SideX; a<= Paddle.Origin.X + SideX; a++)
    {
        if (Distance( Ball.Origin.X, Ball.Origin.Y, a, Math.Sin(paddleAngle) * a / Math.Cos(paddleAngle) )
            < ball.Radius + Math.Cos(paddleAngle) * Paddle.Height / 2)
            return true;
    }
    return false;
}

// returns the ball s angle (in degrees) when it bounces on the circle line
private int AngleCircle()
{
    int angle, tangentAngle;
   
    // the circunpherence s tangent line at the collision point behaves as a paddle, then we get its angle and
    // then we get the new ball s angle; we add PI/2 (90 degrees) cos the tangent is normal to the radius 
    tangentAngle = (Math.Asin( (ballY - 240) / radius ) + PI / 2) * 180 / PI;   // converted to degrees

    angle = 180 - 2 * tangentAngle - ballAngle;   // here we use the same formula than when the ball
                                                                      // bounces with the paddle
    return angle;
}

// returns the ball s angle (in degrees) when it bounces on the paddle
private int AnglePaddle()
{
    int angle;
    angle = 180 - 2 * paddleAngle - ballAngle;
    return angle;
}

// makes the ball move - i don t know if already implemented
private void BallMove()
{
    Ball.Position.X += Math.Cos(ballAngle) * 5.0;   
    Ball.Position.Y -= Math.Sin(ballAngle) * 5.0;
}

I will repeat, i couldn t run this program Jycerian that sent the link, because of the MSVCP110.DLL file ... now, could any member tell me how to fix that, so i can see the game?
i don t know about DLL s nor OS s very much ... just programming
thank you

please let us know if now, the Pong works fine now
and be carefull with the variable names, if you have any doubt tell me

Pablo

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #26 on: September 20, 2013, 09:10:12 pm »
That's a Microsoft-specific Visual Studio-related DLL.  Offhand I have no idea what visual studio settings make it a dependency, but I personally haven't had problems with my programs needing it on other people's computers (and I can run his program just fine).  Since you forgot to mention what your OS is we don't know if Jycerian introduced a strange dependency somehow or if you're simply not running Windows (in which case of course it wouldn't work).

Still, you should be able to copy and paste his code and compile it yourself.  That worked for me with his collision test just now.

@Jycerian: It's not hugely relevant to the current collision discussion, but I noticed with your original pong program that dragging the window around for several seconds causes the ball to escape the playing field and never come back (I assume it's oscillating indefinitely since it's always outside the circle).  Something to tackle once you've gotten basic bouncing that looks right.

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #27 on: September 20, 2013, 10:02:07 pm »
Thank you, MiLord!
I m using Windows 7 Ultimate 32 bit ... and i have installed Visual C# 2008 Express Edition, NOT C++
i downloaded the DLL file, tried copying it to the game s folder, to C:\Windows\System32, also i ran regsvr32 at the command shell, and it says it couldn t load the MSVCP110.DLL file ...
when i tried to run the Pong, a messagebox said the DLL wasn t installed on my system, ... but it really is!

about Jycerian s pong game, i really hope that now it will work, with the circular collision and so ... actually, i am looking for solving this DLL problem, and then waiting for the binaries to see this sophisticated game

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Re: C++ SFML, Circular Movement - Help!
« Reply #28 on: September 21, 2013, 01:12:16 am »
@Jycerian: It's not hugely relevant to the current collision discussion, but I noticed with your original pong program that dragging the window around for several seconds causes the ball to escape the playing field and never come back (I assume it's oscillating indefinitely since it's always outside the circle).  Something to tackle once you've gotten basic bouncing that looks right.

Thank you, I noticed this also I will take small steps forward so this would probably be the last issue to fix :)
 
My current goals are: Paddle Rotation (I know how to do this now) Ball Collision and Bounce (Working on this now) Enemy AI (Not yet done) Score (Not yet done) Menu (Not yet done) Fixing bugs (Not yet done)

about Jycerian s pong game, i really hope that now it will work, with the circular collision and so

I hope so too, tomorrow I will continue to play around with the collision and ball bounce. BTW: I use windows 7 64x and use visual studio 2012. with C++ and SFML 2.1

please let us know if now, the Pong works fine now
and be carefull with the variable names, if you have any doubt tell me

Pablo

I will look into your post tomorrow and play around with it, I did some C# myself with XNA but now I am learning C++ and SFML, because I want to get into the Game Industrie and C++ is standard there. But I agree that C# is easier for sure.

Again, thank you all guys for helping and I am sure this topic will be helpful to others too :D I never realized that a round game would be so much trouble haha but yeah it's my first C++ SFML game so after I get all this finished I am sure I could create more games with ease.

Also I google'd your DLL problem and found some useful stuff:

Quote
You will need to install the correct Redistributable Package from Microsoft. Please note that you cannot just take any of those, you need to pick the one that goes with your very specific version of Visual Studio. The link for example is for VS 2012 SP1. If you have another version, you need another vcredist package.

Quote
Answer of user nvoigt seems to be correct (+1 for that). As an alternative to install Redist Package you can deploy "manually" MSVCP110.dll with your application. Easiest way is to put the dll where your exe is. But as the other people say: you need the correct version of redist pack which fits your system configuration.
« Last Edit: September 21, 2013, 01:40:08 am by Jycerian »

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: C++ SFML, Circular Movement - Help!
« Reply #29 on: September 21, 2013, 03:01:21 am »
I forgot to write the Distance function, i don t know why i have realized right now

// returns the distance between points P(x1, y1) and Q(x2, y2)
private int Distance(int x1, int y1, int x2, int y2)
{
    return Math.Sqrt( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) );
}

this function is used by the one that tests the ball s bounce on the paddle

Now i ll check out about the problem with the microsoft package and the dll

if you are using VS 2012, then it s .NET 4.0 or 4.5, do i have to update that? and i guess the dll is not the same from one to another?