Can I look at a SpriteMaps naughty bits? (I want to iterate through its animations without knowing their names)


(Helios) #1

Spritemap is a pretty cool class in that you can package up a number of animations inside of it and send it off to be used somewhere else.

The only problem is, if I build up a coolSpritemap in classOne (complete with animations "stand", "run", "ponder", and "'splode") and send that spritemap over to classTwo,… well poor classTwo doesn’t know how to access the animations in coolSpritemap because it can’t (to my knowledge) say something like “play the first animation” or “play the second animation” as in coolSpritemap.play(coolSpritemap[0])

the only way to inform classTwo about these awesome animations that are already packaged inside of coolSpritemap would be to also pass it an array of strings that hold the animations, so that classTwo could say coolSpritemap.play(arrayOfNames[0])

is there any way I can avoid having to pass around two objects?


(Jacob Albano) #2

You can always modify the library itself.

Might I ask why you’re trying to do all this indirection? Loose coupling is all well and good, but I can’t help but feel you’re taking it to an extreme that might just make your life more difficult.


(Helios) #3

Would it be weird if I said I wanted to use the game I’m building as an application to get picked up by Google?

No, but seriously, It’s a combination of academic interest, preparing for larger future projects, not being able to control myself (decoupling is like the taste of the lotus fruit, once you start you forget how to come back), and genuinely thinking its a useful approach for this project.

I’ll be using plenty of direct dependencies, but in this case, I’m just curious if I can do something else.


(Helios) #4

I think I’m going to build a custom data type that packages together a spritemap and an array of names, that way I can enforce the usage.


(Ultima2876) #5

Be careful. I’ll leave you to explore without bursting your bubble too much, but almost every great programmer goes through a phase of “MUST PERFECTLY ENGINEER EVERYTHING”. Which isn’t always the best idea… I’m hoping that by telling you that I can shorten your overengineering phase :smile:

Basically, as with everything, a balance is best. If you spend all your time engineering the perfect game architecture you’ll never make a game, and if you do get lucky enough to end up with a playable product you’ll be sacrificing a lot of performance (and probably a lot of code readability and reusability - which is a lot of the point of what you’re trying to achieve in the first place!).

… I know that doesn’t answer the question, just thought I’d throw it out there!

[To give you a reasonable answer, making a small class that packages a spritemap and list of animation names sounds like a good way to handle it.]


(Jacob Albano) #6

Believe me, I know how addictive it can be; I have a hard time thinking without message broadcasting after using it for so long. I just think there comes a point where you’ve decoupled so many things that it’s more trouble to keep them working together than you could have possibly spared.

Flashpunk has a specific way of working which it’s very good at. I feel like you’re going to run into issues wrangling it to act in the way you want it to.


(Helios) #7

Points well made and taken :smiley: now to ignore them! I’m just kidding, it probably won’t be long before I abandon this visual abstraction thing and just use the ones that are there. It seems like graphic list may be more or less the thing im trying to build, but I don’t really know how to use them.


(Zachary Lewis) #8

You could always create a Spritemap and reference it from elsewhere.

public class SpritemapCatalog
{
  public static const CAT_WALK:String = "walk";
  public static const CAT_SWIPE:String = "swipe";
  public static function createCatSpritemap():Spritemap
  {
    var s:Spritemap = new Spritemap(CAT_SPRITE, 64, 64);
    s.add(CAT_WALK, [0, 1, 2, 3, 2, 1], true);
    s.add(CAT_SWIPE, [4, 5, 6], false);
    return s;
  }
}
var goodCat:Entity = new Entity(0, 0, SpritemapCatalog.createCatSpritemap());
Spritemap(goodCat.graphic).play(SpritemapCatalog.CAT_WALK);

(Helios) #9

Mhmm, so far so good. The problem is that you still have to reference the animation by name(albeit a nice, typesafe constant) rather than by index. So whatever other place you reference it from needs to have SpritemapCatalog.CAT_WALK hard coded into it, rather than learning about it dynamically at runtime.

Heres what I ended up doing to solve it:

public class SpriteMapWrapper 
{
	public var spriteMap:Spritemap;
	public var animations:Vector.<String>;
	public function SpriteMapWrapper(spriteMap:Spritemap, animations:Vector.<String>) 
	{
		this.spriteMap = spriteMap;
		this.animations = animations;
	}
	
}

