Arrange z order of two movieclips on click - actionscript-3

i have 2 layes with one movieclip each.
How is it possible to bring forward the clickable movie clip and the other goes backwards?
I tried some methods but i didn't had any luck.
If it is not too much code and someone has a little time please help me to solve it.
Thank you all again!

put both movie clip in arraylist suppose we say (zorder),and call bringttofronthandler or sendtobackhandler on some event as you wish.
private function recalculateDepth():void
{
for (var i:int = 0; i < zorder.length; i++)
{
zorder.getItemAt(i).depth = i;
}
}
protected function bringToFrontHandler(event:Event):void
{
zorder.removeItem(selectedItem);
//set to top of array
zorder.addItem(selectedItem);
recalculateDepth();
}
protected function sendToBackHandler(event:Event):void
{
zorder.removeItem(selectedItem);
//set to bottom of array
zorder.addItemAt(selectedItem, 0);
recalculateDepth();
}
}

You should check these links to understand the concept of display lists.
http://www.adobe.com/devnet/flash/quickstart/display_list_programming_as3.edu.html
http://www.republicofcode.com/tutorials/flash/as3displaylist
http://active.tutsplus.com/tutorials/actionscript/as3-101the-display-list/
All these will help you understand the operations that you can perform on various objects on screen including the swap functionality that you are asking for.

swapChildren() or swapChildrenAt();
this.swapChildren(mc1,mc2)
or
this.swapChildrenAt(0,1)

Related

AS3 tween object not working with .hitTestObject()

I am having a major problem in my new browser app.
Okay so I made game where different cubes (squares) spawn at the top of the screen and I use the Tween class to make them go down the screen and then disappear.
However I want to detect a collision when a cube hits the player (that is also a flying cube).
I tried everything, truly everything but it does not seem to work. The problematic thing is that when I remove the "Tween" function it does detect collision with the hitTestObject method but when I add the "Tween" line collision won't be detected anymore.
It looks like this:
function enemiesTimer (e:TimerEvent):void
{
newEnemy = new Enemy1();
layer2.addChild(newEnemy);
newEnemy.x = Math.random() * 700;
newEnemy.y = 10;
if (enemiesThere == 0)
{
enemiesThere = true;
player.addEventListener(Event.ENTER_FRAME, collisionDetection)
}
var Tween1:Tween = new Tween(newEnemy, "y", null, newEnemy.y, newEnemy.y+distance, movingTime, true);
}
And the collision detection part:
private function collisionDetection (e:Event):void
{
if (player.hitTestObject(newEnemy))
{
trace("aaa");
}
}
I am desperate for some information/help on the topic, it's been bugging me for days.
Thanks for your time, I would be very happy if someone could help me out^^
First, make sure the "newEnemy" instance and the "player" instance are within the same container. If they are not, their coordinate systems might not match up and could be the source of your problem.
Otherwise, you need to keep a reference to each enemy instance you create. It looks like you are only checking against a single "newEnemy" variable which is being overwritten every time you create a new enemy. This might be why you can successfully detect collision between the player and the most recent "enemy" instance.
So... you need a list of the enemies, you can use an Array for that.
private var enemyList:Array = [];
Every time you create an enemy, push it to the Array.
enemyList.push(newEnemy);
In your "collisionDetection" function, you need to loop through all of the enemies and check if the player is touching any of them.
for(var i:int = 0; i < enemyList.length; i++)
{
var enemy = enemies[i];
if (player.hitTestObject(enemy))
{
trace("Collision Detected!");
enemy.parent.removeChild(enemy); // remove the enemy from the stage
enemies.splice(i, 1); // remove the enemy from the list
}
}
I'd suggest that you move to TweenMax, it just might solve your problem, and in my experience it's much better in every possible way.
Scroll down the following page to see a few variations of this library, I myself use TweenNano, they're completely free of charge:
https://greensock.com/gsap-as
I think some plugins cost money, but I doubt you'll ever need them.

How to construct nested eventlisteners in AS3

Working a bit with AS3 and hit a wall on how to program through this situation. I have a class which represents a number say 103. I have a movieclip for each digit which I add to a holding movieclip and then add to the stage. I want to enable the ability to single click a digit like the zero in the number 103 and have it react since it is an individual movieclip and at the same time double click the entire number and have that react. Is there a way to cleanly do this wtihout confusing the code below is what I have thus far.
public function test()
{
numberimage = new MovieClip();
var images:Vector.<MovieClip> = generateNumericArray("");
for (var i:int = 0; i < String(value).length; i++) {
var temp:MovieClip = parsevalue(String(value).substr(i,1),images);
temp.x = i*50;
temp.addEventListener(MouseEvent.CLICK,click)
numberimage.addChild(temp);
}
numberimage.addEventListener(MouseEvent.MOUSE_DOWN,drag);
numberimage.addEventListener(MouseEvent.MOUSE_UP,drop);
numberimage.addEventListener(MouseEvent.MOUSE_OVER,doubleClick);
stage.addChild(numberimage);
}
any help on this would be much appreciated
Do, doubleclick on clip : stop listening to main movie, and listen now to sub clips. On click outside the main clip, listen back to the main movie and stop listening to its children.
Not sure if this is 100% what you are looking for: use the following, depending on what you are adding the listener to. You do have to enable double clicking first
numberimage.doubleClickEnabled = true;
numberimage.addEventListener(MouseEvent.DOUBLE_CLICK, click);

