ActionScript3: Cannot save and load objects - AIR - actionscript-3

I am trying to create functions to save and load objects. I am storing the objects in File.applicationStorageDirectory...and using File Streams. At some point I thought my code did work, and then it stopped soon after. It also saved the last string I inputed but none of the others. I have pastebinned the functions I think will be necessary, even if someone could point me in the right direction. I am aiming to publish this on an Apple iPad...
http://pastebin.com/61WLLUAB
I am in the process of learning to program, and appreciate any constructive criticism with my layout.
Thanks

I think flash.utils.registerClassAlias() and SharedObjects will be the key for loading/saving objects. Be sure to implement IExternalizable on all objects that will be processed while you save and load your game.
About why does your function not work - first, you don't actually save your state between main sessions, you instead initialize all the objects anew, write them to files and then read them back, thus erasing previous data. You need to try reading an object out of file system prior to instantiating them anew, for each of the charID.IDs you have there. You don't have your IDs instantiated when your Main constructor starts, so Main doesn't know if any of the objects were saved beforehand.

Related

Where should these AS3 variables go?

I am trying to build the foundations for a platformer game in Actionscript 3. I'm still fairly novice at AS3, but I'm hoping this will help build my knowledge.
Anyway,
I understand that I can create Actionscript files that are associated with something such as a Sprite or a MovieClip by extending the Sprite/Movieclip class. I also know about Actionscript files that work as the 'Document class'.
Each level in my game will have different properties that vary such as gravity. Where should I store these variables? Obviously not in the player... Not sure if they're supposed to go in the timeline or the document class, or if they have a separate AS file of their own. I've been told that having global variables is generally bad, so I'm not sure what to do.
You can make levels as separate files that are even not Actionscript, but XML or JSON, since your levels are basically data structures with different starting values. And you can make a Level class that can take such a file, parse it and initialize an in-game level structure based on what's read. Yes, such data should not go to timeline, because should you need to change one piece of that data, it could implicitly affect other game processes. Also, one simple right click can ruin such a game :) I myself use JSON files as my level data holders, and I parse them at the initialization time, you can do like this or say when your level is being loaded.
In short, if something is different by initial data, but common in methods, it should reside separately from main code, or entire code, and be included as data.
I think this similar question and answers will help you somewhat:
As3 OOP game structure (class architecture)
Basically, "What you want to do is to separate what changes in your game from the game itself". So definitely do not include the code in the timeline.

AS3: How to save every object on stage

I'm trying to make something similar to this:
http://www.personalwine.com/catalog/label_designer_app.php?templateId=5046&action=4C92&userId=0
in Flash IDE with AS3.
My problem is how to save all objects on a stage, save it as a "template" and reuse it again - not as images, but as objects that can be editable again.
Could anyone point me to the right direction on how to solve this problem.
Thanks in advance!
Maybe a xml save/load function could help. Once one created something on save, all attributes of each object are written to a xml file. If you want to recreate, then you parse the info and build the screen.
Where?
You have two choices for saving data, you can either save it on the user's computer (client-side) or on your own server (server-side).
On the server
If you're going to use anything that is server-side related well, obviously you're going to need a server (and a database). Using php with mysql is both free and very fast for this sort of usage (small). You might also want to look into node.js since it will probably come very intuitively to an actionscript user since node is javascript and the syntax and structure of node.js files and actionscript files are very similar.
On the user's pc
If you just want to store the data on the user's computer, you can use a SharedObject, it will save all the data you need (variables and such) on the user's computer.
Here is a short nice tutorial on how to do so:
http://kirill-poletaev.blogspot.com/2010/07/how-to-save-local-data-with.html
Here is a much bigger and more detailed tutorial:
http://active.tutsplus.com/tutorials/actionscript/movieclip-reconstruction-with-the-sharedobject-class/
Basically you can do this for all the variables you want to save (movieclip locations, etc) and then load them. It is very straightforward, you can even store a whole movieclip object.

Garbage collection - manually wiping EVERYTHING!

I have been building a game for a while (nearly done) - But the game needs a replay button and its a big task.
I know the GC is dreadful in flash, but I wanted to know if there is a way to wipe EVERYTHING as if the flash app has just begun. Clearing memory, game data - I haven't to worry about game loading as its not really heavy on data.
Everything pretty much lives in a DataModel - but I fear if I just clear the all variables, I'll have pockets of orphaned memory.
Any forwarding idea would be great.
cheers guys.
I would do this:
make a class that encapsulates your entire game, called GameContainer or whatever.
Do a search on all your source code, and make sure that in every call to addEventListener, you are passing true for the "use weak references" argument.
In your document class (or frame script), make a single instance of GameContainer and add it to the stage, and do nothing else.
Now when you want to entirely clear your game from memory, remove GameContainer from the stage and null the reference. Memory will not immediately be released, but everything in your game will now be eligible for release. If Flash thinks it needs more memory it will trigger a GC, and the large orphaned GameContainer will be nuked. (Step 2 above will keep your event listeners from counting as references to your objects, and make sure that all self-contained objects are eligible for disposal.
Not sure what you mean about Flash's GC being dreadful though. I can't recall having heard of any bugs in it. It won't nuke your objects unless you are careful with your references, but that's true of all garbage collection.
Not short of refreshing the page. There might be some hack you could do by loading a separate swf and then unloading it, but that would be just as error prone as doing it the proper way.
My advice would be to just buckle down and write your reset function then get something to monitor memory and make sure it works by reiniting/resetting a bunch of times.
The problem with Flash's garbage collector is that as far as I know you cannot FORCE it to "collect". I had this issue with a program in which I would load in various external SWF's, and occasionally Flash would simply not load them. What you may need to do is make a function to set every major variable in your code to null at the end of a game, if you want a true reset.
There is still no guarantee, but unfortunately I'm fairly certain there is no shortcut to force a memory release.
(For me this meant also making sure my event handlers were cleared properly, and my loaders would "unload()" after passing their content off, in the case of my external SWF loader.)

AS3: Model and View Communication in a Game

So I'm attempting to use the MVC pattern for a game I'm working on. Everything has been going pretty smoothly so far, but I'm having trouble figuring out how to get my model and my view to talk to each other effectively.
My general model structure involves lots of nested information.
a Level has Rooms
a Room have Layers
a Layer has Objects
Each layer has an index and a corresponding layer in the view that is rendering it. I need the objects to post an update message as they animate so it's corresponding layer in the view can update. I'm trying to use the built in event system to handle these updates.
My issue is I'm not sure how to avoid putting listeners on every object in the game - which strikes me as bad ( perhaps I'm wrong here ). If I change the rooms, the layer doesn't have a way of removing listeners from the objects in the last room because it only accesses layers through the current room. Objects are only updated when they are in the current room, so the other objects won't need to fire events.
The view is set up to cascade events to all of the children, so the root node can receive all updates ( I think I did that part correctly ), and the layer can match the target because it knows which layer it's rendering. The problem is getting the message out from the objects to the view.
Of course this makes sense to me, because I've been working with the code for a while now.
If I can provide more clarification please ask. This is my first time working with the MVC pattern, so I'm sure I could do things better.
If you have any suggestions as to how I might solve this conundrum, please share!
Edit: I have something working keeping track of the current layerset from outside of the view and the model which manages adding/removing the appropriate event listeners and delegating the update event to the layer as suggested. But please, anything I can do to improve this please do.
If you are new to MVC you may want to check out the PureMVC framework for AS3. When I first started learning MVC I started by trying to build my own implementation of the pattern. After trying out PureMVC I got a much better understanding of the structure of MVC.
Your rooms/layers/objects sound like they have a parent/child like relationship and may be a good candidate for the composite design pattern. Basically this is a tree like structure where you could trigger an event which would then cascade through all branches. If you do a search for 'composite pattern' you may get a better explanation of how this may work for you.
There a few solutions you could take, adding event listeners is reasonable, but as mentioned you are going to need to make sure you clean them up appropriately, but this will be a requirement with a lot of other solutions as well.
Another one would be to pass in the layer on object construction, perhaps in the form of a "parent" property. In this case the object would notify its parent whenever it has changed, then on layer update, it would go through and handle all objects who have registered as having changed. This has performance benefits in that the object could change several time between renders, but the parent would only act on this changes once, (when its been told to update itself.) In this case you would still need to make sure you clean up your references properly to avoid garbage collection problems.
Yet another solution would be objects register with them selves as having been changed, typically in the form of a simple Boolean value. In this case the parent (your layer) would loop through all children, presumable stored in some form of collection, and handle updates to all those who say they've been changed. This solution removes the dependencies from object to layer, but in extreme cases, could lead to performance issues, (Extreme case being so many objects the process of checking a single Boolean value on them is too much to handle (that'll be A LOT of objects))
Hope that helps.
Using the Mediator pattern in PureMVC, rather than putting listeners on every object, you could have a Mediator listen to the application instance for the events. Then inside the actual objects, send a bubbling event that bubbles up the display hierarchy to the application where the Mediator hears it. Then the mediator takes the appropriate action such as sending off a notification to trigger a command with some logic, perhaps. The target of the event, would of course be the item in your world that sent the event, so if the Command would need to manipulate or inspect that item, then just pass the event.target in the notification body. QED.
-=Cliff>

How to save and load different types of objects?

During coding I frequently encounter this situation:
I have several objects (ConcreteType1, ConcreteType2, ...) with the same base type AbstractType, which has abstract methods save and load . Each object can (and has to) save some specific kind of data, by overriding the save method.
I have a list of AbstractType objects which contains various ConcreteTypeX objects.
I walk the list and the save method for each object.
At this point I think it's a good OO design. (Or am I wrong?) The problems start when I want to reload the data:
Each object can load its own data, but I have to know the concrete type in advance, so I can instantiate the right ConcreteTypeX and call the load method. So the loading method has to know a great deal about the concrete types. I usually "solved" this problem by writing some kind of marker before calling save, which is used by the loader to determine the right ConcreteTypeX.
I always had/have a bad feeling about this. It feels like some kind of anti-pattern...
Are there better ways?
EDIT:
I'm sorry for the confusion, I re-wrote some of the text.
I'm aware of serialization and perhaps there is some next-to-perfect solution in Java/.NET/yourFavoriteLanguage, but I'm searching for a general solution, which might be better and more "OOP-ish" compared to my concept.
Is this either .NET or Java? If so, why aren't you using serialisation?
If you can't simply use serialization, then I would still definitely pull the object loading logic out of the base class. Your instinct is correct, leading you to correctly identify a code smell. The base class shouldn't need to change when you change or add derived classes.
The problem is, something has to load the data and instantiate those objects. This sounds like a job for the Abstract Factory pattern.
There are better ways, but let's take a step back and look at it conceptually. What are all objects doing? Loading and Saving. When you get the object from memory, you really don't to have to care whether it gets its information from a file, a database, or the windows registry. You just want the object loaded. That's important to remember because later on, your maintanence programmer will look at the LoadFromFile() method and wonder, "Why is it called that since it really doesn't load anything from a file?"
Secondly, you're running into the issue that we all run into, and it's based in dividing work. You want a level that handles getting data from a physical source; you want a level that manipulates this data, and you want a level that displays this data. This is the crux of N-Tier Development. I've linked to an article that discusses your problem in great detail, and details how to create a Data Access Layer to resolve your issue. There are also numerous code projects here and here.
If it's Java you seek, simply substitute 'java' for .NET and search for 'Java N-Tier development'. However, besides syntactical differences, the design structure is the same.