AS3: MouseEvent not working? - actionscript-3

When I click on it nothing is being outputted. Is there a reason why the MouseEvent is not being applied to the rectangle. Where am I going wrong?
My Code:
import flash.display.Shape;
import flash.events.MouseEvent;
stop();
var rectangle001:Shape = new Shape;
rectangle001.graphics.beginFill(0x00D783);
rectangle001.graphics.drawRect(10, 10, 50, 50);
rectangle001.addEventListener(MouseEvent.CLICK, rectangle001Click);
function rectangle001Click (event:MouseEvent){
trace("Hello World!");
}
addChild(rectangle001);
All answers appreciated.

You should use Sprite instead of Shape if you want mouse interactivity.
Quoting from an answer on this page:
Shape is the one with the least possibilities. Use it when you only want a DisplayObject with graphics, and no mouse interaction.
Sprite is the parent class of quite everything you need. Since it is a DisplayObjectContainer, you can use it as a basic container for other components. You can also catch mouse events on this one.
MovieClip is a Sprite with the ability to use frames. Only use it for frame-by-frame animation (Flash style).

Related

Bring Timeline animation to top

I have a movie that adds a MovieClip to it's stage in the constructor, i Also have an animation on the timeline that plays on certain events. Everything is working, except the movie I need the movie on the timeline to be the top layer, it is on the bottom currently.
public Class BallCollision extends MovieClip{
public function BallCollision(){
mcBall = new MovieClip();
stage.addChild(mcBall);
//Adds stuff to the movie clip
}
}
You can do one of the following:
Create a container on the timeline called 'container' and then add mcBall to that instead. This container will be on a layer underneath the existing animation.
Place all of the existing animation into a MovieClip and give it an instance name like animation. Whenever you add something to the stage, also use stage.addChild(animation) to bring it back to the top.
Obviously option 1 is preferable, but I've offered option 2 for the sake of free knowledge.

How to add/get Sprite to/from UIComponent

How to add Sprite to BorderContainer (UIComponent)?
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(10,0);
sprite.graphics.moveTo(40,40);
sprite.graphics.lineTo(60,60);
mybordercontainer.addChild(sprite);
//mybrodercontainer is id of BorderContainer created in mxml
This code doesnt work. I cant see Sprite on my BorderContainer. How can I add Sprites on UIComponents, so I can see them? I tried this and it kinda worked:
var comp:UIComponent = new UIComponent();
comp.addChild(sprite);
myborderconteiner.addElement(comp);
But I dont think, that this is a right way to add Sprites to UIComponents. Is there another method to do that?
Second problem:
When I have few Sprites added to my UIComponent (lines/circles/images or others) how can I receive an object Sprite from that UIComponent, which is containing all Sprites added before to that UIComponent?
I need to create Bitmap from that Sprite and do some things.
I hope I make myself clear
Use the SpriteVisualElement as container. That should serve nicely as a container or Sprite substitute. You could also draw in the UIComponent itself.

Rotate movieclip on different axis on mouse position As3

I am looking for direction to this old UFC effect - http://84.ufc.com/ that appears on the main page. It is movieclips rotating on different axis based on the mouse position. So far I have found this script:
stage.addEventListener(MouseEvent.MOUSE_MOVE,EnterFrame);
function EnterFrame(e:Event)
{
mc.rotation = (180*Math.atan2(mouseY-mc.y,mouseX-mc.x))/Math.PI + 90;
}
But this only rotates on x and y. What's a way to approach this effect? Please any suggestions. I have searched this for months.
If you are using Flash CS4+ and targeting Flash Player 10+, you can use the 3D DisplayObject APIs (aka "postcards in space") to achieve this effect! All DisplayObjects will have x, y, z, rotationX, rotationY, and rotationZ properties that you can tweak.
Create a movieclip and place it on the stage. The origin--the crosshair that appears when the clip is selected--should be in the middle in the stage. Give the movieclip an instance name of clip.
Double-click the movieclip, and place other movieclips inside it. Use the 3D Rotation and Translation tools to orient these clips in 3D inside your parent clip. You can find the 3D tools in your toolbar -- it has an egg-like icon, or press the W or G keys on your keyboard.
Now, here's some simple code that will tweak the orientation of that parent clip based on the mouse position:
import flash.events.Event;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(event:Event):void
{
clip.rotationX = (stage.mouseY - stage.stageHeight/2) * 0.1;
clip.rotationY = (stage.mouseX - stage.stageWidth/2) * 0.1;
}
You can play around with this to come up with many other effects. Note that you can only do simple 3D effects with these properties, however. You can't do full 3D rotation, because the clips won't be sorted from back to front. For more complex effects, you'll want to use a framework like Papervision3D or Five3D.
i just found out...
import flash.events.Event;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(event:Event):void
{
anim.rotationX += ((stage.mouseY - stage.stageHeight/2)-anim.rotationX*3) * 0.05;
anim.rotationY += ((stage.mouseX - stage.stageWidth/2)-anim.rotationY*5) * 0.05;
}

Same mouseover/-out effect for many buttons

