problems with multiple function calls

Hello!

I'm making a 2D platformer game, and are currently working on collision and AI. The collision is working fine, but I have encountered a problem with multiple fuction calls and modifying a shared variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //in main.cpp
    ///Create 2 solid blocks 
    bandit->eCollision(1000,screenHeight-170,200,40);
    bandit->eCollision(200,screenHeight-170,200,40);

    //in enemyCollision.cpp
    ///Check if the enemy is under the block and player is on the block
    if (enemyPosX+enemySizeW > blockPosX-enemySizeW-15 &&
        enemyPosX < blockPosX+BLOCK_WIDTH &&
        enemyPosY > playerPosY)
        {
             underBlock = true;
        }else{underBlock = false;}


The problem is that the program creates 2 copies of the underBlock boolean value. How can I make both function calls change the same variable.

sorry bad English :)

Last edited on
Where is underBlock defined? Is it a global variable? Do you know why it is copied?
underBlock is created in the protected section in the enemy class in the enemy.h file.
where a other class called bandit inhertance all the variables from the enemy class. I try to use polymorphism, so the function virtual void eCollision is the standard collision function for all the enemy types. It's copied because I call the bandit->eCollision(1000,screenHeight-170,200,40) two times. Every time I call the eCollision function it creates a copy.
Do you mean that the second call overwrites the underBlock value so that the value set by the first call is lost? Is that the problem?
Last edited on
Every time I call the eCollision function it creates a copy.

Creates a copy of what? You're not passing underBlock into eCollision - just a bunch of numbers.

You're really not showing us enough code to be able to understand your problem.

Last edited on
@Peter87
Do you mean that the second call overwrites the underBlock value so that the value set by the first call is lost? Is that the problem?

yeah, that's exactly what I mean :)

in main.cpp
1
2
3
4
5
6
7
8
9
10
    ///Create a object to the bandit class
    bandit banditEnemy;
    enemy *bandit = &banditEnemy;
    
    while (!quit)
{
    ///create two solid blocks 
    bandit->eCollision(1000,screenHeight-170,200,40);
    bandit->eCollision(200,screenHeight-170,200,40);
}


in enemy.h
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class enemy
{
    public:
        int enemyPosX,enemyPosY, enemySizeW, enemySizeH;

        virtual void eHealth(int amount);
        virtual void ePosition(int posX,int posY, int sizeW, int sizeH);
        virtual void eMovement(int velX)=0;
        virtual void eJump()=0;
        virtual void eDraw()=0;
        virtual void eAttack()=0;
        virtual void eFall();
        virtual void eAccelerate(float accI, float accD)=0;
        virtual void eCollision(int blockPosX, int blockPosY, const int BLOCK_WIDTH, const int BLOCK_HEIGHT);
        virtual void eRandom();
        virtual void eAnimation()=0;
        virtual void eDefense()=0;

    protected:
        int health;
        bool underBlock;
        float gY, eForceY;
        float timer;
        SDL_Rect enemyRect;
        SDL_Rect eAtkBox;
    private:
};

class bandit : public enemy
{
    public:
        bandit();
        void eDraw();
        void eMovement(int velX);
        void eAttack();
        void eAccelerate(float accI, float accD);
        void eJump();
        void eAnimation();
        void eDefense();
        void eAttackBox(int offsetX,int offsetY, int sizeW, int sizeH);
    private:
        float accT;
        bool eLeft;
        bool eRight;

};


in enemy.cpp
1
2
3
4
5
6
7
8
9
10
void enemy::eCollision(int blockPosX, int blockPosY, const int BLOCK_WIDTH, const int BLOCK_HEIGHT)
{
///Check if the enemy is under the block and player is on the block
    if (enemyPosX+enemySizeW > blockPosX-enemySizeW-15 &&
        enemyPosX < blockPosX+BLOCK_WIDTH &&
        enemyPosY > playerPosY)
        {
             underBlock = true;
        }else{underBlock = false;}
}


