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

Author Topic: What's wrong with my code? Angles won't work  (Read 1300 times)

0 Members and 1 Guest are viewing this topic.

Ashmor

  • Newbie
  • *
  • Posts: 6
    • View Profile
What's wrong with my code? Angles won't work
« on: July 30, 2019, 09:05:12 am »
Hey guys, I'm new to programming and SFML. I'm trying to make something like a canon. It's gonna fire balls that will be flying in an arc. Sounds like a very simple task to accomplish, yet I cannot seem to figure out how angles work in SFML. For example, with ang_const = 0.13 Rad (7.44 Deg), my balls flies in a beautiful arc. However, when I change the value of ang_const to 0.14 Rad (8.021 Deg), the ball flies in the opposite direction! If I change the angle to 0.19 Rad (10.88 Deg), it flies downwards for whatever reason.

So here's my code:
#include <SFML/Graphics.hpp>
#include <math.h>
int WIDTH = 1024, HEIGHT = 704;

class Ball {
private:
    float radius = 16.00;
public:
    sf::CircleShape shape;
    Ball () {
        shape.setPosition(0 + radius*2, HEIGHT - radius*2);
        shape.setRadius(radius);
        shape.setFillColor(sf::Color::Cyan);
        shape.setOrigin(radius, radius);
    }
    void update() {
        if (x() - radius > WIDTH) {
            this->shape.setPosition(0 - radius, y());
        }
        if (x() + radius < 0) {
            this->shape.setPosition(WIDTH + radius, y());
        }
        if (y() - radius > HEIGHT) {
            this->shape.setPosition(x(), 0 - radius);
        }
        if (y() + radius < 0) {
            this->shape.setPosition(x(), HEIGHT + radius);
        }
    }
    float RadToDeg (float radian) {
        double pi = 3.14159;
        return radian * (180 / pi);
    }
    float x() { return shape.getPosition().x; }
    float y() { return shape.getPosition().y; }
    float getRadius() { return radius; }
};

int main()
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "del");
   
    // Some variables
    float ang_const = 0.13;                  
    float velX_const = 3.5, velY_const = 3.5;
    float grav_const = -0.02;                
   
    float ang = ang_const;
    float velX = velX_const, velY = velY_const;
    float grav = grav_const;
   
    // Text
    int size_for_text = 64;
    sf::Font f;
    f.loadFromFile("Keyboard.ttf");
    sf::Text text1;
    text1.setFont(f);
    text1.setCharacterSize(27);
    text1.setFillColor(sf::Color::White);
    text1.setPosition(size_for_text, size_for_text);
   
    // Ball
    Ball ball;
   
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window: exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }
           
            // Escape pressed: exit
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
                window.close();
            }
           
            // Restart
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space) {
                ang = ang_const;
                velX = velX_const, velY = velY_const;
                grav = grav_const;
                ball.shape.setPosition(0 + ball.getRadius()*2, HEIGHT - ball.getRadius()*2);
            }
        }
       
        // Ball movement
        ball.update();
       
        velY += grav;
        ball.shape.move(velX * cos(ball.RadToDeg(ang)),
                        velY * -sin(ball.RadToDeg(ang)));
       
        // Clear screen
        window.clear(sf::Color(0,0,80,100));
       
        // Draw ball
        window.draw(ball.shape);
       
        // Draw text
        text1.setString("ang " + std::to_string(ang));
        window.draw(text1);
       
        // Update the window
        window.display();
    }
   
    return EXIT_SUCCESS;
}
 

The main lines are these:
Variables:
float ang_const = 0.13;                
float velX_const = 3.5, velY_const = 3.5;
float grav_const = -0.02;              
 

Ball movement:
velY += grav;
ball.shape.move(velX * cos(ball.RadToDeg(ang)), velY * -sin(ball.RadToDeg(ang)));
 

Radians to Degrees function:
float RadToDeg (float radian) {
        double pi = 3.14159;
        return radian * (180 / pi);
}
 

Could someone explain what's wrong with my code and how angles work in SFML? I'd be appreciated for your help guys.
« Last Edit: July 30, 2019, 09:20:43 am by Ashmor »

