My array of sprites is not getting drawn on my renderwindow - c++

So I am trying to make a chessgame, and of course I am starting out with just making the board. For this I am creating a two-dimensional array like 8x8. Each tile has their own object sprite called tileSprite and I am trying to define them as 1/8th of the width and height of the screen, which has a fixed size of 1024x768. The textures that are loaded in are just 1 pixel black or white. The program gives no definitive error, but the drawn tiles aren't getting displayed onto my window, and all I see is a red screen, which I get from clearing the screen (following the standard clear/draw/display cycle of SFML).
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
#include "SFML/Audio.hpp"
#include <iostream>
#include <vector>
#include <array>
bool playing = true;
class Textures {
public:
static void loadTextures();
sf::Texture static blackTile;
sf::Texture static whiteTile;
};
/*---Class--Definitions----*/
sf::Texture Textures::blackTile;
sf::Texture Textures::whiteTile;
/*-------------------------*/
void Textures::loadTextures() {
if (blackTile.loadFromFile("Images/blackTile.PNG")) {
return;
}
else if (whiteTile.loadFromFile("Images/whiteTile.PNG")) {
return;
}
}
class ChessBoard_Tiles {
public:
static void _initialize();
static void draw(sf::RenderWindow& window);
enum TileStatus { EMPTY, OCCUPIED, HIGHLIGHTED };
struct TileSlot {
sf::Sprite tileSprite;
TileStatus tileStatus;
};
private:
typedef std::array< std::array<TileSlot*, 8>, 8 > TileType;
static TileType tileBoard;
};
/*-Class Definition that has to be called-*/
ChessBoard_Tiles::TileType ChessBoard_Tiles::tileBoard = ChessBoard_Tiles::TileType();
void ChessBoard_Tiles::_initialize() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
tileBoard[i][j] = new TileSlot();
if ((i + j) % 2 == 0) {
tileBoard[i][j]->tileSprite.setTexture(Textures::whiteTile);
}
else {
tileBoard[i][j]->tileSprite.setTexture(Textures::blackTile);
}
tileBoard[i][j]->tileSprite.setPosition(128 * j, 96 * i);
tileBoard[i][j]->tileSprite.setScale(128, 96);
tileBoard[i][j]->tileStatus = EMPTY;
}
}
}
void ChessBoard_Tiles::draw(sf::RenderWindow& window) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
window.draw(tileBoard[i][j]->tileSprite);
}
}
}
int main(int argc, char* argv[]) {
sf::RenderWindow renderWindow;
renderWindow.create(sf::VideoMode(1024, 768), "Chess");
Textures::loadTextures();
ChessBoard_Tiles::_initialize();
while (playing) {
sf::Event currentEvent;
renderWindow.pollEvent(currentEvent);
if (currentEvent.type == sf::Event::Closed) {
renderWindow.close();
playing = false;
}
if (currentEvent.type == sf::Event::KeyPressed) {
if (currentEvent.key.code == sf::Keyboard::Escape) {
renderWindow.close();
playing = false;
}
}
renderWindow.clear(sf::Color::Red);
std::cout << "Clear\n";
ChessBoard_Tiles::draw(renderWindow);
std::cout << "Draw\n";
renderWindow.display();
std::cout << "Display\n";
}
return 0;
}
If anyone knows what is wrong then that would be a big help for me.. Otherwise I'd probably have to entirely remake this program, which I think should work so far, but I haven't the slightest idea why it doesn't. Big thanks in advance =)
EDIT: Read a little about how the sprites seem to disappear if the textures are running out of scope.. If this is the case, could that just be pointed out and then I can work on that, because I have tried so many different things by now that I feel like I'm just going in circles?

The fault was from the loadTextures() function, where I had forgotten to include the file extension of the file to be loaded, and I screwed the logic about the loadFromFile() function up so the program only continued when it couldn't load the file..

Related

Dragging a sprite in sfml

