• 沒有找到結果。

第四章 數位化數學遊戲程式設計說明

第四節 馬不停蹄遊戲

壹、數學遊戲模式架構

元件製作與 佈置場景。

開始遊戲宣告變 數、陣列與設定初始 值。

ReplayDown 函數重新遊 戲。

設定甲勝利或乙勝利及平手 時所出現的效果。

建立 CreateAnswerPanel 函數,新增圖樣影片物件 到棋盤上。

建立 DoCount 函 數,判定哪一位玩家 選了哪幾塊蛋糕。

建立 AnswerBallDown 函數 並搭配 BallAction 及 UpdateActionInformation 函數,玩家進行遊戲時分別 執行馬的跳動,走過路徑編 號,更新棋盤上可走的圖樣 影片物件資訊。

建立 Check 函數,檢 查玩家是否可再進

行遊戲。

貳、數學遊戲設計重點 一、第一影格

01 stop();

PlayBtn.addEventListener(MouseEvent.MOUSE_DOWN,PlayBtnDown);

function PlayBtnDown(me:MouseEvent) {

PlayBtn.visible = false;

gotoAndPlay(2);

}

//第01 行:開啟遊戲後將此影片片段的畫面停止在影格1 的圖案。建立遊戲開始 按鈕的滑鼠按下監聽事件,並將監聽函數命名為PlayBtnDown。於函數中設定事 件發生時將遊戲開始按鈕的visible屬性設為false,並進入第二影格。//

二、第二影格

001 stop();

//第 001 行: 進入第二影格後將此影片片段的畫面停止在影格 2 。//

002 var AnswerPatternArray:Array=

[[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,2,2,2,2,2,2,2,2,1,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0]];

//第002~011 行: 宣告並建立一個答案圖樣陣列(AnswerPatternArray),是由 數字0,1,2 組成的9×13陣列,用來設定棋盤上45個交點上的的圖樣影片,其中 數字1代表播放圖樣影片的第一影格,顯示馬,數字2是代表播放圖樣影片的第二 影格,顯示可選擇的空圓圈,數字0則表示不將圖樣影片放上去,遊戲開始時我 們這個陣列把馬放在棋盤最右上角,其他棋盤內的圖樣影片顯示空圈圈,而棋盤 外另外多排兩圈沒有圖樣影片,以便走馬步時可以選擇,但是又沒有實體物件可 按。//

012 var ActionArray:Array=

[[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,2,2,2,2,2,2,1,2,2,0,0],

[0,0,2,2,2,2,2,2,2,1,2,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,2,2,2,2,2,2,2,2,2,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0]];

//第012~021 行: 宣告並建立一個動作圖樣陣列(AnswerPatternArray),也是 由數字0,1,2 組成的9×13陣列剛好對應前面的答案圖樣陣列,用來設定棋盤上 45個交點上的圖樣影片的可選擇性,其中數字1代表該圖樣影片為可以選擇的空 圓圈,按下之後馬就走到那裡,數字2是代表該圖樣影片為不可選擇,就算按了 也沒反應的空圓圈,數字0則表示沒有東西,棋盤外另外多排兩圈沒有圖樣影片,

以便走馬步時可以選擇,但是又沒有實體物件可按。,遊戲開始時因為我們把馬 放在棋盤最右上角,而馬步走日字型所以遊戲開始用此陣列設定只有這兩個空圓

圈可以選擇。//

022 var AnswerBallArray:Array = [[],[],[],[],[],[],[],[],[]];

var i,j,m,k:int;

var CurrentI,CurrentJ;

var PreI,PreJ;

var totalcount:int = 2;

var chnum:int = 2;

var Count:int = 3;

var CheckCount:int = 0;

var TempBallArray:Array=new Array();

var PreBallArray:Array=new Array();

var n:int = 1;

var l:int;

//第 022~033 行: 宣告各項變數與陣列。//

035 say_mc.gotoAndStop(1);

ReplayBtn.visible = false;

num_mc.visible = false;

num1_mc.visible = false;

//第 035~038 行: 設定指導語 say_mc 影片停在第一影格,另外重玩按鈕 (ReplayBtn)及坐標文字影片(num_mc、num1_mc)的 visible 屬性為 false,坐標 文字影片為解說之用,或於教師課堂實施時可讓對戰學生喊出坐標由老師操作電 腦,方便小組競爭及提高效率。//

040 ReturnBtn.addEventListener(MouseEvent.MOUSE_DOWN,

ReturnBtnDown);

function ReturnBtnDown(me:MouseEvent) {

ReturnBtn.visible = false;

for (i=2; i<7; i++) {

for (j=2; j<11; j++) {

removeChild(AnswerBallArray[i][j]);

} }

gotoAndPlay(1);

}

