Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Vector of projectile sprites problem  (Read 4976 times)

0 Members and 1 Guest are viewing this topic.

Noob

  • Newbie
  • *
  • Posts: 15
    • View Profile
Vector of projectile sprites problem
« on: February 13, 2014, 07:21:54 pm »
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.


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.
Killing goblins at Lumbridge. Windows 7 - 64 bit. AMD Radeon HD 6700. Using VS2012 Express, SFML 2.1 - Static.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Vector of projectile sprites problem
« Reply #1 on: February 13, 2014, 07:33:25 pm »
For starters how does updating the vector of fireballs only when a new one is created work out for ya?

Try moving them every frame.  ;)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Noob

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Vector of projectile sprites problem
« Reply #2 on: February 13, 2014, 08:38:36 pm »
...

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...


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.
Killing goblins at Lumbridge. Windows 7 - 64 bit. AMD Radeon HD 6700. Using VS2012 Express, SFML 2.1 - Static.

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Vector of projectile sprites problem
« Reply #3 on: February 13, 2014, 08:48:11 pm »
You always call clear, but not always display on the window. That's wrong. Every frame you need to clear and display. That should solve the issue

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Vector of projectile sprites problem
« Reply #4 on: February 13, 2014, 08:59:34 pm »
In fact, you should call clear, display, AND draw each time (in order: clear, draw, display), regardless of whether the clock is telling you to update the position.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Noob

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Vector of projectile sprites problem
« Reply #5 on: February 13, 2014, 09:02:56 pm »
What do you mean?

I'm only calling window.display() once every update as it seems pointless to call it if nothing has changed.



Am I going to have to redo a lot of code to make it fall into the 'Update' and 'Draw' paradigm?
« Last Edit: February 13, 2014, 09:07:25 pm by Noob »
Killing goblins at Lumbridge. Windows 7 - 64 bit. AMD Radeon HD 6700. Using VS2012 Express, SFML 2.1 - Static.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Vector of projectile sprites problem
« Reply #6 on: February 13, 2014, 09:48:04 pm »
I'm only calling window.display() once every update as it seems pointless to call it if nothing has changed.
Don't assume things, read tutorials.

http://www.sfml-dev.org/tutorials/2.1/graphics-draw.php
There's a big red box explaining why you shouldn't do it the way you do ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Vector of projectile sprites problem
« Reply #7 on: February 13, 2014, 09:51:21 pm »
I'm only calling window.display() once every update as it seems pointless to call it if nothing has changed.
You should be, on every loop, be calling clear, draw, and display. Get used to it; it works wonders  ;D
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Noob

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Vector of projectile sprites problem
« Reply #8 on: February 13, 2014, 10:56:35 pm »
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.
Killing goblins at Lumbridge. Windows 7 - 64 bit. AMD Radeon HD 6700. Using VS2012 Express, SFML 2.1 - Static.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Vector of projectile sprites problem
« Reply #9 on: February 13, 2014, 11:34:55 pm »
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)
{
}
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Noob

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Vector of projectile sprites problem
« Reply #10 on: February 13, 2014, 11:59:06 pm »
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.
« Last Edit: February 14, 2014, 12:00:38 am by Noob »
Killing goblins at Lumbridge. Windows 7 - 64 bit. AMD Radeon HD 6700. Using VS2012 Express, SFML 2.1 - Static.