I'm trying to implement SAT collision detection in a game i'm making with SFML but I noticed that the vertices positions from the vertex array I used to make the player are not changing position even though the transform I applied to it works properly.
this is the Player class:
Player.h
#include <SFML/Graphics.hpp>
#ifndef PLAYER_H
#define PLAYER_H
class Player : public sf::Drawable, public sf::Transformable
{
private:
sf::VertexArray square;
sf::Vector2f velocity;
float speed = 10.f;
sf::Vector2f position;
sf::Transform m_transform;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
public:
Player() = default;
Player(int screen_width, int screen_height);
void create(int screen_width, int screen_height);
void move(bool w, bool a, bool s, bool d);
void setVertexColor(sf::Color color, int vertex);
int getVertexCount();
sf::Vector2f getVertexPos(int n);
};
#endif
Player.cpp
#include <SFML/Graphics.hpp>
#include "Player.h"
#include <cmath>
#include<iostream>
Player::Player( int screen_width, int screen_height)
{
create(screen_width, screen_height);
}
void Player::create( int screen_width, int screen_height)
{
float size = 60.f;
square.setPrimitiveType(sf::Triangles);
square.resize(6);
square[0].position = sf::Vector2f(0.f, 0.f); //top left
square[1].position = sf::Vector2f(0.f, size); //bottom left
square[2].position = sf::Vector2f(size, 0.f); //top right
square[3].position = sf::Vector2f(0.f, size); //bottom left
square[4].position = sf::Vector2f(size, 0.f); //top right
square[5].position = sf::Vector2f(size, size); // bottom left
square[0].color = sf::Color(200,200,200);
square[1].color = sf::Color::White;
square[2].color = sf::Color(100,100,100);
square[3].color = sf::Color::White;
square[4].color = sf::Color(100,100,100);
square[5].color = sf::Color(200,200,200);
m_transform = getTransform();
}
void Player::move(bool w, bool a, bool s, bool d)
{
float mod_velocity;
sf::Vector2f t;
sf::Vector2f pos;
velocity = sf::Vector2f(0.f, 0.f);
if (w)
{
velocity.y -= 1;
}
if (a)
{
velocity.x -= 1;
}
if (s)
{
velocity.y += 1;
}
if (d)
{
velocity.x += 1;
}
if ((velocity.x != 0.f) || (velocity.y != 0.f))
{
mod_velocity = sqrt((velocity.x * velocity.x) + (velocity.y * velocity.y));
t = velocity/mod_velocity;
velocity = t * speed;
}
m_transform.translate(velocity);
for (int i = 0; i < 6; i++)
{
std::cout << "square[" << i << "].position: " << square[i].position.x <<" " <<square[i].position.y <<std::endl;
}
}
void Player::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= m_transform;
// draw the vertex array
target.draw(square, states);
}
int Player::getVertexCount()
{
return square.getVertexCount();
}
sf::Vector2f Player::getVertexPos(int n)
{
sf::Vertex vertex = square[n];
return getTransform().transformPoint( vertex.position );
}
void Player::setVertexColor(sf::Color color, int vertex)
{
square[vertex].color = color;
}
Inside the class there is a cout that shows the positions of the vertices and they remain constant even when I move the player (and it moves on the screen). how do I get the actual position of the vertices?
In the Player::create
method you assign a copy of sf::Transformable
to class member m_transformable
. And then you modify this copy instead of changing the original object. However, Player::getVertexPos
returns original transformation, not modified.
To solve this problem you can either change return statement in the method to
return m_transformable.transformPoint(vertex.position);
... or apply transformations to original sf::Transformable
base of your class (otherwise you don't need this base class at all).