syntax error : 'constant'

Jul 28, 2011 at 2:37am
Not really sure why im getting this error. Basically, in class state
i am trying to instantiate a Graphics object.

Graphics constructor
1
2
3
4
5
6
Graphics::Graphics( int screenWidth, int screenHeight, int screenBPP, std::string Caption)
{
	SDL_Init(SDL_INIT_VIDEO);
	screen = SDL_SetVideoMode( screenWidth, screenHeight, screenBPP, SDL_SWSURFACE );
	SDL_WM_SetCaption( Caption.c_str(), NULL );
}


class State
1
2
3
4
5
6
7
8
9
10
class State
{
public:
	virtual void HandleEvents() = 0;
	virtual void Logic() = 0;
	virtual void Render() = 0;

	Graphics* graphics( 640, 480, 32, "MyGame" );
	GameState nextState;
};
Jul 28, 2011 at 3:04am
You can't initialize it in your declaration, and It's a pointer, also I'd suggest you not use any namespaces in headers.

The reason why it mentioned constant is because only constant static variables can be initialized in the class declaration scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class State
{
public:
   virtual void HandleEvents() = 0;
   virtual void Logic() = 0;
   virtual void Render() = 0;

   Graphics* graphics;
   GameState nextState;
             
   State();
};

State::State()
{
   graphics = new Graphics( 640, 480, 32, "MyGame" );
}
Last edited on Jul 28, 2011 at 3:26am
Jul 28, 2011 at 3:07am
You can't construct members in class bodies like that*. You'll have to put that in the constructor.

