娃娃走動程式 ─ 定義娃娃的限制走動範及會轉向的變化游標



請用滑鼠在畫面任意點左鍵,娃娃即以正確方向走到滑鼠所點之處

滑鼠點在天空,娃娃則不會走過去 。並且游標有指示方向的功能。




 


步驟 1

 

產生一個MovieClip,命名為"myCursor",進入"myCursor"的編輯介面

在它的Frame 1設stop();的action

並且在畫面隨便亂畫一個白色的手指頭,如圖 1


圖 1

在它的Frame 2畫面,畫一個十字圖形,如圖 2


圖 2

 

打開Library,用右鍵點選"myCursor",跳出選單,選擇"linkage"指令

在Linkage Properties,給予Indntifier 名稱,並做以下設定,如圖 3


圖 3

 

步驟 2

 

回到場景上,將作品畫面尺寸設為720x500,在Scene 1場景設計以下畫面(或是自行設計故事場景),如圖 4


圖 4

步驟 3

 

再產生一個新圖層,命名為"娃娃及走動範圍"

在該圖層用繪圖工具畫出一個娃娃走動的範圍,記得必須要是有填色的色塊。將此色塊轉為MovieClip,並給予InstanceName為 area,如圖 5


圖 5

 

 

 

在Scene1 場景的"娃娃及走動範圍"圖層,放入一個軟大娃娃,並且給予InstanceName為wawa,如圖 6


圖 6

 

步驟 4

 

進入area娃娃走動範圍這個MovieClip的編輯介面,如圖 7


圖 7

在它的Frame 1寫以下程式,如圖 8


圖 8

 

程式說明

_alpha = 0 ;

/* 使用 attachMovie() 將 myCursor 這個自定游標symbol的 movie clip實例貼在_root movie clip
然後把 myCursor的_visible設定為 false,把 myCursor 隱藏*/

_root.attachMovie("myCursor", "myCursor", 1);
_root.myCursor._visible = false;

cursorLimit = 5; //娃娃移動中心點與滑鼠游標影格切換的距離。小於這個值時,把自定游標改為十字標,大於時,為手指頭游標

 

/*
onEnterFrame() 事件處理函式
函式執行的時機:在每次播放這個 movice clip 的影格時都會執行
目的:決定游標的
1.位置
2.形狀
3.轉向
*/

onEnterFrame = function(){

/*
把自定游標的位置設定為目前滑鼠游標的位置
*/

_root.myCursor._x = _root._xmouse;
_root.myCursor._y = _root._ymouse;

/*
取得娃娃移動中心點的座標與滑鼠座標在 x, y 軸的距離。
*/

var dx = _root.myCursor._x - _root.wawa._x;
var dy = _root.myCursor._y - _root.wawa._y - 25;

/*
檢查是否在 cursorLimit 的範圍內:
是的話,自定游標移到十字標的影格,並把轉向的角度改為0
否則,移到箭頭的影格,並使用 Math.atan2()計算弧度。
所得的弧度 * 57 轉換為箭頭旋轉的角度。
*/

if(Math.abs(dx) < cursorLimit and Math.abs(dy) < cursorLimit){

_root.myCursor.gotoAndStop(2);
_root.myCursor._rotation = 0;

}else{

_root.myCursor.gotoAndStop(1);
_root.myCursor._rotation = Math.atan2(dy, dx) * 57;

}

}

 

onRollOver = function(){

Mouse.hide();
_root.myCursor._visible = true;

}

onRollOut = function(){

_root.myCursor._visible = false;
Mouse.show();

}

 

步驟 5

 

回到Scene 1場景

進入這個娃娃內部的TimeLine,把它的結構改為只有四格的Frame,這個格Frame的畫面內容,如圖 9如下

Frame 1→ 左半側面娃娃
Frame 2→ 向下走娃娃
Frame 3→ 向上走娃娃
Frame 4→ 向左走娃娃

 


圖 9

 

在娃娃內部TimeLine的Frame1寫以下Action,如圖 10


圖 6

程式說明如下

stop();

/* movie clip 的變數 */

y_offset = 25; // y 座標的位移值,原本娃娃的中心點在頭上面,要把中心點移到娃娃的腳時,需減掉25個像素的距離
speed = 10; // 每播放一次影格娃娃移動的速度(以像素點為單位)

// x_dest 及 y_dest 分別代表娃娃走動目的點的 x, y 座標,一開始的值設定為娃娃目前的座標,這樣子一啟動程式時娃娃才是靜止的
x_dest = _x;
y_dest = _y;