I'm doing an assignment at the moment and for it, I need to drag chess pieces on a board, the problem is that I have no idea how to make this work for more than one piece. I can compute the mouse position and I've been able to move just one piece but the code only works for that single piece. My question is how do I click on a piece, have it become the active piece until I release the mouse button. This won't work if I only check if it intersects with one piece because it isn't dynamic then. My code is a mess from me trying different things but here are some of the relevant parts.
Here is the setup for the sprites:
// load the texture and setup the sprite for the logo
void Game::setupSprite()
{
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
if (!m_boardTexture.loadFromFile("ASSETS\\IMAGES\\board.png"))
{
// simple error message if previous call fails
std::cout << "problem loading board" << std::endl;
}
m_boardSprite.setTexture(m_boardTexture);
m_boardSprite.setPosition(0.0f, 0.0f);
//pieces
if (!m_wkingTex.loadFromFile("ASSETS\\IMAGES\\PIECES\\wking.png"))
{
// simple error message if previous call fails
std::cout << "problem loading piece" << std::endl;
}
m_wking.setTexture(m_wkingTex);
m_wking.setPosition(0.0f, 0.0f);
sf::IntRect wkingRect(pieceRect);
}
If the mouse button is down
void Game::processMouseButtonDown(sf::Event t_event)
{
if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
std::cout << "Mouse button pressed\n";
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
if (isSpriteClicked() && !m_holdingPiece) {
m_holdingPiece = true;
}
}
}
Mouse button is up:
void Game::processMouseButtonUp(sf::Event t_event)
{
m_holdingPiece = false;
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
m_wking.setTextureRect(pieceRect);
}
If the sprite is clicked
bool Game::isSpriteClicked()
{
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
sf::FloatRect bounds(mouse.x, mouse.y, 1.0f, 1.0f);
if (bounds.intersects(wkingRect.I dont know what Im doing)) {
std::cout << "King has Been clicked!\n";
return true;
}
else {
return false;
}
}
And finally to move the sprite:
void Game::move()
{
if (m_holdingPiece) {
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
m_wking.setPosition(mouse);
}
}
Sorry if that seems like a lot of code, but I feel like it was all relevant to the problem.
Problem:
You have hardcoded all your variables so even if you create a list and iterate over it to run Game::move() it will move all the pieces instead of only one because the variable m_holdingPiece is the same for all pieces.
Solution:
You should use a more OOP aproach creating a class for the chess pieces while the Game class should probably just control when the game starts, when it ends and check whether moves are legal or not. Explaning all that would be too broad Stack Overflow and it's part of the work you must do, so I will just let an example of how a basic chessPiece class would be to make pieces dragabble.
Example:
Here is an example of how you can make a group of pieces draggable.
#include <SFML/Graphics.hpp>
#include <string>
class chessPiece: public sf::Drawable, public sf::Transformable
{
private:
sf::RenderWindow& window;
sf::Texture texture;
sf::Sprite sprite;
bool moving;
public:
chessPiece(sf::RenderWindow& windowRef, const std::string& fileName): window(windowRef)
{
if(!texture.loadFromFile(fileName))
exit(0);
this->sprite.setTexture(this->texture);
this->moving = false;
this->sprite.setScale(128/this->sprite.getGlobalBounds().width,128/this->sprite.getGlobalBounds().height);
}
chessPiece(chessPiece&& rval): window(rval.window)
{
this->texture = std::move(rval.texture);
this->sprite.setTexture(this->texture);
this->sprite.setScale(rval.sprite.getScale());
this->moving = std::move(rval.moving);
}
chessPiece(const chessPiece& lval): window(lval.window)
{
this->texture = lval.texture;
this->sprite.setTexture(this->texture);
this->sprite.setScale(lval.sprite.getScale());
this->moving = lval.moving;
}
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= this->getTransform();
target.draw(this->sprite,states);
}
void move(bool& movingAPiece)
{
sf::Vector2f mousePosition = window.mapPixelToCoords(sf::Mouse::getPosition(window));
if(this->moving)
{
this->setPosition(mousePosition.x - this->sprite.getGlobalBounds().width/2,mousePosition.y - this->sprite.getGlobalBounds().height/2);
if(!sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
{
this->moving = false;
movingAPiece = false;
}
}
else
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && mousePosition.x > this->getPosition().x &&
mousePosition.y > this->getPosition().y && mousePosition.x < this->getPosition().x + this->sprite.getGlobalBounds().width &&
mousePosition.y < this->getPosition().y + this->sprite.getGlobalBounds().height && !movingAPiece)
{
this->moving = true;
movingAPiece = true;
}
}
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(1000,500),"Window");
std::vector<chessPiece> pieces = {chessPiece(window,"white-king.png"),chessPiece(window,"white-pawn.png")};
pieces[0].setPosition(400,400);
bool movingAPiece = false;
while(true)
{
sf::Event event;
if(window.pollEvent(event))
if(event.type == sf::Event::Closed)
window.close();
for(unsigned int i = 0; i < pieces.size(); i++)
pieces[i].move(movingAPiece);
window.clear();
for(unsigned int i = 0; i < pieces.size(); i++)
window.draw(pieces[i]);
window.display();
}
}

