How to create an SFML image as a global

Hey there I am having a frustrating problem with my Asteroids game in which the dynamically created EnemyShip class seems unable to draw its own sprite (but will draw others).

To this end I decided to attempt to make the actual image global and load it in my globals.cpp file. Except it says:


This declaration has no storage type or class specifier.


Sample of my globals.cpp
1
2
3
4
5
6
7
8
9
#include <SFML\Graphics.hpp>
#include "drawing.h"
#include "utilities.h"

...

//images
sf::Image g_enemyShipImage;
enemyShipImage.LoadFromFile("images/enemyShip.png");



Sample of my globals.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef GLOBALS_H
#define GLOBALS_H

#include <SFML/Graphics.hpp>
//#include "drawing.h"
//#include "utilities.h"

...

//images
extern sf::Image enemyShipImage;

#endif



Sample of EnemyShip::init()
1
2
3
4
5
6
7
8
9
10
11
12
void EnemyShip::init()
{
	//load images
	//enemyShipImage.LoadFromFile("images/enemyShip.png");
	bulletImage.LoadFromFile("images/bullet.png");
	

	//load sprites
	enemyShipSprite = sf::Sprite(enemyShipImage);

...
}



Does anyone have any idea what could be causing this behaviour?

Thank you for any help you can give.
Using a global for that purpose is probably a bad idea and you should fix what's wrong with EnemyShip instead, but you're declaring two different names:

extern sf::Image enemyShipImage;

sf::Image g_enemyShipImage;
Also traditionally images are loaded at the Initiation function, this way you have everything occuring in one spot. You can still have an sf::Image in the Global scope, but to keep things organized you should load the image about the same time you set the screen resolution and create the rendering context.
@filipe:

O yeah sorry I forgot to remove that, rest assured it was gone within the code I was trying. I changed it to g_ when I stuck it in globals and then removed it after but forgot to remove it here. That was not the problem sorry.

Also I agree it should not be done as a global but it refuses to draw itself if I call it within the init() function but will draw other sprites / images.

For example I have a bulletSprite as well and if I stick it in the correct place it draws it fine but as soon as I attempt to use enemyShipSprite it will not draw. It loads up the image correctly because my code works out a radius from the picture itself and it is setting the radius to the correct amount. It is simply refusing to draw to the screen when I try to draw the enemyShipSprite (no matter what picture the image loads up.



@computergeek01:

That solution worked perfectly thank you. Although I am still curious why it would not work when I kept it as a class variable (like I did with all my other sprites) or when I tried to load it from within the globals.cpp after declaring it :s
It is simply refusing to draw to the screen when I try to draw the enemyShipSprite

This means there's something wrong either with the class' code or with the image file. It seems you're just "accepting" that there's a bug somewhere and you're trying to bypass it instead of fixing it. I don't think it's a good idea.
The Image never gets drawn because the File never gets loaded. The main(...) function is refered to as the "Entry Point" for a reason, your code executes like this:

1: Preprocessor Commands. Such as includes, macros and runtime links.

2: Application Constructor. If present this is the only code that is executed before the entry point to your application.

3: Forward Declarations. These include functions, global variables definitions for classes etc. Constructors for global variables would be called at this point since they would be needed to declare the variables. EDIT: NOTE: sf::Image.LoadIMG(...) is a member function, not a part of the constructor for sf::Image.

4: Main(...) Function. This is where you code starts to be processed, everything up until this point is just loaded into memory or accounted for in some way.EDIT: Unless otherwise noted.

5: User Defined Regular Functions. These are the functions that you call, no matter where they are written, in your code or imported from a DLL\lib, these are not executed until they are called either from Main(...) or from another function that is called from Main(...).

6: Clean Up. At the conclusion of Main(...) your program starts to clean up variables that may still be present in memory by calling their destructors and also starts to run any functions pointed to by "atexit(...)".

7: Application Destuctor. If present this is executed anytime your application is killed "cleanly". This runs after any calls to "atexit(...)" functions.

8: Return to shell. This is the part where you exit code is returned to the shell that was hosting your application.

As you can see the only way that this command could have executed is if it were a constructor to that variable. Seeing how it isn't there is no place where you program actually called the "LoadIMG(...)" function even though you wrote it at the top. Where as with your "bulletImage" you called that as part of your "void EnemyShip::init()" function.
Last edited on
Topic archived. No new replies allowed.