Object was not declared in this scope?

Started by
5 comments, last by stitchs_login 11 years ago

Hello

I was trying to make some simple demo to learn basics of the physics. I want the cannon to shoot single bullet whenever I press left mouse button.

I have the bullet class, that stores variables such as veolocities, position etc. Here is my problem:


    //bullet myBullet(90, 530, 20, -20, 1);
    while(!quit)
    {
        fps.start();
        while(SDL_PollEvent(&event))
        {
            if(event.type==SDL_QUIT) quit=true;
            if(event.type==SDL_MOUSEBUTTONDOWN)
            {
                // creating the object
                if(event.button.button==SDL_BUTTON_LEFT) bullet myBullet(90, 530, 20, -20, 1);
            }
        }
        myBullet.update(); //calculating position etc
        
        // RENDERING
        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
        myBullet.show();
        my_AttachImage(10, 520, cannon, screen);
        SDL_Flip(screen);
        if(fps.getTicks()<1000/FPS) SDL_Delay(1000/FPS-fps.getTicks());
    }

I keep getting error on the myBullet.update() line. It says: |error: 'myBullet' was not declared in this scope|. Everything works when I create the object before the main loop ( the commented line that you can see ). But I need the bullet to be created when i press LMB. How can I have it working?

Advertisement
One option is to use dynamic memory. Put a bullet pointer before the loop, initialize to a null pointer and new a bullet in the if statement. Then have the other statements that refer to the bullet check for null before operating on it. You can also make the bullet pointer a smart pointer.

Alternately, since it's fairly likely that you'd want more than one bullet at a time, create a container of bullets like a std::vector<bullet> and when the mouse button is pressed, push_back() a new bullet in the container. Then have the parts that reference the bullet loop over the container and operate on each bullet.

I should have thought about the dynamic memory.. everything works fine now. As for the vector: I wanted to get this to work first, before rendering multiple bullets at a time. You know, small steps :) Thanks for help

If you use the raw pointer solution SiCrane posted, don't forget to delete the pointer in the new bullet maker and after the end of the program so you won't leak memory!

E.g.


...
Bullet * myBullet = 0; //nullptr instead of 0 if using C++11
while (!quit)
{
  if (shootNew)
  {
    delete myBullet; //does nothing if myBullet is null
    myBullet = new Bullet();
  }
  if (myBullet != 0)
    myBullet.doSomething();
}
delete myBullet;
...

If you don't, the old bullets are still in memory, so after pressing the fire button 2000 times, there are 2000 bullets in memory. Yuck.

When you doing this:

// creating the object
if(event.button.button==SDL_BUTTON_LEFT) bullet myBullet(90, 530, 20, -20, 1);


You're using *automatic* (EDITED, thanks @rip-off. Don't confuse with "auto" C++11 reserved word) declaration -> allocation on the variable "myBullet". That means (among other things) that the "myBullet" timelife remains in the scope in which that variable was declared, in this case, the precedent if statement. When the if statement is consumed, all the *automatic* resources inside the "if" scope are destroyed, including "myBullet". That is the reason why "myBullet.update()" is undefined, because there's no declaration of "myBullet" in the present scope or an outter scope (When you comment out the first line, myBullet declaration, this is in a outter scope, and therefore works).
What you need to do is using dynamic allocation, something like the solutions presented by the others members.

@nimrodson, your description is confusing because you are using the term "static", which has a specific meaning in C++ which has more or less the opposite meaning than the one you are trying to give it here. You may have meant "automatic", which is the correct C++ term for this case.

As an additional note,

When you do go down the container root, so you can have multiple bullets, set a 'roof' of the number of maximum bullets you can have on-screen. This stops any new bullets being created before you are allowed to fire a new one. Without this you could have ALOT of them on screen at one time which, when rendered, will slow down you program considerably.

You can use this max value as part of the test to check whether a 'newShoot' is allowed, and implement other tests. For example, if the max value has been reached, check if a bullet goes off-screen, then you can kill it, free its pointer up, and set newShoot to true so that a you can create a new one.

I hope that is clear,

Stitchs.

This topic is closed to new replies.

Advertisement