Flash: AS3 – Bring symbol to front on rollover within movie - actionscript-3

I have created a map of Europe in Flash using AS3. I am an absolute beginner. Each country has been converted into a movie (using lasso tool). These movies are on one layer (with slight outline visible) on main timeline. On the other main timeline layer is the original outline map of Europe.
I have managed to make it so when a country is rolled over, a box tweens in scale to full size (to later insert text in).
I need to make it so that when each country is rolled over, that country's text box (which appears on Roll_Over) comes 'to the front'.
At the moment a couple of countries' text boxes work perfectly (ie: filled with white and completely visible), but most are either buried beneath the main map, or threading randomly through the faint movie clip outlines (which are at the front).
I'm guessing that this has to do with the display list. The countries that work perfectly are probably at the top. But how do I make it so that the country rolled over immediately goes to the top and returns on Roll_Out?
This would complete my map so any help would be VERY MUCH appreciated.
I have used following code:
//FRAME ONE
this.stop();
movieClip_6.addEventListener(MouseEvent.ROLL_OVER, fl_MouseOverHandler_15);
function fl_MouseOverHandler_15(event:MouseEvent):void
{
gotoAndPlay(2);
}
movieClip_6.addEventListener(MouseEvent.ROLL_OUT, fl_MouseOutHandler_67);
function fl_MouseOutHandler_67(event:MouseEvent):void
{
gotoAndStop(1);
}
//SECTION BELOW IS MY PROBLEM
movieclip_6.addEventListener(MouseEvent.ROLL_OVER,Rollover,false,0,true);
function Rollover(event:MouseEvent): void
{
setChildIndex(MovieClip(e.target),this.numChildren-1);
}
Many thanks in advance.

You can try calling addChild() again to the DisplayObject/Movieclip to bring it to the front. Instead of:
setChildIndex(MovieClip(e.target),this.numChildren-1);
Try going:
addChild(MovieClip(e.target));

You can use "layers" to bring objects in front of another.
constructor:
//Create the front layer
var frontLayer:Sprite = new Sprite();
//put all text boxes into front layer
frontLayer.addChild(textbox1); //etc...
//Add layer to mc
addChild(frontLayer);
rollover pops up:
textbox1.visible = true;
pop down:
textbox1.visible = false;

Related

Libgdx and Box2d / Particles are not following bodies

i'll just cut to the chase.
So i'm making this game where you should kill other objects with your spells i've created bullets and their bodies we're all good it's working.
But i wanted to make it look special and "magiclike" so i decided to use particles. I've made the particles and put and made them follow the bullet bodies with this code:
for (Bullet bullet : bullets) {
bullet.update(dt);
if (!bullet.destroyed){
fireFx.start();
fireFx.setPosition(bullet.getPosition().x, bullet.getPosition().y);
fireFx.update(dt);
}
}
but there's a problem when i fire multiple bullets particles are just dissappearing from the all of the first bullets i fired and just appears on the last one. Can someone lead me on this one please ?
-----------------EDIT-----------------
Now i've got another problem that when bullet collides with something it gets destroyed and render method stops working but i want it to keep rendering till the animation is over. Like i don't want them to disappear suddenly here is my code for this:
for(int i = 0; i<bullets.size; i++){
if(!bullets.get(i).destroyed && !bullets.get(i).fireFx.isComplete())
bullets.get(i).fireFx.draw(game.batch);
}
fireFx.isComplete() is not working correctly what is the reason ?
The issue is that you're updating a single particle to have the coordinates of all the bullets in a list, and effectively keeping the coordinates of the last bullet in the list. You could maintain a Map that maps Bullets onto Particles, but I would instantiate a fireFx object when a Bullet is created and add it to the Bullet object. Then, in the Bullet#update method you can call the particle update method:
public void update(float dt) {
[...]
if ( !this.isDestroyed()) {
[...]
this.fireFx.start();
this.fireFx.setPosition(this.getPosition().x, this.getPosition().y);
this.fireFx.update(dt);
[...]
}
[...]
}

AS3 Swap depths in Flash IDE without destroying movieclips