Making Functions For Movieclips

I'm trying to create a function that modifies all of my movieclips.
This is what I have tried, but it's not working:
for (var i:Number = 0; i<50;i++) {
checkLine(this["line" + i + "_mc"]);
}
my movieclips are all on the stage and have instance names of line0_mc, line1_mc, up until line_49mc. What have I done wrong?
I think the best solution is to put each MovieClip in an array for better accessibility.

Flex 4 image object returning as MovieClip object

I am working on a custom context menu in Flex4. The context menu itself works fine but I am looking for a way to tell if the ContextMenuEvent mouseTarget is an image. As it stands, the mouseTarget shows that it is a "[object MovieClip]". Which is strange because I have no movie clips in my application, only image containers. Any idea what is going on?
private function openContextMenu(e:ContextMenuEvent):void {
Alert.show(e.mouseTarget.toString());// shows [object MovieClip] when it should show [Object Image]
}
Thanks
You need to set mouseChildren on the Image to false, then the MouseEvent will refer to the Image:
if (event.target is Image) {
//do stuff
}
So after a few more hours of research I came up with the below attached to the contextMenu's item select event listener. I am sure there has to be a better way to do this, but until then...
for(var i:int = 0; i < getObjectsUnderPoint(new Point(this.mouseX, this.mouseY)).length; i++)
{
if(getObjectsUnderPoint(new Point(this.mouseX, this.mouseY))[i].parent.parent is Image)
{
//do what I need to do
}
}
Thanks NHubben for your input. It got me going down the right path of looking at children.
The component name Image has no relevance concerning what makes it up. The flex inheritance is: Image -- SWFLoader -- UIComponent -- FlexSprite -- [...] (from mx.controls.Image docs).
So what you need to do is understand what you actually have when you bring it into a AS3 environment. It seems like it gets wrapped up in a MovieClip to allow it be in the Flash's display list. It also looks like you have to go through a loader, but I'm not sure of that.
Run a test or two to find out what the object is actually made up of:
// not foolproof, and will break on some stuff,
// so you will have to fix this as needed:
private function loopDisplay(obj:Sprite):void
{
trace(obj.name + ": " + obj);
if (obj.numChildren > 0)
{
for (var i:int = 0; i < this.numChildren; i++)
{
loopDisplay(obj.getChildAt(i));
}
}
}
If you put this in a mouse down handler, then you can see what is actually there.
However, the event.target or event.currentTarget should also hold the menu item object, so you can also just loop into those objects and see what is in them.

ActionScript 3: Bullet Ricocheting

I've been having a problem with my Actionscript code. I am fairly new to Flash and AS3, so I apologize if my code seems crude or rudimentary, but I'm doing this as best as I can.
Well, in this project I'm trying to get a bullet to ricochet off a wall once. If it hits a wall again after ricocheting, the bullet will disappear.
I've created a for loop which moves the bullets, in an array. At the same time, I try to keep track of each bullet's individual number of ricochets. This works fine when I shoot a first bullet - it will ricochet and then disappear after hitting another wall. However, every bullet I fire after that disappears on the first wall it hits, before it has ricocheted. I've tried to get this to work but I just can't seem to do it.
I would be grateful if somebody could show me the problem, or suggest a change to my code.
Here is a link to my code as it is now.
Thanks, to anybody who helps.
Here are some suggestions I have:
1: Create a Bullet class that tracks its own collisions against walls. I'd also move the clearBullet() method into the bullet class itself.
public class Bullet extends Sprite
{
public var collisions:int = 0;
public var xv:Number = 0;
public var yv:Number = 0;
public function clear():void
{
if(parent)
parent.removeChild(this);
}
}
2: Update your loop to deal with this new info.
for each(var i:Bullet in bulletholder)
{
// Move bullet.
// Check for collision.
// When there is a collision, do this:
i.collisions ++;
if(i.collisions >= 2)
{
var n:int = bulletholder.indexOf(i);
bulletholder.splice(n, 1);
i.clear();
}
else
{
// Deal with changing bullet position.
}
}
I see at least a couple of problems with your code:
Your ricochetcount is clearly out of sync. i.e. you need to delete an element from that array as well.
When you delete an element from the bulletholder array (via clearBullet), you're still incrementing i, which means you end up inadvertently skipping an element.
Also I'm not sure why you need clearBullet(). You already have the index i as well as a reference to the bullet object right there in the main loop.