//第040~052 行: 建立返回按鈕的滑鼠按下監聽事件,並將監聽函數命名為 ReturnBtnDown。於函數中設定事件發生時,將返回按鈕的visible屬性設為 false,用巢狀for迴圈移除棋盤上所有的圖樣影片,返回第一影格。//

053 CreateAnswerPanel();

function CreateAnswerPanel() {

for (i=0; i<9; i++) {

for (j=0; j<13; j++) {

if (AnswerPatternArray[i][j] != 0) {

AnswerBallArray[i][j]=new Ball();

AnswerBallArray[i][j].x = 30 + 60 * j;

AnswerBallArray[i][j].y = 30 + 60 * i;

AnswerBallArray[i][j].scaleX = 1;

AnswerBallArray[i][j].scaleY = 1;

AnswerBallArray[i][j].buttonMode = true;

AnswerBallArray[i][j].gotoAndStop(AnswerPatternAr ray[i][j]);

addChild(AnswerBallArray[i][j]);

AnswerBallArray[i][j].PositionI = i;

AnswerBallArray[i][j].PositionJ = j;

AnswerBallArray[i][j].addEventListener(MouseEvent .MOUSE_DOWN,AnswerBallDown);

} } }

//第053~075 行: 建立並執行函數CreateAnswerPanel(寫在這裡將於進入第二 影格時執行),於函數中設定事件發生時,利用三層巢狀for迴圈對照答案圖樣陣 列(AnswerPatternArray)新增圖樣影片物件到棋盤,並訂定每個圖樣影片物件在 舞台中的x、y位置及縮放倍率,設定每個圖樣影片物件按鈕模式為true,即滑鼠 移到圖樣影片物件上方會出現手指的形狀,圖樣影片物件對照答案圖樣陣列 (AnswerPatternArray)中的每個元素將影片顯示為陣列中指定的影格,並設定每 個圖樣影片物件的參數PositionI為它在陣列中的列數i,每個圖樣影片物件的參

數PositionJ為它在陣列中的行數j,之後增加每個圖樣影片物件的滑鼠監聽,玩 家對每個圖樣影片物件按下時執行AnswerBallDown函數。//

076 PreI = 2;

PreJ = 10;

AnswerBallArray[2][10].Counter = 1;

AnswerBallArray[2][10].removeEventListener(MouseEvent.MOUSE_D OWN,AnswerBallDown);

}

//第076~080 行: 另於函數CreateAnswerPanel中設定事件發生時(就是進入第 二影格時),將參數PreI的值設定為2,將參數PreJ的值設定為10,這兩個參數在 之後的遊戲中用來記錄玩家前一步走的位置,在此先存入馬的初始位置。設定馬 初始位置的圖樣影片物件的參數Counter值為1,原本將所有圖樣影片物件增加的 監聽為物件按下時執行AnswerBallDown函數,在此移除馬初始位置的圖樣影片物 件原先的滑鼠監聽。//

081 function AnswerBallDown(me:MouseEvent) {

CurrentI = me.currentTarget.PositionI;

CurrentJ = me.currentTarget.PositionJ;

//第 081~084 行:於 AnswerBallDown 函數中設定事件發生時,抓取玩家所按下 的圖樣影片物件參數 PositionI 及 PositionJ 分別存入變數 CurrentI、CurrentJ 中,此時 CurrentI、CurrentJ 存入的值分別為對應 AnswerBallArray 及

ActionArray 兩陣列中第 i 列及 j 行。//

085 if (ActionArray[CurrentI][CurrentJ] == 1) {

DoCount();

AnswerBallArray[CurrentI][CurrentJ].gotoAndStop(1);

AnswerBallArray[PreI][PreJ].gotoAndStop(Count);

AnswerBallArray[CurrentI][CurrentJ].Counter = Count - 1;

//第 085~090 行:用 if 語法判斷玩家所按下的圖樣影片物件,對應到

ActionArray 陣列中元素的值若為 1 代表為可以選擇的空圓圈,則進行下列動 作:執行 DoCount 函數,將該圖樣影片物件顯示第一影格(即出現馬),玩家所下 的前一步則顯示變數 Count 現存值表示的影格,另外將玩家現在所按下的這一個 圖樣影片物件的參數 Counter 值設定為 Count 的值減 1。//

091 TempBallArray=[

ActionArray[CurrentI+2][CurrentJ+1],

ActionArray[CurrentI+2][CurrentJ-1],

ActionArray[CurrentI-2][CurrentJ+1],

ActionArray[CurrentI-2][CurrentJ-1],

ActionArray[CurrentI+1][CurrentJ+2],

ActionArray[CurrentI+1][CurrentJ-2],

ActionArray[CurrentI-1][CurrentJ+2],

ActionArray[CurrentI-1][CurrentJ-2]];

//第 091~099 行: 以現在玩家所按下的圖樣影片物件,在 ActionArray 陣列中 對應的坐標為中心,抓取在 ActionArray 陣列中日步可走的八個位置的元素存入 TempBallArray 陣列。//

100 PreBallArray=[

ActionArray[PreI+2][PreJ+1],

ActionArray[PreI+2][PreJ-1],

ActionArray[PreI-2][PreJ+1],

ActionArray[PreI-2][PreJ-1],

ActionArray[PreI+1][PreJ+2],

ActionArray[PreI+1][PreJ-2],

ActionArray[PreI-1][PreJ+2],

ActionArray[PreI-1][PreJ-2]];

//第 100~108 行: 以玩家前一步所按下的圖樣影片物件,在 ActionArray 陣列 中對應的坐標為中心,抓取在 ActionArray 陣列中日步可走的所有位置的元素存 入 PreBallArray 陣列。//

109 BallAction();

ActionArray[CurrentI][CurrentJ] = 0;

AnswerBallArray[CurrentI][CurrentJ].removeEventListener(Mouse Event.MOUSE_DOWN,AnswerBallDown);

} }

