Ok, so I'm having major problems with creating and updating a vector of sprites that are meant to represent projectiles. Everything compiles fine, but my sprite, or should I say sprite, has other plans it seems...
The fireball is meant to be moving across the screen, but it doesn't.
(http://oi57.tinypic.com/5tw85c.jpg)
All relevant code, will compile to the above exe.:
Entity.h
#pragma once
#include "SFML/Graphics.hpp"
#include <Windows.h>
class Entity : public sf::Drawable, public sf::Transformable
{
public:
void createTexture(const sf::Image& imageRef, int xTexturePosition, int yTexturePosition, int xTextureSize, int yTextureSize);
void createSprite(int width, int height, int xPosition, int yPosition, float scale);
protected:
sf::Texture texture;
sf::Sprite sprite;
private:
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= getTransform();
target.draw(sprite, states);
};
};
Entity.cpp
#include "Entity.h"
void Entity::createTexture(const sf::Image& imageRef, int xTexturePosition, int yTexturePosition, int xTextureSize, int yTextureSize)
{
texture.loadFromImage(imageRef, sf::IntRect((xTexturePosition * xTextureSize), (yTexturePosition * yTextureSize), xTextureSize, yTextureSize));
}
void Entity::createSprite(int width, int height, int xPosition, int yPosition, float scale)
{
sprite.setTexture(texture);
sprite.setTextureRect(sf::IntRect(0, 0, width, height));
sprite.setOrigin((width / 2), (height / 2));
sprite.setScale(scale, scale);
sprite.setPosition(xPosition, yPosition);
}
Fireball.h
#pragma once
#include "Entity.h"
#include <vector>
class Fireball : public Entity
{
public:
void createFireball(sf::Keyboard& keyboard);
private:
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= getTransform();
for(unsigned int i = 0; i < fireball.size(); i++)
{
target.draw(fireball[i], states);
}
};
std::vector <sf::Sprite> fireball; // A vector of sprites called fireball.
};
Fireball.cpp
#include "Fireball.h"
void Fireball::createFireball(sf::Keyboard& keyboard)
{
if( keyboard.isKeyPressed(keyboard.Space))
{
fireball.resize(fireball.size() + 1);
}
for (unsigned int i = 0; i < fireball.size(); i++)
{
fireball[i] = sprite; // Gives the fireball at [i] the properties of the protected sprite in Entity.
fireball[i].move(1,1); // This seems to do nothing.
if(fireball[i].getPosition().x > 700)
{
fireball.erase(fireball.begin() + i);
}
fireball.shrink_to_fit();
}
}
Game.h
#pragma once
#include "SFML/Graphics.hpp"
class Game
{
public:
Game();
void runGame();
private:
int screenHeight;
int screenWidth;
sf::Clock clock;
long float updateRate;
};
Game.cpp
#include "Game.h"
#include "Fireball.h"
Game::Game()
{
screenWidth = 1600;
screenHeight = screenWidth / 16 * 9;
}
void Game::runGame()
{
sf::Keyboard keyboard;
sf::Keyboard& keyboardRef = keyboard;
sf::RenderWindow window(sf::VideoMode(screenWidth, screenHeight), "Y U NO WORK");
sf::RenderWindow& windowRef = window;
sf::Image spriteSheet;
spriteSheet.loadFromFile("Main sprite sheet.png");
sf::Image& imageRef = spriteSheet;
Fireball fb;
fb.createTexture(imageRef, 0, 8, 16, 16);
fb.createSprite(16, 16, 150, 150, 4);
long float updateRate = 1000.0f / 60.0f;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || keyboard.isKeyPressed(keyboard.Escape))
window.close();
}
window.clear(sf::Color(0,0,0));
if(clock.getElapsedTime().asMilliseconds() >= updateRate)
{
clock.restart();
// * * * * * * * * * * * * * * * * Game logic goes here
fb.createFireball(keyboardRef);
window.draw(fb);
window.display();
}
}
}
int main()
{
Game game;
game.runGame();
return 0;
}
I've been stuck on this problem for what seems like an age. I think the problem is something to do with the draw function that is being used. Is window.draw(fb) using the draw function from Entity or the one in Fireball?
Also, shouldn't the fireball.move() in Fireball be doing something? The sprite just sits there.
I'm no C++ pro so plz help a noob out.
(http://i1.kym-cdn.com/photos/images/original/000/284/709/7ae.png)...
Ok, so after commiting suicide I added
if(!fireball[i].spriteIsSet)
{
fireball[i] = sprite;
fireball[i].spriteIsSet = true;
}
to Fireball.cpp and put 'bool spriteIsSet' into the Sprite SFML header file and set it to false, but now...
(http://oi57.tinypic.com/vg34t1.jpg)
What the...? O_o
Pressing space adds new elements to the vector and they show up and start moving, but if quickly tapping on the space key some of the sprites go like that. It happens randomly upon key presses.
I have no idea where to begin with this.
Ok, so I've done that and I've gave to documentation a good seeing to but none of it seems to have remedied the visual artifacts seen in the second screenshot.
I have to ask. Are all three (clear, draw, display) now outside of this conditional:
if(clock.getElapsedTime().asMilliseconds() >= updateRate)
{
}
Yep, my loop looks like this now:
if(clock.getElapsedTime().asMilliseconds() > updateRate)
{
clock.restart();
// * * * * * * * * * * * * * * * * Update logic stuff here
fb.updateFireballs(keyboardRef);
}
window.clear(sf::Color::Black);
// * * * * * * * * * * * * * * * * Draw stuff here
window.draw(fb);
window.display();
}
But the thing is, none of that was the problem (though I'm sure it would have gave me problems in the future).
After an hour of just messing about trying random stuff, I realised it was something to do with the locations of my exe. and the Spritesheet that it needed.
The flickering/warped sprites problem only happens when I run the program from the exe. in my Release folder (I'm using VC2010, Release mode, static SFML config btw) which also has the Spritesheet in it that the exe. is looking for.
When I run from VC itself there are no problems at all.