How can I declare a SFML window to all my class functions?

This might be a noob question, but I'm trying to make a simple player move in a 2D-grid in SFML. I'm creating a while loop for rendering what is happening, and I can get it to work, but I want to use classes for the grid and players etc. The problem is that when I create a window called 'window', I don't know how to implement classes since these don't know what the 'window' is. I hope I have described my problem sufficiently, and I would like any respons on how to make this work or if my method of doing it is already bad and should be changed for another method. Here is a snippet of my code for the class and the undeclared window error.
class myEvents {
public:
//Variables
int tSize = 40;
int tileCount = 20;
int width = tileCount * tSize;
int height = tileCount * tSize;
//Function to create a grid with RectangleShapes
void grid() {
for (int i = 0; i < tileCount; i++)
{
for (int j = 0; j < tileCount; j++)
{
sf::RectangleShape tile(sf::Vector2f(40, 40));
tile.setFillColor(sf::Color::Magenta);
tile.setPosition(i*tSize, j*tSize);
window.draw(tile); //Problem occurs here, 'window' is not declared, it is in the next function
//window.draw(tile); must execute in the loop to render a full grid
}
}
}
//Includes while loop for rendering and events. Could be written without class, but I'd still like a class for the grid and later on a player.
//So I need the window to work with my classes.
void loop() {
sf::RenderWindow window(sf::VideoMode(width, height), "Game"); //'window' declared here. Can I move this statement
//somewhere so that my funcions know where it comes from?
while (window.isOpen) {
sf::Event event;
while (window.pollEvent(e))
{
//to be further developed
}
}
}
};
Try making the window a class member:
class myEvents {
public:
//Variables
int tSize = 40;
int tileCount = 20;
int width = tileCount * tSize;
int height = tileCount * tSize;
sf::RenderWindow window{sf::VideoMode(width, height), "Game"};
void grid() {
for (int i = 0; i < tileCount; i++)
{
for (int j = 0; j < tileCount; j++)
{
sf::RectangleShape tile(sf::Vector2f(40, 40));
tile.setFillColor(sf::Color::Magenta);
tile.setPosition(i*tSize, j*tSize);
window.draw(tile);
}
}
}
void loop() {
while (window.isOpen) {
sf::Event event;
while (window.pollEvent(e))
{
//to be further developed
}
}
}
};
Alternatively, pass the window around:
class myEvents {
public:
//Variables
int tSize = 40;
int tileCount = 20;
int width = tileCount * tSize;
int height = tileCount * tSize;
void grid(sf::RenderWindow& window) {
for (int i = 0; i < tileCount; i++)
{
for (int j = 0; j < tileCount; j++)
{
sf::RectangleShape tile(sf::Vector2f(40, 40));
tile.setFillColor(sf::Color::Magenta);
tile.setPosition(i*tSize, j*tSize);
window.draw(tile);
}
}
}
void loop() {
sf::RenderWindow window{sf::VideoMode(width, height), "Game"};
while (window.isOpen) {
sf::Event event;
while (window.pollEvent(e))
{
//to be further developed
// call grid(window)
}
}
}
};
Well an easy thing for the window you can do is to create a class and
add the window in it, then include the .h where the class is as you've set the sf::window in the public section. Now I will show you how you can use it
we've got an .h file named window.h (you can name it whatever is comfortable for you)
#include <SFML/Grpahics.hpp>
class window
{
public:
sf::RenderWindow window;
}
and you have the main.cpp(or whatever file you want)
#include "window.h"
window w;
int main()
{
w.window.create(sf::VideoMode(800,600),"Title");
}
the int main() can be whatever function you want it just has to be
called as soon as possible so the window will show.
I hope this helps you with your problem =)
[EDID]:
As the "sf::RenderWindow window" is public every file that has the header with the public "sf::RenderWindow window" can use the window as it is not private. I think you know that but in any case to add it.

THREAD 1 :EXC_BAD_ACCESS error, this error appears at the handle function in the cpp file at the first line

this is a code that creates a chicken invaders game, the game(or whatever part i can do of the game) worked fine when i was just initializing one chicken, but when i made it a 2d array of chickens it showed me this error.
RenderWindow window;
int main(int, char const**)
{
chicken chick[4][7];
Sprite back;
Clock clock;
window.create(VideoMode(1800, 1000), "Menu");
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::KeyPressed && event.key.code == Keyboard::Escape)
window.close();
if (event.type == Event::Closed)
window.close();
}
Texture texture;
if (!texture.loadFromFile(resourcePath() + "background.jpg"))
{
std::cout << "Error loading texture" << std::endl;
}
Time time;
time = clock.getElapsedTime();
if (time.asSeconds() >= 0.001)
{
chick[4][7].handle(window, clock);
clock.restart();
}
window.clear();
back.setTexture(texture);
back.setPosition(0, 0);
back.setTextureRect(IntRect(0, 0, 1800, 1000));
window.draw(back);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 7; j++)
chick[i][j].initialize(window);
window.display();
}
}
///////////////////
this is the app file for the chicken class
using namespace sf;
class chicken
{
private:
RectangleShape chick;
bool flag;
public:
chicken();
void initialize(RenderWindow &window);
void handle(RenderWindow & window, Clock clock);
~chicken();
};
#endif /* chicken_hpp */
/////////////////////////////////////////////////////////////
this is the cpp file for the chicken class
using namespace sf;
chicken::chicken()
{
chick.setPosition(500, 500);
chick.setSize(Vector2f(200, 200));
chick.setOrigin(100, 100);
flag = true;
}
void chicken::initialize(RenderWindow & window)
{
Texture texture2;
if (!texture2.loadFromFile(resourcePath() + "chicken3.jpg"))
{
std::cout << "Error loading texture" << std::endl;
}
chick.setTexture(&texture2);
window.draw(chick);
}
void chicken::handle(RenderWindow & window, Clock clock)
{
if (flag) //the error appears here
{
chick.move( 10 , 0 ) ;
}
else
{
chick.move(-10 , 0);
}
if (chick.getPosition().x >= window.getSize().x)
flag = false;
if(chick.getPosition().x < 0)
flag = true;
}
chicken::~chicken()
{
}
In the future please include the entire error message in your question, however the issue here is you are accessing an out of bounds index in your chicken array.
your array size is 4x7 this means your valid indices are 0 - 3 and 0 - 6.
Your handle function is being called on chick[4][7], which is out of bounds.
If you are trying to call that function on only the last chick in the array it would be
chick[3][6].handle(window, clock);
to call it on every chicken you need a double for loop like
for(int i = 0; i < 4; ++i)
{
for(int j = 0; j < 7; ++j)
{
chick[i][j].handle(window, clock);
}
}

Unhandled exception error Visual Studio 2012 and Allegro 4