//第 109~113 行:執行 BallAction 函數,將現在玩家所按下的圖樣影片物件對 照在 ActionArray 陣列中的元素值設定為 0,移除現在玩家所按下的圖樣影片物 件的滑鼠監聽事件。//

115 function BallAction() {

for (m=0; m<8; m++) {

if (PreBallArray[m] != 0) {

PreBallArray[m] = 2;

} }

ActionArray[PreI + 2][PreJ + 1] = PreBallArray[0];

ActionArray[PreI + 2][PreJ - 1] = PreBallArray[1];

ActionArray[PreI - 2][PreJ + 1] = PreBallArray[2];

ActionArray[PreI - 2][PreJ - 1] = PreBallArray[3];

ActionArray[PreI + 1][PreJ + 2] = PreBallArray[4];

ActionArray[PreI + 1][PreJ - 2] = PreBallArray[5];

ActionArray[PreI - 1][PreJ + 2] = PreBallArray[6];

ActionArray[PreI - 1][PreJ - 2] = PreBallArray[7];

//第 115~131 行:於 BallAction 函數中設定函數執行時,先以 for 迴圈將 PreBallArray 陣列中每一個值不是 0 的元素的值改成 2。此時 PreBallArray 陣 列中存的是玩家前一步可以走的圖樣影片物件,值為 0 的是棋盤外沒有圖樣影片 物件的地方,故 if 判斷執行的對象只對棋盤內的物件動作,將棋盤內玩家前一 步可以走的圖樣影片物件對應的值全部設定為 2,再存回 ActionArray 陣列中那 些對應的元素以為更新之用,使得玩家走過之後這些圖樣影片物件就不能再按 了,讓棋盤上可以走的圖樣影片物件只有最新的那幾步可以選擇。//

132 for (k=0; k<8; k++) {

if (TempBallArray[k] != 0) {

TempBallArray[k] = 1;

CheckCount += 1;

} }

Check();

UpdateActionInformation();

}

//第 132~142 行:接著再使用 for 迴圈和 if 語法將 TempBallArray 陣列中每一 個值不是 0 的元素的值改成 1。此時 TempBallArray 陣列中存的是玩家下一步可 以走的圖樣影片物件,值為 0 的是棋盤外沒有圖樣影片物件的地方,故 if 判斷 執行的對象只對棋盤內的物件動作,將棋盤內玩家下一步可以走的圖樣影片物件

對應的值全部設定為 1,接著將變數 CheckCount 的值加 1 再存回,回到函數 BallAction 中執行 Check 函數及 UpdateActionInformation 函數。變數

CheckCount 的功能在檢查下一個玩家可以走的選項有幾個,所以之後搭配 Check 函數作檢查,如果上一個玩家走完之後下一個玩家沒路可走的時候遊戲就結束。

//

143 function UpdateActionInformation() {

ActionArray[CurrentI + 2][CurrentJ + 1] = TempBallArray[0];

ActionArray[CurrentI + 2][CurrentJ - 1] = TempBallArray[1];

ActionArray[CurrentI - 2][CurrentJ + 1] = TempBallArray[2];

ActionArray[CurrentI - 2][CurrentJ - 1] = TempBallArray[3];

ActionArray[CurrentI + 1][CurrentJ + 2] = TempBallArray[4];

ActionArray[CurrentI + 1][CurrentJ - 2] = TempBallArray[5];

ActionArray[CurrentI - 1][CurrentJ + 2] = TempBallArray[6];

ActionArray[CurrentI - 1][CurrentJ - 2] = TempBallArray[7];

PreI = CurrentI;

PreJ = CurrentJ;

Count += 1;

CheckCount = 0;

}