in bandit.cpp
1
2
3
4
5
6
7
void bandit::eMovement(int velX)
{
     if (underBlock == true)
    {
        enemyPosX += velX;
    }
}


Thats all the files that use the underBlock variable.
Last edited on
There are multiple options.

You could set underBlock to false before starting to call eCollision, and let eCollision only set the variable to true.

Another possibility is to return true or false from eCollision and instead of setting underBlock in that function you let the code that call the function set the variable correctly.
Last edited on
You have a single enemy, with a single underBlock value.

Each time you call eCollision(), it updates the value of underBlock with a new value.

Is that not what you want to happen? What exactly do you want to happen?

In your original post, you said that you want both functions to change the same variable. That seems to be exactly what's happening, so I don't understand what the problem is.

Can you try and explain more clearly what you want to happen?
@Peter87
I will try that out.

@MikeyBoy
Sorry for my extremely misleading topic and explaination. here is probably a more clear explaination. i have 2 solid blocks that I want the enemy to have collision with. if the player stands on top of the block and the enemy is under the block (underBlock = true) then the enemy will move to right and try to jump on the block so it could reach the player. The problem is that the program creates two copies of the underBlock variable, and in the bandid.cpp file it only test the underBlock variable to the last block/last line of code I declared in main.cpp . So the "go right" code that should run when underBlock is true, will only work on one of the boxes :/
.
The problem is that the program creates two copies of the underBlock variable, and in the bandid.cpp file it only test the underBlock variable to the last block/last line of code I declared in main.cpp .

What makes you think it's creating two copies of the underBlock variable?

In the code you've posted, there is one, and only one, instance of the enemy class. This instance has one, and only one, data member called underBlock. The value of that data member changes each time you call eCollision().

If you need to check the value of underBlock after the first call to eCollision(), then you should do that. There's no point setting the value of it, then overwriting that with a new value, because then you lose the old value.

Consider the following code:

1
2
3
4
5
int x;
x = 1;  // Assign a value to x
x = 5;  // Overwrite the value of x with another value
// ...
std::cout << x << std::endl; // What will this print out? 


Have you created two copies of x? No. All you've done is assigned a value to x, then changed it again to a new value When you print it out, you'll only get the new value.

That's exactly the equivalent to what you're doing:

1
2
3
4
    bandit->eCollision(1000,screenHeight-170,200,40);  // Assigns a value to bandit->underBlock
    bandit->eCollision(200,screenHeight-170,200,40);  // Overwrites the value of bandit->underBlock with another value
// ...
    bandit->eMovement(someValue);  //  Checks the current value of  bandit->underBlock 


It sounds like you need to reorganize your code so that you handle the results of one call to eCollision() before you make the next call.
Last edited on
@mikeyBoy
Ahh stupid me, of course it will overwrite the last variable. btw I tried to call eMovement between the eCollision like this:

1
2
3
4
5
              bandit->eCollision(1000,screenHeight-170,200,40);
              ///eMovement(velocity in x direction)
              bandit->eMovement(6);
              bandit->eCollision(200,screenHeight-170,200,40);
              bandit->eMovement(6);


but that did not work so well, because the enemy ignore the collision with the bottom of the block and jumps right through it.

so I tried this:
1
2
3
4
5
6
7
8
9
10
11
        if (playerPosX > screenWidth/2)
        {
              bandit->eCollision(1000,screenHeight-170,200,40);
              bandit->eMovement(6);
              
        }
        if (playerPosX < screenWidth/2)
        {
              bandit->eCollision(200,screenHeight-170,200,40);
              bandit->eMovement(6);
        }


and that seems to work. But this method will be a problem if I add one more block, and the block is between the block 1 and block 2. Do you have an Idea of a better method than this. Sorry for noobie questions
Topic archived. No new replies allowed.