Keeping the values of variables while world changes


(christopf) #1

since a few days i’m wondering how to i can keep values of variables throughout worldchanges. with some help i found a solution for my player entity with transfering him at every end to the next and back if needed.

but it need some lines and its only one single entity. now i want to keep the variables of some entities in the worlds (that won’t leave the world) but i can’t find a solution for that.

i think the problem lays at the way i switch worlds because i always call FP.world = new world(); so every entity always is newly created and added (which resets the values i want to be saved).

i could create all entities in a preworld and then position them out of the map but this would cost unnecessary ram i guess. is there n easier way?

TL’DR how can i keep my world unchanged when entering with the player entity a new one and come later back


(Bora Kasap) #2

You should read this topic(not for solution to your problem actually, but it have good information)

Also, i have an idea about your problem.

I think you should use “world.recycle(player)” function to remove your player entity with keeping it’s variables with actual values just before switching the world. Then you can call it back with “world.create()” function.

take a look in forum about using “create and recycle” functions.

Also you may use global static class for global variables, but it is not a suggested way to keep variables between worlds.


(christopf) #3

that’s a good link thanks @AlobarNon !

i actually fell over it already but since my player problem was solved i didnt thought of rechecking it. and now its working thanks to @jacobalbano tip with the var and the constructor.

but…now is my hero problem back on the table. before i solved it with adding the player from the current world to the new world before i switched them. so i could ensure the current hero with all its own vars will be the same in the new world. but this is only working if create a new one so i can directly call special functions in it (i think)