//第 143~157 行: 於 UpdateActionInformation 函數中設定函數執行時,將前 面更新過的 TempBallArray 陣列再存回 ActionArray 陣列中那些對應的元素以為 更新之用,使得現在棋盤上可以走的圖樣影片物件有最新的那幾步可以選擇。而 將這個部份獨立出來特別使用一個函數,是要讓前一步原來可以走的先更新成不 能走,而下一步可以走的最後再更新故獨立寫成一個函數,等前面的步驟執行完 再呼叫出來更新。將變數 CurrentI 、CurrentJ 的值分別存入變數 PreI、PreJ 中,這一步走完就變成前一步。將變數 Count 的值加 1,變數 CheckCount 的值 說定為 0。//

159 function DoCount() {

totalcount += 1;

chnum = totalcount % 2;

ReturnBtn.removeEventListener(MouseEvent.CLICK,

ReturnBtnDown);

ReturnBtn.visible = false;

if (chnum == 1) {

say_mc.gotoAndStop(3);

}

if (chnum == 0) {

say_mc.gotoAndStop(2);

} }

//第159~173 行: 於函數DoCount中設定事件發生時,移除返回按鈕的滑鼠按下 監聽事件並設定visible屬性為false,並於每次事件發生時將變數totalcount 的值加1,將增加後totalcount的值除以2並取餘數存入變數chnum當中。接著使 用if陳述式來判斷變數chnum的值,變數chnum的值為1時指導語影片片段播放第 三影格顯示輪到甲,變數chnum的值為0時指導語影片片段播放第二影格顯示輪到 乙。//

175 function Check() {

if (Count == 47) {

var QuestionTimer:Timer = new Timer(10,1);

QuestionTimer.start();

QuestionTimer.addEventListener(TimerEvent.TIMER,

QuestionTimerStart);

function QuestionTimerStart(te:TimerEvent) {

AnswerBallArray[CurrentI][CurrentJ].gotoAndStop(47);

}

CloseBall();

say_mc.gotoAndStop(6);

ReplayBtn.visible = true;

ReplayBtn.addEventListener(MouseEvent.CLICK,ReplayDown);

}

//第 260~277 行: Check 函數用在判斷玩家是否完成遊戲,使用 if 語法來判斷 Count 值是否等於 47,於遊戲中 Count 值用來顯示圖樣影片物件播放第幾影格,

第一影格為馬,第二影格為空圓圈,第三影格為第一步,依此類推第四十七影格 為第四十五步。所以第二位玩家走到第四十五步時,代表兩人平手。但那時候玩

家最後選擇的那一步顯示馬,故使用一個計時器,在 10 毫秒後將馬轉為第四十 五步,代表原本是兩個競爭的遊戲最後卻意外完成了上一個遊戲的要求,變成兩 個玩家合力用馬步不重複走完棋盤上 45 個點。之後將所有圖樣影片物件使用 CloseBall 函數關閉所有監聽,指導語播放第六影格顯示兩人平手,將重玩鈕 visible 屬性設定為 true,增加滑鼠監聽事件,並將監聽函數命名為

ReplayDown。//

192 if (CheckCount == 0) {

if (chnum == 1) {

say_mc.gotoAndStop(4);

Afire_mc.gotoAndPlay(2);

}

if (chnum == 0) {

say_mc.gotoAndStop(5);

Bfire_mc.gotoAndPlay(2);

}

CloseBall();

ReplayBtn.visible = true;

ReplayBtn.addEventListener(MouseEvent.CLICK,ReplayDown);

} }

//第 192~208 行:於 Check 函數中用 if 語法判斷,若變數 CheckCount 的值為 0 時有人獲勝,變數 CheckCount 的功能在檢查下一個玩家可以走的選項有幾個,

如果上一個玩家走完之後下一個玩家沒路可走的時候遊戲就結束。故再用 if 語 法檢查變數 chnum 的值判斷誰獲勝,若變數 chnum 的值為 1 代表甲獲勝,指導語 播放第四影格甲勝利並施放煙火。若變數 chnum 的值為 0 代表乙獲勝,指導語播 放第五影格乙勝利並施放煙火。之後將所有圖樣影片物件使用 CloseBall 函數關

如果上一個玩家走完之後下一個玩家沒路可走的時候遊戲就結束。故再用 if 語 法檢查變數 chnum 的值判斷誰獲勝,若變數 chnum 的值為 1 代表甲獲勝,指導語 播放第四影格甲勝利並施放煙火。若變數 chnum 的值為 0 代表乙獲勝,指導語播 放第五影格乙勝利並施放煙火。之後將所有圖樣影片物件使用 CloseBall 函數關