Bonjour je suis en train d'essayer de faire un rpg en 2d isométrique et je ne sais pas comment faire pour le déplacement d'un personnage.
Mon programme de test :
1:position du curseur dans la fenêtre
2:position du curseur dans le "monde"
3:"case" ou est le curseur
4:position d'affichage du sprite sur la case ou est le curseur
Ce que j'aimerais pouvoir faire est un déplacement simple:
- l'utilisateur clique sur une case
- le mage se délace en direction de spriteo à une vitesse donnée
-on continue le déplacement tant que la distance parcourue (trajet) est inférieure à la lougueur du déplacement ou tant que la position du sprite n'est pas le point d'arrivée
Le code :
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
int loading ( 1 );
int largeurfond = 0;
int main()
{
sf::RenderWindow window(sf::VideoMode(1280, 720,32), "SFML Test",sf::Style::Close);
window.setVerticalSyncEnabled(true);
sf::Font font;
if (!font.loadFromFile("ff.ttf"))
{
// error...
}
sf::Text text;
sf::Text text1;
sf::Text text2;
text.setFont(font);
text.setString("Ligne 1");
text.setCharacterSize(48);
text.setColor(sf::Color::White);
text.setPosition(sf::Vector2f(140, 588));
text1.setFont(font);
text1.setString("Ligne 2");
text1.setCharacterSize(48);
text1.setColor(sf::Color::White);
text1.setPosition(sf::Vector2f(140, 618));
text2.setFont(font);
text2.setString("Ligne 3");
text2.setCharacterSize(48);
text2.setColor(sf::Color::White);
text2.setPosition(sf::Vector2f(140, 650));
sf::View view(sf::FloatRect(0, 0, 640, 360));
sf::Color alpha(250,100,250);
sf::Color fond (128,225,255);
sf::Texture background;
if (!background.loadFromFile("test.png"))
return -1;
sf::Sprite back;
back.setTexture(background);
largeurfond = background.getSize().x;
sf::Texture splashscreen;
if (!splashscreen.loadFromFile("Intro.png"))
return -1;
sf::Sprite intro;
intro.setTexture(splashscreen);
sf::Image mage;
if (!mage.loadFromFile("mage.png"))
return -1;
mage.createMaskFromColor(alpha);
sf::Texture maget;
if (!maget.loadFromImage(mage,sf::IntRect(0, 0, 64, 64)))
return -1;
sf::Sprite spritemage;
spritemage.setTexture(maget);
spritemage.setPosition(sf::Vector2f(480, 160));
sf::Image textbox;
if (!textbox.loadFromFile("chatboxx.png"))
return -1;
textbox.createMaskFromColor(alpha);
sf::Texture boxtex;
if (!boxtex.loadFromImage(textbox,sf::IntRect(0, 0, 1280, 720)))
return -1;
sf::Sprite textbo;
textbo.setTexture(boxtex);
textbo.setPosition(sf::Vector2f(0,480));
sf::Clock clock;
sf::Clock clock2;
while (window.isOpen())
{
if( loading == 1 )
{
sf::Time tt = sf::seconds(5.0);
sf::Time elapsed = clock.getElapsedTime();
window.draw(intro);
window.display();
if (elapsed >= tt)
{
loading = 0;
clock.restart();
}
}
if( loading == 0 )
{
window.setView(view);
sf::Vector2i position = sf::Mouse::getPosition(window);
sf::Vector2f worldPos = window.mapPixelToCoords(position);
string title ( "SFML Test ");
std::string posx = std::to_string ( (int)position.x );
std::string posy = std::to_string ( (int)position.y );
std::string worldPosx = std::to_string ( (int)worldPos.x );
std::string worldPosy = std::to_string ( (int)worldPos.y );
float mousemapx = ( worldPos.x - 320 );
float mousemapy = worldPos.y;
float tilemx = ((mousemapy/32) + (mousemapx/64));
float tilemy = ((mousemapy/32) - (mousemapx/64));
int tilecx = (int)floor (tilemx );
int tilecy = (int)floor (tilemy );
std::string tilex = std::to_string ( tilecx );
std::string tiley = std::to_string ( tilecy );
int spriteox = (320 + (( tilecx - tilecy )*(64/2))) -32;
int spriteoy = ((( tilecx + tilecy ) * (32/2))) -32;
std::string spriteorix = std::to_string ( spriteox );
std::string spriteoriy = std::to_string ( spriteoy );
sf::Vector2f spriteo (spriteox,spriteoy);
title += "Pos Window ";
title += posx;
title += " ";
title += posy;
title += " ";
title += "Pos World ";
title += worldPosx;
title += " ";
title += worldPosy;
title += " ";
title += "Tile ";
title += tiley;
title += ":";
title += tilex;
title += " ";
title += "Spriteorigin ";
title += spriteorix;
title += ":";
title += spriteoriy;
window.setTitle(title);
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
// window closed
case sf::Event::Closed:
window.close();
break;
// key pressed
case sf::Event::KeyPressed:
{
if (event.key.code == sf::Keyboard::S)
{
view.move(0, -32);
}
else if (event.key.code == sf::Keyboard::X)
{
view.move(0, 32);
}
else if (event.key.code == sf::Keyboard::W)
{
view.move(-64, 0);
}
else if (event.key.code == sf::Keyboard::C)
{
view.move(64, 0);
}
}
break;
case sf::Event::MouseButtonPressed:
{
if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left)
{
}
}
break;
default:
break;
}
}
window.setView(view);
window.clear(fond);
window.draw(back);
window.draw(spritemage);
window.setView(window.getDefaultView());
window.draw(textbo);
window.draw(text);
window.draw(text1);
window.draw(text2);
window.display();
}
}
return 0;
}
Comme idées pour l'instant j'ai ça :
Point de départ : coordonnés du mage
sf::Vector2f posmage = spritemage.getposition();
sf::Vector2f depart = posmage;//appellé une seule fois
Point d'arrivée : coordonnées correspondant à la case ou j'ai cliqué
sf::Vector2f spriteo (spriteox,spriteoy);
Trajet parcouru :
float longueur = sqrt (pow((spritox-posmage.x),2)+(pow((spritoy-posmage.y),2));
Longueur du déplacement :
float trajet = sqrt (pow((spritox-depart.x),2)+(pow((spritoy-depart.y),2));//appellé une seule fois
Variable qui me servira plus tard à modifier la vitesse :
int vitesse = 100;
Je suis pas 100%sur de ce que j'ai. Je sais que j'aurais besoin d'utiliser le temps mais je ne sais pas comment faire.
Est ce que quelqu'un peut m'aider à trouvé ( et comprendre ) la solution ou m'orienter vers un tuto pour le même problème?