Search code examples
actionscript-3saveflash-cs6shared-objects

Save Number with Shared Object and Add to that Saved Number.


Hey everyone so basically what I am trying to accomplish is saving a number with the Shared Object which the the coins that the player collects in the game and if they player quits out of the game and comes back to play again the amount of coins he had when he quit will still show and he will be able to add to that amount if the player picks up more coins. I had this working for a bit but then the textfield started displaying "NAN".

Here is how I have it set up.

The Variable private var nCoins:Number;

In the constructor function I have:

sharedObjectCoins = SharedObject.getLocal("CoinsData");

        nCoins = 0 + sharedObjectCoins.data.tCoins;

        if (sharedObjectCoins.data.tCoins == null)
        {
             sharedObjectCoins.data.tCoins = nCoins;

        }else 
         {
               trace("Save data found."); // if we did find data...
               loadDataTimeAttack(); // ...load the data
         }

and in the games Enter.Frame Loop I have the function saveDataCoins which is setup like so:

    private function saveDataCoins():void 
    {

        if (nCoins > sharedObjectCoins.data.tCoins )
        {
            sharedObjectCoins.data.tCoins = nCoins; 
        }


        coinsGraphic.coinsText.text = " " + sharedObjectCoins.data.tCoins;
        sharedObjectCoins.flush();

    }

not sure if you need the function to where the hitTest takes place between the coins and player but here it is:

private function checkPlayerHitCoins():void 
    {

        for (var i:int = 0; i < aCoinsArray.length; i++)
            {
                //get current point in i loop
                var currentCoins:mcCoin = aCoinsArray[i];

                //test if  player is hitting current point
                if(player.hitTestObject(currentCoins))
                {

                    nCoins += 1;
                    updatecoinsTextScore();
                    updateCoinsPauseScreen();
                    //Add points sound effects
                   var coinsSEffect:Sound = new coinsSound();
                   coinsSEffect.play();

                    //remove point on stage
                    currentCoins.destroyCoins();
                    //remove points from array
                    aCoinsArray.splice(i, 1);
                    trace("Hit:  " + aCoinsArray.length);
                }
            }
    }

Please if anyone could help me with this maybe point something out that I am doing wrong. This code worked perfect one time and when I closed the screen and came back to re test it the textfield displayed NAN and thats it when I hitTest the coins sometimes the NAN switches to a number for like a second but then goes back to NAN.


Solution

  • The first time (or rather every time it creates a new shared object) you will be trying to add undefined to 0, which will result in either a runtime error or NaN.

    You need to check if the value exists before attempting to do addition with it.

        if(sharedObjectCoints.data && sharedObjectCoins.data.tCoins && !isNaN(sharedObjectCoins.data.tCoins)){
             nCoins = Number(sharedObjectCoins.data.tCoins); //there's not point in adding 0
             trace("Save data found."); // if we did find data...
             loadDataTimeAttack(); // ...load the data
        }else{
             sharedObjectCoins.data.tCoins = nCoins;
        }
    

    Also, if you don't manually set a value to a number var, it will start off life as NaN. eg var nCoins:Number will be NaN until you set it to something.

    That said, working with the sharedObject directly like this is a very sloppy way to code your program. Really you should just use shared object to load and save the value, and everything in between use a strongly typed variable.

    var nCoins:int = 0;
    var tCoins:int = 0;
    
    sharedObjectCoins = SharedObject.getLocal("CoinsData");
    if(sharedObjectCoins.data && sharedObjectCoins.data.tCoins && !isNaN(sharedObjectCoins.data.tCoins){
        tCoins = int(sharedObjectCoins.data.tCoins);
    }else{
        //no shared object, use default value for tCoins
        tCoins = 0; //or whatever it should start off as.
    }
    

    Then write a save function

    private function saveSharedObject():void {
        sharedObjectCoins.data.tCoins = tCoins;
        sharedObjectCoins.flush();
    }
    

    Then replace all other instances of sharedObjectCoins.data.tCoins with the var tCoins

    It's probably best not to flush the shared object every frame for performance purposes.

    Also, shared objects may or may not actually save, depending on user preferences, storage space available, etc. They should not be relied upon for critical data retention.

    You can listen for problems with the shared object with AsyncErrorEvent.ASYNC_ERROR I believe (It's been a while since I've worked with AS3 Shared Objects)