32
M1205 Interactivity Topic 05: Properties and Events Part II Spring 2011 SCM-CityU 1

SM1205 Interactivity Topic 05: Properties and Events Part II Spring 2011SCM-CityU1

  • View
    213

  • Download
    0

Embed Size (px)

Citation preview

SM1205 Interactivity

Topic 05: Properties and Events Part II

Spring 2011 SCM-CityU 1

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); }

SM1205 Interactivity

Ping Pong Game

Spring 2011 SCM-CityU 12

Today’s Example

• Pingpong-like game

Spring 2011 SCM-CityU 13

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

Registration Point• In this example, choose center as registration point

Spring 2011 SCM-CityU 15

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

Spring 2011 SCM-CityU 17

OX

Y

How?

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