Last time I touched flash was 10 years ago, or so... In other words, I'm quite rusty. I am going to make a interactive map of Europe. I want the strongly green circles to have a mouseover/-out effect (First I was thinking some size-change, but I think maybe I'll go for opacityfading). I have a couple problems. The code under is working, but Is there a good way to either force the fadingout(...) to finish, before fadingin(...) is called? If not, is there a smart way to get the current opacityvalue when fadingin(...) and make that the start value. If the user moves the mouse outside quickly, the effect is not looking very nice. Also, what is the best way to get these functions to work with every circle in the map? If the user drags the mouse around, I want this to create a tracing effect.
import fl.transitions.Tween;
import fl.transitions.easing.*;
var outTween:Tween;
myButton.addEventListener(MouseEvent.MOUSE_OVER, fadingout);
myButton.addEventListener(MouseEvent.MOUSE_OUT, fadingin);
function fadingout(event:MouseEvent): void {
outTween = new Tween(myButton, "alpha", None.easeNone, 1, 0, 1, true);
}
function fadingin(event:MouseEvent): void {
outTween = new Tween(myButton, "alpha", None.easeNone, 0, 1, 1, true);
}
What I would probably do is create a class for the circle. In there I would create the eventlisteners for mouseover and mouseout to change the opacity and/or size.
On a second note, I recommend that you use TweenLite or TweenMax from greensock http://www.greensock.com/tweenlite/
TweenLite should probably suffice for you. Look into it's properties especially the "overwrite"-property which controls the tween overriding you mentioned
overwrite : int Controls how (and if)
other tweens of the same target are
overwritten by this tween. There are
several modes to choose from, but only
the first two are available in
TweenLite unless
OverwriteManager.init() has been
called
You could very well create a class for the green circles, and contain all listeners and tweened reaction features within it. A very solid method.
You may also leverage event propagation on a movie clip / sprite containing all mouseable elements to achieve the same thing with a single listener set:
var myContainer:Sprite = new Sprite();
//add all elements
myContainer.addEventListener(MouseEvent.MOUSE_OVER, over, true, 0, false);
myContainer.addEventListener(MouseEvent.MOUSE_OUT, out, true, 0, false);
private function over(e:MouseEvent):void
{
TweenLite.to(e.target, .5, { alpha:1.0 });
}
private function out(e:MouseEvent):void
{
TweenLite.to(e.target, .5, { alpha:0.5});
}
Basically, you add the listener to the containing object, and events are passed down to the children, who then receive the event instructions. The ".target" of the propagating object, received in the MouseEvent argument is the key here.
I'm using the fantastic TweenLite framework here, as mentioned by others, and you should too.
cheers and good luck!

Prevent height change of a DisplayObject

Is there a way to prevent the automatic change of the height property of a DisplayObject? It automatically resizes to match content, though my swf file is 32 pixels height. The code below can show prove of this, first frame enemy.height is 32 but later is 27.5, and this messes up my script.
getRect() and getBounds() return exactly the same. Also, I want to know why in the first frame it shows the correct height and in the second it changes, it should show 27.5 from the beginning.
package {
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
private var enemy:Sprite;
[Embed(source = '../lib/enemy.swf')] private var swf:Class;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function update(e:Event):void {
trace(enemy.height);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
enemy = new swf();
addChild(enemy);
addEventListener(Event.ENTER_FRAME, update);
}
}
}
This has to do with the fact that you're instantiating a whole SWF, and 1 frame has to pass for it to be synced to the Main swf. What I would do is export the symbol in the .fla, then use the "embed symbol" syntax in Flex:
[Embed(source='enemy.swf#Symbol1')]
private var swf:Class;
In this case, the height will be consistent even in the first ENTER_FRAME. If it's not the height you want, you can use the invisible shape to set the bounds.
A "hacky" solution might be to add a shape to the enemy that has the max size you want, then set it to be invisible. I have created hit boxes for objects that way and it worked quite well.
One way would be to add it when creating the object in the Flash IDE. Just draw it and position it as you want the shape to be, then give it an instance name, like "sizeHolder". After you create the enemy you would then call
enemy.sizeHolder.visible = false;
In the Flash IDE you could place it on another timeline, then make that timeline invisible and lock it, so it wouldn't get in your way when editing the actual object.
The other way would be to add it by code. Draw the object in another DisplayObject, set it to invisible and then addChild it to enemy.
The enemy sprite animation sequence
will vary in height.This is part of
the animation process. Hence the
actual height per frame will vary
based on bounding box of the sprite.
As you very well observed this is the
default behavior.
The ways:
The One you are presently following storing height and using for calculations.(better)
As EyeSeeEm suggested if i understood him correctly having an invisible height sprite background with proper centering of the movie clip center point and centering of the sprite in each frame to be contained in the invisible height sprite bounds.
You will often find that you will come across features in action script not working the way you want it to.Whats important is that you adapt the coding to facilitate the solution . It is not hack y or inefficient when and coding/method allows for easily making further changes/extensions.
P.S:
This would depend on situation but personally i would rather the height be dynamic according to the sprite animation instance so any hits to the enemy just nearly over its head by projectiles doesn't actually kill the enemy.
Try
import flash.display.StageAlign;
import flash.display.StageScaleMode;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;