Ashmor

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: What's wrong with my code? Angles won't work
« Reply #1 on: July 30, 2019, 09:55:01 am »
I found my mistake guys. cos() and sin() take argument in radians, not degrees. Problem solved.

Ashmor

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: What's wrong with my code? Angles won't work
« Reply #2 on: July 30, 2019, 05:24:52 pm »
I improved my code, using some suvat formulas. It seems to be working just fine. Here's the code just in case someone's interested in it.

#include <SFML/Graphics.hpp>
#include <math.h>
int WIDTH = 1024, HEIGHT = 704;

class Ball {
private:
    float radius = 16.00;
public:
    bool isGameStarted = false;
    sf::CircleShape shape;
    Ball () {
        shape.setPosition(0 + radius*2, HEIGHT - radius*2);
        shape.setRadius(radius);
        shape.setFillColor(sf::Color::Cyan);
        shape.setOrigin(radius, radius);
    }
    void update() {
        if (x() - radius > WIDTH) {
            this->shape.setPosition(0 - radius, y());
        }
        if (x() + radius < 0) {
            this->shape.setPosition(WIDTH + radius, y());
        }
        if (y() - radius > HEIGHT) {
            this->shape.setPosition(x(), 0 - radius);
        }
        if (y() + radius < 0) {
            this->shape.setPosition(x(), HEIGHT + radius);
        }
    }
    float RadToDeg (float radian) {
        double pi = 3.14159;
        return radian * (180 / pi);     // deg = rad * (180 / pi)
    }
    float DegToRad (float degree) {
        double pi = 3.14159;
        return degree * pi / 180;       // rad = deg * pi / 180
    }
   
    float x() { return shape.getPosition().x; }
    float y() { return shape.getPosition().y; }
    float getRadius() { return radius; }
};

int main()
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "del");
   
    // Ball
    Ball ball;
   
    // Some variables
    float angel_var = 70;
    float gravity_var = 9.8;
    float velocity_var = 5.0;
    float time_var = 0;
   
    float angel = angel_var;
    float gravity = gravity_var;
    float velocity = velocity_var;
    float t = time_var;
   
    float vx = velocity * cos(ball.DegToRad(angel));
    float vy = velocity * -sin(ball.DegToRad(angel));
   
    // Text
    int size_for_text = 64;
    sf::Font f;
    f.loadFromFile("Keyboard.ttf");
    sf::Text text1;
    text1.setFont(f);
    text1.setCharacterSize(27);
    text1.setFillColor(sf::Color::White);
    text1.setPosition(size_for_text, size_for_text);
   
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window: exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }
           
            // Escape pressed: exit
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
                window.close();
            }
           
            // Angle
            if (event.type == sf::Event::KeyPressed &&
                event.key.code == sf::Keyboard::Up) {
                angel_var += 5;
            }
            if (event.type == sf::Event::KeyPressed &&
                event.key.code == sf::Keyboard::Down) {
                angel_var -= 5;
            }
           
            // Start movement
            if (event.type == sf::Event::KeyPressed &&
                event.key.code == sf::Keyboard::Space) {
                if (ball.isGameStarted) {
                    ball.isGameStarted = false;
                }
                else {
                    ball.isGameStarted = true;
                }
            }
        }
       
        // Ball movement
        if (ball.y() - ball.getRadius() > HEIGHT ||
            ball.x() - ball.getRadius() > WIDTH) {
            ball.isGameStarted = false;
        }
       
        if (ball.isGameStarted) {
            t += 0.002;
            ball.shape.move(vx * t, vy * t + (gravity/2)*t*t);
        }
        else {
            angel = angel_var;
            gravity = gravity_var;
            velocity = velocity_var;
            vx = velocity * cos(ball.DegToRad(angel));
            vy = velocity * -sin(ball.DegToRad(angel));
            t = time_var;
            ball.shape.setPosition(0 + ball.getRadius()*2, HEIGHT - ball.getRadius()*2);
        }
       
        // Clear screen
        window.clear(sf::Color(0,0,80,100));
       
        // Draw ball
        window.draw(ball.shape);
       
        // Draw text
        text1.setString("ang " + std::to_string((int)angel_var));
        window.draw(text1);
       
        // Update the window
        window.display();
    }
   
    return EXIT_SUCCESS;
}