Game Development Community

Weird Bug in my code involving private fields

by Michael Malandra · in Torque X 2D · 04/13/2009 (6:52 pm) · 1 replies

Ok. So I am at a complete loss here. Perhaps someone can help me out.

Here is my problem. I have a defined InputMap that calls an Action delegate when I press the A button. The proper function is called and ran through, but a problem arises when I try to play the game after loading the scene, unloading the scene, then loading the scene again. When I use the A button on the second playthrough, the function is run through but does NOT actually afffect any of the private fields once the function is done running. So, for example, I have a boolean field named 'x'. When the scene loads, I set 'x' to false. I then press the A button to call the function. The function is called, and in that function I set 'x' to true. Once the function is done running, I check the value of 'x' in ProcessTick. In ProcessTick, the value of 'x' is false!!!!!!

What gives!!!

Here is my function that is tied to my Action delegate.

protected internal void _GetFortune()
        {
            Game.Instance.GettingFortune = true;
            _fortuneStep = 0;
            _waitTime = 0;

            _fortuneText.Visible = true;
            _controls01.Visible = false;
            //Console.WriteLine(this._controls01.Visible);

            //pick a fortune
            Random rand = new Random();
            _fortuneText.SetAnimationFrame((uint)rand.Next(0, _fortuneText.FinalFrame));

            if (Guide.IsTrialMode)
            {
                if (Game.Instance.TrialFortuneCounter < 3)
                {
                    Game.Instance.TrialFortuneCounter++;
                }
                else
                {
                    TrialEndScreen tes = new TrialEndScreen();
                    GUICanvas.Instance.SetContentControl(tes);
                    return;
                }
            }
        }

The values of _fortuneStep, _waitTime, _controls01.Visible all return to their prior value once the function is done running. I have a feeling the other ones do as well, but they seem to function (I must have a fallback somewhere else). I originally had the Game.Instance.GettingFortune boolean variable stored as a private field of the component as well, but the same problem was resulting.

For the sake of completeness, her is my OnRegister function as well:
protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner) || !(Owner is T2DSceneObject))
                return false;

            // retain a reference to this component's owner object
            _interiorMist = owner as T2DSceneObject;

            Game.Instance.GettingFortune = false;

            _SetupInputMap("gamepad" + Game.Instance.ActiveController);

            _camera = TorqueObjectDatabase.Instance.FindObject<T2DSceneCamera>("Camera");
            _defaultCameraExtent = _camera.Extent;
            _zoomedCameraExtent = new Vector2(50, 50);
            _maxWaitTime = 5.0f;

            _exteriorMist = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("globeMistOutside");
            _glowingGlobe = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("glowingGlobe");
            _blackMistExterior = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("blackMist02");
            _blackMistInterior = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("blackMist01");
            _fortuneText = TorqueObjectDatabase.Instance.FindObject<T2DAnimatedSprite>("resultText");
            this._controls01 = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("instructions");

            _blackMistExterior.VisibilityLevel = 0;
            _blackMistInterior.VisibilityLevel = 0;
            _fortuneText.VisibilityLevel = 0;

            _blackMistExterior.Visible = true;
            _blackMistInterior.Visible = true;
            _controls01.Visible = true;

            _wb = new WaveBank(Game.Instance.Engine.SFXDevice, @"datasoundsWave Bank.xwb");
            _sb = new SoundBank(Game.Instance.Engine.SFXDevice, @"datasoundsSound Bank.xsb");

            // tell the process list to notifiy us with ProcessTick and InterpolateTick events
            ProcessList.Instance.AddTickCallback(Owner, this);

            return true;
        }


I load a scene in which I have my own custom component attached to a T2DStaticSprite. I set up an input map for Player 1 defined in PlayerManager. Here is that code:

public void _SetupInputMap(String gamePad)
        {
            // Get input map for this player and configure it
            InputMap inputMap = PlayerManager.Instance.GetPlayer(0).InputMap;

            if (!Game.Instance.InputMapCreated)
            {
                int gamepadId = InputManager.Instance.FindDevice(gamePad);

                InputMap.ActionDelegate bButtonDelegate = new InputMap.ActionDelegate(_DetermineBButtonFunctionality);
                InputMap.ActionDelegate aButtonDelegate = new InputMap.ActionDelegate(_DetermineAButtonFunctionality);

                if (gamepadId >= 0)
                {
                    inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.Back, bButtonDelegate);
                    inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.B, bButtonDelegate);
                    inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.A, aButtonDelegate);
                }

                Game.Instance.InputMapCreated = true;

                return;
            }

            //Make sure only the controller that just activated the game can play
            inputMap.ChangeDevice(gamePad);
        }

The last line in that function changes the controller that controls that player to the proper device determined by the active controller.

Now, all of these variables change correctly outside of the _GetFortune() function, so I am thinking this may be an error tied to the PlayerManager, but like I said, I am at a loss and could be completely wrong. Any ideas anyone?


#1
04/13/2009 (7:22 pm)
Ok. I think I may have fixed it. Here is my updated _SetupInput() function:
public void _SetupInputMap(String gamePad)
        {
            PlayerManager.Player player = PlayerManager.Instance.GetPlayer(0);
            player = null;

            player = new PlayerManager.Player(null);
            player.InputMap = new InputMap();

            // Get input map for this player and configure it
            //InputMap inputMap = PlayerManager.Instance.GetPlayer(0).InputMap;
            InputMap inputMap = player.InputMap;

            int gamepadId = InputManager.Instance.FindDevice(gamePad);

            InputMap.ActionDelegate bButtonDelegate = new InputMap.ActionDelegate(_DetermineBButtonFunctionality);
            InputMap.ActionDelegate aButtonDelegate = new InputMap.ActionDelegate(_DetermineAButtonFunctionality);

            if (gamepadId >= 0)
            {
                inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.Back, bButtonDelegate);
                inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.B, bButtonDelegate);
                inputMap.BindAction(gamepadId, (int)XGamePadDevice.GamePadObjects.A, aButtonDelegate);
            }

        }

What i do here is null out the player defined in the player 1 slot, create a new player in that slot, add a new input map to it and define the new mapping. For whatever reason, this fixes the problem i was having...