Code performance, event listeners, multiple rotating boxes
I've created a grid of 3D cubes using modulus, and the 3d cubes are were created from the Math and Flash tutorial
I have set up listeners so when the mouse hovers over a cube it starts 开发者_如何转开发to rotate:
private function setUpListeners():void {
spBoard.addEventListener(MouseEvent.ROLL_OUT,boardOut);
}
That works fine.
To begin the rotation of the cube when the mouse passes over it I have used:
private function boardOut(e:MouseEvent):void {
addEventListener(Event.ENTER_FRAME,rotateSquare);
var i:int = 1;
function rotateSquare(e:Event) {
renderView(curTheta+i,curPhi+i);
i++;
}
}
I can see why this would be inefficient, as it is running the loop every every frame, and for so many multiple cubes it just lags (very badly).
Does anybody have a better method of doing this? I'd be happy to post more code if people need/require it.
Thanks in advance.
EDIT: I should clarify, i'm hoping for the rotation to continue indefinitely once the mouse moves off the cube.
2nd EDIT:
Here is how I am creating the cubes onto the "grid":
public function FlowerMenu(){
var rowY:Number = 0;
for (var i:int = 0; i < 190; i++) {
var myCube = new CubeMenu(["anemon.jpg","parodia.jpg","anagallis.jpg","lila.jpg","cosmos.jpg","adonis.jpg"],100);
myCube.x = 0 + ((i % 10) * 200);
if (i % 10 == 0) {
rowY += 200;
}
myCube.y = rowY;
addChild(myCube);
}
New Answer:
In this case you can put every cube that you want to rotate in a Array and call ENTER_FRAME on the a container clip (not for every cube).
Looping through your Array (in the container) will be faster than dispatching tons of ENTER_FRAME events (I think).
(ask for examples if you need ;D)
Example
Assuming renderView
is a method of MenuCube, I suggest that you put all code needed for rotation inside renderView
(information like i++
, curTheta
and curPhi
).
// The container where every cube will reside
public var CubeContainer:Sprite;
// Creating Cubes, setting a listener to rotate them on MOUSE_OVER
// and adding them to the container.
public function CreateCubes()
{
CubeContainer = new Sprite();
for (var i:int = 0; i < 10; i++)
{
var NewCube = new CubeMenu(/*...*/);
NewCube.addEventListener(MouseEvent.MOUSE_OVER, RotateMe);
CubeContainer.addChild(NewCube);
}
CubeContainer.addEventListener(Event.ENTER_FRAME, RotateCubes);
}
// When MOUSE_OVER fires, start rotating (by pushing it into an Array)
// and remove MOUSE_OVER listener
public function RotateMe(e:MouseEvent):void
{
var TargetCube:CubeMenu = e.currentTarget;
CubesToRotate.push(TargetCube);
TargetCube.removeEventListener(MouseEvent.MOUSE_OVER, RotateMe);
}
// ENTER_FRAME of the container...
// This will check every container that need to be rotated
// and call renderView for it.
public function RotateCubes(e:Event):void
{
for(var i:int = 0; i <= CubesToRotate.length; i++)
{
var CurrentCube:CubeMenu = CubesToRotate[i];
CurrentCube.renderView();
}
}
Old answer:
If I got it right, you can use MOUSE_OVER and MOUSE_OUT events:
private var i:int = 0;
private function setUpListeners():void
{
spBoard.addEventListener(MouseEvent.MOUSE_OVER, boardOver);
spBoard.addEventListener(MouseEvent.MOUSE_OUT, boardOut);
}
private function boardOver(e:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, rotateSquare);
}
private function boardOut(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, rotateSquare);
}
private function rotateSquare(e:Event)
{
renderView(curTheta+i, curPhi+i);
i++;
}
This way your Mouse Events will be dispatched only when you move your mouse over and out the spBoard
.
ps: As you see, the i
variable must be defined outside the functions for this to work.
Use a tweening library to do the animation (it replaces the enter frame event handler). Most of those libraries are much more efficient than doing it “by hand” with an enter frame handler, and for example will do multiple animation steps within a single handler. So instead of calling n
functions (for n
squares that needs to be rotated), it just calls a single function that does the animation at once.
精彩评论