How to manage entity display data and logical data? - language-agnostic

What's a good way to store an entity's display data and an entity's logical data? Entities need to go on seperate layers (so like, background objects go behind foreground or so that enemies are always displayed underneith of bullets, etc.). The problem is, how do you manage these lists?
Does this seem like a logical solution?
I have a World object. The World object stores a list of all entities. To create a new entity, you go world.createEntity(type) and when a new entity is created, the world fires an entityCreatedCallback function that notifies all of the listeners that a new entity was created. In my PlayGameState class, I attach a listener to the world to listen in and when a new entity is created, I add that entity to an appropriate display layer for drawing later.
Then during the game loop I cascade like this:
allScreens.update() -> world.update() -> allEntities.update()
allScreens.draw() -> playGameScreen.draw() -> allLayers.draw()
Does that seem reasonable?

You are talking about a 2D game, right?
I like your architecture, because it seperates the creation of the entities with their initialization and use. I think it is clean and extensible.
In a game I wrote I had a similar approach, but my rendering engine made it easy for me and supported DisplayGroups which automatically rendered the objects in the right order. I don't know what technology you are using, but generally speaking if you are using hardware rendering with OpenGL/DirectX you could use the Z values to achieve the effect (literally place background objects behind).
In case you use software rendering, I think there is no other option than to order the objects before you draw them on the surface.
HTH

Related

Reuse Instance Names for Different Objects