I´m using allegro 4.4.2 on Visual Studio 2012 for a school project. Allegro is installed and working, and I'm trying to get it to load a map.txt file which is located in the project folder. When debugging, allegro freezes and becomes incredibly slow and throws an unhandled exception, violation access code at me.
This is Map.h:
#include <allegro.h>
#include "Global.h"
#include <fstream>
using namespace std;
class Map
{
public:
Map();
~Map();
void Init();
void Update();
void Draw(BITMAP *Buffer);
void LoadMap (const char*filename);
private:
int loadCounterX;
int loadCounterY;
int mapSizeX;
int mapSizeY;
int MapFile[20][15];
};
And this is Map.cpp:
#include "Map.h"
Map::Map()
{
}
Map::~Map()
{
}
void Map::Init()
{
loadCounterX = loadCounterY = 0;
Map::LoadMap("map1.txt");
}
void Map::Update()
{
}
void Map::Draw(BITMAP *Buffer)
{
for (int i = 0; 1 < mapSizeX; i++)
{
for (int j = 0; j < mapSizeY; j++)
{
if (MapFile[i][j] == 1)
{
rectfill(Buffer, i*BlockSize, j*BlockSize, i*BlockSize + BlockSize, j*BlockSize + BlockSize, makecol(0, 255, 255));
}
else if (MapFile[i][j] == 2)
{
rectfill(Buffer, i*BlockSize, j*BlockSize, i*BlockSize + BlockSize, j*BlockSize + BlockSize, makecol(0, 255, 0));
}
}
}
}
void Map::LoadMap(const char*filename)
{
ifstream openfile (filename);
if (openfile.is_open())
{
openfile >> mapSizeX >> mapSizeY;
while (!openfile.eof())
{
openfile >> MapFile[loadCounterX][loadCounterY];
loadCounterX ++;
if (loadCounterX >= mapSizeX)
{
loadCounterX = 0;
loadCounterY ++;
}
}
loadCounterX = loadCounterY = 0;
} //File is opened
else
{
allegro_message ("Map File couldn't be found");
}
}
and here is my main file:
#include <allegro.h>
#include "Player.h"
#include "Global.h"
#include "Camera.h"
#include "Map.h"
using namespace std;
volatile int counter = 0;
void Increment ()
{
counter ++;
}
int main (void)
{
allegro_init();
install_keyboard();
install_mouse();
install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, "A");
set_color_depth(32);
set_gfx_mode (GFX_AUTODETECT_WINDOWED, ScreenWidth, ScreenHeight, 0, 0);
LOCK_VARIABLE (counter);
LOCK_FUNCTION (Increment);
install_int_ex (Increment, BPS_TO_TIMER(100));
BITMAP *Buffer = create_bitmap (6000, ScreenHeight);
bool done = false;
Player player;
Camera camera;
Map map;
player.Init();
camera.Init();
map.Init();
while (!done)
{
while (counter > 0)
{
//Input
if (key[KEY_ESC])
done = true;
//Update
map.Update();
player.Update();
camera.Update(player.x, player.y);
counter --;
}
//Draw
map.Draw(Buffer);
player.Draw(Buffer);
camera.Draw(Buffer);
clear_bitmap(Buffer);
}
return 0;
}
END_OF_MAIN();
It crashes at this line
if (MapFile[i][j] == 1)
everytime. All of the variables shown in "Autos" in Visual Studio turn red; "MapFile" "MapFile[i]" (which I don't understand.. shouldn't this just be "i"?) "j" "mapSizeY" and "this" However when I expand the "MapFile", the first 20 blocks are filled out correctly as they are in my map.txt file.
I'm completely lost and have no idea what to do... any help is greatly appreciated!
In void Map::Draw(BITMAP *Buffer) you use 1 < mapSizeX instead of i < mapSizeX.
You might also want to prevent calling Map::Draw when the Map::LoadMap wasn't called before.

