Forum Topic: Unwanted MC to Sprite at runtime

(141 views • 12 replies)

This topic is 1 page long.

<< < > >>
None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/2/09 07:51 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

So I'm working on a pause function for my game.

Instead of manually writing code to pause all possible animations that a movieclip has, I wrote a function that runs through its children recursively until it reaches the end. For each child it checks to see if it's a movieclip, if so it will run a stop() on it. This works fine, except that I noticed it wasn't pausing my walk cycle. Upon some investigation I found that while I created the walk cycle as a movieclip, it is recognized by flash as a sprite when the game is actually loaded. This does not make sense because the walk cycle clearly has more than one frame.

Adding any kind of code to the MovieClip will stop flash from seeing it as a sprite, so to fix this I can just go into the animation and add '//' to any of the frames. An easy fix, but annoying. Also feels like a hack. Maybe I'm missing something fundamental here, but I was wondering if anyone else had encountered this or had some insight.

Here's my pause code btw:

public static function togglePauseChildren(curObject:*):void
		{
			if(getQualifiedSuperclassName(curObject)=="flash.display::MovieClip")
			{
				if(curObject.numChildren>0)
				{
					for(var i:uint=0; i<curObject.numChildren; i++)
					{
						var curChild:* = curObject.getChildAt(i);
						if(getQualifiedSuperclassName(curChild)=="flash.display::MovieClip")
						{
							if(gamePaused)curChild.stop();
							else curChild.play();
							togglePauseChildren(curChild);
						}
					}
				}
			}
BBS Signature

None

AshlynSanchez

Reply To Post Reply & Quote

Posted at: 6/2/09 11:08 PM

AshlynSanchez NEUTRAL LEVEL 02

Sign-Up: 07/23/08

Posts: 7

shouldn't you be using getQualifiedClassName instead of getQualifiedSuperclassName
???


None

AlyssaShafer

Reply To Post Reply & Quote

Posted at: 6/2/09 11:20 PM

AlyssaShafer NEUTRAL LEVEL 01

Sign-Up: 01/14/09

Posts: 32

check BOTH superclass and class for movieclip
that will take care of just movieclips in addition to classes inherited directly from movieclip


None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 03:21 AM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

I was checking the superclass because that's all I needed to know, if the base class was movieclip or not. It didn't matter what the (potential) inherited class was

That being said, I fixed the problem (via help from kirupa) by simply doing

if(curObject is MovieClip)

THAT being said, I realized this method wont work because I don't always want to pause/play every movieclip contained within any other given movieclip

BBS Signature

None

GustTheASGuy

Reply To Post Reply & Quote

Posted at: 6/3/09 04:51 AM

GustTheASGuy LIGHT LEVEL 08

Sign-Up: 11/02/05

Posts: 11,429

Use an empty interface to indicate what should be paused. Or instead, define a method for pausing the right stuff in each element.

Or really easily, you can set stage.frameRate to 0. If that makes the screen look bad because some elements shouldn't be paused, blur everything and put a minimal pause screen on top. That looks cool and not too cheap, usually.

#ngprogramming at irc.freenode.net
haXe | Keel imperative | Spyro! | Thru you


None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 01:25 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

At 6/3/09 04:51 AM, GustTheASGuy wrote: Use an empty interface to indicate what should be paused. Or instead, define a method for pausing the right stuff in each element.

Yeah, that's what I'm going with now. Classes based on game objects all have a pauseMe/unpauseMe function. When the game pauses the main game container loops through its children, if the curChild is a MovieClip it will attempt to call its pauseMe function with a try/catch. However I think I'm going to create custom 'game_paused' and 'game_unpaused' events that are dispatched at the right time, so only the classes that can pause will listen to them. Not sure what you mean by an 'empty interface' though, I never use interfaces. Are you saying that the interface would contain these pause methods, so any class implementing it will be forced to use them?

Or really easily, you can set stage.frameRate to 0. If that makes the screen look bad because some elements shouldn't be paused, blur everything and put a minimal pause screen on top. That looks cool and not too cheap, usually.

I tried the frameRate thing but that wont work the way I want, for example when accessing the map I want the game to pause and fade the map in over top. If the frameRate is 0 the fade will never occur. If there still end up being animated elements not covered by my pause event then yeah, I can draw a copy of the screen over top of everything as a bitmap.

BBS Signature

None

GustTheASGuy

Reply To Post Reply & Quote

Posted at: 6/3/09 01:44 PM

GustTheASGuy LIGHT LEVEL 08

Sign-Up: 11/02/05

Posts: 11,429

public interface Pausable extends flash.display.MovieClip { }

public function pauseAll (mc : flash.display.DisplayObject)
{
  if (mc is Pausable) mc.stop ();
  var mc_;
  if (mc_ = mc as flash.display.Sprite)
    for each (x in mc.children) pauseAll (x);
}

Your way is really ugly is all.

But don't you only need to pause entire known sub-branches of the display list (as in the container of the game view and stuff)? Cause you don't need to check which elements to pause if you apply the function to those branches.

#ngprogramming at irc.freenode.net
haXe | Keel imperative | Spyro! | Thru you


None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 01:59 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

At 6/3/09 01:44 PM, GustTheASGuy wrote: public interface Pausable extends flash.display.MovieClip { }

public function pauseAll (mc : flash.display.DisplayObject)
{
if (mc is Pausable) mc.stop ();
var mc_;
if (mc_ = mc as flash.display.Sprite)
for each (x in mc.children) pauseAll (x);
}

Your way is really ugly is all.

But don't you only need to pause entire known sub-branches of the display list (as in the container of the game view and stuff)? Cause you don't need to check which elements to pause if you apply the function to those branches.

I'll have to pause things like the walk animation and attack animations that aren't associated with any class at all, they're just vanilla movieclips placed at certain spots in the character sprite. I also couldn't assign boolean variables (from the parent class) to them for being 'pausable' because they don't necessarily exist on the first frame of the character.

I'm still thinking the event model would be most efficient-

function pauseGame():void
{
var pauseEvent:Event = new Event("game_pause");
dispatchEvent(pauseEvent);
}

then in any class I make

addEventListener("game_pause", pauseMe);

function pauseMe(e:Event):void
{
if(mc_attack!=null)mc_attack.stop();
if(mc_walk!=null)mc_walk.stop();
}

That might not be the right syntax, I haven't worked much with custom events yet. But I think that would be the general idea.

BBS Signature

None

GustTheASGuy

Reply To Post Reply & Quote

Posted at: 6/3/09 02:06 PM

GustTheASGuy LIGHT LEVEL 08

Sign-Up: 11/02/05

Posts: 11,429

Implementing an interface is less painful than having to name all the animation elements. But it looks like you can safely pause all animation elements and the like without having to name them, right?

Anyway just do it how you like (or describe exactly what you want to pause for me).

#ngprogramming at irc.freenode.net
haXe | Keel imperative | Spyro! | Thru you


None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 02:23 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

At 6/3/09 02:06 PM, GustTheASGuy wrote: Implementing an interface is less painful than having to name all the animation elements. But it looks like you can safely pause all animation elements and the like without having to name them, right?

Anyway just do it how you like (or describe exactly what you want to pause for me).

yeah, I'd still have to name them all

I guess my question is, how do I implement the Pausable interface for movieclips like my walk cycle that don't have an explicit class definition?

The pause function's first task is to make sure that all active game objects (player, enemies, particles, etc) inside the game container remove their ENTER_FRAME event listeners. Then it needs to stop any movieclips marked as 'pausable' inside of each game object. This is the current 'pauseMe' function I use for the main player:

public function pauseMe():void 
		{
			removeEventListener(Event.ENTER_FRAME, this[mainEventHandler]);
			if(walk!=null)walk.stop();
			if(attack!=null)attack.stop();
		}

also I didn't realize you could iterate children by just

for each (x in mc.children)

Thanks for that. And thanks for your comments so far, it helps to see how someone else would go about doing this.

BBS Signature

None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 02:25 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

oh, and I know I said "Then it needs to stop any movieclips marked as 'pausable' inside of each game object" but that's not what I'm doing right now, I'm just manually recognizing any possible animations that could be playing when the game is paused.

BBS Signature

None

GustTheASGuy

Reply To Post Reply & Quote

Posted at: 6/3/09 02:42 PM

GustTheASGuy LIGHT LEVEL 08

Sign-Up: 11/02/05

Posts: 11,429

^I don't think that was valid syntax. AS is too verbose so I make stuff up.

Still not clear what you're doing and what you have, so I'll assume I'm making a real-time game where objects act on their own (like you described), and I'd like to pause the game and graphics, but have some kind of UI animation while they're paused.

First of all I don't use an ENTER_FRAME listener for each object. I store active objects in a list and iterate them from a single enterframe listener. So pausing is as easy as skipping that iteration.
Secondly I'd put the game graphics in a designated sprite object, so when I want to pause all sprites, I only apply the recursive pause function to that sprite.

So the code would look like this:

function mainUpdate (_)
{
  if (Game.paused) return;
  for (x in activeobjs) x.update ();
}

function applyToAll (f, target : Sprite)
{
  for (d in 0 ... target.numChildren-1)
  {
    var child = target.getChildAt (d)
    f (child);
    if (child is Sprite) applyToAll (f, child);
  }
}

function pause ()
{
  Game.paused = true;
  applyToAll (gameviewcont, function (x) x.stop ());
}

function unpause ()
{
  Game.paused = false;
  applyToAll (gameviewcont, function (x) x.play ());
}

...Or somethiiiing. Seriously do it however.

#ngprogramming at irc.freenode.net
haXe | Keel imperative | Spyro! | Thru you


None

Afro-Ninja

Reply To Post Reply & Quote

Posted at: 6/3/09 03:52 PM

Afro-Ninja EVIL LEVEL 38

Sign-Up: 03/02/02

Posts: 13,469

At 6/3/09 02:42 PM, GustTheASGuy wrote: First of all I don't use an ENTER_FRAME listener for each object. I store active objects in a list and iterate them from a single enterframe listener. So pausing is as easy as skipping that iteration.

Ah, that's probably a more efficient way to go about doing this. The only problem I see with that is in the event that I would want any object to have multiple ENTER_FRAME events. If the player gets hit by an enemy and starts flashing I'd assign that to a separate handler, though I could still just do it from the main function.

Secondly I'd put the game graphics in a designated sprite object, so when I want to pause all sprites, I only apply the recursive pause function to that sprite.

Yeah, all game graphics are inside of a sprite called GAME_CONTAINER. The problem I ran into with the recursive thing is that it still doesn't mean I want all sprites to be paused or not. For example if the main character has a helmet sprite that changes as the player equips different things- when the game is unpaused that sprite will be caught in the loop and will start cycling through all the helmets.

Sorry for not being descriptive enough, the engine I'm making is still pretty early and I'm really not sure what all it will need to account for yet, just trying to keep it flexible. I'll play around with these ideas as the engine develops and see what works best. Thanks again for the input.

BBS Signature

All times are Eastern Standard Time (GMT -5) | Current Time: 05:18 PM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!