actor position resets to original when changing scenes

hi guys
i asked a similar question a while ago and got some good advice but am still wondering about something....i have an actor in my scene...i originally placed the actor with simply draging and dropping....then i use a move behavior to move it to a specific place...but then if i change scenes and go back to this scene, my actor is back in its original position. why is that?

thanks!
dan

Best Answers

  • tatiangtatiang Posts: 11,949
    Accepted Answer
    When a scene resets (or is reset using a Change Scene behavior to that scene), all of the actors are in their original positions.

    If you want the scene to remember where the actor is, you need to store the position and then retrieve it.

    So in that actor, you would have two self attributes, both real, called self.LastX and self.LastY. When you change scenes from that scene, change self.LastX to self.position.X and self.LastY to self.position.Y. At the top of that actor have two behaviors: Change Attribute self.position.X to self.LastX and Change Attribute self.position.Y to self.LastY. Be sure to manually set self.LastX and self.LastY to the actor's starting position (wherever you dragged it to).

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tatiangtatiang Posts: 11,949
    edited March 2013 Accepted Answer
    and similarly....i have a rule in a scene that says:
    if game attribute x != 0 then add to game attribute y

    it works except if i change scenes and go back to this scene, it reruns the run and indexes it by 1 again. how do you make it index it only once using this rule? i want a seperate rule that can also index y further using another game attribute Z, but only want x to index it once if its not 0.....
    any ideas?
    thanks
    To run something once, wrap it in a rule with a boolean that gets changed when the scene starts. So you might change scene.firstRun (boolean) to true at the bottom of the actor that is increasing those attributes and then use scene.firstRun=true as a condition for any rules you want to run only once. Or if you don't want to deal with scene attributes, use a game attribute for each scene (game.Scene1FirstRun) or a table if you have many scenes.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tatiangtatiang Posts: 11,949
    Accepted Answer
    You might be better off using a game attribute for each actor. When Touch is Pressed AND game.ActorAPressed = false --> [change index]; Change Attribute game.ActorAPressed to true.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