but since you gave me new input i feel the solution isn’t so far away (:


(christopf) #4

lmao…it’s easy as that:

FP.world = prevworld; prevworld.add(player);


(Bora Kasap) #5

if you have some initialization for variables in your player character’s “override public function added()” section that variables will be reinitialized when player added to another world even you use create and recycle functions.

So, you need to initialize your player’s variables only when defining new variables at the top of your player class like

private var currenthealth:int = 100;

or inside the constructor

public class Player extends Entity
{
  private var _currenthealth:int;
  public function Player(x:Number, y:Number, currenthealth:int)
  {
    super(x,y);
    _currenthealth = currenthealth; //this function doesnt work again when you add your player to a new world after recycle function.
  }

  override public function added()
  {
     x = levelstartX;
     y = levelstartY; //both works when you add your player to a new world so your player's x and y positions changed.
  }
}

(Mike Evmm) #6

This is not really a solution, but usually when I want “universal” variables, I just create a class (usually named S, for Statics) with a number of static variables that can be accessed and changed from anywhere.


(Bora Kasap) #7

Me too… Always… If you don’t need globals, finally you’ll need… So, do it now? Right?


(christopf) #8

I was just about to edit the post above to explain more in detail where the problem lays. I don’t have any variables in the added() function of my player that doing problems i guess. also i don’t have any global static yet since i read here so often that you shoudl try to avoid em. but can you change the value of a static variable? that would be quite cool to know

i will post now in this one here and more in detail desription of the problem. i think its working cause of coincidence but maybe i’m just too un-experienced? maybe it shouldn’t work at all x:

So i got 3 world classes to show: endtraume (kind of a preworld just to create a new instance for my hero so i dont need to create it in the other worlds and maybe to create all instances of entities for the game if that makes sense :blush:), aufwachen (the first level, fobb (the player) appears), morgentau (the second level).

I want fobb be able to move freely between the worlds without any changes of entities like plants or variables like collected plants caused through the levelchange.

endtraume looks like this:

        public function endtraume() 
        {
            super();
            
            FOBB = new fobb();
            add(FOBB);
        }
        
        override public function begin():void
        {
            super.begin();
            
            var _Aufwachen:aufwachen = new aufwachen(A.aufauf);
            _Aufwachen.addFOBB(FOBB, _Aufwachen.mapXML...x, _Aufwachen.mapXML...y);    
            FP.world = _Aufwachen;
            removeAll()
        }

aufwachen is next, the player appears so does some plants. the constructor() and the begin() are looking casual. the intersteing part should be the addFOBB() function (and the same endThis() like before just this one gets triggered through collision

        public function addFOBB(_FOBB:fobb, x:Number = 0, y:Number = 0):void
        {
            FOBB = _FOBB;
            FOBB.x = x;
            FOBB.y = y;
            add(FOBB)
        }
        protected function endThis():void
        {
            var _Morgentau:morgentau = new morgentau(A.moin, FP.world);
            FP.world = _Morgentau;
            _Morgentau.addFOBB(FOBB, _Morgentau.mapXML...x, _Morgentau.mapXML...y);
            remove(FOBB);
        }

and the thrid one, level2 morgentau. here its getting interesting because when i go back from morgentau to aufwachen everything is as i wish, only that its +1 entity i can explain (if the world would be added completly new there must been more new entities. but its only one so i think its fobb doubled)

        private var letzteWelt:World;
              
        public function morgentau(mapData:Class = null, wokommichher:World = null)
        {
            super();
            
            letzteWelt = wokommichher;
        }

        public function addFOBB(_FOBB:fobb, x:Number = 0, y:Number = 0):void
        {
            FOBB = _FOBB;
            FOBB.x = x;
            FOBB.y = y;
            add(FOBB)
        }

        protected function getBack():void
        {
            var _Aufwachen:aufwachen = new aufwachen(A.aufauf);
            _Aufwachen.addFOBB(FOBB, _Aufwachen.mapXML...x, _Aufwachen.mapXML...y);
            FP.world = letzteWelt;
            letzteWelt.add(FOBB);
            remove(FOBB)
        }

i’m quite confused, maybe you can see something in there? (hopefully its not too messy posted)


(Bora Kasap) #9

Omg, you made things really complicated.

Why are you trying to add FOBB to next world from current world? You need that? Did you tried adding FOBB to the next world inside the next world’s(i don’t mean next world with that, i mean previous world, so i mean letzteWelt) “begin()” function?

also you don’t need to add fobb in endtraume, using new fobb() is enough.

 FOBB = new fobb();
 add(FOBB); //no need this one

(Mike Evmm) #10

Again, why not have a separate class with a static var FOBB = new fobb(), and then add(S.FOOB) at the beggining of each level?


(Zachary Lewis) #11

You don’t have to create a new world to change the maps. I usually set up projects with two worlds: MenuWorld and GameWorld.

  • MenuWorld
    • Displays game title
    • Allows user to change settings, like sound
    • Allows users to clear game data
  • GameWorld
    • Covers all gameplay aspects
    • Loads levels
    • Handles combat

In GameWorld, if the player needs to go through a door into a new map, you can just fade out, clear all non-player Entities and tiles, load new Entities and map images, then fade back in. There’s no need to swap worlds.


(Nicole Brauer) #12

Hey, basicly what @miguelmurca and @AlobarNon said. But since you messaged me I’ll try to sum it up again:

There is nothing wrong with the way you change worlds (other than that you make it really complicated). To save “global” variables or entity variables you need a new class with static vars that store the values.

Create this: Globals.as (you can call it however you like)

    package game
    {
        
        public class Globals
        {
                                
                public static var lives:int = 3;
                public static var dead:Boolean = false;
                
                public static var num_magic_orbs_collected:int = 0;
            
        }
    
    }

You can create any global variables you want in there just like I did above. They should be vars you want to keep between worlds like your life count, items you collected (gotSword:Boolean = true/false) or if you have talked to guyX or what world you were in last (lastWorld:String = “letztewelt”)

Then in you world class do this:

public class morgentau extends World 
{
        
        public function morgentau(mapData:Class = null)
        {
                  

                  add(new Fobb());

                  super();

        }

    protected function getBack():void
    {
        //This is when you want to change the world/level, this doesn't have to be in your world class, can also be in an entity or something
        FP.world = new nächsteWelt();

    }
}

Note that your class morgentau (your world) should extend World if it isn’t already. To add your player just do add(new Fobb());

Now in your entities where you want to have variables that persist in every world (like your player ent) instead of this:

public class Fobb extends Entity 
{

    private var lives:int = 3;

    public function Fobb() 
    {
        lives += 1;
    }
}

do this:

import game.Globals; //Import your Globals.as , or whatever you called it.
public class Fobb extends Entity 
{

    //no need to set live to 3, it's already set in Globals.as (see above)

    public function Fobb() 
    {
        Globals.lives += 1;
    }
}

~

Or just do what @zachwlewis said.


(Jacob Albano) #13

I’m going to take this opportunity to refer to another post which explains why using a monolithic class of global variables is a bad idea and you should avoid it if at all possible.

@AlobarNon your solution (recycle/create) won’t work because each world instances keeps its own list of recycled entities. It has nothing to do with properties being overwritten or initialization being done in the wrong order.


(Mike Evmm) #14

I give in, perfectly good point there. However, how would you go about in this situation?


(Zachary Lewis) #15

More people should take @VoEC’s advice.

I think they have their uses. I’m quite fond of using them for keeping track of overall game progress. For example, consider a Puzzle RPG.When a game starts, it pulls saved data from a local SharedObject and pushes them into a GameVariables class to store things like totalCoins and playerExperience. Then, whenever the player plays (PuzzleWorld), the coins and experience he earns is saved to GameVariables. Then, when he buys potions or whatever (StoreWorld), his coin total would be reduced.

How would you do this? Read and write directly to the SharedObject?


(christopf) #16

For now it seems to me that zachs solution is the one that fits most and makes it the hardest too because i have to rethink this whole model again.

With the statics its working now but i still get +1 entity every time i switch the world. (i thought first its because i save the world state and after it remove fobb. but the other way around it aint changing)

my first approach before asking for other solutions were the idea of inherit some variables through a mother world class. but somehow it didnt work either. i think for this game i will keep it with the globals and for the next try zachs approach.

but i still like jacobs idea of leaving the globals out. (means i like reading your discussion =) )


(Jacob Albano) #17

Well, I suppose I could be super pedantic and say that SharedObjects are functionally the same as global variables, but that’s taking it a bit too far, don’t you think? :wink:

There’s certainly a point where some amount of global state is just flat-out required. Saved-game data is a good example. For the record, I use basically the same approach as you described in Iridescence. The only static variable in the whole game is a property on my Game class called config. On that class I have properties for which levels are unlocked, what the volume is for sounds and music, and other things like that.

The important thing is that I’m never doing logic with those values; no using them in conditions outside of the class or allowing my game at large to modify them except through strictly defined interfaces. And the best part is, since it’s not just a static class with a whole mess of variables, I can reset everything to default (for clearing progress or recovering from a failed load) by just doing Game.config = new Config() – from within the Game class, natch.

Unfortunately the vast majority of the time I see global variables being used or recommended is for cases like this; one class that acts as a catch-all for a bunch of unrelated data that will probably end up causing problems down the line as more and more variables get promoted to statics. I think I can confidently say that having a class called Globals.as is always a bad idea, but I’m far more accepting of private static properties that only one specific class type can access, or more widely available read-only values that exist as properties on a static instance of a configuration class.


(Mike Evmm) #18

So sorry Zach, I completely forgot your solution! :frowning: