第四章 數位化數學遊戲程式設計說明
第四節 馬不停蹄遊戲
壹、數學遊戲模式架構
元件製作與 佈置場景。
開始遊戲宣告變 數、陣列與設定初始 值。
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 函數關