Simple question: how can I reuse instance names for different objects (obviously on different frames)? I really want to be able to use the same instance name for all my scenes, "ground", even though these ground instances are of different classes. I really don't want to have to go about naming them "ground0", "ground1", etc.I realize that there are ways around this, but I would hate to fool around with all that extra work. So that being said, how do I reuse the instance name "ground" without having this warning thrown at me?:
Menu, Layer 'ground', Frame 1 Warning: The instance name 'ground' is declared on an object of type Ground but there is a conflicting use of the instance name 'ground' on an object of type Ground2.
And by the way, I realize that an instance is supposed to be an occurrence of a specific object, but to be honest I don't quite see the point in not being allowed to reuse instance names when appropriate. Any help would be much appreciated.
If I recall how finicky Flash was, it may have something to do with how you created the "ground" instance on those frames.
By that, I mean:
Did you create one instance first, and then created new keyframes afterwards (meaning: the same instance would be used in all keyframes), or...
Did you begin by creating your empty keyframes first, and then drag-dropping / pasting one "ground" instance in each frames? (meaning: in this case, it would likely be treated as 3 separate instances).
I'm not sure if this assumption is correct, but Flash doesn't necessarily tie instances to layers, as in "Oh, ground is on Layer 1, therefore every frames should reuse the same instance...". In a perfect world, I agree this would make sense. But from the early versions of Flash when it was mostly targeted to animators, where anything goes (from having multiple shapes and instances on the same frame, from re-arranging the depth of groups / instances on one frame/layer), it's still making the assumption that if you drag / copy an item from the library to the stage, it doesn't necessarily mean they are the same instance. Instead, you have to babysit Flash by creating more keyframes (or tween keyframes depending on your need) after the frame with the existing asset instance you want to reuse.
Again, the above is an assumption based on my experience - but if you did enter the "ground" instance-name manually for each instances found on each frames, chances are you previously copy/pasted or dragged new instances to those frames.
Does it sound like something you may have done?
EDIT:
If you have "ground" assets across a few frames, which are instances of different Symbols, then that definitely would trigger those Warnings you've been getting. I'm not sure where you can turn those off (Preferences? Project Publish settings? Advanced AS3 settings maybe?).. but regardless, here's a way that may work for you, programmatically.
Since each frames have a unique instance, with each instances named "ground", you could create a helper function to work like the .getChildByName("ground") method (and to be honest, I'm not sure if that method would work right-off the bat, you could try). You would need to for-loop through the given MovieClip's children (In your Menu's children, in your case I believe?), and check if(child.name==theNameInQuestion) return child;.
That being said, I can't guarantee this is THE proper solution (didn't test), as I don't know how you're navigating the frames at runtime (play/stop/gotoAndPlay/gotoAndStop/etc), and that may affect which "ground" instance is available at a given time. Internally, Flash does addChild/removeChild to swap out those various "ground" instances as it cycles through the frames, it's not a simple visible=true/false toggle (AFAIK).
EDIT 2:
This could be what you need?
If any programming language if you want to reuse instance name variables you simply type them with the top most superclass type. In your case that would be:
var ground:DisplayObject;
ground = new Ground!();
ground = new Ground2();
//etc ....
Edit: If using property panel you can't use the same name for 2 objects as there will be no way to differentiate between them. So an error will be correctly thrown.
Now if you want to use in code only one name same principle as shown above applies:
var ground:DisplayObject;
ground = ground0;
ground = ground1;
//etc ....
Then you can safely use in code the variable ground.

Preferable way to manage data, classes or arrays?

I'm making a turn based RPG in Flash, with AS 3 as the language, though I'm pretty sure you could help me regardless of the language you are using.
Basically, my idea was to put all of my weapon data on a single multi-dimensional array. Now if I want to add a weapon into my inventory, easy, i just use inventoryArray.push(weaponArray[1]) Easy, I just added the weapon into my inventory.
I've been looking into Design patterns, and it seems that most OOP designs are using classes and inheriting from a superclass. Component-->Weapon-->Sword-->LongSword.
What should I go with, putting all data in one array or using the inherit style, with one class containing a single weapon?
Any Ideas are welcome! I basically know how to make the game in itself, its just that I don't know some patterns I should go with.
Most of the objects in your game are going to have some properties in common - for example, maybe they will all have an ID, a name and a description.
If you don't use inheritance, you will have all your classes having this duplicate information in them, which will make your game hard to maintain.
If you do use inheritance, you can have all these common properties in a base (probably abstract) class and have all the other classes inherit from it. So yes, the design pattern you looked at is the way to go.
Also, rather than do inventoryArray.push(weaponArray[1]), you should also create an Inventory class with an add() method. That will allow you to dispatch events when an object is added to the inventory. The front end can then listen to this event and, for example, update the inventory graphics. In general, you should never use generic Flash objects (Array, Object, etc.) for potentially complex objects like inventory, characters, etc. Using your own custom classes allows you to easily extend them as your game becomes more complex.
I'd say composition over inheritance is the way to go.
There is a basic gameobject class that could be extended to weapons,rings,helms,shields, potions etc. These all have a set of restrictions that can be managed through inheritance (like the fact that you can place a weapon in hands and inventory only). But abilities of all of these (how they affect the character) should be done through compositions. Every time you add an object to the sash, hand, head etc. they affect the character through composition. So when you're dealing with the character's action, you don't loop through every object, you just use the composite function like attack, which has all the functions of the inventory that apply part of the character action.
The other design pattern you can look into is the decorator pattern. I find that the outcome is pretty similar to composition. "While the decorator pattern lets us add responsibilities to objects without subclassing, the composite pattern has a different goal: structuring classes in order to handle related objects in the same way, and multiple objects can be treated as one." source
example of decorator pattern:
http://www.as3dp.com/2011/06/well-armored-warrior-decorator-for-beginners/

How should I substitute an image in a larger animation using AS3?

We're making a Flash browser game with a few reasonably complex animations. Our designer is making the animations in Flash Professional while I'm wiring everything up and adding some logic through AS3 (using FlashDevelop).
In one of our more complex animations a "bonus item" moves around the screen. It tweens hither and tither, there special effects and as such, it disappears for a few frames and then reappears later.
From AS3 we want to be able to dynamically decide which bonus item (say a mushroom or a star) to include in the animation. We don't want to have to ask our designer to replicate the entire animation for each of our bonus items.
This is what we've tried:
Created a two frame (1 mushroom frame, 1 star frame) "BonusItem" movieclip in FlashPro and Exported for ActionScript.
Created the complex animation movieclip in FlashPro and added the BonusItem movieclip to the relevant frames. Gave the BonusItem instance an instance name on all necessary KeyFrames. Exported entire movieclip for ActionScript (exported as "ComplexAnimation").
Intention:
The intention was to be able to do this:
var complexAnimation:ComplexAnimation = new ComplexAnimation();
complexAnimation.bonusItem.gotoAndStop("star"); // Frame labels have been added in FlashPRo.
this.addChild(complexAnimation);
This would play the complex animation with the star and we could easily call gotoAndStop("mushroom") to play the same animation with the mushroom.
Problems:
The first problem was that complexAnimation.bonusItem was null on line 02 above. I solved this by handling ADDED_TO_STAGE for complexAnimation and putting line 02 above in the handler.
The next problem was that each time the bonusItem movieclip started tweening, or if it was not present in some frames and was subsequently re-added the complexAnimation.bonusItem attribute/reference was reassigned to a new bonusItem instance. I then had to find a way to know when this was happening and call gotoAndStop("star") on the new instance.
I've found two ways to do this:
1) Listen for ADDED events on complexAnimation with a target.name of "bonusItem". It's a bit crap in a strongly typed language to have to resort to matching strings, but this works. Btw, when the ADDED event is fired new frame object references are still null.
2) Listen for FRAME_CREATED events. This happens later than ADDED at a point where new frame references have been initialized. As such I can check if complexAnimation.bonusItem is non-null at then call gotoAndStop("star") on it. One problem with this is that calling gotoAndStop actually triggers another FRAME_CREATED event to fire, so I need to guard against infinite looping. Again, it works but I don't have a great feeling about it.
Conclusion:
Well I don't really have a conclusion other than I feel like I'm working really hard to do something relatively simple. I'm hoping there's an easier & more robust approach. I have a strong feeling that I'm going crazy. Anyone know a better way to do this?
If you have an object that exists on a timeline and it has an instance name, and you need to be able to maintain a reference to it through the duration of the timeline, then it must exist on every frame (and in the same layer!) of the movieclip. I grant you, your workarounds get the job done but you have already experienced the pain involved in doing so.
The path of least resistance is to just have the object exist at all times. If the user shouldn't "see" it, just hide it offscreen somewhere. Just make sure it always exists, contiguously, on that timeline layer from frame 1 all the way to the final frame.
The other thing I'd suggest is to stop deeply nesting movieclips in the hopes of using those nested clips as state representations. This is one of the things that sadly was very easy to do in the AS2 days, but has been rendered impractical to the point of madness in AS3. Anything deeper than 1 layer is getting into some dicey territory. 3 layers deep and you need to rethink your strategy. Perhaps instantiating different movieclip instances from the library and adding/removing dynamically instead of relying on frames.
I thought I'd update this post with our current (and hopefully long-term) solution.
First of all, I made an error in the above post:
The next problem was that each time the bonusItem movieclip started tweening ... the complexAnimation.bonusItem attribute/reference was reassigned to a new bonusItem instance.
This was incorrect. Flash was indeed assigning a new instance of BonusItem, but it was caused by a Mask layer keyframe rather than the tween.
I had been keen to try to avoid having any logic which relied on string comparisons, but in the end I swallowed my pride to make life easier.
Our designer gives all relevant objects (stuff that we'll need to access from AS3) instance names on each keyframe in the timeline. If the object is nested within other objects our designer must assign those parent objects instance names too. We must coordinate those instance names so that dev know what the accessors are called - we would've had to do all this anyway. Our designer also still has to "Export For Actionscript" a class for each relevant movieclip (e.g. BonusItem).
In AS3 we're using Robotlegs for dependency injection and as the basis of our MVC framework. Robotlegs suggests that application-specific logic should be separated from view-specific logic. It allows us to specify a logic class (called a Mediator) to be associated with each and any of our views. As such we can do the following mapping:
BonusItem -> BonusItemMediator
This means that every time Flash creates a BonusItem on the timeline Robotlegs somehow knows about it and creates a new instance of BonusItemMediator (which we write ourselves and have full control over). In addition, Robotlegs can easily give us a reference from our BonusItemMediator to its associated view instance (the BonusItem instance). So inside my BonusItemMediator I can ask the view reference what its instance name is. I also walk up its parents to the stage and record each of their names to generate a resultant string of instance names that uniquely specified this instance of the BonusItem.
e.g.
"game.complexAnimation.bonusItem"
Once I know this I can ensure that the bonusItem is showing the correct image (star or mushroom) with the following code:
var frameLabelName:String myGameModel.whatTheHellShouldThisBeShowing("game.complexAnimation.bonusItem");
this.view.gotoAndStop(frameLabelName); // where view is the BonusItem instance
So now regardless of how or when Flash seemingly randomly decides to destroy and recreate my bonusItem I'll hear about it and can ensure that that new BonusItem instance is displaying on the correct frame.
The main weakness with this solution is that we're relying on string comparisons. Our designer could easily mistype an instance name and we wouldn't hear about it until that code was hit at runtime. Of course tests mitigate that risk, but I still feel that it's a shame that I'm using a strongly typed language, but then not making use of the compile time type checking.

AS3 OOP Game Development Structure

I'm wondering what is the best practise for gamedevelopment for actioncript 3.
I'm currently in the progress of creating a tile-based game, but I'm already having some troubles using seperate classes.
This is the current situation:
Main class
Generates the tiles
Adds player class
Adds interface class
The interface class contains all interface elements. For example, there is an option to spawn an object into the game. This object could be placed on a selected tile.
Now the problem is a followed: The spawned object is placed within the interface class, how should the spawned object be able to communicate with the tiles?
This same problem arises with several other parts in the game. Like how should the player be able to interact with the spawned object? Everything is in different classes making the communcation between all these things so difficult.
Is there any standard procedure regarding game development which handles this problem?I was thinking of making a "world" class where every object should be placed somehow. But it's hard for me to actually make this with the little knowledge of this sort of structure that I posess.
This is all sort of new to me, so I would appreciate it if the explanation would be as noob proof as possible.
Thanks in advance!
You can use event dispatching for your objects to communicate with one another, there are several approaches available, one of the simpler approach would be for you to create a controller class whose sole responsibility would be to dispatch & listen to events, in order to inform the relevant classes of what's occurring within your game
A better approach could be to use a framework such as Robotlegs, the learning curve is a bit steeper but worth the extra effort.
http://www.robotlegs.org/
You should easily find examples & tutorials for Robotlegs.
Try to imagine the organization of the parts of your game in a slightly different way. In the first place this World class you mention could contain both the Map object also contain the Unit objects for the spawned player or creatures. The Map object which also contains Tile objects which each one have its own information as terrain and attributes. Also the Unit objects would contain the information related to each spawn. For the interaction with your player you could have a Game object that contains both the World and a representation of your player, namely a Player object, and this Game object would communicate the instructions from the player towards the World as to make things happen. As you can see each object contains other objects of finer detail, the World contains the Map that contains the Tile's, this way the higher object uses the lower finer objects and makes them all communicate between them.
This could be a good approach to start something quickly or to learn while you experiment. More complex situation require other ways of arranging all the information of the game like the Model-View-Controller structure, but you probably should not worry to much about it until you have learned enough as to know you need a better solution.
I would suggest to read a little about design patterns. A singleton Dispatcher class can help in your case, you just bind everything to it and send events from one entity to another.
The reason why not use the built-in events is that you would need your objects to be on the display list.

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>