Log in

View Full Version : scalling with instances



evan
07-17-2008, 07:14 PM
I can have as many objects on the screen and when I select any of them they will get bigger as I click them
This works:


this.addEventListener(MouseEvent.MOUSE_DOWN, scale);

function scale (evt:MouseEvent):void{
evt.target.scaleX +=.05;
evt.target.scaleY +=.05;
}

-alternately I can switch over to another evenhandler and scale them down

There is a better way to resize an object whith the mouse:


(BTY as it's coded it will not work -substitute the instance name for "evt.target" to get it to work)

What I did here is try to apply "evt.target"

to select instances to scale with the mouse I'm stuck.


//another way to scale smoother but harder to control conditional needed
//controls scaling --you don't want to scale until you click the ball
var OnScale:Boolean;
//another way to scale smoother but harder to control conditional needed

//sets cond boolean to true

this.addEventListener(MouseEvent.MOUSE_DOWN, ongo, false, 0, true);
//sets cond boolean to false
//stage is the object here becuse while dragging the cursor is off the stage
this.addEventListener(MouseEvent.MOUSE_UP, onstop, false, 0, true);
//loops trough scaling process
this.addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);

//cicle clicked scaling is allowed to begin
function ongo(evt:MouseEvent):void {(OnScale=true);}
//mouse up scaling stops
function onstop(evt:MouseEvent):void {(OnScale=false);
}
//loop for scaling, loop is controlled by conditional.
function onLoop(evt:Event):void {
if (OnScale)
{
evt.target.width = Math.max(mouseX - this.x, 10);
evt.target = Math.max(mouseY - this.y, 10);
}
}

Medyman
07-17-2008, 08:46 PM
Hey Evan....

I think you're better off sticking with your original logic. Using a Boolean value is fine, but by using that approach, you would need to attach a "onScale" property to each MovieClip object. Can be done, but is a messy way of doing it.

Also, I don't see the need for the onScale Boolean here. You're setting onScale to true on MOUSE_OVER and then setting it to false on MOUSE_OUT. To me, it seems more logical to create the ENTER_FRAME event handler in the MOUSE_OVER stage and then delete it in the MOUSE_OUT state. The result of this would be the same as you're getting now, but without the need for another variable in the mix.

ActionScript 3.0's most difficult concept to grasp, in my opinion, is the display list. The logic and order in which you can/should call on objects within the different reference frames and DisplayObject instances is really something you should understand though. I think it'll be a huge boon to you in the construction of this drawing board. Because, by understanding the DispayList, its properties, and how it's implemented, you'll be able to cut down on your code a whole lot. Now, of course the DisplayList can really be leveraged using OOP, but even in standard coding, it's useful.

Take this demo (http://www.visualbinary.net/files/tutorials/display-list/), for example. There are four movieclips on the stage. I'd like to have them scale up by 5% or to a total of 105% of their current size when I mouse over them. On mouse out, I'd like it to go back to it's original size (100%). Both of these scaling tweens should occur over 0.2 seconds. Now, using the logic above, I would create event listeners on all four movieclips (MOUSE_OVER, MOUSE_OUT) and create ENTER_FRAME events etc...

But using external tweening libraries (Tweener in this case, though I've just seen some benchmarking that claims that TweenMax and TweenLite are much faster/lighter tweening engines) and some logic, I can accomplish it all in one swoop.

Under normal coding conventions, I would use something like:


Movieclip1.addEventLister(MouseEvent.MOUSE_OVER, scaleUp)
Movieclip1.addEventLister(MouseEvent.MOUSE_OUT, scaleDown)

...
TIMES 4

With four clips, it might no be a big deal. But as you add more, it gets really inefficient and hard to read. So, using the display list...we can reduce the writing by using a for loop.


for(var i:uint=0; i< this.numChildren; i++)
{
var child = this.getChildAt(i)
child.addEventListener(MouseEvent.ROLL_OVER, scaleUp);
child.addEventListener(MouseEvent.ROLL_OUT, scaleDown);
}

This would apply those events to anything on the main timeline. Of course, you can target it within whatever parameter you want to achieve the targetting you want. But the code reduction of this technique, is immense.

evan
07-17-2008, 09:09 PM
I get the logic with controlling the events with listeners.

There isn't an easy way to get this part right with evt.target?

function onLoop(evt:Event):void {
if (OnScale)
{
evt.target.width = Math.max(mouseX - this.x, 10);
evt.target = Math.max(mouseY - this.y, 10);

can I control the scope of evt.target?

I can set the scaling up the way I had it the frist way -but the annoying side effect is that it makes ANY selected object scale.

I thought to remove event Listeners on mouseover of anything I DON'T want to scale.

I just wish I could "target" evt.target to work with all objects in just one movieclip,
or to several objects -but just in a certain area.

Medyman
07-17-2008, 09:23 PM
evt.target only has one definition. The object that the event listener is attached to. It's bascially the equivalent of the this selector in AS2.

So if you say:

red.addEventListener(MouseEvent.CLICK, draw);
function draw(e:MouseEvent):void {
trace(e.target)
}

The result would be "red" (or that object, rather). The scope of the event listener is only within that object. So, no you can't control what e.target refers to.

You could, only attach the event listener to child objects of a particular object.

Say, you have a movieclip called pencilBox. In tihs movieclip are 20 movieclips of different pencils (and nothing else). You could do this to attach event listeners to all 20.


for(var i:uint=0; i< pencilBox.numChildren; i++)
{
var child = pencilBox.getChildAt(i)
child.addEventListener(MouseEvent.ROLL_OVER, scaleUp);
child.addEventListener(MouseEvent.ROLL_OUT, scaleDown);
}


Now, using e.target within the scaleUp and scaleDown functions would refer to the individual movieclips that you're currently mousing over.

Is that what you're going for?

evan
07-20-2008, 03:31 PM
Two questions:
1)
I looked at your example's FLA file and placed it in a folder with the "caurina" folder as I did with the "wise words" demonstration. Unless the caurina folder was updated or changed since then or I placed the file incorrectly I shouldn't have any more difficulties. Unless I'm missing something.
2)
The other question I have is more a thought or idea I wanted to share. I looked at that link you sent me about "Jack Doyle's Transform Manager"
wow -great but complicated. (spent a good 2 hrs staring at it)
in my other post. I have three options -wait on his class in AS3 -do it myself or find a workaround.

How about this:

for shapes, if I can't figure out how to make work by coding it 100% I could
take a shape, "tween" it in the timeline and take some of those tweens and export them for actionscript and control them with mousevents. I haven't tried it yet but it sounds like an interesting and approach for drawing shapes, placing and scaling them -or for that matter letting a user create a customized object -lets say it's a car or a spaceship and then have the game animate this character in so many ways- that is not for now though.

otherwise, going back to basics I could draw an API circle or square on the stage, have the instance appear where the user clicks it and allow it to be scaled once(meaning after that it's pretty much over). I have an example in AS2 how to do it, and a buggy one in As3 which I'll post soon.