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

Author Topic: Fire Bullet At Angle  (Read 3486 times)

0 Members and 1 Guest are viewing this topic.

coltranenaima

  • Newbie
  • *
  • Posts: 11
    • View Profile
Fire Bullet At Angle
« on: April 22, 2018, 03:31:14 am »
Hello,

I am working on a game that so far has:
  • A square moving around with a basic velocity system (wasd)
  • The Square also rotates based on mouse position

I am now trying to implement bullets that will fire in the direction the square (player) is rotated, I made a very simple system with the last game I made (thanks again Hapax) that only went in one direction.

The bullets fire (yay), just not at the right angle (boo). I debugged and looked at the rotation each time and the numbers matched....it just doesn't come out correctly visually.

Thanks!

This is main.cpp (I chopped a major chunk of code to isolate what the issue may be)

#include "Player.h"
#include "Bullet.h"
#include <iostream>

int main()
{
        //declare
        float delta, deltaCd, bulletTime, bulletCd, bulletSpeed, bulletAngle;
        float& dCd = deltaCd;
        sf::Clock gameClock, bulletClock;
        Player playerOne;
        Player& pO = playerOne;
        Bullet playerBullet;
        Bullet& pB = playerBullet;
        std::vector<sf::RectangleShape> bulletVector;
        std::vector<float> bulletAngleVector;

        //initialize
        delta = .0f;
        deltaCd = .25f;
        bulletTime = 1.0f;
        bulletCd = 2.0f;
        bulletSpeed = 1.5f;
        bulletAngle = .0f;

        playerBullet.bulletShape.setPosition(sf::Vector2f(playerOne.playerShape.getPosition().x,
       
        //window loop
        //TODO: Create game loop
        while (win.isOpen())
        {
                window.clear();
                delta = gameClock.restart().asSeconds();
                playerOne.PlayerRotation(win, pO.playerShape);
                playerBullet.BulletAngle(win, pB.bulletShape);

                if (sf::Mouse::isButtonPressed(sf::Mouse::Left) && bulletTime > bulletCd)
                {
                        bulletTime = bulletClock.restart().asSeconds();
                        playerBullet.bulletShape.setPosition(sf::Vector2f(playerOne.playerShape.getPosition().x, playerOne.playerShape.getPosition().y));
                        bulletAngle = playerBullet.bulletShape.getRotation();
                        bulletVector.push_back(playerBullet.bulletShape);
                        bulletAngleVector.push_back(bulletAngle);
                }              

                for (unsigned int i = 0; i < bulletVector.size(); i++)
                {
                        bulletVector[i].move(cos(bulletAngleVector[i]), sin(bulletAngleVector[i]));
                        window.draw(bulletVector[i]);
                }
               
                bulletTime = bulletClock.getElapsedTime().asSeconds();

                window.draw(pO.playerShape);
                window.display();
        }
}


bullet.cpp

#include "Bullet.h"

Bullet::Bullet()
{
        bulletSizeX = 5.f;
        bulletSizeY = 5.f;
        bulletShape.setSize(sf::Vector2f(bulletSizeX, bulletSizeY));
        bulletShape.setOrigin(sf::Vector2f(bulletShape.getGlobalBounds().width / 2.f, bulletShape.getGlobalBounds().height / 2.f));
        bulletShape.setFillColor(sf::Color::Red);
}

void Bullet::BulletAngle(sf::RenderWindow& win, sf::RectangleShape& bS)
{
        dx = 0.f;
        dy = 0.f;
        mouse = sf::Mouse::getPosition(win);
        mouseWorld = win.mapPixelToCoords(mouse);
        dx = mouseWorld.x - bS.getPosition().x;
        dy = mouseWorld.y - bS.getPosition().y;
        rotation = atan2(dy, dx) * 180 / PI;
        bS.setRotation(rotation);
}

bullet.h

#pragma once
#include <SFML/Graphics.hpp>

class Bullet
{
public:
        float bulletSizeX, bulletSizeY, dx, dy, rotation;
        const float PI = 3.14159265f;
        sf::Vector2i mouse;
        sf::Vector2f mouseWorld;
        sf::RectangleShape bulletShape;
        void BulletAngle(sf::RenderWindow& win, sf::RectangleShape& bS);
        Bullet();
};
« Last Edit: April 22, 2018, 09:31:18 pm by coltranenaima »

coltranenaima

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Fire Bullet At Angle
« Reply #1 on: April 22, 2018, 09:26:55 pm »
I recorded what is currently happening, see gif link below.

Thanks for reading and I appreciate any suggestions!

https://gfycat.com/LimpFrankBumblebee

Geheim

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Email
Re: Fire Bullet At Angle
« Reply #2 on: April 22, 2018, 11:29:28 pm »
rotation = atan2(dy, dx) * 180 / PI;
should just be:
rotation = atan2(dy, dx);
atan2 already gives you radians.  ;)
Failing to succeed does not mean failing to progress!

coltranenaima

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Fire Bullet At Angle
« Reply #3 on: April 23, 2018, 12:01:02 am »
rotation = atan2(dy, dx) * 180 / PI;
should just be:
rotation = atan2(dy, dx);
atan2 already gives you radians.  ;)

Thanks for your feedback! I tried your suggestion with the remaining code as is, unfortunately I am getting the same result. If that is the case where I do not need to convert from radians, maybe this piece of code is suspect?

                for (unsigned int i = 0; i < bulletVector.size(); i++)
                {
                        bulletVector[i].move(cos(bulletAngleVector[i]), sin(bulletAngleVector[i]));
                        window.draw(bulletVector[i]);
                }

I will be honest...I have not taken real trig classes....just simple review course on khan academy, soh cah toa! The movement is what I am leaning towards being the issue (with your suggestion in place).

coltranenaima

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Fire Bullet At Angle
« Reply #4 on: April 23, 2018, 02:04:00 am »
I was able to get it to work, thanks Geheim. You mentioning radians helped fix the first issue and it helped me with tracking down the other issue by reading this thread:

https://en.sfml-dev.org/forums/index.php?topic=4951.0

from Nexus:

Quote
Note that the functions std::sin() and std::cos() take radians, not degrees.

cos and sin take radians, I was feeding it a rotation degree.

Thanks!!!!

Geheim

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Email
Re: Fire Bullet At Angle
« Reply #5 on: April 23, 2018, 01:35:49 pm »
Just for your info: you can calculate pi with
const double pi = atan(1) * 4;
Failing to succeed does not mean failing to progress!