Bonjour,
pour commencer, je débute autant en C++ qu'en SFML. Ma question porte très probablement sur des bases de C++ qui m'échappent.
Je souhaite créer un mini programme me permettant de passer d'une "scène" à l'autre.
Comme passer du menu de démarrage, au jeu en lui même, au travers d'un clic sur un bouton du menu démarrage.
Je suis en train de concevoir le menu de démarrage. Je n'en suis qu'au début.
Ce menu est conçu avec ma class Scene_menu.
Cette class contient un sf::Text pour le nom du jeu, ainsi qu'un vector<sf::RectangleShape>, qui contient deux rectangles sf::RectangleShape, pour simuler des boutons.
Dans mon main, je créé un objet scene_menu de la class Scene_menu.
Ensuite, dans une boucle while, j'appelle une fonction draw() de mon objet scene_menu
Cette fonction draw() me permet d'afficher sans problème mes deux rectangles : je parcours avec un itérateur mon vecteur, et j'envoie mon itérateur à la fonction draw() d'un objet de type RenderWindow.
Par contre, si j'envoie mon sf::Text, j'ai une l'erreur "violation de mémoire"
(je n'arrive pas à afficher d'image ... normalement une capture est jointe au post)
Cette erreur apparait donc si je veux afficher le sf::Text de mon objet.
Mais si je créé un nouvel objet sf::Text dans la fonction draw(), et essai de l'afficher : OK
Je ne comprend pas la différence entre ma variable locale l_title et mon attribut de class title. Qu'est ce qui fait que ces 2 objets instanciés avec les même valeurs (même string, même font), ne me donnent pas les mêmes résultats avec la méthode sf::Renderwindow::draw() ?
voici une partie de mon code :
Mon main :
#include "main.h"
int main(){
RenderWindow window;
window.create(VideoMode(WIN_WIDTH, WIN_HEIGHT, 32), "Un titre", sf::Style::Default);
window.setVerticalSyncEnabled(true);
SharedContext* sharedContext= SharedContext::GetInstance(window);
Scene_Menu scene_menu;
while (sharedContext->getWindow().isOpen()) {
sharedContext->getWindow().clear(Color::Black);
scene_menu.draw();
sharedContext->getWindow().display();
}
return 0;
}
Scene_Menu.h
#pragma once
#include <vector>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/Text.hpp>
#include "sharedContext.h"
class Scene_Menu {
public:
Scene_Menu();
~Scene_Menu();
void draw();
void update();
void setTitle(const sf::Text &l_txt);
void setRectancle(const int &number,const sf::Vector2u &dimension, const sf::Vector2u &position);
void pressButton(int button);
private:
sf::Text title;
std::vector<sf::RectangleShape> rectangleShapeList;
SharedContext* sharedContext;
};
Scene_Menu.cpp
#include "Scene_Menu.h"
#include <iostream>
Scene_Menu::Scene_Menu() {
sharedContext = SharedContext::GetInstance();
sf::Font font;
font.loadFromFile("res/poppins.ttf");
title = sf::Text("Menu", font);
// Bouton jouer
sf::RectangleShape rectangleShape(sf::Vector2f(120.f, 50.f));
rectangleShape.setPosition(200, 300);
rectangleShape.setFillColor(sf::Color(100, 115, 180, 200));
rectangleShape.setSize(sf::Vector2f(180.f, 100.f));
// Bouton quitter
sf::RectangleShape rectangleShape2(sf::Vector2f(120.f, 50.f));
rectangleShape2.setPosition(200, 400);
rectangleShape2.setFillColor(sf::Color(175, 175, 175, 200));
rectangleShape2.setSize(sf::Vector2f(180.f, 100.f));
rectangleShapeList.push_back(rectangleShape);
rectangleShapeList.push_back(rectangleShape2);
}
Scene_Menu::~Scene_Menu(){}
void Scene_Menu::draw(){
sf::Font font;
font.loadFromFile("res/poppins.ttf");
sf::Text l_title = sf::Text("Menu", font);
sharedContext->getWindow().draw(title); // ne marche pas
// sharedContext->getWindow().draw(l_title); // marche très bien
for (auto &itr : rectangleShapeList) {
sharedContext->getWindow().draw(itr);
}
}
void Scene_Menu::update(){}
void Scene_Menu::setTitle(const sf::Text& l_txt){}
void Scene_Menu::setRectancle(const int& number, const sf::Vector2u& dimension, const sf::Vector2u& position){}
void Scene_Menu::pressButton(int button){}
en espérant que vous saurez m'aider :-)
Merci par avance
J'ai réglé mon problème en ajoutant la sf::Font à ma classe, en tant qu'attribut donc.
Puis, j'ai initialisé cette sf::Font dans le constructeur de ma classe.
Enfin j'ai initialisé mon sf::Text en utilisant cette sf::Font.
Dans la fonction draw() de ma classe, j'ai pu passer mon sf::Text à la fonction draw() du sf::RendererWindow
Edit>> En fait, mon problème venait effectivement des mes connaissances en C++.
Le constructeur d'un sf::Text demande une référence d'une sf::Font.
Or, dans mon cas, je créais une sf::Font, dans mon constructeur. La sf::Font était détruite à la fin de mon constructeur.
funny shooter 2 (https://funnyshooter2.com)
Dans ma fonction Draw(), je voulais utiliser mon sf:Text. Ce dernier était incapable de retrouver le sf::Font auquel il était lié, puisque celui-ci était détruit.
Bonjour
Super. J'ai eu le même problème que toi et maintenant je peux le résoudre.