(*at least not yet, I think the C++11 standard allows it, but you're still doing it wrong because you have a pointer and not an object).


Although, I won't directly answer your question because I suspect you are doing something you shouldn't.

Your 'graphics' object probably shouldn't be owned by the State like that. Since you will have many states, they will all want to share the same Graphics object. If they are each creating their own, that means you will be creating a new window for each state! Not something you want.


Your 'Game' class (or something similar) should own the graphics, then pass a pointer to it to each state. Or maybe instead, it should be a parameter passed to Render, since that's the only time you'll need it anyway.


EDIT:

Looks like I was too slow and Turbine already answered.

Please heed by warning though: you don't want each State to have its own Graphics. That is very weird and will not do what you want.
Last edited on Jul 28, 2011 at 3:08am
Jul 28, 2011 at 1:17pm
@ disch

Thanks for the help but i need to be able to use Graphics functions in each states Constructor, Destructor, and Render function.

Jul 28, 2011 at 1:21pm
I tried making a Graphics object in main, and then passing that to each states constructor but that doesnt work. I'm not sure what else to try.
Jul 28, 2011 at 3:25pm
OK, you're going to have stuff that you want to share between all states, right? Things like game settings (use configurable stuff like controls and whatever), graphics, and maybe some other stuff.

Throw all of that in a struct. Your game should have 1 instance of that struct that it passes around between states.

Something like this:

1
2
3
4
5
6
struct Environment
{
  Graphics* graphics;
  UserSettings settings;
  WhateverElse foobar;
};


Your Game or similar class (or I guess main() if you don't have a Game class) would create the graphics and put a pointer to it in the struct. I wouldn't recommend putting the actual graphics object in the struct, just a pointer.

1
2
3
4
5
6
7
8
9
10
int main()
{
  Graphics theGraphics( ... whatever ... );
  Environment theGameEnvironment;

  theGameEnvironment.graphics = &theGraphics;

  // now give the environment to your states when they're created
  GameState* currentState = new WhateverState( &theGameEnvironment );
}


Your State ctors would then need to take an Environment* as a parameter. You can then access the graphics (and other shared info) through that pointer.
Jul 28, 2011 at 4:23pm
I feel so close Disch!! But it still doesnt work, maybe a did it wrong. Graphics is not working in the state classes( says "graphics" is undefined ) .

I created Environment.h to hold the Environment struct.

in main i did this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main( int argc, char** argv )
{
	Graphics graphics( 640, 480, 32, "MyGame" );
	Environment GameEnvironment;

	GameEnvironment.graphics = &graphics;

	currentState = new Intro( &GameEnvironment );

	while( currentState->nextState != STATE_EXIT)
	{
		currentState->HandleEvents();
		currentState->Logic();
		currentState->Render();

		//if needed, change state
		switch( currentState->nextState )
		{
		case STATE_MENU:
			delete currentState;
			currentState = new Menu( &GameEnvironment );
			break;
		/*case STATE_GAME:
			delete currentState;
			currentState = new Game();
			*/
		}
	}


and the constructors for the states look like this
1
2
3
4
5
6
Intro::Intro( Environment* GameEnvironment  )
{
	
	introImage = graphics->LoadImage( "Media/introBG.bmp" );
	fading[0]  = graphics->LoadImage( "Media/introFade_0.bmp" );
}
Jul 28, 2011 at 7:10pm
*bump

Im anxious lol
Jul 28, 2011 at 8:43pm
In your state classes, since graphics is in the Environment struct, it would be
 
GameEnvironment->graphics->LoadImage(
Jul 28, 2011 at 9:19pm
I did that, but it only works in the Constructors. The rest of the functions dont work
Jul 29, 2011 at 1:35am

Intro::Intro( Environment* GameEnvironment )
{

introImage = graphics->LoadImage( "Media/introBG.bmp" );
fading[0] = graphics->LoadImage( "Media/introFade_0.bmp" );
}


For all pointer related variables, always place a pointer valid check before de-referencing them.

e.g

1
2
3
4
5
6
7
8
if (GameEnvironment) {
  Graphics graphics = GameEnvironment->graphics;
  if (graphics) {  
    introImage = graphics->LoadImage( "Media/introBG.bmp" );
    fading[0]  = graphics->LoadImage( "Media/introFade_0.bmp" );
  } esle cout << "graphics is null!\n";
} else cout << "GameEnvironment is nul!\n";
Jul 29, 2011 at 1:47am
nano511 wrote:
I did that, but it only works in the Constructors. The rest of the functions dont work


That's because GameEnvironment is a parameter. Which makes it local to the constructor.

If you want it to work in the rest of the functions, you'll need to make it available in the rest of the functions =P. Read up on scope rules and member variables.

Basically you need to make a member variable for your states (probably an Environment* whatever), then set that pointer to GameEnvironment in the constructor. Then you can use 'whatever' anywhere in your state class.


sohguanh wrote:
For all pointer related variables, always place a pointer valid check before de-referencing them.


Meh. I don't agree. Unnecessary extra code and overhead.
Jul 29, 2011 at 1:52am
yeah disch i made a Graphics object in each state, then in the constructors it looks like
1
2
3
4
5
6

contructor( Environment* gameEnvironment )
{
     graphics = gameEnvironment.graphics;
}
Jul 29, 2011 at 1:53am
There you go. Although I would recommend making an Environment* in each state instead of a Graphics*, since you'll probably want to have access to more than just the graphics.

Or if all you need is the graphics, then don't bother with the Environment struct at all anywhere and just pass a graphics pointer (I recommended the Environment struct because I figured you'd want to share other things -- but if not then it doesn't make much sense to have it)
Last edited on Jul 29, 2011 at 1:54am
Jul 29, 2011 at 1:56am
yeah im just doing it like that for now. Now i just need to get rid of these LNK errors :(
Jul 29, 2011 at 2:27am

sohguanh wrote:
For all pointer related variables, always place a pointer valid check before de-referencing them.


Meh. I don't agree. Unnecessary extra code and overhead.


Well if it is a C++ program, we can pass in by reference then there is no extra code and overhead.

 
Intro::Intro( Environment& GameEnvironment)


In fact passing by reference is highly recommended for new C++ program who does not have to deal with legacy C code baggage.
Topic archived. No new replies allowed.