I am working on a little project where I am trying to get a player in my 2D view (actually a circle) and let him move left to right, up and down flawless, also I want to be able to press 2 keys at ones so he moves sideways or something like that.
Also i want to be able to shoot with the player in a certain direction in a later state of the project (it could be important as of now)
I am doing this project because I want to learn how C++ OOP works.
The structure im having in my mind is simple :
Main > (Creates) > GameWindow
Main > (creates) > EntityManager > (creates) > Player
Player > (creates via) > EnitityManager > Gun
Gun > (Creates via) > EntityManager > Bullet
Player can :
Walk up/down/left/right
Shoot.
So to get to the code, This is what I have in my FirstGame.cpp
#include "stdafx.h"
#include "GameWindow.h"
#include "EntityManager.h"
int main()
{
// Create an entity manager
EntityManager::Instance();
// Display the window
GameWindow::Instance().Run();
}
in my GameWindow.h I have :
#pragma once
#include <SFML/Graphics.hpp>
using namespace sf;
class GameWindow
{
public:
static GameWindow& Instance()
{
static GameWindow instance;
return instance;
}
RenderWindow& GetRenderWindow();
void Run();
private:
static const int DEF_WIDTH = 1366;
static const int DEF_HEIGHT = 720;
GameWindow();
GameWindow(const GameWindow&);
GameWindow& operator=(const GameWindow&);
~GameWindow();
string windowTitle;
int windowWidth;
int windowHeight;
void Initialize();
void DisplayWindow();
void CheckWindowEvent();
};
and in my GameWindow.cpp
#include "StdAfx.h"
#include "GameWindow.h"
#include "Player.h"
#include "SFML\Graphics.hpp"
RenderWindow renderWindow;
Event eventSF;
GameWindow::GameWindow()
{
Initialize();
}
GameWindow::~GameWindow()
{
}
void GameWindow::Initialize()
{
// Set width & height to default settings
windowWidth = DEF_WIDTH;
windowHeight = DEF_HEIGHT;
// Create the render window
renderWindow.create(VideoMode(windowWidth, windowHeight), windowTitle, Style::Titlebar | Style::Close | Style::Resize);
Cmd::WriteLine("GameWindow Initialized!");
}
RenderWindow& GameWindow::GetRenderWindow()
{
return renderWindow;
}
void GameWindow::Run()
{
// Loop until window has closed
while (renderWindow.isOpen())
{
// Check current window events
CheckWindowEvent();
// Display window
DisplayWindow();
}
}
void GameWindow::DisplayWindow()
{
// Display the render window
renderWindow.clear();
renderWindow.display();
}
void GameWindow::CheckWindowEvent()
{
Event _event;
while (renderWindow.pollEvent(_event))
{
// Request for closing the window
if (_event.type == Event::Closed)
renderWindow.close();
}
}
and in my EntityManager.h I got :
#pragma once
#include "Entity.h"
#include "Player.h"
class EntityManager
{
public:
static EntityManager& Instance()
{
static EntityManager instance = EntityManager();
return instance;
}
private:
EntityManager();
~EntityManager();
void Initialize();
};
and my EntityManager.cpp
#include "StdAfx.h"
#include "EntityManager.h"
#include "GameWindow.h"
#include "Player.h"
EntityManager::EntityManager()
{
Initialize();
}
EntityManager::~EntityManager()
{
}
void EntityManager::Initialize()
{
Player::Create();
}
and now the Player.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Entity.h"
using namespace sf;
class Player: Entity
{
public:
Player();
~Player();
void GotDamage(int damage);
static void Create();
void Draw();
void Shoot();
void Move(float x, float y);
void Controls(Event _eventSF);
private:
string name;
int health;
Event eventSF;
CircleShape playerVisual;
protected:
void Initialize() override;
};
and last the Player.cpp
#include "StdAfx.h"
#include "Player.h"
#include "GameWindow.h"
#include <SFML/Graphics.hpp>
Player::Player()
{
}
Player::~Player()
{
}
void Player::Create()
{
Player player;
player.Initialize();
player.Draw();
player.Controls(player.eventSF);
}
void Player::Initialize()
{
CircleShape playerVisual(50);
playerVisual.setPosition(800, 450);
playerVisual.setFillColor(sf::Color(100, 250, 50));
Entity::Initialize();
}
void Player::Controls(sf::Event _eventSF)
{
while(GameWindow::Instance().GetRenderWindow().isOpen())
{
while(GameWindow::Instance().GetRenderWindow().pollEvent(_eventSF))
{
switch(_eventSF.type)
{
case sf::Event::KeyPressed:
if (_eventSF.key.code == sf::Keyboard::Up)
{
Move(0,-1);
}
if (_eventSF.key.code == sf::Keyboard::Down)
{
Move(0,1);
}
if (_eventSF.key.code == sf::Keyboard::Left)
{
Move(-1,0);
}
if (_eventSF.key.code == sf::Keyboard::Right)
{
Move(1,0);
}
if (_eventSF.key.code == sf::Keyboard::BackSpace)
{
GotDamage(20);
}
break;
}
}
}
cout << " Checking Controls " << endl;
}
void Player::Move(float _x, float _y)
{
cout << "Move Player " << endl;
playerVisual.move(_x, _y);
Draw();
}
void Player::GotDamage(int _damage)
{
//for some reason health is -858993460
cout << "Your current health is " << Player::health << " you received " << _damage << " damage now you have " << Player::health - _damage << " health left. " << endl;
health -= _damage;
}
void Player::Draw()
{
cout << "Draw Player" << endl;
CircleShape visual(50);
playerVisual.setPosition(800, 450);
playerVisual.setFillColor(sf::Color(100, 250, 50));
GameWindow::Instance().GetRenderWindow().draw(visual);
}
I know it is a lot but I hope someone can help me.
To repeat my goal :
I am trying to get my player to be drawn on the screen and let him move sideways and if possible diagonal.
Thanks in advance!
To add onto KeyHeart's answer.
I hacked up your code a bit and managed to get it working.
Keep in mind the scope of your variables. There's CircleShape playerVisual(50) in Player::Initialize() which is a local variable, but you already have a CircleShape playerVisual inside Player.h! So the former is unnecessary. Likewise in Player::Create() you create a local player object.
I don't have a full copy of your code, so I assume what you plan on doing is having EntityManager handle all existing entities, such as the player. Therefore you should have Player player declared in the EntityManager's header file. Thus calling the constructor, which I have taken everything from Player::Create() and placed it into Player::Player(). And this player will exist for lifespan of EntityManager.
The order in which you should be updating the buffer is:
renderWindow.clear()
renderWindow.draw()
renderWindow.display()
As you have it now, you draw() then clear() effectively displaying nothing.
There are many approaches, but the simplest would be adding a call to Player::Draw() in GameWindow::DisplayWindow(). Though GameWindow will need a player object to call Draw().
Regarding moving the player. Player::Controls contains what may be an infinite loop in a sense. The line while (GameWindow::Instance().GetRenderWindow().isOpen()) will continue to loop as long as the window is open thus can block anything else from updating, such as drawing.
Shouldn't you be drawing playerVisual rather than visual which exists locally inside the Player::Draw() function?
Also shouldn't you call Player::Draw() in GameWindow::Run(), since you call GameWindow::DisplayWindow() which will update the screen. Calling Player::Draw() in Player::Move() limits drawing of the sprite only to when it moves. The results of this would be the sprite existing only in frames in which it moves otherwise an empty canvas.
Related
I'm trying to create a game. I have a class GameObjects that many classes will inherit from. The class GameObject has a draw method that takes the window address to the display. Why does the sprite show up without the texture when displayed like this?
This is the texture, more of a placeholder. I was able to load it in other files directly creating the sprite and drawing it.
Here is my main.cpp
#include <iostream>
#include "Game.h"
int main()
{
//window setup
Game game;
//Initialize game
game.start();
return 0;
}
Here is my Game.h
#pragma once
#include "GameObject.h"
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
class Game
{
private:
//window variables
int w_width;
int w_height;
sf::RenderWindow window;
sf::Event ev;
bool isRunning;
std::vector<GameObject> o_vector;
void initVariables();
void initWindow();
void initObjects();
void drawObjects();
public:
void start();
void run();
void input();
void update();
void render();
};
And Game.cpp
#include "Game.h"
#include "GameObject.h"
void Game::start()
{
this->initVariables();
this->initWindow();
this->initObjects();
this->run();
}
//Initializations
void Game::initVariables()
{
isRunning = true;
//window variables
w_width = 1280;
w_height = 720;
}
void Game::drawObjects()
{
for (int o_count = 0; o_count < o_vector.size(); o_count++)
{
o_vector.at(o_count).draw(window);
}
}
void Game::initWindow()
{
//window creation
window.create(sf::VideoMode(w_width, w_height), "The Dungeon Crawler", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
}
void Game::initObjects()
{
GameObject baseObject;
o_vector.push_back(baseObject);
}
void Game::run()
{
while (isRunning)
{
input();
update();
render();
}
}
void Game::input()
{
while (window.pollEvent(ev))
{
switch (ev.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (ev.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
case sf::Keyboard::A:
break;
}
}
}
}
void Game::update()
{
}
void Game::render()
{
window.clear(sf::Color(0, 0, 128));
drawObjects();
window.display();
}
Here is GameObject.h
#pragma once
#include <vector>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
class GameObject
{
private:
std::string name;
std::vector<int> o_position;
std::vector<int> o_size;
std::string t_path;
sf::Sprite o_sprite;
sf::Texture o_texture;
void initVariables();
public:
//Constructors & Destructors
GameObject();
~GameObject();
//Getters
std::vector<int> getPos();
std::vector<int> getSize();
sf::Sprite getSprite();
//Setters
void setPos(std::vector<int>pos_in);
void setSize(std::vector<int> size_in);
//Graphics
void draw(sf::RenderWindow &displayWindow);
};
And GameObject.cpp
#include "GameObject.h"
GameObject::GameObject()
{
initVariables();
}
GameObject::~GameObject()
{
}
void GameObject::initVariables()
{
o_position = { 0,0 };
o_size = { 64,64 };
t_path = "Resources/EmptySquare.png";
if (!o_texture.loadFromFile(t_path))
{
std::cout << "Failed to load" << std::endl;
return;
}
o_sprite.setTexture(o_texture);
}
std::vector<int> GameObject::getPos()
{
return o_position;
}
std::vector<int> GameObject::getSize()
{
return o_size;
}
sf::Sprite GameObject::getSprite()
{
return o_sprite;
}
void GameObject::setPos(std::vector<int> pos_in)
{
o_position = pos_in;
}
void GameObject::setSize(std::vector<int> size_in)
{
o_size = size_in;
}
void GameObject::draw(sf::RenderWindow &displayWindow)
{
displayWindow.draw(o_sprite);
}
Thank you for any help!
the problem is this line in Game::initObjects()
GameObject baseObject;
o_vector.push_back(baseObject);
you creata a copy of GameObject.
so it will make a copy of o_sprite.
the o_sprite copies the texture pointer.
after this function ends, the texture pointer is no longer valid.
sf::Sprite has the member const Texture* m_texture; and when calling sf::Sprite::setTexture(const Texture& texture) this member m_texture will in fact point to the texture. That texture will be destructed after initObjects() ends, and your element at position 0 will have a o_sprite.m_texture that points to this destructed object. SFML/Sprite.hpp
you could define the correct operator=(GameObject) that implements the correct sprite copy - or in this case simply say:
void Game::initObjects()
{
o_vector.resize(1);
}
resize will call the constructor of GameObject and you will have no copies and therefore dangling pointers.
Another way would be for you to allocate game object on the heap and store a pointer to it in the vector. This way you will avoid the cost of copying.
To make these changes, declare baseObject as private member of Game class and in initObjects method allocate it on the heap.
class Game
{
private:
GameObject *baseObject;
std::vector<GameObject *> o_vector;
};
void Game::initObjects()
{
baseObject = new GameObject;
o_vector.push_back(baseObject);
}
void Game::drawObjects()
{
for (int o_count = 0; o_count < o_vector.size(); o_count++)
{
o_vector.at(o_count)->draw(window); // use -> operator to call draw
}
}
PS: Instead of raw pointer, you can also use C++11 smart pointer.
I want to display my player in the window but my player sprite is not showing in the window. I am new to c++. I want to learn classes, inheritence, composition, etc in this way.I have 3 files Player.cpp, Game.cpp and main.cpp. I am using main.cpp to call Game.cpp using a fuction called Run().
Got nothing to try.
Player.cpp
#include "Player.hpp"
#include "string.h"
#include <iostream>
void Player::initPlayer()
{
const char* playerTexturePath = "/Users/don/Desktop/sfmlgames/game1/img/MCmid.png";
if(!mPlayerTexture.loadFromFile(playerTexturePath))
{
std::cout << "mPlayerTexturePath not found!!" << std::endl;
}
mPlayerSprite.setTexture(mPlayerTexture);
mPlayerSprite.setPosition(100.f, 100.f);
mPlayerSprite.setScale(1.f, 1.f);
}
void Player::draw_player(sf::RenderWindow &win)
{
win.draw(mPlayerSprite);
}
Game.cpp
#include "Game.hpp"
#include <iostream>
Player player1;
//Constructor: Create a window and Player
Game::Game() : mWindow(sf::VideoMode(640, 480), "Game")
{
//Frame rate 60
mWindow.setFramerateLimit(60);
player1.initPlayer();
}
//Game loop
void Game::Run()
{
while(mWindow.isOpen())
{
render();
events();
update();
}
}
void Game::events()
{
sf::Event event;
while (mWindow.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
mWindow.close();
}
}
}
void Game::update()
{
}
void Game::render()
{
mWindow.clear(sf::Color::Red);
player1.draw_player(mWindow);
mWindow.display();
}
main.cpp
#include "Game.hpp"
int main()
{
Game game;
game.Run();
}
I don't think I will need to give code to hpp files.
The problem was with image I dont know why. I used another image and it worked fine.
i'm making a little game just for pratice. I basically want to make my character (a red triangle) move left and right, jump, etc.
The program is still very small at this state, And I wanna know 'how' I should do such things.
I've created a Player Class(QObject, QGraphicsPolygonItem) and a Game Class(QGraphicsView). It worked at first when I gave the Player Class a method for KeyPressEvent, but I had a problem with the jump loop : I wanted to do a scene->update() inside my jump loop, But I couldn't because the scene is an attribute of my Game Class.
Then, I tried giving the Game Class the PressKeyEvent method, so it would move the Player * player attribute.
So basically, what I want is to be able to see the position of my rect update every iteration of my for loop. Can I do that ?
Hope this makes sense, and as always, thanks a lot guys !!
Player.h & Player.cpp
#pragma once
#include <QGraphicsPolygonItem>
#include <QBrush>
class Player :
public QObject, public QGraphicsPolygonItem
{
Q_OBJECT
public:
Player();
// Setters
void setIsJumping(bool);
// Getters
bool getIsJumping();
public slots:
private:
bool isJumping;
};
#include "Player.h"
Player::Player()
{
// ***************
// Draw the player
// ***************
QVector<QPointF> gemPoints;
gemPoints << QPointF(0, 2) << QPointF(1, 0) << QPointF(2, 2);
// Size
int SCALE_BY = 8;
for (size_t i = 0; i < gemPoints.size(); i++)
{
gemPoints[i] *= SCALE_BY;
}
// Create the polygon
QPolygonF gemModel(gemPoints);
setPolygon(gemModel);
setPos(400, 500);
// Color
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::red);
setBrush(brush);
// Make player focusable
this->setFlag(QGraphicsItem::ItemIsFocusable);
this->setFocus();
}
void Player::setIsJumping(bool jump)
{
if (jump == true)
{
isJumping = true;
}
else
{
isJumping = false;
}
}
bool Player::getIsJumping()
{
return isJumping;
}
Game.h & Game.cpp
#pragma once
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QKeyEvent>
#include "Player.h"
class Game :
public QGraphicsView
{
Q_OBJECT
public:
// Constructors
Game(QWidget* parent = NULL);
// Methods
void start();
void jump();
void keyPressEvent(QKeyEvent *event);
// Attributes
QGraphicsScene* scene;
Player* player;
};
#include "Game.h"
Game::Game(QWidget* parent)
{
// Set up the screen
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFixedSize(1024, 768);
// Set up the scene
scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 1024, 768);
setScene(scene);
}
void Game::start()
{
scene->clear();
player = new Player();
scene->addItem(player);
}
void Game::keyPressEvent(QKeyEvent * event)
{
if (event->key() == Qt::Key_Left)
{
player->setPos(x() - 3, y());
}
else if (event->key() == Qt::Key_Right)
{
player->setPos(x() + 3, y());
}
else if (event->key() == Qt::Key_Space)
{
for (size_t i = 0; i < 10; i++)
{
player->setIsJumping(true);
this->jump();
}
}
}
void Game::jump()
{
if (player->getIsJumping() == true)
{
for (size_t i = 0; i < 100; i++)
{
this->player->setPos(x(), y() - 0.1);
this->update();
}
player->setIsJumping(false);
}
}
Main.cpp
#include "plateforme.h"
#include <QtWidgets/QApplication>
#include "Game.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Game game;
game.show();
game.start();
return a.exec();
}
The problem is that I can't move the player correctly now, It moves only once and in a weird way. Any help is appreciated.
The problem is that when you set the position for player, you should modify the coordinates of player and not of this. Therefore, whenever you want to move the player, use:
player->setPos(player->x() - 3, player->y());
^ ^
and the same for jumping in your loop:
player->setPos(player->x(), player->y() - 0.1);
^ ^
When you use setPos(x()-3, y()), it sets the player position to position of your QGraphicsView, that is why it disappears from the view. Good luck with your game!
I'm just playing around with C++ SFML stuff and I kinda don't understand why my code isn't working. The thing I want to do is to draw like let's say 5, squares in Window randomly placed around the screen using vector, but I don't understand why it's not working. And it doesn't give any error as well, I can open game like normal, but it's just not rendering.
This is the main game class:
#include "main_game.h"
#include "main_menu.h"
void main_game::Initialize(sf::RenderWindow* window)
{
this->Player = new player();
this->Player->setOrigin(this->Player->getGlobalBounds().width / 2, this->Player->getGlobalBounds().height / 2);
this->TestObject = new testObject();
this->TestObject->Initialize();
this->TestObject->setOrigin(this->TestObject->getGlobalBounds().width / 2, this->TestObject->getGlobalBounds().height / 2);
}
void main_game::Update(sf::RenderWindow* window)
{
this->Player->setPosition(sf::Mouse::getPosition(*window).x, sf::Mouse::getPosition(*window).y);
this->Player->Update();
if (this->Player->CheckCollision(TestObject))
{
this->TestObject->setColor(sf::Color::Red);
}
else
{
this->TestObject->setColor(sf::Color::Cyan);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape))
{
coreState.SetState(new main_menu());
}
}
void main_game::Render(sf::RenderWindow* window, std::vector<sf::Sprite> sprites)
{
this->TestObject->Render(*window, sprites);
window->draw(*this->Player);
}
void main_game::Destroy(sf::RenderWindow* window)
{
delete this->Player;
delete this->TestObject;
}
This is the testObject.h class
#pragma once
#include "entity.h"
class testObject : public Entity
{
public:
testObject();
void Initialize();
void Render(sf::RenderWindow &window, std::vector<sf::Sprite> sprites);
void Update();
private:
sf::RenderWindow window;
};
And this is testObject.cpp class
#include "testObject.h"
testObject::testObject()
{
this->Load("testObject.png");
}
void testObject::Initialize()
{
sf::Texture testObjectTexture;
sf::Sprite testObjectSprite;
testObjectTexture.loadFromFile("testObject.png");
testObjectSprite.setTexture(testObjectTexture);
std::vector<sf::Sprite> sprites(5, sf::Sprite(testObjectSprite));
srand(time(0));
for (unsigned int i = 0; i < sprites.size(); i++)
{
sprites[i].setPosition(1 + (rand() % 1024 - 32), rand() % 640 - 32);
}
}
void testObject::Render(sf::RenderWindow &window, std::vector<sf::Sprite> sprites)
{
for (unsigned int i = 0; i < sprites.size(); i++)
{
window.draw(sprites[i]);
}
}
void testObject::Update()
{
Entity::Update();
}
main_game.h:
#pragma once
#include "game_state.h"
#include "player.h"
#include "testObject.h"
class main_game : public tiny_state
{
public:
void Initialize(sf::RenderWindow* window);
void Update(sf::RenderWindow* window);
void Render(sf::RenderWindow* window, std::vector<sf::Sprite> sprites);
void Destroy(sf::RenderWindow* window);
private:
player* Player;
testObject* TestObject;
};
An easy fix to this is simply use an array, or any other data structure that can store by copy rather than store by reference instead of a vector, which stores by reference, to hold the sprites.
The problem is two fold, its not just a scope issue, if you moved the render function into the initialize scope, you will draw your sprite 5 times in the same place, because every element in your vector is pointing to testObjectSprite's memory location (the same place).
I've been trying to make a sprite display in C++ SFML but with the use of classes. However, when I compile and run the program, nothing appears: there are no errors either.
(The only thing that happens in main is that a 'Game' object is created)
Game.h
#ifndef GAME_H
#define GAME_H
#include <SFML/Graphics.hpp>
#include "Player.h"
class Game
{
public:
Game();
private:
//Variables
sf::RenderWindow _mainWindow;
enum _gameState { Playing, Paused, Splash, Menu };
//Methods
void gameLoop();
};
#endif // GAME_H
Game.cpp
#include "Game.h"
#include "Player.h"
Game::Game() {
//Variables
_mainWindow.create(sf::VideoMode(960, 640), "Game", sf::Style::Titlebar | sf::Style::Close);
_mainWindow.setFramerateLimit(60);
//Start Game Loop
gameLoop();
}
void Game::gameLoop() {
Player player;
while(_mainWindow.isOpen()) {
sf::Event ev;
while(_mainWindow.pollEvent(ev)) {
if(ev.type == sf::Event::Closed)
_mainWindow.close();
if(ev.type == sf::Event::KeyPressed) {
if(ev.key.code == sf::Keyboard::Escape)
_mainWindow.close();
}
}
//Draw Stuff
_mainWindow.clear(sf::Color::White);
player.drawSprite(_mainWindow);
_mainWindow.display();
}
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <iostream>
class Player
{
public:
Player();
void drawSprite(sf::RenderWindow& window);
private:
bool loadSprite();
sf::Texture _playerTexture;
sf::Sprite _playerSprite;
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
#include "Game.h"
Player::Player()
{
if(!Player::loadSprite()){
return;
}
}
bool Player::loadSprite() {
sf::Texture _playerTexture;
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
return true;
}
void Player::drawSprite(sf::RenderWindow& window) {
//sprite.setTextureRect(sf::IntRect(10, 10, 32, 32));
window.draw(_playerSprite);
std::cout << "Sprite Drawn Successfully" << std::endl;
}
You are declaring a new, local _playerSprite here:
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
instead, use the existing class member:
} else {
_playerSprite.setTexture(_playerTexture);
}
You may want to drop the first line from this code as well, same issue:
bool Player::loadSprite()
{
sf::Texture _playerTexture; // <--- local redeclaration
From my memories: the texture must be a member of your class; it must exist while you are using it. In your code, _playerTexture is destroyed at the end of loadSprite(). Same problem for _playerSprite.
Edit:
You don't have to re-declare the member of your class in your methods :
bool Player::loadSprite() {
sf::Texture _playerTexture;
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
return true;
}
Should be:
bool Player::loadSprite() {
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
_playerSprite.setTexture(_playerTexture);
}
return true;
}
(PS: Your code doesn't respect the SRP (Single Responsability Principle), Player doesn't have to display itself.)
you are drawing but not displaying the sprite for that do this
void Player::drawSprite(sf::RenderWindow& window) {
//sprite.setTextureRect(sf::IntRect(10, 10, 32, 32));
window.draw(_playerSprite);
std::cout << "Sprite Drawn Successfully" << std::endl;
//this is the display function
window.display()
}