Bon après plusieurs ajustements j'ai réussi à bien positionner les tiles :
IntRect subRect = parent->getSubRectImage();
Vec2f position (rectBrush.getPosition().x - subRect.width * 0.5f, rectBrush.getPosition().y - subRect.height * 0.5f);
En retirant la moitié de la taille du subrect à la position du coin supérieur gauche de la tile avant de faire la transformation.
Tile::Tile (sf::Texture &image, Vec2f position, Vec2f size, IntRect subRect, bool bToAnim) : TexturedDynamicDrawableEntity (position, Vec2f (subRect.width, subRect.height), Vec2f (size.x * 0.5f, size.y * 0.5f), 0, E_TILE) {
sprite.setTexture(image);
sprite.setTextureRect(subRect);
float factorX = size.x / (float) subRect.width;
float factorY = size.y / (float) subRect.height;
setScale(Vec2f(factorX, factorY));
this->bToAnim = bToAnim;
}
#ifndef DYNAMIC_DRAWABLE_ENTITY
#define DYNAMIC_DRAWABLE_ENTITY
#include "drawableEntity.h"
class DynamicDrawableEntity : public DrawableEntity {
public :
FloatRect getLocalBounds() {
return localBounds;
}
void setCenter(Vec2f center) {
Vec2f t = center - m_center;
move(t);
needToUpdate = true;
inverseNeedToUpdate = true;
}
Vec2f getCenter() {
return m_center;
}
void setPosition(Vec2f position) {
Vec2f t = position - m_position;
move(t);
needToUpdate = true;
inverseNeedToUpdate = true;
}
Vec2f getSize() {
return m_size;
}
Vec2f getPosition() {
return m_position;
}
void setRotation (float angle) {
m_rotation = static_cast<float>(fmod(angle, 360));
if (m_rotation < 0)
m_rotation += 360.f;
angle = -m_rotation * 3.141592654f / 180.f;
m_size.x = getTransform().transformRect(localBounds).width;
m_size.y = getTransform().transformRect(localBounds).height;
Vec2f t (m_scale.x * m_origin.x, m_scale.y * m_origin.y);
m_position = m_center - t;
needToUpdate = true;
inverseNeedToUpdate = true;
onRotate(angle);
}
void setScale(Vec2f scale) {
m_scale = scale;
m_size.x = localBounds.width * m_scale.x;
m_size.y = localBounds.height * m_scale.y;
Vec2f t (m_scale.x * m_origin.x, m_scale.y * m_origin.y);
m_position = m_center - t;
needToUpdate = true;
inverseNeedToUpdate = true;
onScale(scale);
}
void scale(Vec2f s) {
setScale(m_scale * s);
}
void rotate (float angle) {
setRotation(m_rotation + angle);
}
void move (Vec2f t) {
m_position += t;
m_center += t;
needToUpdate = true;
inverseNeedToUpdate = true;
onMove(t);
}
void setOrigin(Vec2f origin) {
m_origin = origin;
Vec2f t = origin - m_origin;
m_center -= t;
m_position -= t;
needToUpdate = true;
inverseNeedToUpdate = true;
}
Vec2f getScale() {
return m_scale;
}
float getRotation() {
return m_rotation;
}
Vec2f getOrigin() {
return m_origin;
}
void setSize (Vec2f size) {
setScale(size / m_size);
needToUpdate = true;
inverseNeedToUpdate = true;
}
FloatRect getGlobalBounds() {
FloatRect globalBounds = getTransform().transformRect(localBounds);
}
const sf::Transform getTransform() const {
// Recompute the combined transform if needed
if (needToUpdate) {
float angle = -m_rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(std::cos(angle));
float sine = static_cast<float>(std::sin(angle));
float sxc = m_scale.x * cosine;
float syc = m_scale.y * cosine;
float sxs = m_scale.x * sine;
float sys = m_scale.y * sine;
float tx = -m_origin.x * sxc - m_origin.y * sys + m_center.x;
float ty = m_origin.x * sxs - m_origin.y * syc + m_center.y;
const_cast<DynamicDrawableEntity*>(this)->m_transform = sf::Transform( sxc, sys, tx,
-sxs, syc, ty,
0.f, 0.f, 1.f);
const_cast<DynamicDrawableEntity*>(this)->needToUpdate = false;
}
return m_transform;
}
const sf::Transform& getInverseTransform()
{
// Recompute the inverse transform if needed
if (inverseNeedToUpdate)
{
const_cast<DynamicDrawableEntity*>(this)->m_inverseTransform = getTransform().getInverse();
const_cast<DynamicDrawableEntity*>(this)->inverseNeedToUpdate = false;
}
return m_inverseTransform;
}
protected :
DynamicDrawableEntity(Vec2f position, Vec2f size, Vec2f origin, int zOrder, TYPE type) : DrawableEntity(type) {
localBounds = FloatRect(position.x, position.y, size.x, size.y);
m_position = position;
m_size = size;
m_center = Vec2f (m_position.x + origin.x, m_position.y + origin.y);
m_origin = origin;
m_scale = Vec2f(1.f, 1.f);
m_rotation = 0;
setZOrder(zOrder);
needToUpdate = true;
inverseNeedToUpdate = true;
}
virtual void onRotate(float angle) {}
virtual void onScale(Vec2f s) {}
virtual void onMove(Vec2f t) {}
private :
FloatRect localBounds;
Vec2f m_position, m_size, m_center,m_scale,m_origin;
float m_rotation;
sf::Transform m_transform;
sf::Transform m_inverseTransform;
bool needToUpdate, inverseNeedToUpdate;
};
#endif // TRANSF_ENTITY
Cependant j'ai toujours un soucis pour les ombres, elle s'affichent pas au bonne endroit, je voudrais les afficher en dessous du mur, mais au lieu de ça, elles s'affichent à la place du mur. :/
#include "shadowWall.h"
#include "wall.h"
ShadowWall::ShadowWall (const Light &light, Wall *wall) : Shadow (light, wall) {
shadow = NULL;
createShadow (light, wall);
}
void ShadowWall::createShadow (const Light &light, Wall *wall) {
Vec2f lightPos (const_cast<Light&> (light).getCenter().x, const_cast<Light&> (light).getCenter().y);
Vec2f v = lightPos.normalize() * WALL_HEIGHT;
int lightHeight = const_cast<Light&> (light).getHauteur();
float scale;
if (lightHeight == 0)
scale = 1.f;
else if (lightHeight >= 200)
scale = 0.f;
else
scale = 1.f / (100.f / (float) const_cast<Light&> (light).getHauteur());
shadow = new ConvexShape (wall->getBottomPoints().size() * 2);
vector<Vec2f*> points;
Vec2f positionShadow (wall->getBottomPoints()[0]->x, wall->getBottomPoints()[0]->y);
for (int i = 0; i < wall->getBottomPoints().size(); i++) {
Vec2f *point = new Vec2f(*wall->getBottomPoints()[i]);
shadow->setPoint(i, Vector2f(point->x - positionShadow.x, point->y - positionShadow.y));
points.push_back(point);
}
for (int j = wall->getBottomPoints().size(), i = wall->getBottomPoints().size() - 1; i >=0 ; j++, i--) {
Vec2f *projPoint = new Vec2f(*wall->getBottomPoints()[i] + -v * scale);
shadow->setPoint(j, Vector2f ((int) projPoint->x - positionShadow.x, (int) projPoint->y - positionShadow.y));
points.push_back(projPoint);
}
Vec2f shadowOrigin = Computer::getMoy(points);
shadow->setFillColor(Color::Black);
shadow->setPosition(Vec2f(positionShadow.x, positionShadow.y));
setOrigin(shadowOrigin);
setRotation(wall->getRotation());
for (unsigned int i = 0; i < points.size(); i++) {
delete points[i];
}
points.clear();
}
void ShadowWall::draw(RenderTarget &target, RenderStates states) const {
states.transform = states.transform * getTransform();
target.draw(*shadow, states);
}
Drawable* ShadowWall::getShadow () {
return shadow;
}
int ShadowWall::getType() {
return SHADOWWALL;
}
ShadowWall::~ShadowWall () {
delete shadow;
}
#include "shadow.h"
using namespace sf;
/*Crée une ombre à partir de la lumière (light) et le tile (tile.)
*/
Shadow::Shadow (const Light &light, DrawableEntity *entity) : DynamicDrawableEntity (entity->getPosition(), entity->getSize(), Vec2f(0, 0), DEFAULT_SHADOW_Z_ORDER, Entity::E_SHADOW) {
entityId = &entity->getId();
lightId = &(const_cast<Light&> (light).getId());
}
int& Shadow::getLightId () {
return *lightId;
}
int& Shadow::getEntityId () {
return *entityId;
}
bottomPoints sont 2 points qui sont de chaque côté en bas du mur que j'utilise pour projeter les 2 autres points en fonction de la position et de la hauteur du soleil.
Bref avant je n'avais pas de soucis tout s'affichais au bonne endroit.