SFML community forums

Help => General => Topic started by: LTahboub on July 17, 2020, 11:10:10 am

Title: Moving an X, Y Point Forward Relative to a certain Rotation
Post by: LTahboub on July 17, 2020, 11:10:10 am
Hello everybody,

I'm making a 2D Top-Down-Shooter game, and I currently have a player who can move around the screen, face the mouse, and almost properly shoot bullets. The problem I'm having is when setting the current bullet's position, it starts at the player's shoulder and not the muzzle of the gun. I know I should probably be adding a value to the initial position of the bullet which depends on the player's rotation and location, but I'm having trouble figuring this value out. If you didn't understand my description, here's a clip of the current game running: https://streamable.com/wzr3qd.

This is what my main.cpp file (where I'm handling shooting) looks like:

#include <SFML/Graphics.hpp>
#include <vector>
#include <random>
#include <utility>
#include <cmath>
#include <iostream>
#include "Player.h"
#include "Enemy.h"
#include "Bullet.h"

int screenX = 1200, screenY = 1200;

sf::RenderWindow window(sf::VideoMode(screenX, screenY), "");
sf::Event event;


int main() {
    Player player;
    Bullet b1;
    std::vector<Bullet> bullets;
    sf::Vector2f bulletStart, mousePosition, aimDir, aimDirNorm;
    while (window.isOpen()) {
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
            }
        // Bullet vector math
        bulletStart = sf::Vector2f(player.x, player.y);
        mousePosition = sf::Vector2f(sf::Mouse::getPosition(window));
        aimDir = sf::Vector2f(mousePosition - bulletStart);
        aimDirNorm = sf::Vector2f(aimDir.x / sqrt(pow(aimDir.x, 2) + pow(aimDir.y, 2)), aimDir.y / sqrt(pow(aimDir.x, 2) + pow(aimDir.y, 2)));

        // Shoot
        if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
            b1.shape.setPosition(bulletStart);
            b1.shape.setRotation(player.angle);
            b1.currVelocity = aimDirNorm * b1.maxSpeed;
            bullets.emplace_back(Bullet(b1));
        }
        for (auto &bullet : bullets) {
            bullet.shape.move(bullet.currVelocity);
        }
        // Draw
        window.clear();
        player.update(window);
        player.show(window);
        for (Bullet &bullet : bullets)
            window.draw(bullet.shape);
        window.display();
    }
    return 0;
}
 

Any help would be highly appreciated!
Title: Re: Moving an X, Y Point Forward Relative to a certain Rotation
Post by: Laurent on July 17, 2020, 02:34:18 pm
Take the player sprite's global transform (Sprite::getTransform()), and use it to convert your offset from local to global coordinates. That's the starting coordinates for your bullet. No math for you, and it works regardless of how the player is transformed (translated, rotated, scaled, ...).
Title: Re: Moving an X, Y Point Forward Relative to a certain Rotation
Post by: LTahboub on July 17, 2020, 05:32:24 pm
That sounds great! I'm currently trying to implement this, but I'm having some trouble finding the right functions and what not. Could you possibly give me a more detailed example.

Though I'm sure it's completely wrong, here's the line of code I currently have for setting the initial position:
bulletStart = sf::Vector2f(player.sprite.getTransform().transformPoint(player.x, player.y));
 
Title: Re: Moving an X, Y Point Forward Relative to a certain Rotation
Post by: Laurent on July 18, 2020, 09:02:02 am
Almost OK. You call the right functions, but with the wrong initial coordinates: you transform the player position, which has nothing to do with your bullets.

The initial coordinates should be the starting point of bullets relatively to the player's texture, ie. a fixed offset (for example, sf::Vector2f(5, 12)).
Title: Re: Moving an X, Y Point Forward Relative to a certain Rotation
Post by: LTahboub on July 18, 2020, 10:14:13 am
That worked! Thanks a lot, this really helped since I've been struggling with this for about 3 days. Thanks again!