View
213
Download
0
Tags:
Embed Size (px)
Citation preview
Frame Event
• Each time the playhead enters a frame, a frame script is executed
• For a frame script to execute more than once, the playhead must leave the frame and return– Either because of an ActionScript navigation
instruction • E.g., gotoAndStop, gotoAndPlay
– Or playback loop that returns the playhead to frame 1 when it reaches the end of the timeline
Spring 2011 SCM-CityU 2
Example
• Create a new FLA with 3 key frames – Each frame has the script shown below
Spring 2011 SCM-CityU 3
var i:int = 0; trace("frame 1", i); i++; // i = i + 1;
var i:int = 0; trace("frame 1", i); i++; // i = i + 1;
trace("frame 2", i); i++;
trace("frame 2", i); i++;
trace("frame 3", i); i++;
trace("frame 3", i); i++;
Note: variables defined in a frame script (e.g., i in frame 1) can be accessed by the script at other frames (frames 2 and 3). Note: variables defined in a frame script (e.g., i in frame 1) can be accessed by the script at other frames (frames 2 and 3).
Enter Frame Event• Case 1: every time the playhead is entering a new
frame, a special event will happen, called enter frame event – Event type: Event.ENTER_FRAME
• Case 2: if the playhead is NOT moving, or there is only a single frame, this event is dispatched continuously– In conjunction with the frame rate
• I.e., 24 times per second by default
Spring 2011 SCM-CityU 4
Example 1• With single frame (case 2)– Frame script executes only once – But event listener for ENTER_FRAME will be
invoked continuously • E.g., frameLoop will be called continuously • Perfect for creating animation (by continuously
changing symbol instance’s properties)
Spring 2011 SCM-CityU 5
var i:int = 0; trace("init", i);
stage.addEventListener(Event.ENTER_FRAME, frameLoop);
function frameLoop(e:Event): void { trace("i =", i); i++;
}
var i:int = 0; trace("init", i);
stage.addEventListener(Event.ENTER_FRAME, frameLoop);
function frameLoop(e:Event): void { trace("i =", i); i++;
}
Example 2• With multiple frames (case 1)
Spring 2011 SCM-CityU 6
var i:int = 0; trace("frame 1", i);
stage.addEventListener(Event.ENTER_FRAME, frameLoop);
function frameLoop(e:Event): void { trace("enter frame", currentFrame, "i=", i); i++;
}
var i:int = 0; trace("frame 1", i);
stage.addEventListener(Event.ENTER_FRAME, frameLoop);
function frameLoop(e:Event): void { trace("enter frame", currentFrame, "i=", i); i++;
}
trace("frame 2", i); trace("frame 2", i); trace("frame 3", i); trace("frame 3", i);
Example 2
Spring 2011 SCM-CityU 7
Note: event listeners registered in a frame script (e.g., frameLoop in frame 1) will take effect for the life of the timeline until they are removed. Note: event listeners registered in a frame script (e.g., frameLoop in frame 1) will take effect for the life of the timeline until they are removed.
Example 2
• What if we put stop(); at the beginning of frame 1 script? – Reduce to case 2: if playhead is not moving…
Spring 2011 SCM-CityU 8
Another Example
• frame_events.fla in W drive – From book “Learning ActionScript 3.0”, second
edition
Spring 2011 SCM-CityU 9
Another Example
Spring 2011 SCM-CityU 10
Name: cycle
Name: wheel
stage.addEventListener(Event.ENTER_FRAME,onFrameLoop);
function onFrameLoop(evt:Event):void { cycle.x = stage.mouseX; cycle.wheel.rotation = stage.mouseX;
}
stage.addEventListener(Event.ENTER_FRAME,onFrameLoop);
function onFrameLoop(evt:Event):void { cycle.x = stage.mouseX; cycle.wheel.rotation = stage.mouseX;
}
Another Example• This example also demonstrates how to remove event
listeners – eventTarget.removeEventListener (
EventType, eventListener);• eventTarget, EventType, eventListener should be compatible with
those used for addEventListener
Spring 2011 SCM-CityU 11
stage.addEventListener(MouseEvent.MOUSE_UP, removeFrameLoop);
function removeFrameLoop(evt:MouseEvent):void { stage.removeEventListener(Event.ENTER_FRAME, onFrameLoop);
stage.removeEventListener(MouseEvent.MOUSE_UP, removeFrameLoop); }
stage.addEventListener(MouseEvent.MOUSE_UP, removeFrameLoop);
function removeFrameLoop(evt:MouseEvent):void { stage.removeEventListener(Event.ENTER_FRAME, onFrameLoop);
stage.removeEventListener(MouseEvent.MOUSE_UP, removeFrameLoop); }
Class Exercise • Create a symbol instance similar to the one below and
change its properties in ActionScript – Fill shape with gradient color using Paint Bucket Tool
Spring 2011 SCM-CityU 14
Instance name: ball
Let’s Make Ball Moving • Add event listener for ENTER_FRAME
update ball’s position inside this listener
Spring 2011 SCM-CityU 16
OX
Y
ball.x+=ball_speed_x;ball.y+=ball_speed_y;
Bouncing Against Boundary
• If ball.y is too large (i.e., > stage.stageHeight)– Set ball.y = stage.stageHeight;– And set ball_speed_y *= -1; // moving along negative y axis
• Class Exercise
Spring 2011 SCM-CityU 18
OX
Y
y = stage.stageHeight
...if (conditionA) {
// process B}...
...if (conditionA) {
// process B}...
x = stage.stageWidth
OX
Y
Bouncing Against Boundary
• Since ball has its radius (i.e., r = ball.width / 2), it should bounce at
y = stage.stageHeight - r; // for bottom border
• Class Exercise – Update and fix
Spring 2011 SCM-CityU 19
y = stage.stageHeight - r
Bouncing Against Catcher
• Next step: add user interaction – User controls a horizontal bar, called catcher
Spring 2011 SCM-CityU 20Instance name: catcher
Keyboard Event
• Making the catcher move horizontally by pressing left or right key– stage is a variable you can always access
Spring 2011 SCM-CityU 21
stage
Hi buddy, some key has been
pressed
Hi buddy, some key has been
pressed
OK. Let me check if left or right key has been pressedOK. Let me check if left or right key has been pressed
Keyboard Event
• KeyboardEvent provides event types for key down or up
• The info that be passed from stage to listener includes the key being pressed (keyCode)
Spring 2011 SCM-CityU 22
stage.addEventListener(KeyboardEvent.KEY_DOWN, onBarControl);
function onBarControl(e:KeyboardEvent):void {if (e.keyCode==Keyboard.LEFT) {
trace("Left key pressed");}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, onBarControl);
function onBarControl(e:KeyboardEvent):void {if (e.keyCode==Keyboard.LEFT) {
trace("Left key pressed");}
}
Class Exercise
• Change x property of catcher when left or right key is pressed– catcher.x -= catcher_speed; // for left key– catcher.x += catcher_speed; // for right key
• Catcher movement should stop if it hits the stage border – cather.x < catcher.width / 2; // for left border
Spring 2011 SCM-CityU 23
When Ball Hits Catcher
• This is true only if– ball.y > catcher.y – r AND – ball.x > catcher.x – catcher.width / 2 AND– ball.x < catcher.x + catcher.width / 2
• Class Exercise – Add code in frameLoop
Spring 2011 SCM-CityU 24
Game Over
• When catcher fails to get the ball, the game is over– I.e., ball.y > stage.stageHeight – r is true
Spring 2011 SCM-CityU 25
Game Over
• Idea: if game over is detected, go to the second key frame
• Let’s insert a key frame first
• Test movie!
Spring 2011 SCM-CityU 26
Errors • You will get error – TypeError: Error #1009: Cannot access a property or method
of a null object reference. at PingPong_Try5_fla::MainTimeline/frameLoop()
• Why?– Symbol instances can be accessed only by the script of
frames where symbol instances are defined• E.g., ball and catcher are in Frame 1 but not Frame 2. Thus neither
ball nor catcher can be used in the script for Frame 2
– However registered event listeners take effect for the life of animation before they are removed • E.g., frameLoop will be called when entering Frame 2
Spring 2011 SCM-CityU 27
Solution • First, stop animation at Frame 1 by inserting stop(); – frameLoop will be continuously executed
• Second, we need to remove unused event listeners at Frame 1 before jump to Frame 2 (for game over)– Removing event listeners is very simple. Just replace
addEventListener with removeEventListener
Spring 2011 SCM-CityU 28
stage.removeEventListener(Event.ENTER_FRAME, frameLoop);stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);
stage.removeEventListener(Event.ENTER_FRAME, frameLoop);stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);
Function Return
• One remaining issue
Spring 2011 SCM-CityU 29
function frameLoop(evt:Event):void {...
if (ball.y > stage.stageHeight-r) {trace("game over");stage.removeEventListener(Event.ENTER_FRAME, frameLoop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);gotoAndStop(2);
}
// Remaining code possibly accesses symbol instances at frame 1// However, those instances cannot be accessed at frame 2...
}
function frameLoop(evt:Event):void {...
if (ball.y > stage.stageHeight-r) {trace("game over");stage.removeEventListener(Event.ENTER_FRAME, frameLoop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);gotoAndStop(2);
}
// Remaining code possibly accesses symbol instances at frame 1// However, those instances cannot be accessed at frame 2...
}
Function Return
Spring 2011 SCM-CityU 30
function frameLoop(evt:Event):void {...
if (ball.y > stage.stageHeight-r) {trace("game over");stage.removeEventListener(Event.ENTER_FRAME, frameLoop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);gotoAndStop(2);
return; // directly exit the function }
// Remaining code possibly accesses symbol instances at frame 1// However, those instances cannot be accessed at frame 2...
}
function frameLoop(evt:Event):void {...
if (ball.y > stage.stageHeight-r) {trace("game over");stage.removeEventListener(Event.ENTER_FRAME, frameLoop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onBarControl);gotoAndStop(2);
return; // directly exit the function }
// Remaining code possibly accesses symbol instances at frame 1// However, those instances cannot be accessed at frame 2...
}
Function Return
• After calling “return”, it would directly exit the function and – Set the output as the returned value or void
Spring 2011 SCM-CityU 31
function returnTest(): void {return; trace("this line will never execute");
}
function returnTest2(): int {return 1; // set output = 1 and exit function return 2;
}
returnTest();trace(returnTest2());
function returnTest(): void {return; trace("this line will never execute");
}
function returnTest2(): int {return 1; // set output = 1 and exit function return 2;
}
returnTest();trace(returnTest2());
Class Exercise
• Add some AS code at Frame 2 such that pressing any key will restart the game– I.e., go back to frame 1
• Hints– Add an event listener to check if there is any key
down event for stage (KeyboardEvent.KEY_DOWN)• Similar to what we did at Frame 1
– gotoAndStop(1);
Spring 2011 SCM-CityU 32