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

Author Topic: How can I create global sprites?  (Read 4174 times)

0 Members and 1 Guest are viewing this topic.

Toad The Mushroom coder

  • Newbie
  • *
  • Posts: 5
    • View Profile
    • Email
How can I create global sprites?
« on: January 04, 2018, 03:28:26 pm »
Hello!

So, I have finished creating a project on SFML. However, I noticed that my code inside the int main() function was too messy, especially with those sprites' and textures' declarations "cramming" the function. As I am aware, it is impossible to declare and create sprites in different functions than the one containing the 'window.draw' and 'window.display' commands, as they will be destroyed as soon as the function is done being executed, due to being local to said function only (Just like when declaring variables).

My question is: can we create a "global sprite" system similar to variables? What I mean is that, if you want to have global variables that can be used by all the functions in your project, you declare them in a header file, and define them in a C++ source file (I do this, at least, and it works for most types of variables). Can the same be done here?

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: How can I create global sprites?
« Reply #1 on: January 04, 2018, 04:11:10 pm »
Your sprites don't have to be global, they just have to live long enough to be drawn!

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: How can I create global sprites?
« Reply #2 on: January 04, 2018, 04:38:40 pm »
Only memory that is allocated on the stack gets destroyed when going out of scope (such as a function ending). You can easily dynamically allocate memory on the heap using c++'s new operator that won't get automatically destroyed. In addition to this, you can organize your sprites and textures as members of C++ classes or structs to keep things from getting "messy". Those classes and structs themselves can be allocated on the heap if need be. Or maybe std::vector would work for your use case.

You may want to spend a little more time learning C++ and the standard library to fully understand what your organizational options are. From there, you might consider reading through one of the SFML game design books to get an idea on how you can structure the logic for a game.

In general you don't want to use SFML classes like sf::Texture as global variables. Some SFML classes depend on other global variables themselves for technical reasons. In C++ the order of destruction of global objects is undefined across translation units. That means if you have 2 global variables that depend on each other, such as the case with a global sf::Texture, the wrong one might get destructed first and you end up with undefined behavior (possibly a crash).

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: How can I create global sprites?
« Reply #3 on: January 04, 2018, 06:00:49 pm »
There's absolutely no need to dynamically allocate sprites using the new keyword. Also if you copy sprites into a vector, they'll lose their reference to their texture. Otherwise I agree with everything Arcade said.

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: How can I create global sprites?
« Reply #4 on: January 04, 2018, 08:28:56 pm »
The point of my first paragraph wasn't about sprite specifically, but just to point out OP's misunderstanding that their only options were to create everything in the main function or as globals due to scope concerns. There are several other ways to organize code such that this is not the case. There are legitimate reasons why you may want to allocate textures dynamically, or custom classes that encapsulate your textures and sprites among other things.

Also, why would a sprite lose its reference to the texture when being copied into a vector? A sprite simply holds a pointer to its texture. As long as the texture doesn't move in memory you can copy the sprite as many times as you want and they will all point to the same texture just fine. Now, if a sprite's texture is in a vector you may run into trouble because in that case the texture can get moved and invalidate the sprite's pointer, but there is no problem with the sprite itself being in a vector.

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: How can I create global sprites?
« Reply #5 on: January 04, 2018, 08:42:24 pm »
Sorry I wasn't clear. You gave him this advice:

Quote
you can organize your sprites and textures as members of C++ classes or structs to keep things from getting "messy".


if he/she happens to keep the sprite and the texture in the same class, and copy that class into a vector then the reference would be lost.

Toad The Mushroom coder

  • Newbie
  • *
  • Posts: 5
    • View Profile
    • Email
Re: How can I create global sprites?
« Reply #6 on: January 12, 2018, 02:18:14 pm »
You can organize your sprites and textures as members of C++ classes or structs to keep things from getting "messy". Those classes and structs themselves can be allocated on the heap if need be.

So declaring textures and sprites on a class does not have the same effect as declaring them in a function?

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: How can I create global sprites?
« Reply #7 on: January 12, 2018, 04:00:17 pm »
That sentence you quoted was just to give you ideas on how to solve this:

However, I noticed that my code inside the int main() function was too messy, especially with those sprites' and textures' declarations "cramming" the function.

Instead of having something like this
sf::Texture texture;
if (!texture.loadFromFile("image.png"))
{
    // error
}
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setTextureRect(...);
window.draw(sprite);
 

You can create an class that does all of that for you. Your main would just then be:
MyDrawableClass object;
window.draw(object);
 

However, designing your code like this leads to other things you need to consider. For example, if you simply store your texture in an object, then every time you create a new object of the same type you will be making unnecessary copies of that texture. Typically, you would create some kind of full blown "resource manager" class (or use the ones in libraries like "thor") for your textures and similar resources.

Basically, the topic of how to structure your code is a pretty big one with several different answers. It may be hard for people to give full explanations here on the forums without skimping on the details. Again, I recommend looking around the internet for typical game design patterns, or if you don't mind spending a small amount of money, buying one of the SFML game development books. I've actually never read the books myself, but I've heard that they can be a big help for beginners.
« Last Edit: January 12, 2018, 04:05:51 pm by Arcade »