1
Graphics / sf::setTextureRect Not Working As Expected?
« on: September 29, 2022, 10:18:27 am »
This is a problem that I've been troubleshooting for a full week & it's making me lose my mind. And the problem? Let me explain:
Whenever I set my sprite's texture rect, it just gives me a white square instead of the texture file cropped. And if you're asking if my file exists & if I set the correct directory for it, I'm 100% sure it is as it loads whenever I remove the "sf::setTextureRect" code. I've read others' problems here in the SFML Forums as well as in the subreddit and applied to my code, but none of them worked.
Here are the code files:
game.h (where I load everything):
game.cpp (where I handle everything):
player.h (of course the player itself):
player.cpp:
Although it WORKS whenever I put sf::IntRect inside this->sprite.loadTextureFile() in player.cpp, but that's not what I want because my goal here is to make a spritesheet animation..
I need an answer asap, as well as an explanation so I can troubleshoot all of this by myself in the future. Again, this has already wasted me a full week & I'm getting frustrated the more time flies .
Whenever I set my sprite's texture rect, it just gives me a white square instead of the texture file cropped. And if you're asking if my file exists & if I set the correct directory for it, I'm 100% sure it is as it loads whenever I remove the "sf::setTextureRect" code. I've read others' problems here in the SFML Forums as well as in the subreddit and applied to my code, but none of them worked.
Here are the code files:
game.h (where I load everything):
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <cmath>
#include "player.hpp"
class Game {
private:
// Window Specifications
sf::RenderWindow* window;
sf::VideoMode videoMode;
// Window Event Handler
sf::Event event;
// The Player Itself
Player* player;
// Private Functions
void initWindow();
void initPlayer();
public:
// Constructor & Destructor
Game();
virtual ~Game();
// Accessor
const bool isRunning() const;
// Game Functions
void pollEvents();
void update();
void render();
};
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <cmath>
#include "player.hpp"
class Game {
private:
// Window Specifications
sf::RenderWindow* window;
sf::VideoMode videoMode;
// Window Event Handler
sf::Event event;
// The Player Itself
Player* player;
// Private Functions
void initWindow();
void initPlayer();
public:
// Constructor & Destructor
Game();
virtual ~Game();
// Accessor
const bool isRunning() const;
// Game Functions
void pollEvents();
void update();
void render();
};
game.cpp (where I handle everything):
#include "game.hpp"
//////////////////////////////// GAME WINDOW SPECIFICATIONS ////////////////////////////////
// Private Game Window Function
void Game::initWindow() {
this->videoMode.width = 800;
this->videoMode.height = 600;
this->window = new sf::RenderWindow(this->videoMode, "SFML Game Sample", sf::Style::Titlebar | sf::Style::Close);
this->window->setFramerateLimit(120);
this->window->setKeyRepeatEnabled(false);
this->window->setVerticalSyncEnabled(false);
}
////////////////////////////////////////////////////////////////////////////////////////////
void Game::initPlayer() {
this->player = new Player();
}
// Game Constructor
Game::Game() {
this->initWindow();
this->initPlayer();
}
// Game Destructor
Game::~Game() {
delete this->window;
delete this->player;
}
// Game Accessor
const bool Game::isRunning() const {
return this->window->isOpen();
}
//////////////////// While-Loop Event to Keep the Game Window Running ////////////////////
void Game::pollEvents() {
while (this->window->pollEvent(this->event)) {
switch (this->event.type) {
case sf::Event::Closed:
this->window->close();
break;
case sf::Event::KeyPressed:
if (this->event.key.code == sf::Keyboard::Escape)
this->window->close();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Game Functions
void Game::update() {
// Call The Poll Event to Update Game
this->pollEvents();
}
void Game::render() {
// Clears Each Frame
this->window->clear(sf::Color(125, 125, 125, 255));
// Render Player
this->player->render(*this->window);
// Displays Frame in Game Window
this->window->display();
}
//////////////////////////////// GAME WINDOW SPECIFICATIONS ////////////////////////////////
// Private Game Window Function
void Game::initWindow() {
this->videoMode.width = 800;
this->videoMode.height = 600;
this->window = new sf::RenderWindow(this->videoMode, "SFML Game Sample", sf::Style::Titlebar | sf::Style::Close);
this->window->setFramerateLimit(120);
this->window->setKeyRepeatEnabled(false);
this->window->setVerticalSyncEnabled(false);
}
////////////////////////////////////////////////////////////////////////////////////////////
void Game::initPlayer() {
this->player = new Player();
}
// Game Constructor
Game::Game() {
this->initWindow();
this->initPlayer();
}
// Game Destructor
Game::~Game() {
delete this->window;
delete this->player;
}
// Game Accessor
const bool Game::isRunning() const {
return this->window->isOpen();
}
//////////////////// While-Loop Event to Keep the Game Window Running ////////////////////
void Game::pollEvents() {
while (this->window->pollEvent(this->event)) {
switch (this->event.type) {
case sf::Event::Closed:
this->window->close();
break;
case sf::Event::KeyPressed:
if (this->event.key.code == sf::Keyboard::Escape)
this->window->close();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Game Functions
void Game::update() {
// Call The Poll Event to Update Game
this->pollEvents();
}
void Game::render() {
// Clears Each Frame
this->window->clear(sf::Color(125, 125, 125, 255));
// Render Player
this->player->render(*this->window);
// Displays Frame in Game Window
this->window->display();
}
player.h (of course the player itself):
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <cmath>
class Player {
private:
friend int main();
// Private Player Variables
sf::Sprite sprite;
sf::Texture texture;
sf::IntRect currentFrame;
// Private Player Functions
void initTexture();
void initSprite();
public:
// Constructor & Destructor
Player();
virtual ~Player();
// Player Functions
void update();
void render(sf::RenderTarget & rt);
};
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <cmath>
class Player {
private:
friend int main();
// Private Player Variables
sf::Sprite sprite;
sf::Texture texture;
sf::IntRect currentFrame;
// Private Player Functions
void initTexture();
void initSprite();
public:
// Constructor & Destructor
Player();
virtual ~Player();
// Player Functions
void update();
void render(sf::RenderTarget & rt);
};
player.cpp:
#include "player.hpp"
void Player::initTexture() {
// Load The Texture File
if(!this->sprite.setTexture(this->texture)) {
this->texture.loadFromFile("Textures/spring.png");
}
}
void Player::initSprite() {
// Set a Texture to The Sprite
std::cout << "ERROR: Could Not Load Texture File.\n";
// Crops The Spritesheet The Way I Want it
this->currentFrame = sf::IntRect(2, 2, 120, 120); // THIS IS THE
this->sprite.setTextureRect(this->currentFrame); // PROBLEM !!!
// Set Sprite Position
this->sprite.setOrigin(sf::Vector2f(sprite.getLocalBounds().width, sprite.getLocalBounds().height) / 2.f);
this->sprite.setPosition(300.f, 300.f);
// Resize The Sprite
this->sprite.setScale(sf::Vector2f(1.5f, 1.5f));
}
// Constructor
Player::Player() {
this->initTexture();
this->initSprite();
}
// Destructor
Player::~Player() {
}
void Player::update() {
// still empty for now.
}
void Player::render(sf::RenderTarget & rt) {
rt.draw(this->sprite);
}
void Player::initTexture() {
// Load The Texture File
if(!this->sprite.setTexture(this->texture)) {
this->texture.loadFromFile("Textures/spring.png");
}
}
void Player::initSprite() {
// Set a Texture to The Sprite
std::cout << "ERROR: Could Not Load Texture File.\n";
// Crops The Spritesheet The Way I Want it
this->currentFrame = sf::IntRect(2, 2, 120, 120); // THIS IS THE
this->sprite.setTextureRect(this->currentFrame); // PROBLEM !!!
// Set Sprite Position
this->sprite.setOrigin(sf::Vector2f(sprite.getLocalBounds().width, sprite.getLocalBounds().height) / 2.f);
this->sprite.setPosition(300.f, 300.f);
// Resize The Sprite
this->sprite.setScale(sf::Vector2f(1.5f, 1.5f));
}
// Constructor
Player::Player() {
this->initTexture();
this->initSprite();
}
// Destructor
Player::~Player() {
}
void Player::update() {
// still empty for now.
}
void Player::render(sf::RenderTarget & rt) {
rt.draw(this->sprite);
}
Although it WORKS whenever I put sf::IntRect inside this->sprite.loadTextureFile() in player.cpp, but that's not what I want because my goal here is to make a spritesheet animation..
I need an answer asap, as well as an explanation so I can troubleshoot all of this by myself in the future. Again, this has already wasted me a full week & I'm getting frustrated the more time flies .