X in namespace 'sf' does not name a type [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am working with SFML1.6 to produce a graphical app (a game). It was working fine when I only had one file beyond the Main file. Now I added a new file, Level, and I get these errors:
C:\Users\...\Window.hpp|6|error: 'RenderWindow' in namespace 'sf' does not name a type|
C:\Users\...\Window.hpp|7|error: 'Image' in namespace 'sf' does not name a type|
C:\Users\...\Window.hpp|8|error: 'Sprite' in namespace 'sf' does not name a type|
C:\Users\...\Window.hpp|9|error: 'Color' in namespace 'sf' does not name a type|
Since it was working fine, I suppose it is due to the new file:
Level.cpp
#include <SFML/Window.hpp>
#include <iostream>
#include "Window.hpp"
class Level
{
sf::Window* pResultScreen;
public:
Level( sf::Window& );
};
Level::Level( sf::Window &app)
{
pResultScreen = &app;
};
Level.hpp
#ifndef Level_hpp
#define Level_hpp
class Level
{
sf::Window* pResultScreen;
public:
Level( sf::Window& );
};
#endif
Does anyone see a problem with the above code?
EDIT:
Window.cpp
class Window
{
sf::RenderWindow appWindow;
sf::Image charImage;
sf::Sprite charSpriteSheet;
sf::Color deleteColor;
bool keyPressed;
int curFrame;
int stateChar;
int timerFrame;
int flipChar;
public:
Window();
int Loop();
void SheetCutter(int); // Prepares tiles
void Animate(int); // Loop through animations
void ColourCleaner(); // Remove the sprite's color.
};
Window::Window()
{
stateChar = 0;
curFrame = 0;
flipChar = 1;
deleteColor.a = 255;
deleteColor.r = 255;
deleteColor.g = 47;
deleteColor.b = 198;
appWindow.Create(sf::VideoMode( 800, 600, 32), "AI_Fighter");
appWindow.SetFramerateLimit(30);
if( !charImage.LoadFromFile("Bass.png") )
{
std::cout << "Problem opening file 'Bass.png'";
}
charImage.SetSmooth(false);
ColourCleaner();
charSpriteSheet.SetImage(charImage);
SheetCutter(curFrame); // This allows it to not show the entire tile set at the beginning.
};
int Window::Loop()
{
// Start game loop
while (appWindow.IsOpened())
{
sf::Event evt;
while (appWindow.GetEvent(evt))
{
// Window closed
if (evt.Type == sf::Event::Closed)
appWindow.Close();
// Escape key pressed
if ((evt.Type == sf::Event::KeyPressed) && (evt.Key.Code == sf::Key::Escape))
appWindow.Close();
if (evt.Type == sf::Event::KeyPressed)
keyPressed = true;
else
keyPressed = false;
}
// Get elapsed time
float ElapsedTime = appWindow.GetFrameTime();
// Move the sprite
if ( appWindow.GetInput().IsKeyDown(sf::Key::Left) || appWindow.GetInput().IsKeyDown(sf::Key::Right) || appWindow.GetInput().IsKeyDown(sf::Key::Up) || appWindow.GetInput().IsKeyDown(sf::Key::Down) )
{
if (appWindow.GetInput().IsKeyDown(sf::Key::Left))
{
charSpriteSheet.Move(-100 * ElapsedTime, 0);
stateChar = 1;
flipChar = 0;
Animate(6);
}
if (appWindow.GetInput().IsKeyDown(sf::Key::Right))
{
charSpriteSheet.Move( 100 * ElapsedTime, 0);
stateChar = 1;
flipChar = 1;
Animate(6);
}
if (appWindow.GetInput().IsKeyDown(sf::Key::Up))
{
charSpriteSheet.Move(0, -100 * ElapsedTime);
stateChar = 2;
Animate(6);
}
if (appWindow.GetInput().IsKeyDown(sf::Key::Down)) charSpriteSheet.Move(0, 100 * ElapsedTime);
}
else
{
stateChar = 0;
Animate(12);
}
// Clear the screen (fill it with black color)
appWindow.Clear(sf::Color( 0, 0, 0));
appWindow.Draw(charSpriteSheet);
// Display window contents on screen
appWindow.Display();
}
return 0;
};
void Window::SheetCutter(int offset)
{
charSpriteSheet.SetSubRect(sf::IntRect((offset * 26), 0, ((offset * 26) + 26), 35));
};
// This changes the curFrame, so that animations loop and stuff. Pretty easy, although unelegant.
void Window::Animate(int rate)
{
charSpriteSheet.FlipX(flipChar);
if((timerFrame%rate) == 0) // This is, rather obviously, a variable designed to allow to change the frames at the right rate.
{
if(stateChar == 0) // ? Not getting activated. Not getting called...
{
if(curFrame >= 2)
{
curFrame = 0;
}
else
{
curFrame++;
}
}
else if(stateChar == 1) // Walking.
{
if(curFrame >= 5 || curFrame <= 2 )
{
curFrame = 3;
}
else
{
curFrame++;
}
}
else curFrame = 6; // Jump.
SheetCutter(curFrame);
}
std::cout << stateChar;
timerFrame++;
};
// This removes the magenta background, changing the colour to tempClr. Color doesn't really matter as long as the fourth digit is set
// to 0, since it's the alpha value.
void Window::ColourCleaner()
{
sf::Color tempClr(0, 0, 0, 0);
for(int i = 0; i < 182; i++ )
{
for(int j = 0; j < 35; j++)
{
sf::Color CLR = charImage.GetPixel(i, j);
if(deleteColor == CLR)
{
charImage.SetPixel(i, j, tempClr);
}
}
}
};
Window.hpp
#ifndef Window_hpp
#define Window_hpp
class Window
{
sf::RenderWindow appWindow;
sf::Image charImage;
sf::Sprite charSpriteSheet;
sf::Color deleteColor;
int curFrame;
int stateChar;
int timerFrame;
public:
Window();
int Loop();
void SheetCutter();
void Animate(int rate);
void ColourCleaner();
};
#endif
You should put the #include <SFML/Window.hpp> into your header file, as you need its definitions there. (the source file should then include the header instead of duplicating its contents