/* movie clip 的事件處理函式 */

/*
onEnterFrame() 事件處理函式
函式執行的時機:在每次播放這個 movice clip 的影格時都會執行
目的:藉由檢查娃娃是否移動到指定的地點,決定是否繼續移動娃娃的座標。
*/

onEnterFrame = function() {

//檢查是否娃娃已經移動到終點的座標值,使用 Math.round()函式來作比較,避免小數點之後的誤差
if(Math.round(x_dest) == Math.round(_x) and Math.round(y_dest) == Math.round(_y)){

//是的話,將娃娃的影格移到第一格(靜止的影格)
gotoAndStop(1);

}else{

//否則,呼叫 updatePosition()函式,移動娃娃的位置
updatePosition();

}

}

 

/*
onMouseUp 事件處理函式
函式執行的時機:當使用者放開滑鼠鍵時執行
目的:
1. 檢查使用者是否點選在限定移動的區域 --- v3版新增的功能 ---
2. 取得滑鼠點選的 x, y 座標值(y 軸需減掉位移植),並把座標值存放在 x_dest, y_dest 這兩個變數中
3. 使用畢氏定理求得娃娃起點到終點的移動距離。
4. 取得移動距離後,即可求出每個影格娃娃應該移動的 x, y 軸的距離
5. 決定娃娃左右的方向
6. 決定娃娃移動時應該使用哪個影格
*/

onMouseUp = function(){

// 檢查使用者點選滑鼠的位置是否在 _root.area 這個 movie clip 的區域內。 --- v3版新增的功能 ---
if(_root.area.hitTest(_root._xmouse, _root._ymouse, true)){

/*
讀取 _root._xmouse 和 _root._ymouse 並減掉 y_offset 位移值,
然後把所得的 x, y 座標值,分別放到 x_dest, y_dest這兩個變數。
*/

x_dest = _root._xmouse;
y_dest = _root._ymouse - y_offset;

/*
分別求出 x, y 軸的移動距離,再使用畢氏定理求出移動距離
*/

var dx = x_dest - _x;
var dy = y_dest - _y;
var distance = Math.sqrt((dx * dx) + (dy * dy));

/*
求得距離後,使用等比三角形的原理,求出每個影格 x, y 軸移動的距離
*/

x_speed = speed * (dx / distance);
y_speed = speed * (dy / distance);

/*
如果點選的位置在目前娃娃位置的右邊時(點選位置 x 軸的座標,大於目前位置 x 軸的座標),
藉由改變 _xscale 作水平鏡射,改變娃娃面對的方向。
*/

if(x_dest > _x){

_xscale = -100;

}else{

_xscale = 100;

}

/*
使用 Math.abs()--Math物件的abs方法,取得移動距離在 x, y 軸的絕對值(dx, dy)
比較這兩個絕對值,決定是否娃娃移動影格使用垂直移動的影格,或是水平移動的影格。

如果垂直移動的距離大於水平移動的距離時,
則檢查是否 dy > 0(終點的位置在目前位置的下面),
是的話,使用第二格(即向下走娃娃的影格),
否則使用第三格(娃娃向上走的影格)

如果垂直移動的距離小於或等於水平移動的距離時,
則使用第四格(即娃娃向左走的影格)
*/

if(Math.abs(dy) > Math.abs(dx)){

gotoAndStop(dy > 0? 2: 3);

}else{

gotoAndStop(4);

}

}

}

 

/* 自定的函式 */
/*
updatePosition() 自定函式
函式執行的時機:由 onEnterFrame()函式執行
目的: 移動娃娃的位置
*/

function updatePosition(){

/*
分別檢查在 x, y 座標上,是否每次應移動的距離(x_speed, y_speed)大於或等於娃娃目前座標與終點座標的距離
(除了最後一次移動的距離,可能小於應移動的距離之外,其他狀況下,娃娃目前的位置與終點之間的距離應該大於每次移動的距離)
*/

if(Math.abs(x_speed) >= Math.abs(x_dest - _x)){

_x = x_dest;
x_speed = 0;

}
if(Math.abs(y_speed) >= Math.abs(y_dest - _y)){

_y = y_dest;
y_speed = 0;

}
/*
要分別遞增 _x, _y 這兩個 movie clip 的屬性來移動娃娃。
*/

_x += x_speed;
_y += y_speed;

}


 

 

Test Movie 預覽測試

原始檔下載

 

 


回課程目錄