I have two movieclips, one is on top, one is on bottom. The top one is set to the second frame. I move it to the z axis bottom on the next frame, and for the remaining frames it plays all frames like it has been reset without any code (like I didn't tell it gotoAndStop(2)).
Image example: http://i.imgur.com/mQ8f5uT.gif (hard to tell by the frame rate, but the dark green box starts playing as if I didn't set it's frame once I move it below)
I know it doesn't have that issue when I code the depth swapping with setChildIndex, but the animations are lost.
If you're wondering, it's a simplified issue of a larger moving character sprite animation that I would like to swap depths of movie clips in the animation without resetting the movie clips underneath the depth change. So I'm not really looking for a work around per se, unless there's a well design solution and not a band aid "hack."
I think I didn't understand your question fully. A MovieClip will keep playing or keep being stopped no matter what you do with it, even if it was removed from the scene. I made a simple example which shows that MovieClip state is not affected by depth change.
The working SWF is here to test: http://zdg.ru/tmp/updown.swf
And the code is:
import flash.events.MouseEvent;
var is_playing:Boolean = true;
btn_toggle.addEventListener(MouseEvent.CLICK, doToggle);
btn_updown.addEventListener(MouseEvent.CLICK, doUpdown);
function doToggle(evt:MouseEvent) {
if (is_playing) mv_test.stop(); else mv_test.play();
is_playing = !is_playing;
}
function doUpdown(evt:MouseEvent) {
var tmp:int = getChildIndex(mv_block);
setChildIndex(mv_block, getChildIndex(mv_test));
setChildIndex(mv_test, tmp);
}

AS3: How can I implement a perfect ROLL_OVER(or MOUSE_OVER) event listener on curved movieclips

I've a problem with ROLL_OVER event listener. When I enter the empty area withing the movieclip with mouse cursor, ROLL_OVER event triggers. But I want that event trigger only when mouse cursor is on the colored area.
To Make it more clear: Think about " O " letter, when mouse cursor is between the empty area of O letter (inside of O) , event shouldn't trigger. It should trigger only when mouse curser is on the black area.
How can I implement this?
Thanks
-Ozan
PROBLEM IS SOLVED THANKS TO #Ethan Kennerly
I just want to add a few things to help people have problem same as me. In my situation I tried to make continents glow when my mouse is over them. I used the ROLL_OVER/MOUSE_OVER eventlistener to check if my mouse is over them or not. But with the data given by Ethan Kennerly I produced another way.
In Ethan Kennerly's solution, if your mouse enters the area of continent from a transparent area , it doesn't get blur effect because ROLL_OVER and MOUSE_OVER event listeners only trigger once per enters so I used MOUSE_MOVE event listener on each continent movieclips.
And for this statement:
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
add whatever is in the "ROLL_OUT or MOUSE_OUT" eventlistener function, add all of them inside this statement. But don't remove ROLL_OUT or MOUSE_OUT functions.
It sounds like the movie clip contains a shape that has transparent pixels. Transparent pixels respond to mouse over and roll over. If you could draw vector graphics that have no shapes with transparent pixels, the mouse would ignore the empty space in the movie clip's bounding box.
Yet it sounds like you need to use transparent pixels and you want the mouse to ignore them, so you could guard, like this:
private function onRollOver(event:MouseEvent):void
{
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
// respond to roll over.
}
To detect transparency, Miguel Santirso rendered the pixels and translated the coordinate space here: http://sourcecookbook.com/en/recipes/97/check-if-a-pixel-is-transparent-in-a-displayobject (Except line 38 looks on my computer like "rect" got rendered as "ct"). You could optimize that code by only drawing the pixel in question, instead of the whole image, and checking if that pixel value (getPixel32) is 0, instead of calling a hitTest. I would optimize Miguel's code like this:
public static function isPixelTransparent(objectOnStage:DisplayObject, globalPoint:Point):Boolean
{
var local:Point = objectOnStage.globalToLocal(globalPoint);
var matrix:Matrix = new Matrix();
matrix.translate(-local.x, -local.y);
var data:BitmapData = new BitmapData(1, 1, true, 0x00000000);
data.draw(object, matrix);
return 0x00000000 == data.getPixel32(0, 0);
}
By the way, if all your movie clips would have the same hit test shape, you could create a separate transparent shape that listens to the roll over. I use a transparent shape to define a custom hit test shape that is a consistent and simple shape (like a circle) when the image is a more complicate shape (like an X or an O with nothing in the middle). The custom hit test shape is a Sprite with a transparent shape. The sprite listens to the roll over. A separate mouse listener shape is also useful if your movie clip, on later frames, creates new shapes that alter the silhouette of the movie clip.
The easiest solution would be using the Interactive PNG class by Moses.
http://blog.mosessupposes.com/?p=40
Normally the clear areas of a PNG are treated as solid, which can be especially frustrating when dealing with a lot of images that overlap each other because they tend to block mouse interactions on the clips below them.
This utility fixes that so that mouse events don't occur until you
bump against a solid pixel, or a pixel of any transparency value
besides totally clear. InteractivePNG lets you set an alphaTolerance
level to determine what transparency level will register as a hit.

XY restrictions for custom mouse cursor in Actionscript3

I have this interactive 5 seconds animated intro for a website. the preloader and one item are animating and i made the second animation follow the mouse cursor but it has to stay within a certain part of the stage to work with the other animation happening on screen.
I have this code on the movie clip
Mouse.hide();
potistiri.addEventListener(Event.ENTER_FRAME, newCursor);
function newCursor(event:Event): void { potistiri.x = mouseX;
potistiri.y = mouseY; }
and i like i said i just want it to stay in the area i want...
i found this code which gives me errors for not putting the staments if and else if correctly or that it needs a rightparen when i input my numbers in...
if(this._x>Stage.width){
this._x=Stage.width;
}else if(this._x<0){
this._x=0; }
but i cant get it to work...
i need it to move between x 208-656 and y 140-336 and when it gets out of that area the object stay there doing its loop and you see the normal mouse cursor moving in the rest of the screen.
thanks a lot in advance...im leaving my it to the experts in here to pls help me ouy!
The logic you're using in your if/else is fine for clamping the movie clip to a specific area, what exactly do your errors say?
In regards to seeing the normal mouse cursor again you could try using the same if/else checks to determine whether the mouse should or should not be hidden ie if the mouse is outside the area and is hidden, call Mouse.show(), else if it is inside the area and shown, call Mouse.hide().

Drag Won't Stop with ActionScript 3

In writing an ActionScript 3 program, I am trying to make it so that I can drag an object from one location to another after doing some other stuff. The trouble is, I can drag just fine, but apparently I can't stop dragging, even with a listener to make it stop. I can't figure out any reason why this is happening. The relevant part of my code is as follows:
public function setToDragAndDrop(){
this.graphic.removeEventListener(MouseEvent.CLICK, rotate);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
this.graphic.addEventListener(MouseEvent.MOUSE_UP, endDrag);
}
private function drag(e:MouseEvent):void{
trace("Dragging...");
this.graphic.startDrag(true);
trace(this.graphic.hasEventListener(MouseEvent.MOUSE_UP)); //Returns true
}
private function endDrag(e:MouseEvent):void{
trace("Stopped dragging.");
this.graphic.stopDrag();
}
I do not get the "Stopped dragging" line in my output, so the endDrag MouseEvent is never getting called, even though it exists (as the trace proves). So instead whether the mouse is up or down, it continues to drag. I've found that if I click on another draggable object, that one starts dragging instead.
I'm baffled. Any help would be greatly appreciated!
I figured out the problem. Apparently when you create the shape, it's "drag point" is at (0,0), or if you premake the shape in Flash, the upper left corner of the "rectangle" that surrounds the figure. When you click on the shape, your mouse jumps to this "drag point."
Apparently, if the drag point does not actually lie on the body of the shape, drag and drop doesn't work. So the ovals I was using earlier didn't work because the drag point was off the shape. Your example did work because it was created at (0,0) and your drag point was at (0,0). But if you draw a circle that isn't at (0,0), like drawCircle(200,200,100) (i.e. draw a circle at point (200,200) with a radius of 100), then you encounter the problem that I have because the drag point is not on the shape.
The solution then is to create the circle at 0,0, then move it to the position you want. It's strange, but I finally got it to work.
public function setToDragAndDrop(){
this.graphic.removeEventListener(MouseEvent.CLICK, rotate);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
}
private function drag(e:MouseEvent):void{
this.graphic.startDrag(true);
this.graphic.removeEventListener(MouseEvent.MOUSE_DOWN, drag);
this.graphic.addEventListener(MouseEvent.MOUSE_UP, endDrag);
}
private function endDrag(e:MouseEvent):void{
this.graphic.stopDrag();
this.graphic.removeEventListener(MouseEvent.MOUSE_UP, endDrag);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
}
it works very well here.
http://wonderfl.net/c/CvWO
Check the flash "fiddle" .