Answers

  • danshawdanshaw Member Posts: 38
    and similarly....i have a rule in a scene that says:
    if game attribute x != 0 then add to game attribute y

    it works except if i change scenes and go back to this scene, it reruns the run and indexes it by 1 again. how do you make it index it only once using this rule? i want a seperate rule that can also index y further using another game attribute Z, but only want x to index it once if its not 0.....
    any ideas?
    thanks
  • danshawdanshaw Member Posts: 38
    thanks! i tried that but what what i think is going on is that i want the indexing event to happen when an attribure is changed...., so if i add the boolen firstRun attribute at the end, it gets changed to indicate it has been run before the attribute is changed so it doesnt index...

    in other words..when actor A is pressed, index changes to changes to 1..when actor B is pressed, it indexes to 2....but each actor press only can change the index once....not each time its pressed....

    thanks!
  • RedCubeGamesRedCubeGames Member Posts: 37
    edited May 2015

    @tatiang Hello I have a similar problem. I have one actor that is on my main scene (Sound on) that changes image when i press it (Sound off). My problem is now when i change scene to next and then i come back to main scene my actor is reset to original (Sound on) . So i want my actor to remember he was pressed (Sound off) and when i change scenes and come back to main scene he is still pressed (Sound off). If you could tell me how to do that i would be very grateful! Thank you :smiley:

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    @RedCubeGames Well, I would give you pretty much the same advice I gave above at http://forums.gamesalad.com/discussion/comment/387742/#Comment_387742. Being two years wiser I would say to use a game attribute and be sure to save and load it.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • RedCubeGamesRedCubeGames Member Posts: 37

    Ok, i made a game atribute and named it sound_off

    I created a rule in my actor - when touch is pressed and attribute game.sound_off is false

    change atribute game.sound_off to true

    I am really new to gamesalad so i know i am making mistake here with these rule and probably missing huge part of code but i don't know what next :blush: ... But If you could guide me please @tatiang

  • NspeelNspeel Member Posts: 17

    @tatiang said:
    When a scene resets (or is reset using a Change Scene behavior to that scene), all of the actors are in their original positions.

    If you want the scene to remember where the actor is, you need to store the position and then retrieve it.

    So in that actor, you would have two self attributes, both real, called self.LastX and self.LastY. When you change scenes from that scene, change self.LastX to self.position.X and self.LastY to self.position.Y. At the top of that actor have two behaviors: Change Attribute self.position.X to self.LastX and Change Attribute self.position.Y to self.LastY. Be sure to manually set self.LastX and self.LastY to the actor's starting position (wherever you dragged it to).

    @tatiang said:
    When a scene resets (or is reset using a Change Scene behavior to that scene), all of the actors are in their original positions.

    If you want the scene to remember where the actor is, you need to store the position and then retrieve it.

    So in that actor, you would have two self attributes, both real, called self.LastX and self.LastY. When you change scenes from that scene, change self.LastX to self.position.X and self.LastY to self.position.Y. At the top of that actor have two behaviors: Change Attribute self.position.X to self.LastX and Change Attribute self.position.Y to self.LastY. Be sure to manually set self.LastX and self.LastY to the actor's starting position (wherever you dragged it to).

    Man you really helped me earlier this week.. my games really coming along now! Although I hit a delay when it came to this problem this user posted about... I've read your response probably 50x, tried everything you thought me about tables, spawning invisable actors, and yet I couldn't wrap my head around getting my "towers" to stay put between scene changes..

    I tried giving them all commands to transfer there positions to a table, then when the scene changed just spawn them all to those table locations.. for some reason that failed and wouldn't even spawn a single tower... so could you, if possible, explain this alittle more in depth?

    I cant seem to find a way to allow for anything to happen when a scene changes..

    I also dont understand the wrap a rule in a boolean.. that lost me lol

  • JB makin' a gameJB makin' a game Member, BASIC Posts: 39
    edited March 2019

    First of all (since this is a trick that comes in handy quite often), wrapping a rule in a boolean is used to run something once. So for example, you want something to change size *1.2 when you click on it, but only once, otherwise the actor would grow huge very quickly when clicking a few times. So...
    [if touch is pressed
    and
    (boolean-attr.) self.actorIsClicked = false]
    set self.actorIsClicked to true
    change size *1.2

    Now about getting the towers in your scene that the user previously spawned (by buying or building them or whatever your game does). To be honest, eventhough I haven't tried it, it seems doubtful to me that using self-attributes is gonna do the trick, since they also reset when the scene does. And you seem to be spawning towers everywhere in your game and the newly created towers earlier on aren't going to be there when the scene resets/changes.
    Surely it can be done, though. It'll be a bit of a hassle, but it's certainly doable. Using a table with columns for the x and y positions for the newly spawned towers seems like a good idea for starters. You could add more columns: Tower=upgraded/stronger, DamageDoneAgainstTower, etc. And for the construction I'm thinking of and an integer column called TowerNumber or something like that as well. Create an index game-attr.TowerNumber (set to 1). I'm sure there are hundreds of different ways to do this, by the way.

    The table starts with one row with all fields blank. At some point the user spawns actor spawnedTower somewhere, it gets dragged and the moment the user drops the tower (that's how your game works, right?) and the code for making it draggable (rules with the constrained attr. from your other thread) is turned off, then:

    • set (index-attr) self.TowerNumber to game.TowerNumber
    • Change Table Value of yourTable, row 1
      (real) column "pos.x" to position.x
      (real) column "pos.y" to position.y
      (int) column "TowerNumber" to game.TowerNumber
      and add columns to specify your tower as much as you need.
      then

    • set game.TowerNumber to game.TowerNumber+1

    • Add Row At Beginning of yourTable.
    • Save yourTable.

    This should store all the tower's information in yourTable. To spawn these towers again in the reset/changed scene or even an entirely different scene, make an actor that:

    • set (index) self.rwCntYourTable to tableRowCount(yourTable)
    • set (index) self.rowYourTable to 2 (of course this is put as a default setting, because row 1 of yourTable will always be empty)
      [Loop if self.rowYourTable <= self.rwCntYourTable
      --Spawn actor: spawnedTower at pos.x: tableCellValue(yourTable, self.rowYourTable, col "pos.x") and same for pos.y
      --set self.rowYourTable to self.rowYourTable+1]
      This loop should spawn all towers in the positions that are saved in yourTable.

    In your spawnedTower actor could be an index-attr self.pos.xInRow and self.pos.yInRow that are set to tableSearch(yourTable, self.position.x, "col", tableColNumber("pos.x"), 1, tabelRowCount(yourTable), "exact") and tableSearch(yourTable, self.position.y, "col", tableColNumber("pos.y"), 1, tabelRowCount(yourTable), "exact")
    **and a rule: ** if pos.xInRow = pos.yInRow
    set self.TowerNumber to tableCellValue(yourTable, pos.xInRow, col "TowerNumber") pos.yInRow works as well, of course.

    When the user is playing the game and somewhere along the road, one of his towers gets destroyed. Before it's actually destroyed,
    -set (index-attr) self.rowTower to tableSearch(yourTable, self.TowerNumber, "col", tableColNumber("TowerNumber"), 1, tabelRowCount(yourTable), "exact")
    This returns the row with the tower's information, which needs to be checked again, because more towers may have been made or destroyed, so its rowNumber is probably not the same anymore.

    • Remove Row from yourTable, At Index: self.rowTower
    • Save yourTable
    • Destroy

    Wrote this far too fast to check out if it works or not and to check for mistakes or things that are forgotten. However, even if this doesn't work (and these things usually don't work when it's all theory and no testing), it should give you some inspiration how to approach your problem. And again: there are hundreds of way to do what you want. You seem to pick up GameSalad rather quickly, so I'm sure you can use some of this.

Sign In or Register to comment.