so the client can call

myWrapper.spriteMap.play(myWrapper.animations[0]);

the client can be otherwise completely unaware of any details of the spritemap. It just has to be aware that there is a spritemap and it has animations. That means any client that has the wrapper can call the animations without having any concrete animation names coded into them.

does that make sense?

The upshot of this is that I can now dynamically bind entities to new visual layers with one line of code like this. The following code uses a factory which holds a number of “createX” classes similar to the one Zach made for a spritemap

var thing:entity = new entity(/*middle of the screen*/)
FP.world.add(thing);
thing.addvisual(new visual(referenceToThing, createSpriteMapWrapper("swordguy"), xofThing + 10, yofThing + 10);
thing.addvisual(new visual(referenceToThing, createSpriteMapWrapper("swordguy"), xofThing - 10, yofThing - 10);
thing.addvisual(new visual(referenceToThing, createSpriteMapWrapper("swordguy"), xofThing, yofThing+20);
thing.addvisual(new visual(referenceToThing, createSpriteMapWrapper("swordguy"), xofThing, yofThing-20);
thing.addvisual(new visual(referenceToThing, createSpriteMapWrapper("swordguy"), xofThing+20, yofThing);

and what I just did was create a single entity on screen that is parented to five swordguy graphics that all appropriately use their walking animations or sword swinging animations as needed (the helperObjects manage their own state and decide when to play which animation)

This would be great for a little real time strategy where one entity needs multiple independantly functioning graphics but they all need to share common states and behaviors. Or, picture this (a fight planned for my game):

a boss fight with a giant robot and a team of evil engineers in a junkyard. While the robot is attacking, the engineers are running around the junkyard, picking up salvage and attaching it to the robot. the robot incorporates the salvage and correspondingly gains new movements and attack patterns.

the engineers can attach a laser beam by calling

robot.addAction(new shootLaser());
robot.addVisual(new garbageLaservisual());

and bam its ready to role.

and the really crazy part is I’ll never need to create a “giantrobot” class that subclasses entity. It will just be a regular old entity that gets composed with other helperObjects that define its in game look and feel.

The hope is that in the long run, that means extensive reusability, and incredibly simple extension.

It may or may not work, but that’s the plan.


(Helios) #10

So. long posts, anyone?


(Ultima2876) #11

While that makes sense from a strictly “code” point of view… being able to set an animation based on number like that seems a bit backwards from a higher level (ie, actual use in developing a game) point of view. Why would you want to randomly set an animation without knowing anything about it? Surely it’s better to know something about the animation you’re setting - such as a descriptive identifier for it? Ssn’t setting animations by number going to end up being a code readability nightmare when you come back in 2 years to your project and wonder why your player changes myWrapper.spriteMap’s animation to myWrapper.animations[7] or, even more fun, when you want to add a new animation and have to then manually look up how many animations are in a given SpriteMap to find out which magic number to use etc etc…

Worst case scenario here is that you are creating a dependency on a concrete definition of a particular animation set. What I mean by that, is that every idle animation HAS to be animation #0, every walking anim has to be 1 etc. That’s usually a bad idea too, because even if you do document it somewhere it introduces problems such as inflexibility (what happens if you want to add an animation before your walking anim for whatever reason? Or rearrange all those animation IDs? What about sprites that will never concieveably need all those animations?). Also magic numbers are bad for readability; ideally you should avoid any number that is not 0 or a defined constant as a matter of basic principle. [Sorry I haven’t elaborated on this point much more, I’m currently working and don’t have a lot of time for this post]

It seems to be sacrificing practical code design for theoretical code design. Never a good thing in the long run, even if you could theoretically pull out your class and use it in another project because it has no concrete dependencies. Hint; it still does, they’re just dependencies on the coder’s knowledge, not the code’s knowledge. Who do you think wins when it comes to remembering stuff and spotting tiny logical errors, the human or the computer?

From the second half of your post it sounds like what you’re really trying to create is a component-based entity system (similar to what Unity uses) to avoid an inheritance-based one. This has its own advantages, disadvantages and design methodologies.

Keep up the good work though, the best way to learn is to try and I recognise a lot of what you’re feeling out here from my own experimentation when I was at university! Worst case scenario here is that you’ll learn a lot of stuff, so keep going :slight_smile: