Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Assignment of boolean condition values within if statement not working?

I've been coding a game in C++ using the SDL library. Today while changing the way my player character class works, I've come up against a very puzzling problem. The following code forms part of my logic allowing the player to fire bullets. The control variables, b_canFire and b_shouldFire (I plan to rename these to make more sense), are set elsewhere in the class to allow this function to execute when the user presses a key.

bool PlayerChar::DoFiring()
{
    if(b_canFire && b_shouldFire)
    {
        Fire(box.x + 22, box.y); // This fires a bullet
        b_canFire = false; // Does not work
        b_shouldFire = false; // Does not work

        return true;
    }
}

When I step through this code using my debugger, it becomes aparrent that the values of b_canFire and b_shouldFire are not being changed to false by the assignments inside the if statement. However, if I change the code to the following:

bool PlayerChar::DoFiring()
{
    if((b_canFire) && (b_shouldFire))
    {
        Fire(box.x + 22, box.y); // This fires a bullet
        b_canFire = false; // Works
        b_shouldFire = false; // Works

        return true;
    }
}

or

bool PlayerChar::DoFiring()
{
    if(b_canFire == true && b_shouldFire == true)
    {
        Fire(box.x + 22, box.y); // This fires a bullet
        b_canFire = false; // Works
        b_shouldFire = false; // Works

        return true;
    }
}

Suddenly the assignments work. I have also tried replicating this situation in an empty test-project, as follows:

bool bC = true;
bool bD = true;

if(bC == true && bD == true)
{
    bC = false; // Works
    bD = false; // Works
}


bool bE = true;
bool bF = true;

if(bE && bF)
{
    bE = false; // Works
    bF = false; // Works
}

However, both of these examples assign the values exactly as they should. Clearly I am missing something here, but for the life of me, I can't see what it is. I have figured out how to fix the problem to make my code work, but it's really bothering me not knowing what is breaking the assignments in the first example, because everything I've learned about C++ so far is telling me they should work fine.

This is my first major project using the C++ language, and I am still learning, so any help or advice from more experienced programmers would be great.

Thanks!

EDIT:

As requested here is the entire class:

#include <list>
#include "SDL_mixer.h"
#include "hiGlobalVars.h"
#include "hiGlobalObjects.h"
#include "hiAssetManager.h"
#include "hiRendering.h"
#include "hiTimer.h"
#include "hiBullet.h"
#include "hiPlayerChar.h"
#include "hiDebugger.h"


using std::list;


PlayerChar::PlayerChar()
{
    moveSpeed = 6;
    moveDir = NONE;
    b_canFire = true;
    b_shouldFire = false;
    box.x = 0;
    box.y = 470;
    box.w = 38;
    box.h = 40;
}


PlayerChar::~PlayerChar()
{

}


void PlayerChar::SetPos(int x)
{
    box.x = x;
}


void PlayerChar::Draw()
{
    BlitSurface(box.x, box.y, assets.ss_playerchar_idle, ss_screen);
}


bool PlayerChar::DoFiring()
{
    if((b_canFire) && (b_shouldFire)) 
    {
        // Fire a bullet
        Fire(box.x + 22, box.y);
        b_canFire = false;
        b_shouldFire = false;

        return true; // fired a bullet
    }
    return false; // did not fire a bullet
}


void PlayerChar::Fire(int x, int y)
{
    // Create a new bullet at the correct location and add it to the global bullet list
    Bullet* bullet = new Bullet();
    bullet->SetPos(x, y);
    bullets.push_back(bullet);

    // Play bullet firing sound
    Mix_PlayChannel(-1, assets.mc_firebullet, 0);
}


void PlayerChar::HandleInput(Uint8* keystates)
{
    if(keystates[SDLK_LEFT] && keystates[SDLK_RIGHT])// Both direction keys
        moveDir = NONE;
    if(keystates[SDLK_LEFT] && !keystates[SDLK_RIGHT]) // Left key and not right key
        moveDir = LEFT; 
    if(!keystates[SDLK_LEFT] && keystates[SDLK_RIGHT]) // Right key and not left key
        moveDir = RIGHT; 
    if(!keystates[SDLK_LEFT] && !keystates[SDLK_RIGHT]) // Neither direction key
        moveDir = NONE;

    if(keystates[SDLK_SPACE]) // Space bar
        b_shouldFire = true;

    if(!keystates[SDLK_SPACE]) // Allow another bullet to be fired after release
        b_canFire = true;
}


void PlayerChar::Move()
{
    if(moveDir == LEFT && box.x > 0) // If not off screen, move
        box.x -= moveSpeed;
    if(moveDir == RIGHT && box.x < (ss_screen->w - box.w)) 
        box.x += moveSpeed;
}

and the header:

#ifndef __hiPlayerChar__
#define __hiPlayerChar__


#include "SDL.h"
#include "SDL_mixer.h"
#include "hiGlobalVars.h"


enum MoveDir
{
    LEFT,
    RIGHT,
    NONE
};


class PlayerChar
{
private:
    Sint16 moveSpeed;
    MoveDir moveDir;
    bool b_canFire;
    bool b_shouldFire;

public:
    // Ctr & Dtr
    PlayerChar();
    ~PlayerChar();

    // Functions
    void SetPos(int x);
    bool DoFiring();
    void Fire(int x, int y);
    void Move();
    void Draw();
    void HandleInput(Uint8* keystates);

    // Size and position
    SDL_Rect box;
};


#endif
like image 697
James Hill Avatar asked Oct 28 '12 16:10

James Hill


People also ask

How do you write a boolean condition in an if statement?

Here is a simple if-statement... The simplest if-statement has two parts – a boolean "test" within parentheses ( ) followed by "body" block of statements within curly braces { }. The test can be any expression that evaluates to a boolean value – true or false – value (boolean expressions are detailed below).

Can we use assignment operator in if condition?

Using the assignment operator in conditional expressions frequently indicates programmer error and can result in unexpected behavior. The assignment operator should not be used in the following contexts: if (controlling expression)

How check bool value in if condition?

The if statement will evaluate whatever code you put in it that returns a boolean value, and if the evaluation returns true, you enter the first block. Else (if the value is not true, it will be false, because a boolean can either be true or false) it will enter the - yep, you guessed it - the else {} block.


1 Answers

It is missing last return instruction in your function:

bool PlayerChar::DoFiring()
{
    if(b_canFire && b_shouldFire)
    {
        Fire(box.x + 22, box.y); // This fires a bullet
        b_canFire = false; // Does not work
        b_shouldFire = false; // Does not work

        return true;
    }
    return false; // WAS MISSING HERE
}

Then your function returns whatever (UB) if any of your b_canFire, b_shouldFire are false.

like image 169
PiotrNycz Avatar answered Sep 29 '22 23:09

PiotrNycz