I have a project where I have multiple scenes, each representing a state, such as a splash screen, a main menu, a level, etc. There is a main Game class, and a SceneManager that handles all the scenes. I need to call some of the SceneManager functions from within the individual Scene classes, so I tried to implement passing the SceneManager into the Scene classes via a pointer. However, I keep getting the following error:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
I assume that I haven't initialized something correctly and that I causing the error, but I am having a hard time finding the exact issue and understanding it. I have included the relevant code below:
SceneManager.cpp function that gets the error:
void SceneManager::SetCurrentScene(Scene* scene) {
currentScene = scene;
}
Game.cpp
Game::GameState Game::GAME_STATE = Playing;
sf::RenderWindow Game::mainWindow;
SceneManager* Game::sceneManager;
void Game::Start(void) {
mainWindow.create(sf::VideoMode(GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT,32), GAME_WINDOW_TITLE, sf::Style::Close);
//make a clock
sf::Clock deltaClock;
//load the screen manager
//screenManager = new ScreenManager();
sceneManager->SetCurrentScene(new SplashScene(sceneManager)); // <---- This line is the first use of SetCurrentScene()
while(mainWindow.isOpen()) {
//get the delta time
sf::Time deltaTime = deltaClock.restart();
float delta = deltaTime.asMilliseconds();
GameLoop(delta);
}
mainWindow.close();
}
/*
bool Game::IsExiting()
{
if(gameState == Game::Exiting)
return true;
else
return false;
}
*/
sf::RenderWindow& Game::GetWindow()
{
return mainWindow;
}
void Game::GameLoop(float delta) {
sf::Event currentEvent;
mainWindow.pollEvent(currentEvent);
// "close requested" event: we close the window
if (currentEvent.type == sf::Event::Closed) {
mainWindow.close();
}
//graphics and rendering
mainWindow.clear(GAME_WINDOW_BUFFER_COLOR);
//update the current screen
sceneManager->currentScene->Update(currentEvent, delta);
sceneManager->currentScene->Draw(mainWindow);
//display the window
mainWindow.display();
}
Scene.cpp
Scene::Scene() {
Load();
}
Scene::Scene(SceneManager* sceneManager) {
this->sceneManager = sceneManager;
Load();
}
Scene::~Scene() {
}
void Scene::Load() {
}
void Scene::Draw(sf::RenderWindow& renderWindow) {
}
void Scene::Update(sf::Event event, float delta) {
}
Thank you for all of the help!
Related
So been trying my exit and play button work but they do not react the way I want them too for some strange reason. When I change one to else if and if only statement they either both exit or change them again and both start the game. They act like they are the same button and not individuals despite how they are selected and pressed.
Here is my header file:
#pragma once
#include <memory>
#include "State.h"
#include "Game.h"
#include <SFML/Graphics.hpp>
class MainMenu : public Engine::State
{
public:
enum behavior
{
HOVERED, NORMAL
};
private:
std::shared_ptr<Context> context;
sf::Text gameTitle;
sf::Text playButton;
sf::Text exitButton;
void hover(sf::RenderWindow& window, sf::Event event);
//checking certain conditions if it is true or false
bool isPlayButtonSelected;
bool isPlayButtonPressed;
bool isExitButtonSelected;
bool isExitButtonPressed;
public:
MainMenu(std::shared_ptr<Context>& context);
~MainMenu();
void Init() override;
void ProcessInput() override;
void Update(sf::Time deltaTime) override;
void Draw() override;
};
Here is the cpp file:
#include "MainMenu.h"
#include "GamePlay.h"
MainMenu::MainMenu(std::shared_ptr<Context> &context) : context(context),
isPlayButtonSelected(true), isPlayButtonPressed(false), isExitButtonPressed(false),
isExitButtonSelected(false)
{
}
MainMenu::~MainMenu()
{
}
void MainMenu::Init()
{
//our assets being put here that we stored and implement it
context -> assets ->AddFont(MainFont, "Assets/Asdonuts.ttf");
//Titlle screen name of the game code
gameTitle.setFont(context->assets->GetFont(MainFont));
gameTitle.setString("Final Game Project");
gameTitle.setOrigin(gameTitle.getGlobalBounds().width/2,
gameTitle.getGlobalBounds().height/2);
gameTitle.setPosition(context->window->getSize().x/3.5,
context->window->getSize().y/2 - 450.f);
gameTitle.setCharacterSize(150);
//This is the code for the play button
playButton.setFont(context->assets->GetFont(MainFont));
playButton.setString("Start");
playButton.setOrigin(playButton.getGlobalBounds().width/2,
playButton.getGlobalBounds().height/2);
playButton.setPosition(context->window->getSize().x/2,
context->window->getSize().y/2 - 50.f);
playButton.setCharacterSize(70);
//This is the code for the exit button
exitButton.setFont(context->assets->GetFont(MainFont));
exitButton.setString("Exit");
exitButton.setOrigin(exitButton.getGlobalBounds().width/2,
exitButton.getGlobalBounds().height/2);
exitButton.setPosition(context->window->getSize().x/2,
context->window->getSize().y/2 + 50.f);
exitButton.setCharacterSize(70);
}
//this function is when the screen is running and reads user input when pressing
//the buttons and things that happend when they press certain buttons
//while also keeping the window open till they choose to close it on the x button
//on the top right corner
void MainMenu::ProcessInput()
{
sf::Event event;
while(context->window->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
context->window->close();
}
else if(event.type == sf::Event::KeyPressed)
{
switch(event.key.code)
{
case sf::Keyboard::Up:
{
if(!isPlayButtonSelected)
{
isPlayButtonSelected = true;
isExitButtonSelected = false;
}
break;
}
case sf::Keyboard::W:
{
if(!isPlayButtonSelected)
{
isPlayButtonSelected = true;
isExitButtonSelected = false;
}
break;
}
case sf::Keyboard::Down:
{
if(!isExitButtonSelected)
{
isPlayButtonSelected = false;
isExitButtonSelected = true;
}
break;
}
case sf::Keyboard::S:
{
if(!isExitButtonSelected)
{
isPlayButtonSelected = false;
isExitButtonSelected = true;
}
break;
}
case sf::Keyboard::Enter:
{
isPlayButtonPressed = false;
isExitButtonPressed = false;
if(!isPlayButtonPressed)
{
isPlayButtonPressed = true;
}
else if(!isExitButtonPressed)
{
isExitButtonPressed = true;
}
break;
}
default:
{
break;
}
}
}
}
}
void MainMenu::Update(sf::Time deltaTime)
{
//conditions for the menu fonts and all
//so like we know who is highlighted and not highlighted for the user to understand
//what is going on and what selection they are hovering on
if(isPlayButtonSelected)
{
playButton.setFillColor(sf::Color::Blue);
exitButton.setFillColor(sf::Color::White);
}
else
{
exitButton.setFillColor(sf::Color::Blue);
playButton.setFillColor(sf::Color::White);
}
//important thing for our main menu
//if Play button is pressed the game starts
if(isPlayButtonPressed)
{
context->states->Add(std::make_unique<GamePlay>(context), true);
}
//if the exit button is pressed, the game SHOULD exit
else if(isExitButtonPressed)
{
context->window->close();
}
}
void MainMenu::Draw()
{
//draw everything that needs to be display in the main menu
context->window->clear(sf::Color(53, 189, 164));
context->window->draw(gameTitle);
context->window->draw(playButton);
context->window->draw(exitButton);
context->window->display();
}
So an example what I mean is this one both buttons start the game but if I change it to this:
case sf::Keyboard::Enter:
{
isPlayButtonPressed = false;
isExitButtonPressed = false;
if(!isPlayButtonPressed)
{
isPlayButtonPressed = true;
}
if(!isExitButtonPressed)
{
isExitButtonPressed = true;
}
break;
}
if(isPlayButtonPressed)
{
context->states->Add(std::make_unique<GamePlay>(context), true);
}
//if the exit button is pressed, the game SHOULD exit
if(isExitButtonPressed)
{
context->window->close();
}
They will both exit and not start the game. I have been messing around one if and the other else or both as if statements. Despite the changes and testing none of the buttons act individually and act how they are supposed to act. So curious how to fix this issue?
Unsure if I should provide all my headers and cpp files for more context.
I am not really sure if I understand well your problem, but in your example it seems like isExitButtonPressed is always true at the end.
You're setting it to false at the begining and then setting it to true in the if statement which has always a fulfilled condition giving the fact that you set isExitButtonPressed to false beforehand !
My problem is that I have written this code inside Game::HandleInput() method but I cannot make the sf::Mouse::getPosition() method to get the mouse coordinates relative to window. Without argument, I don't get an error. However, ship doesn't rotate properly. I have tried getPosition(m_window) and getPosition(&m_window). I am getting this error:
no instance of overloaded function "sf::Mouse::getPosition" matches the argument list
EDIT: UPDATED THE WINDOW.H
Window.h:
class Window{
//Constructers
public:
Window();
Window(const std::string& l_title, const sf::Vector2u& l_size);
...
private:
sf::RenderWindow m_window;
...
}
EDIT: ADDED THE FULL CODE OF WINDOW.CPP:
Window.cpp:
#include "Window.h"
Window::Window() {
Setup("Window", sf::Vector2u(640, 480));
}
Window::Window(const std::string& l_title, const sf::Vector2u& l_size) {
Setup(l_title, l_size);
}
Window::~Window() {
Destroy();
}
void Window::Setup(const std::string& l_title,
const sf::Vector2u& l_size)
{
m_windowTitle = l_title;
m_windowSize = l_size;
m_isFullscreen = false;
m_isDone = false;
Create();
}
void Window::Create() {
auto style = (m_isFullscreen ? sf::Style::Fullscreen
: sf::Style::Default);
m_window.create({ m_windowSize.x, m_windowSize.y, 32 },
m_windowTitle, style);
}
void Window::Destroy() {
m_window.close();
}
void Window::Update() {
sf::Event event;
while (m_window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
m_isDone = true;
}
else if (event.type == sf::Event::KeyPressed &&
event.key.code == sf::Keyboard::F5)
{
ToggleFullscreen();
}
}
}
void Window::ToggleFullscreen() {
m_isFullscreen = !m_isFullscreen;
Destroy();
Create();
}
void Window::BeginDraw() { m_window.clear(sf::Color::Black); }
void Window::EndDraw() { m_window.display(); }
bool Window::IsDone() { return m_isDone; }
bool Window::IsFullscreen() { return m_isFullscreen; }
sf::Vector2u Window::GetWindowSize() { return m_windowSize; }
void Window::Draw(sf::Drawable& l_drawable){
m_window.draw(l_drawable);
}
EDIT: UPDATED THE GAME.H
Game.h:
class Game{
public:
Game();
~Game();
void HandleInput();
void Update();
void Render();
Window* GetWindow();
private:
...
Window m_window;
...
}
EDIT: UPDATED THE GAME.CPP
Game.cpp:
Game::Game() : m_window("Multiplayer Space Shooter Game", sf::Vector2u(800, 600)) {
// Setting up class members.
m_shipText.loadFromFile("C:\\Users\\AliTeo\\Desktop\\Piksel çalışmaları\\ship_pixel2.png");
m_ship.setTexture(m_shipText);
m_ship.setOrigin(m_shipText.getSize().x / 2, m_shipText.getSize().y / 2);
m_ship.setPosition(320, 240);
}
void Game::HandleInput() {
...
//Get the angle between ship and mouse.
//Error if there is an argument in getPosition()
m_angle = atan2(sf::Mouse::getPosition().y - m_ship.getPosition().y, sf::Mouse::getPosition().x - m_ship.getPosition().x); //TO DO: getPosition(&Relative To)
m_angle *= 180 / m_PI;
...
}
Window* Game::GetWindow() { return &m_window; }
EDIT: ADDED THE MAIN.CPP
Main.cpp
int main() {
Game game;
while (!game.GetWindow()->IsDone()) {
game.HandleInput();
game.Update();
game.Render();
}
}
First let me give you what I assume is a minimal example reproducing your problem:
#include <SFML/Graphics.hpp>
class MyWindow {
public:
MyWindow()
: m_window({800, 600, 32}, "my window title") {}
private:
sf::RenderWindow m_window;
};
int main() {
MyWindow window;
sf::Mouse::getPosition(window);
}
This code doesn't compile (and admittedly wouldn't do anything interesting when compiled, but that's not the point). I suspect it'd give you the same error that you're currently having if you tried to compile it.
Please note that this is what we expect when we talk about a MCVE: this code is short, simple, exhibits the error and would compile if not because of it.
Besides, it makes the error painfully clear, and if you tried to come up with a MCVE yourself, you may have solved your problem without having to post a question here, which would certainly save you time.
Contrast with your code:
m_angle = atan2(sf::Mouse::getPosition().y - m_ship.getPosition().y
,sf::Mouse::getPosition().x - m_ship.getPosition().x
);
//TO DO: getPosition(Relative To)
This code is legal, but you explained that it is incorrect and you wanted to turn it into something along those lines:
m_angle = atan2(sf::Mouse::getPosition(m_window).y - m_ship.getPosition().y
,sf::Mouse::getPosition(m_window).x - m_ship.getPosition().x
);
//TO DO: getPosition(Relative To)
... which doesn't compile.
However, in this scope m_window is a Window not a sf::RenderWindow!
The problem is that you're passing a reference to an object (MyWindow in my example, Window in your case) that encapsulates a sf::RenderWindow, but isn't convertible to sf::Window& itself.
Therefore, you can't pass it to sf::Mouse::getPosition which expects either nothing or a sf::Window&, but certainly not a Window& or a MyWindow&.
There are a lot of ways of fixing this. Two of which are presented below:
#include <SFML/Graphics.hpp>
class MyWindow {
public:
MyWindow()
: m_window({800, 600, 32}, "my window title") {}
// you could add an accessor
const sf::Window& getSfmlWindow() const { return m_window; }
// you may also expose a method to get the mouse position
// relatively to this window
const sf::Vector2i getMousePosition() const {
return sf::Mouse::getPosition(m_window);
}
private:
sf::RenderWindow m_window;
};
int main() {
MyWindow window;
sf::Vector2i mouse_position;
// this won't work! window isn't convertible to sf::Window&
// mouse_position = sf::Mouse::getPosition(window);
// using the accessor
mouse_position = sf::Mouse::getPosition(window.getSfmlWindow());
// or the exposed method
mouse_position = window.getMousePosition();
}
I have a character sprite moving across the screen and when I press 'a' I want the program to draw the sword sprite onto the screen and make the sword go away when I am not pressing 'a'. Currently I have an attack function that sets a showweapon boolean as true, and a if statement that is supposed to draw the weapon onto the screen but nothing happens. Is there a better way to do this?
main.cpp
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Character.h"
#include "Projectile.h"
#include "Weapon.h"
using namespace std;
bool scroll = false;
Character player("/Users/danielrailic/Desktop/Xcode /NewGame/ExternalLibs/Player.png");
Weapon woodsword("/Users/danielrailic/Desktop/Xcode /NewGame/ExternalLibs/WoodSword.png");
bool showweapon;
int main() {
// insert code here...
int windowWidth = 5000;
int windowHeight = 5000;
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight ), "Awesome Game" );
sf::Texture dungeon;
dungeon.loadFromFile("/Users/danielrailic/Desktop/Xcode /NewGame/ExternalLibs/DungeonBack.png");
sf::Sprite backround;
backround.setTexture(dungeon);
while (window.isOpen()){
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event)){
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
player.left();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
player.right();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
player.forward();
}
if (sf:: Keyboard::isKeyPressed(sf::Keyboard::Down)){
player.backward();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
player.Highspeed();
}
else{
player.Lowspeed();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)){
woodsword.attack();
}
window.clear(sf::Color(255, 255, 255));
window.draw(backround);
if(showweapon == true){
window.draw(woodsword.getSprite());
window.display();
cout << "Hello";
}
window.draw(player.getSprite());
window.display();
window.setFramerateLimit(70);
}
}
I am also not receiving the "hello" message
weapon.h
class Weapon : Character{
bool showweapon;
public:
sf::Texture texture;
//Constructor
Weapon(string wep)
: Character(wep){
texture.loadFromFile(wep);
showweapon = false;
}
sf::Sprite getSprite() {
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setTextureRect(sf::IntRect(0, 0, 100, 100));
sprite.setPosition(x_pos, y_pos);
return sprite;
}
//Methods
void attack();
};
void Weapon::attack(){
showweapon = true;
}
If you need to see anything else let me know. Thanks for any help!
I changed the if statement to : if (woodsword.showweapon == true) and I also made a sheath method in the weapon class that sets showweapon false so the sword goes away when I don't press 'a'. Thanks for everyones help.
I'm using SFML for creating a small game for practice, a replica of the old Tanks game I played when I was young on some type of console.
I've encountered a strage thing when I'm trying to draw the player. I'm saying strange because at first it was showing, so I don't think something is wrong with my function, but after I made a derived class for the enemy tanks and made a new file for that I had some nesting problems with linking all the files togheter(5 files, 1 cpp and 4 headers). After I figured that out, I ran into this problem and can't find any solution to it. It was working before that problem and now it doesn't anymore.
I checked the texture, if it is loading, the position I set it to, they are ok.
Here is the class for the player tank
class tank{
protected:
sf::FloatRect boundingBox;
sf::Sprite tankSprite;
bullet *mBullet;
public :
tank(); // constructor
bullet * get_ptr(){return mBullet;}
sf::FloatRect get_boundingBox(){return boundingBox;}
void setRotation(float);
void show(){game.draw(tankSprite);}
void update();
void shoot(){mBullet = new bullet(tankSprite);}
};
And this is the code in my main where I update the world and draw on my window
if(!stop)
Me.update();
if(Me.get_ptr()->isFired()==true)
Me.get_ptr()->update();
// Output on the window
game.clear();
Me.show();
if(Me.get_ptr()->isFired()==true)
Me.get_ptr()->show();
game.display();
Side note : game is the render window and is globally declared( I know it's bad practice, I'm slowing getting to ditch this bad habit)
main.cpp
#include <SFML/Graphics.hpp>
#include "Tank.h"
int main()
{
tank Me;
init();
while (game.isOpen())
{
sf::Event event;
while (game.pollEvent(event))
{
if (event.type == sf::Event::Closed)
game.close();
else if (event.type == sf::Event::KeyPressed)
{
stop=false;
switch(event.key.code)
{
case sf::Keyboard::W:
{
Me.setRotation(0);
break;
}
case sf::Keyboard::D:
{
Me.setRotation(90);
break;
}
case sf::Keyboard::S:
{
Me.setRotation(180);
break;
}
case sf::Keyboard::A:
{
Me.setRotation(270);
break;
}
case sf::Keyboard::Escape:
{
game.close();
break;
}
case sf::Keyboard::Space:
{
if(Me.get_ptr()->isFired()==false)Me.shoot();
break;
}
case sf::Keyboard::LControl:
{
stop=true;
break;
}
default:
break;
}
}
}
if(!stop)
Me.update();
if(Me.get_ptr()->isFired()==true)
Me.get_ptr()->update();
// Output on the window
game.clear();
Me.show();
if(Me.get_ptr()->isFired()==true)
Me.get_ptr()->show();
game.display();
}
return 0;
}
init.h
#include<iostream>
bool stop;
sf::RenderWindow game(sf::VideoMode(400, 400), "SFML");
sf::Texture myTankTexture;
sf::Texture bulletTexture;
void init(){
srand(time(NULL));
stop = true;
game.setVerticalSyncEnabled(true);
game.setFramerateLimit(60);
if(!myTankTexture.loadFromFile("tank.jpg"))
{
std::cout<<"eroare la textura tank"<<std::endl;
}
myTankTexture.setSmooth(true);
if(!bulletTexture.loadFromFile("bullet.jpg"))
{
std::cout<<"bullet texture error"<<std::endl;
}
bulletTexture.setSmooth(true);
}
sf::Vector2f rotationToDirection(int rotation){
sf::Vector2f dir;
switch (rotation)
{
case 0:
{
dir.x=0.0;
dir.y=-1.0;
break;
}
case 90:
{
dir.x=1.0;
dir.y=0.0;
break;
}
case 180:
{
dir.x=0.0;
dir.y=1.0;
break;
}
case 270:
{
dir.x=-1.0;
dir.y=0.0;
break;
}
}
return dir;
}
bullet.h
#include "init.h"
class bullet{
protected:
sf::Sprite bulletSprite;
sf::FloatRect boundingBox;
bool isBFired = false;
public:
bullet(sf::Sprite); // constructor
~bullet(){isBFired=false;}
sf::FloatRect get_boundingBox(){return boundingBox;}
bool isFired(){if(isBFired)return true;else return false;}
int collision();
void del(){delete this;}
void update();
void show(){game.draw(bulletSprite);}
};
bullet::bullet(sf::Sprite sprite){
isBFired = true;
bulletSprite.setTexture(bulletTexture);
bulletSprite.setOrigin(2.5,5.0);
bulletSprite.setRotation(sprite.getRotation());
bulletSprite.setPosition(sprite.getPosition().x+rotationToDirection(bulletSprite.getRotation()).x*5.0,sprite.getPosition().y+rotationToDirection(bulletSprite.getRotation()).y*5.0);
boundingBox = bulletSprite.getLocalBounds();
}
int bullet::collision(){
if(bulletSprite.getPosition().x < 0
|| bulletSprite.getPosition().x > 400
|| bulletSprite.getPosition().y > 400
|| bulletSprite.getPosition().y < 0 )return 1;
else
return 0;
}
void bullet::update(){
bulletSprite.move(rotationToDirection(bulletSprite.getRotation()).x*6.0,rotationToDirection(bulletSprite.getRotation()).y*6.0);
if(collision()==1)
delete this;
else
boundingBox = bulletSprite.getLocalBounds();
}
tank.h
#include "bullet.h"
class tank{
protected:
sf::FloatRect boundingBox;
sf::Sprite tankSprite;
bullet *mBullet;
public :
tank(); // constructor
bullet * get_ptr(){return mBullet;}
sf::FloatRect get_boundingBox(){return boundingBox;}
void setRotation(float);
void show(){game.draw(tankSprite);}
void update();
void shoot(){mBullet = new bullet(tankSprite);}
};
tank::tank(){
tankSprite.setTexture(myTankTexture);
tankSprite.setOrigin(20,20);
tankSprite.setRotation(0);
tankSprite.setPosition(200,200);
boundingBox = tankSprite.getLocalBounds();
}
void tank::update(){
tankSprite.move(rotationToDirection(tankSprite.getRotation()).x*3,rotationToDirection(tankSprite.getRotation()).y*3);
boundingBox = tankSprite.getLocalBounds();
}
void tank::setRotation(float rotation){
tankSprite.setRotation(rotation);
}
You are not setting the texture rectangle as far as I see, see if this helps you. When you set your tank sprite try :
tankSprite.setTexture(myTankTexture, true);
Passing true will reset your texture rectangle to the size of the sprite, see the SFML docs for more information.
Also, you are creating the Tank class before calling init(), myTankTexture will be empty so the tank constructor uses that, and your texture is loaded later.
As they say in your language, "multa bafta" :)
I am trying to follow a slightly outdated tutorial on making a Tile Engine.
The problem is that the Texture I am trying to draw on screen, doesn't show up. I just get a black screen.
I've taken the most relevant parts of Engine.cpp:
bool Engine::Init()
{
LoadTextures();
window = new sf::RenderWindow(sf::VideoMode(800,600,32), "RPG");
if(!window)
return false;
return true;
}
void Engine::LoadTextures()
{
sf::Texture sprite;
sprite.loadFromFile("C:\\Users\\Vipar\\Pictures\\sprite1.png");
textureManager.AddTexture(sprite);
testTile = new Tile(textureManager.GetTexture(0));
}
void Engine::RenderFrame()
{
window->clear();
testTile->Draw(0,0,window);
window->display();
}
void Engine::MainLoop()
{
//Loop until our window is closed
while(window->isOpen())
{
ProcessInput();
Update();
RenderFrame();
}
}
void Engine::Go()
{
if(!Init())
throw "Could not initialize Engine";
MainLoop();
}
And here is the TextureManager.cpp
#include "TextureManager.h"
#include <vector>
#include <SFML\Graphics.hpp>
TextureManager::TextureManager()
{
}
TextureManager::~TextureManager()
{
}
void TextureManager::AddTexture(sf::Texture& texture)
{
textureList.push_back(texture);
}
sf::Texture& TextureManager::GetTexture(int index)
{
return textureList[index];
}
In the tutorial itself the Image type was used but there was no Draw() method for Image so I made Texture instead. Why won't the Texture render on the screen?
The problem seems to be in:
void Engine::LoadTextures()
{
sf::Texture sprite;
sprite.loadFromFile("C:\\Users\\Vipar\\Pictures\\sprite1.png");
textureManager.AddTexture(sprite);
testTile = new Tile(textureManager.GetTexture(0));
}
You are creating a local sf::Texture and passing that to TextureManager::AddTexture. It's probably going out of scope at the end of the function, and is then no longer valid when you try to draw it. You fix this by using a smart pointer:
void Engine::LoadTextures()
{
textureManager.AddTexture(std::shared_ptr<sf::Texture>(
new sf::Texture("C:\\Users\\Vipar\\Pictures\\sprite1.png")));
testTile = new Tile(textureManager.GetTexture(0));
}
And changing TextureManager to use it:
void TextureManager::AddTexture(std::shared_ptr<sf::Texture> texture)
{
textureList.push_back(texture);
}
sf::Texture& TextureManager::GetTexture(int index)
{
return *textureList[index];
}
You'll also have to change textureList to be an std::vector<std::shared_ptr<sf::Texture> of course.