SlideShare a Scribd company logo
1 of 55
Actionscript 遊戲元素
南台科技大學
多媒體與電腦娛樂科學系
楊智傑 助理教授
scatjay@gmail.com
 Gary Rosenzweig, 2008, “ActionScript
3.0 Game Programming”, Macmillan
Computer Pub.
教材出處
這章會學到的…
 用用 FlashFlash 製作遊戲需要的基本元素製作遊戲需要的基本元素
 了解了解 ActionscriptActionscript 可以做到的效果可以做到的效果
特別注意特別注意 !!
 本章範例程式很多個,回家記得複習本章範例程式很多個,回家記得複習
章節大綱
 產生視覺化物件產生視覺化物件
 接受使用者輸入接受使用者輸入
 產生動畫產生動畫
 撰寫使用者互動程式撰寫使用者互動程式
 存取外部資料存取外部資料
 各式各樣的遊戲元素各式各樣的遊戲元素
產生視覺化的物件
(page-42)
 本章使用原始檔本章使用原始檔 (A3GPU02_GameElements.zip)(A3GPU02_GameElements.zip)
 製作遊戲的第一步製作遊戲的第一步 ->->
產生並控制螢幕上的物件產生並控制螢幕上的物件
 使用元件庫的影片片段的兩種方式使用元件庫的影片片段的兩種方式
 方式一:直接拖拉到場景當中方式一:直接拖拉到場景當中
 在屬性視窗給予實體名稱在屬性視窗給予實體名稱
假如實體名稱為“假如實體名稱為“ myClipInstance””
 使用 myClipInstance 來控制影片片段的屬性
myClipInstance.x = 300;
myClipInstance.y = 200;
 UsingMovieClips.flaUsingMovieClips.fla
 方式二:完全用程式來產生方式二:完全用程式來產生
 在元件庫內選取某個影片片段的元件在元件庫內選取某個影片片段的元件
 設定連結名稱,讓程式可以存取影片片段設定連結名稱,讓程式可以存取影片片段
 勾選 “勾選 “ Export for ActionScript”Export for ActionScript”
 設定類別名稱設定類別名稱 (( 通常會設成和元件名稱相同通常會設成和元件名稱相同 ))
(( 以下的例子類別名稱為以下的例子類別名稱為 MascotMascot ,大概是人名吧…,大概是人名吧… ?)?)
(( 圖圖 2.2)2.2) 設定元件連結的對設定元件連結的對
話框
 再利用以下的語法:再利用以下的語法:
// 使用 var 宣告一個變數,名稱為 myMovieClip
// 變數型態是 Mascot
// 使用 new 替這個變數產生一個新的物件
// 實際上會呼叫 Mascot 的建構函式 ( 目前尚未定義… )
// 注意變數型態和新物件型態都是 Mascot
var myMovieClip:Mascot = new Mascot();
// 把 myMovieClip 這個影片片段加入到場景當中
addChild(myMovieClip);
 因為我們還沒有設定任何屬性,所以元件出現在因為我們還沒有設定任何屬性,所以元件出現在
(0,0)(0,0) 的位置的位置
 修改成以下的語法:修改成以下的語法:
// 一樣是宣告一個新的物件
var myMovieClip:Mascot = new Mascot();
myMovieClip.x = 275; // 修改物件 X 座標
myMovieClip.y = 150; // 修改物件 Y 座標
myMovieClip.rotation = 10; // 修改物件旋轉角度
// 一樣是把物件加入場景當中
addChild(myMovieClip);
 前面的範例只會產生一個物件前面的範例只會產生一個物件
 同一個元件在場景當中可以有很多份同一個元件在場景當中可以有很多份 copycopy
 以下的程式碼會產生以下的程式碼會產生 1010 個個 MascotMascot
由左至右每次位移由左至右每次位移 5050 個像素個像素
元件比例為元件比例為 50%50%
// 這個迴圈執行 10 次 ( 複習一下迴圈參數的用法… )
for(var i=0;i<10;i++)
{
// 宣告新的 Mascot 物件
var mascot:Mascot = new Mascot();
// X 座標以 50 為初始點 , 位置隨著迴圈參數向右每次移動 50
mascot.x = 50*i+50;
// Y 座標固定在 300
mascot.y = 300;
// X 方向比例設為 0.5, 就是 50% 的意思
mascot.scaleX = .5;
// Y 方向的比例設為 50%
mascot.scaleY = .5;
// 加上這行物件才會顯示在場景當中
addChild(mascot);
}
(( 圖圖 2.3)2.3)
 做出來的效果會像這樣…做出來的效果會像這樣…
 製作按鈕製作按鈕 -- MakingButtons.flaMakingButtons.fla
 元件類型可以是“影片片段”或“按鈕”元件類型可以是“影片片段”或“按鈕”
 如果是“影片片段”,必須加入事件監聽器如果是“影片片段”,必須加入事件監聽器 (listener)(listener)
 讓影片片段可以接受事件,像是“滑鼠點擊”事件讓影片片段可以接受事件,像是“滑鼠點擊”事件
// 和前面範例差不多的語法
var myMovieClip:Mascot = new Mascot();
myMovieClip.x = 100;
myMovieClip.y = 150;
addChild(myMovieClip);
 替影片片段指定事件監聽器替影片片段指定事件監聽器
 使用 “使用 “ addEventListener(addEventListener( 參數參數 1,1, 參數參數 2)”2)” 函函
式式
 參數參數 11 :指定要接受何種輸入,例如::指定要接受何種輸入,例如:
“ MouseEvent.CLICK” 代表按下滑鼠
 參數 2 :指定一個函式名稱,當接受到事件時會:指定一個函式名稱,當接受到事件時會
執行這個函式執行這個函式
這邊是用“這邊是用“ clickMascot”…”…
// 所以程式碼像這樣…
myMovieClip.addEventListener(MouseEvent.CLICK,
clickMascot);
 接下來撰寫按下滑鼠會執行的函式
function clickMascot(event:MouseEvent)
{
// 按下滑鼠時輸出這段文字
trace(“You clicked the mascot!”);
}
 以下這行會讓滑鼠顯示成手指的圖案
// 直接把影片片段的 buttonMode 設為 true
myMovieClip.buttonMode = true;
 假如你的元件原本就是“按鈕”假如你的元件原本就是“按鈕”
// 一樣的用法,不過類別型態是 LibraryButton
var myButton:LibraryButton = new LibraryButton();
myButton.x = 450; // 設定 X 座標
myButton.y = 100; // 設定 Y 座標
addChild(myButton); // 加入場景
 用“影片片段”和“按鈕”兩種元件製作按鈕不同的地方
 按鈕元件的影格裡面可以直接設定四種按鈕狀態的圖示
Up( 原始狀態 ), Over( 滑鼠移入 ), Down( 按下滑鼠 ), Hit( 點擊範圍 )
(( 圖圖 2.4)2.4) 按鈕元件的時間軸影按鈕元件的時間軸影
格格
(( 圖圖 2.5)2.5) 按鈕四種狀態按鈕四種狀態
 替按鈕元件加入事件監聽器替按鈕元件加入事件監聽器
// 先指定要監聽的事件類型是 MouseEvent.CLICK
// 再指定事件發生時要執行的函式 clickLibraryButton
myButton.addEventListener(MouseEvent.CLICK,
clickLibraryButton);
// 定義執行函式要做的事情
function clickLibraryButton(event:MouseEvent)
{
// 只輸出一段文字就好…
trace(“You clicked the Library button!”);
}
 繪製圖形繪製圖形 -- DrawingShapes.flaDrawingShapes.fla
 除了使用元件庫裡面的元件之外除了使用元件庫裡面的元件之外
 也可以使用基本的線條和圖形繪圖也可以使用基本的線條和圖形繪圖
 使用使用 graphicsgraphics 物件設定繪圖屬性物件設定繪圖屬性
// 設定線條樣式 , 線寬 2, 顏色為黑色
// 注意顏色的表示方法為 16 進位 (0,1,2,…,9,A,B,C,D,E,F)
// 頭兩個 0x 不看剩餘 RGB 各用兩個數字代表
this.graphics.lineStyle(2,0x000000);
// 開始繪圖 , 劃一條線 , 起點 (100,200)
this.graphics.moveTo(100,200);
// 畫到 (150,250 的位置 )
this.graphics.lineTo(150,250);
( 加分小問題 ) 請問 16 進位的色彩表示法當中,紅綠藍三色要怎麼
寫 ?
 其餘繪圖用法自行參考範例其餘繪圖用法自行參考範例
DrawingShapes.flaDrawingShapes.fla
 畫曲線畫曲線
 畫橢圓畫橢圓
 畫圓畫圓
 繪製文字繪製文字 -- DrawingText.flaDrawingText.fla
 使用使用 TextFieldTextField 類別產生文字類別產生文字
// 產生 TextField 物件
var myText:TextField = new TextField();
// 使用 text 屬性設定文字內容
myText.text = “Check it out!”;
// 設定位置
myText.x = 50;
myText.y = 50;
// 設定寬度和高度
myText.width = 200;
myText.height = 30;
// 設定是否顯示邊框
myText.border = true;
// 設定文字是否可以選取 ,false 為不可選取
myText.selectable = false;
// 還是要記得把文字加入場景當中
addChild(myText);
 設定文字式樣設定文字式樣
// 宣告 TextFormat 物件
var myFormat:TextFormat = new TextFormat();
// 使用 font 屬性來設定字型
myFormat.font = “Arial”;
// 使用 size 屬性設定字體大小
myFormat.size = 24;
// 是否為粗體 , true 代表使用
myFormat.bold = true;
 設定完文字式樣之後,要連結到文字物件
// 把 myText 的預設文字式樣設定為 myFormat
myText.defaultTextFormat = myFormat;
(( 圖圖 2.9)2.9) 設定完文字式樣的效設定完文字式樣的效
果果
 以下內容略過,有興趣同學自行參考以下內容略過,有興趣同學自行參考
 設定超連結文字設定超連結文字 (page-51)(page-51)
 設定群組繪圖物件設定群組繪圖物件 (page-53)(page-53)
 設定群組物件深度設定群組物件深度 (page-55)(page-55)
接受玩家的輸入
(page-55)
 滑鼠輸入滑鼠輸入 -- MouseInput.flaMouseInput.fla
 mouseX 和 mouseY 代表現在滑鼠座標
// 加入事件監聽器 , ENTER_FRAME 一進入影格就觸發
addEventListener(Event.ENTER_FRAME, showMouseLoc);
// 觸發 ENTER_FRAME 事件時執行的函式
// 因為只有一個影格 , 所以以下的函式會一直在執行
function showMouseLoc(event:Event)
{
// 把滑鼠座標顯示在 mouseLocText 文字
mouseLocText.text = “X=”+mouseX+” Y=”+mouseY;
}
 滑鼠移入影片片段的效果滑鼠移入影片片段的效果
// 加入事件監聽器 , MouseEvent.ROLL_OVER 代表滑鼠移
入
mySprite.addEventListener(MouseEvent.ROLL_OVER,
rolloverSprite);
// 滑鼠移入時 , 影片片段透明度設為 1, 為完全不透明
function rolloverSprite(event:MouseEvent)
{
mySprite.alpha = 1;
}
 滑鼠移出影片片段的效果
// 和上面類似的寫法 , 事件改為 ROLL_OUT
mySprite.addEventListener(MouseEvent.ROLL_OUT,
rolloutSprite);
function rolloutSprite(event:MouseEvent)
{
// 透明度變為 50%
mySprite.alpha = .5;
}
 鍵盤輸入鍵盤輸入 -- KeyboardInput.flaKeyboardInput.fla
 按下按鍵效果按下按鍵效果
// 事件監聽器監控 KEY_DOWN
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFunction);
// 按下按鍵執行下列事情
function keyDownFunction(event:KeyboardEvent)
{
// event.charCode 代表按下的按鍵編碼
// 使用內建函式將按鍵碼轉為文字
keyboardText.text = “Key Pressed: +String.fromCharCode(event.charCode);
}
( 加分小問題 ) 請問英文字母 A~Z 的按鍵碼範圍是多少 ?
 修改成可以監控空白鍵是否有按下修改成可以監控空白鍵是否有按下
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFunction);
function keyDownFunction(event:KeyboardEvent)
{
// 空白鍵的按鍵碼是 32
// 如果有按下空白鍵
if (event.charCode == 32)
{
// 把這個變數設定為 true
spacebarPressed = true;
}
}
 在放開按鍵時,監控空白鍵是否放開
// 使用 KEY_UP
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpFunction);
// 觸發 KEY_UP 事件時執行下列函式
function keyUpFunction(event:KeyboardEvent)
{
// 假如是放開空白鍵
if (event.charCode == 32)
{
// 這個變數設為 false
spacebarPressed = false;
}
}
 文字輸入文字輸入 -- TextInput.flaTextInput.fla
 讓使用者可以在文字欄位輸入文字讓使用者可以在文字欄位輸入文字
// 一樣宣告一個文字物件
var myInput:TextField = new TextField();
// 使用 type 屬性來指定可以輸入文字
myInput.type = TextFieldType.INPUT;
// 一樣把這個文字加到場景
addChild(myInput);
 更詳細的程式碼更詳細的程式碼
// 宣告文字格式
var inputFormat:TextFormat = new TextFormat();
inputFormat.font = “Arial”;
inputFormat.size = 12;
// 宣告文字
var myInput:TextField = new TextField();
// 設定文字為可以輸入
myInput.type = TextFieldType.INPUT;
// 設定文字格式
myInput.defaultTextFormat = inputFormat;
// 設定位置
myInput.x = 10;
myInput.y = 10;
// 設定尺寸
myInput.height = 18;
myInput.width = 200;
// 設定邊框
myInput.border = true;
// 文字加入場景
addChild(myInput);
// 設定目前的輸入焦點在 myInput
stage.focus = myInput;
 最後修改成按下 “最後修改成按下 “ ENTER”ENTER” 鍵文字會消失鍵文字會消失
(( 確定輸入完畢的意思…確定輸入完畢的意思… ))
// 事件監聽器監視 KEY_UP
myInput.addEventListener(KeyboardEvent.KEY_UP, checkForReturn);
// 下列函式檢查是否有按下 ENTER 鍵
function checkForReturn(event:KeyboardEvent)
{
// ENTER 的按鍵碼是 13
if (event.charCode == 13)
{
// 按下 ENTER 後執行下列函式
acceptInput();
}
}
// 按下 ENTER 實際上要做的事情
function acceptInput()
{
// 把輸入的文字存到 theInputText
var theInputText:String = myInput.text;
// 把 theInputText 儲存的內容印出來
trace(theInputText);
// 把文字從場景中移除
removeChild(myInput);
}
產生動畫
(page-59)
 影片片段的移動影片片段的移動 -- SpriteMovement.flaSpriteMovement.fla
 以影格為基礎的動畫以影格為基礎的動畫 (frame-based animation)(frame-based animation)
 改變改變 XX 座標或座標或 YY 座標座標
 以固定的速率移動以固定的速率移動
 使用使用 ENTER_FRAMEENTER_FRAME 事件事件
 以時間為基礎的動畫以時間為基礎的動畫 (time-based animation)(time-based animation)
 稍後會看到…稍後會看到…
(( 英文小提示英文小提示 ))
something-based…something-based…
以某某東西為基礎的…以某某東西為基礎的…
 程式碼範例
// 元件庫內已有 Hero 影片片段
// 新增一個 Hero 類別的物件
var hero:Hero = new Hero();
hero.x = 50; // 設定位置
hero.y = 100;
addChild(hero); // 物件加入場景
// 加入 ENTER_FRAME 事件監聽器
// 遇到 ENTER_FRAME 時執行 animateHero() 這個函式
addEventListener(Event.ENTER_FRAME, animateHero);
// 定義函式內要做的事情
function animateHero(event:Event)
{
hero.x++; // 每次把 hero 的位置往右加 1 像素
}
 使用使用 ENTER_FRAMEENTER_FRAME 事件製作動畫事件製作動畫
 物件移動的速度和影格速率有關物件移動的速度和影格速率有關
 預設預設 12 fps12 fps
->-> 每秒跑每秒跑 1212 格格
-> 12-> 12 次次 ENTER_FRAMEENTER_FRAME 事件事件
->-> 執行執行 1212 次次 animateHero()animateHero() 函式函式
->-> 元件往右移動元件往右移動 1212 次次 (( 每次每次 11 像素像素 ))
 如果要加快播放速度,增加影格速率,例如如果要加快播放速度,增加影格速率,例如 60fps60fps
 預期每秒執行預期每秒執行 6060 次…但是會和電腦效能有關次…但是會和電腦效能有關
 以影格為基礎的動畫以影格為基礎的動畫
 簡單易用但是不穩定簡單易用但是不穩定
 電腦速度很慢的話,無法達到預期的播放速度電腦速度很慢的話,無法達到預期的播放速度
 進一步的修改,讓進一步的修改,讓 herohero 走路走路
 herohero 內有內有 88 個影格個影格
 影格影格 11 裡面裡面 stop()stop() 停止動作 – 站立狀態停止動作 – 站立狀態
 影格影格 2~8 –2~8 – 走路循環動畫走路循環動畫
function animateHero(event:Event)
{
hero.x += 7; // 一樣向右移動 , 每次 7 像素
// 如果現在播放到影格 8
if (hero.currentFrame == 8)
hero.gotoAndStop(2); // 回到影格 2
else
// 往後播放一個影格
hero.gotoAndStop(hero.currentFrame+1);
}
(( 圖圖 2.14)2.14) 用用 77 個影格完成走路的個影格完成走路的
 使用計時器使用計時器 (Timer) –(Timer) – UsingTimers.flaUsingTimers.fla
 可以把可以把 timertimer 想成想成 ->-> 會送出訊息的時鐘會送出訊息的時鐘
 產生時鐘、開始執行、開始計時、每隔一段時間送出訊息產生時鐘、開始執行、開始計時、每隔一段時間送出訊息
 例如:讓某個函式每秒執行一次例如:讓某個函式每秒執行一次
 使用使用 TimerTimer 物件產生計時器物件產生計時器
 計時器可以設定編號計時器可以設定編號 (( 可有多個計時器同時執行可有多個計時器同時執行 ))
 指定編號停止計時器指定編號停止計時器
 用毫秒用毫秒 (( 千分之一秒千分之一秒 )) 為單位指定時間為單位指定時間
 1000 milliseconds = 11000 milliseconds = 1 秒秒
// 使用 Timer 物件產生計時器 , 指定多久執行一次 ,1000 毫秒 =1 秒
var myTimer:Timer = new Timer(1000);
// 替 Timer 加入事件監聽器 , 定期 (1000 毫秒 ) 執行 timeFunction 一次
myTimer.addEventListener(TimerEvent.TIMER, timerFunction);
// 觸發事件時實際執行的函式
function timerFunction(event:TimerEvent)
{
// 設定繪圖顏色
this.graphics.beginFill(0x000000);
// 每次在畫面上畫一個小圓 , 位置每次向右位移 10
// 其他細節用 google 自己查
this.graphics.drawCircle(event.target.currentCount*10,100,4);
}
myTimer.start(); // 開始執行 Timer( 沒有這行 ,Timer 不會執行 )
 將將 TimerTimer 套入動畫 –套入動畫 – UsingTimers2.flaUsingTimers2.fla
 和前面和前面 enterFrameenterFrame 事件的例子類似事件的例子類似
 修改事件監聽器的程式修改事件監聽器的程式
 一樣定期執行一樣定期執行 animateHero()animateHero() 函式函式
// 替動畫角色產生一個 Timer,80 毫秒執行一次
var heroTimer:Timer = new Timer(80);
// 加入事件監聽器 , 定時執行 animateHero() 函式
heroTimer.addEventListener(TimerEvent.TIMER,
animateHero);
heroTimer.start(); // Timer 開始跑
 其餘程式碼相同其餘程式碼相同
 不管影格速率多少不管影格速率多少 (6,12,60…)(6,12,60…)
 動畫執行大致速度相同動畫執行大致速度相同
 速度慢的電腦就不一定相同速度慢的電腦就不一定相同
注意注意 !! 這邊的概念會有點難懂…這邊的概念會有點難懂…
 以時間為基礎的動畫 –以時間為基礎的動畫 – TimeBasedAnimation.flaTimeBasedAnimation.fla
 動畫步驟根據經過的時間來進行動畫步驟根據經過的時間來進行
 計算步驟之間的時間計算步驟之間的時間
 根據時間差來移動物體根據時間差來移動物體
移動距離移動距離 == 物體速度物體速度 xx 經過時間經過時間
 首先用變數首先用變數 (( 整數型態整數型態 )) 來儲存經過的時間來儲存經過的時間
// getTimer()// getTimer() 傳回傳回 Flash playerFlash player 開始播放到現在的時間開始播放到現在的時間 (( 單位是毫秒單位是毫秒 ))
var lastTime:int = getTimer();
 再加入事件監聽器再加入事件監聽器
//// 監聽監聽 ENTER_FRAMEENTER_FRAME 事件事件 ,, 觸發執行觸發執行 animateBall()animateBall() 函式函式
addEventListener(Event.ENTER_FRAME, animateBall);
 處理物體移動的函式處理物體移動的函式
function animateBall(event:Event)
{
// 計算經過的時間
// getTimer() 抓現在的時間
// lastTime 是上次存起來的時間
// 兩個相減代表現在和上一步的時間差
var timeDiff:int = getTimer()-lastTime;
// 把時間差累加到 lastTime, 在下一步使用
lastTime += timeDiff;
// 物體距離 = 時間差 * 速度 (0.1),
// 速度 0.1 代表每毫秒移動 0.1 像素 , 一秒移動 100 像素
ball.x += timeDiff*.1;
}
 測試一下效果 , 影格速率 12 和 60 有何不同 ?
 物體移動距離一樣 , 影格速率 60 跑的比較順暢
 以物理為基礎的動畫 –以物理為基礎的動畫 – PhysicsBasedAnimation.flaPhysicsBasedAnimation.fla
 增加物理屬性增加物理屬性
 模擬真實世界的動畫效果模擬真實世界的動畫效果
 真實重力加速度真實重力加速度 : 9.8 (: 9.8 ( 公尺平方公尺平方 // 秒秒 ))
var gravity:Number = .00098; // 設定重力加速度
var dx:Number = .2; // 設定 X 方向速度
var dy:Number = -.8; // 設定 Y 方向速度
// 設定開始時間
var lastTime:int = getTimer();
// 監聽 ENTER_FRAME 事件 , 執行 animateBall() 函式
addEventListener(Event.ENTER_FRAME, animateBall);
(( 圖圖 2.15)2.15) 影格速率影格速率 1212 的動畫的動畫
 定義移動動畫函式
function animateBall(event:Event)
{
// 計算時間差
var timeDiff:int = getTimer()-lastTime;
// 累加經過時間
lastTime += timeDiff;
// 根據重力加速度修改 Y 方向速度
// 速度 = 加速度 x 時間
dy += gravity*timeDiff;
// 距離 = 速度 x 時間
// 計算完的距離累加原本的位移
ball.x += timeDiff*dx;
ball.y += timeDiff*dy;
}
撰寫使用者互動程式
(page-65)
 移動圖形:移動圖形: MovingSprites.flaMovingSprites.fla
 使用方向鍵控制動畫移動方向使用方向鍵控制動畫移動方向
 先使用先使用 BooleanBoolean 變數儲存按鍵狀態變數儲存按鍵狀態 (( 尚未按下:尚未按下:
false)false)
var leftArrow:Boolean = false;
var rightArrow:Boolean = false;
var upArrow:Boolean = false;
var downArrow:Boolean = false;
(( 圖圖 2.16)2.16) 方向鍵與按鍵方向鍵與按鍵
 替按鍵加入事件監聽器替按鍵加入事件監聽器
// 按下按鍵的事件監聽器
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);
// 放開按鍵的事件監聽器
stage.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp);
// ENTER_FRAME 事件監聽器
stage.addEventListener(Event.ENTER_FRAME, moveMascot);
// 觸發按下按鍵事件 , 實際執行的函式
function keyPressedDown(event:KeyboardEvent)
{
// 按下對應的按鍵 , 把按鍵狀態變數設為 true
if (event.keyCode == 37)
leftArrow = true;
else if (event.keyCode == 39)
rightArrow = true;
else if (event.keyCode == 38)
upArrow = true;
else if (event.keyCode == 40)
downArrow = true;
}
 觸發放開按鍵事件 , 實際執行的函式
function keyPressedUp(event:KeyboardEvent)
{
// 對應按鍵將狀態變數設為 true
if (event.keyCode == 37)
leftArrow = false;
else if (event.keyCode == 39)
rightArrow = false;
else if (event.keyCode == 38)
upArrow = false;
else if (event.keyCode == 40)
downArrow = false;
}
 觸發 ENTER_FRAME 事件 , 移動位置產生動畫
function moveMascot(event:Event)
{
var speed:Number = 5; // 設定速度
// 注意以下的判斷式寫法是每個獨立的 if 判斷 , 不是 if…
else if
// 代表以下四個狀態可以同時執行
// 對應方向鍵移動 X 或 Y 方向
if (leftArrow)
mascot.x -= speed;
if (rightArrow)
mascot.x += speed;
if (upArrow)
mascot.y -= speed;
if (downArrow)
mascot.y += speed;
}
 拖拉圖形:拖拉圖形: DraggingSprites.flaDraggingSprites.fla
 使用滑鼠點擊拖拉圖形使用滑鼠點擊拖拉圖形
 加入滑鼠事件監聽器加入滑鼠事件監聽器
// 替影片片段加入按下滑鼠事件監聽器
mascot.addEventListener(MouseEvent.MOUSE_DOWN,mascot.addEventListener(MouseEvent.MOUSE_DOWN,
startMascotDrag);startMascotDrag);
// 替場景加入放開滑鼠事件監聽器
stage.addEventListener(MouseEvent.MOUSE_UP,stage.addEventListener(MouseEvent.MOUSE_UP,
stopMascotDrag);stopMascotDrag);
// 替影片片段加入 ENTER_FRAME 事件監聽器
mascot.addEventListener(Event.ENTER_FRAME,mascot.addEventListener(Event.ENTER_FRAME,
dragMascot);dragMascot);
 處理滑鼠拖拉距離處理滑鼠拖拉距離
 紀錄按下滑鼠的位置紀錄按下滑鼠的位置
// 使用內建 Point 類別紀錄座標 , 預設還未儲存座標
var clickOffset:Point = null;
// 觸發按下滑鼠事件的函式
function startMascotDrag(event:MouseEvent)
{
// 把觸發事件當時的座標儲存到 clickOffset
clickOffset = new Point(event.localX, event.localY);
}
// 觸發放開滑鼠事件執行的函式
function stopMascotDrag(event:MouseEvent)
{
// 放開滑鼠後清除之前儲存的按下位置
clickOffset = null;
}
// ENTER_FRAME 事件觸發的函式
function dragMascot(event:Event)
{
// 如果已經有紀錄滑鼠按下位置
if (clickOffset != null)
{
// 計算現在滑鼠位置和儲存位置的距離差
mascot.x = mouseX - clickOffset.x;
mascot.y = mouseY - clickOffset.y;
}
}
 碰撞檢測:碰撞檢測: CollisionDetection.flaCollisionDetection.fla
 遊戲內的物件常需要檢查是否有碰撞遊戲內的物件常需要檢查是否有碰撞
 兩種用法:兩種用法:
hitTestPoint()hitTestPoint() 檢查某個點座標是否有碰撞物體檢查某個點座標是否有碰撞物體
hitTestObject()hitTestObject() 碰撞兩個物件是否有碰撞碰撞兩個物件是否有碰撞
// 測試上列兩個函式的用法
// 加入 ENTER_FRAME 事件監聽器
addEventListener(Event.ENTER_FRAME, checkCollision);
// 實際處理在觸發 ENTER_FRAME 事件的函式
function checkCollision(event:Event)
{
// 判斷現在的滑鼠座標是否有碰到影片片段
// 這個用法比較少用
if (crescent.hitTestPoint(mouseX, mouseY, true))
messageText1.text = “hitTestPoint: YES”;
else
messageText1.text = “hitTestPoint: NO”;
// 根據滑鼠位置移動 star 影片片段
star.x = mouseX;
star.y = mouseY;
// 判斷兩個影片片段是否有碰撞
if (star.hitTestObject(crescent))
messageText2.text = “hitTestObject: YES”;
else
messageText2.text = “hitTestObject: NO”;
}
存取外部資料
(page-69)
 有時需要存取遊戲外部的資料,例如…有時需要存取遊戲外部的資料,例如…
 從網頁或文字欄位載入遊戲參數從網頁或文字欄位載入遊戲參數
 在本機端在本機端 (( 自己的電腦自己的電腦 )) 儲存或載入資訊儲存或載入資訊
 使用外部變數:使用外部變數:
 ExternalVariables.htmlExternalVariables.html
 ExternalVariables.flaExternalVariables.fla
 AC_RunActiveContent.jsAC_RunActiveContent.js
 遊戲進行時會因為某些選項改變,例如…遊戲進行時會因為某些選項改變,例如…
 拼圖遊戲會使用不同的圖片拼圖遊戲會使用不同的圖片
 機台遊戲用不同的速度進行機台遊戲用不同的速度進行
 注意注意 :: 資料夾內必須要有資料夾內必須要有 AC_RunActiveContent.jsAC_RunActiveContent.js
 可以藉由可以藉由 HTMLHTML 網頁傳遞變數值給網頁傳遞變數值給 flashflash 影片影片
 AC_FL_RunContent()AC_FL_RunContent() 函式函式
 flashvars: Flashflashvars: Flash 變數變數
<script language=”javascript”>
// javascript 開始
AC_FL_RunContent(
‘codebase’,
‘http://download.macromedia.com/pub/shockwave/cabs/flash/swfl
ash.cab#version=9,0,0,0’, // flash 安裝檔網址
‘width’, ‘550’, // flash 影片寬度
‘height’, ‘400’, // flash 影片高度
‘src’, ‘ExternalVariables’, // flash 影片名稱
‘quality’, ‘high’, // flash 影片品質
‘flashvars’, ‘puzzleFile=myfilename.jpg&difficultyLevel=7’
);
// javascript 結束
</script>
 flashvarflashvar 的格式的格式
 變數名稱變數名稱 == 變數值變數值
 用“用“ &”&” 符號區隔符號區隔
 所以 HTML 內這行的意思…
 puzzleFile=myfilename.jpg&difficultyLevel=7
 兩個變數 : puzzleFile, difficultyLevel
 變數值為 : myfilename.jpg, 7
 FlashFlash 裡面存取方式裡面存取方式
 參數儲存在下列物件
var paramObj:Object =
LoaderInfo(this.root.loaderInfo).parameters;
 分開存取 paramObj 內的變數
var diffLevel:String = paramObj[“difficultyLevel”];
 可以用上述方式傳遞遊戲參數,例如…
 圖片名稱 , 開始關卡 , 速度 , 位置…
 載入載入 XMLXML 資料用法:資料用法:
 LoadingData.flaLoadingData.fla
 LoadingData.xmlLoadingData.xml
 結合結合 XMLXML 文字檔儲存資料,格式可自訂文字檔儲存資料,格式可自訂
<LoadingData>
<question>
<text>This is a test</text>
<answers>
<answer type=”correct”>Correct answer</answer>
<answer type=”wrong”>Incorrect answer</answer>
</answers>
</question>
</LoadingData>
 XML 格式是以標籤自訂資料結構,以這樣的形式
<tag>…</tag>
 標籤可設定屬性
 讀取讀取 XMLXML 檔案在檔案在 FlashFlash 內需要兩個物件內需要兩個物件
 URLRequestURLRequest
 URLLoaderURLLoader
 加入事件監聽器,當載入動作完成時執行函式加入事件監聽器,當載入動作完成時執行函式
// 使用 URLRequest 設定 XML 的載入路徑 ( 可以是網址 )
var xmlURL:URLRequest = new URLRequest(“LoadingData.xml”);
// 使用 URLLoader 物件載入 XML 資料 , 並指定讀取網址
var xmlLoader:URLLoader = new URLLoader(xmlURL);
// 加入載入完成事件監聽器
xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
 載入完成後執行下列函式
function xmlLoaded(event:Event)
{
// 將載入的資料存入區域物件 dataXML
var dataXML = XML(event.target.data);
// 以下為存取 XML 資料的用法
trace(dataXML.question.text);
trace(dataXML.question.answers.answer[0]);
// 存取 type 屬性
trace(dataXML.question.answers.answer[0].@type);
}
 使用使用 ShareObjectsShareObjects 儲存區域變數儲存區域變數
 SavingLocalData.fla
 可用來儲存像玩家分數,遊戲設定可用來儲存像玩家分數,遊戲設定
 使用下列用法…使用下列用法…
// 宣告 SharedObject 物件 , 名稱為 myLocalData
// 再使用 getLocal() 函式設定變數 mygamedata
var myLocalData:SharedObject =
SharedObject.getLocal(“mygamedata”);
// 把字串內容儲存到 SharedObject 的 gameinfo 變數
myLocalData.data.gameinfo = “Store this.”;
// 測試是否有儲存成功
trace(“Found Data: “+myLocalData.data.gameinfo);
各式各樣的遊戲元素
(page-72)
 以下內省略,有興趣同學自己研讀,包括…以下內省略,有興趣同學自己研讀,包括…
 自訂鼠標自訂鼠標
 播放聲音播放聲音
 載入畫面載入畫面
 產生亂數產生亂數
 將陣列內容洗牌將陣列內容洗牌 (( 類似像樸克牌類似像樸克牌 ))
 顯示時鐘時間顯示時鐘時間
 系統設定資料系統設定資料
 遊戲作弊與安全性問題遊戲作弊與安全性問題

More Related Content

Similar to Chinese hans

component based html5 game engine
component based html5 game enginecomponent based html5 game engine
component based html5 game enginehbbalfred
 
基于yui3的组件开发进阶
基于yui3的组件开发进阶基于yui3的组件开发进阶
基于yui3的组件开发进阶jay li
 
Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用吳錫修 (ShyiShiou Wu)
 
Android Wear SDK: Level 101
Android Wear SDK: Level 101Android Wear SDK: Level 101
Android Wear SDK: Level 101Jollen Chen
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非Tony Deng
 
Graphic programming in js
Graphic programming in jsGraphic programming in js
Graphic programming in jsjay li
 
Unity遊戲程式設計(02) 應用2D圖片物件
Unity遊戲程式設計(02) 應用2D圖片物件Unity遊戲程式設計(02) 應用2D圖片物件
Unity遊戲程式設計(02) 應用2D圖片物件吳錫修 (ShyiShiou Wu)
 
Html5 canvas 游戏开发实例详解
Html5 canvas 游戏开发实例详解Html5 canvas 游戏开发实例详解
Html5 canvas 游戏开发实例详解believeStrong
 
2017 unity5.5 manual_animation
2017 unity5.5 manual_animation2017 unity5.5 manual_animation
2017 unity5.5 manual_animationRiver Wang
 
Unity脚本入门
Unity脚本入门Unity脚本入门
Unity脚本入门seenen
 
4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程zhang shuren
 
由一个简单的程序谈起--之四
由一个简单的程序谈起--之四由一个简单的程序谈起--之四
由一个简单的程序谈起--之四yiditushe
 
Unity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理IIUnity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理II吳錫修 (ShyiShiou Wu)
 

Similar to Chinese hans (20)

Chinese hans
Chinese hansChinese hans
Chinese hans
 
Chinese hans
Chinese hansChinese hans
Chinese hans
 
testing leads fix for ppt2
testing leads fix for ppt2testing leads fix for ppt2
testing leads fix for ppt2
 
component based html5 game engine
component based html5 game enginecomponent based html5 game engine
component based html5 game engine
 
基于yui3的组件开发进阶
基于yui3的组件开发进阶基于yui3的组件开发进阶
基于yui3的组件开发进阶
 
Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用
 
Actio
ActioActio
Actio
 
Android Wear SDK: Level 101
Android Wear SDK: Level 101Android Wear SDK: Level 101
Android Wear SDK: Level 101
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非
 
Graphic programming in js
Graphic programming in jsGraphic programming in js
Graphic programming in js
 
Unity遊戲程式設計(02) 應用2D圖片物件
Unity遊戲程式設計(02) 應用2D圖片物件Unity遊戲程式設計(02) 應用2D圖片物件
Unity遊戲程式設計(02) 應用2D圖片物件
 
Html5 canvas 游戏开发实例详解
Html5 canvas 游戏开发实例详解Html5 canvas 游戏开发实例详解
Html5 canvas 游戏开发实例详解
 
I os 07
I os 07I os 07
I os 07
 
2017 unity5.5 manual_animation
2017 unity5.5 manual_animation2017 unity5.5 manual_animation
2017 unity5.5 manual_animation
 
Unity脚本入门
Unity脚本入门Unity脚本入门
Unity脚本入门
 
I os 14
I os 14I os 14
I os 14
 
4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程
 
由一个简单的程序谈起--之四
由一个简单的程序谈起--之四由一个简单的程序谈起--之四
由一个简单的程序谈起--之四
 
Unity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理IIUnity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理II
 
YUI 3 菜鳥救星
YUI 3 菜鳥救星YUI 3 菜鳥救星
YUI 3 菜鳥救星
 

More from gr0Jmmd7Q_qarobo gr0Jmmd7Q_qarobo (12)

2 page doc
2 page doc2 page doc
2 page doc
 
sample upload file
sample upload filesample upload file
sample upload file
 
2 slide deck
2 slide deck2 slide deck
2 slide deck
 
Do Not Delete
Do Not DeleteDo Not Delete
Do Not Delete
 
exploratory-testing - Read only not hidden
exploratory-testing - Read only not hiddenexploratory-testing - Read only not hidden
exploratory-testing - Read only not hidden
 
getting-started-1-638
getting-started-1-638getting-started-1-638
getting-started-1-638
 
Environment costs & Benifits
Environment costs & BenifitsEnvironment costs & Benifits
Environment costs & Benifits
 
Environment costs & Benifits
Environment costs & BenifitsEnvironment costs & Benifits
Environment costs & Benifits
 
Plain text presentation for slideshare
Plain text presentation for slidesharePlain text presentation for slideshare
Plain text presentation for slideshare
 
4apachehadoop 0-23hadoopworld2011-111110151810-phpapp02
4apachehadoop 0-23hadoopworld2011-111110151810-phpapp024apachehadoop 0-23hadoopworld2011-111110151810-phpapp02
4apachehadoop 0-23hadoopworld2011-111110151810-phpapp02
 
adrianalimabikinibodyworkoutdietplan-140813113633-phpapp01 (1)
adrianalimabikinibodyworkoutdietplan-140813113633-phpapp01 (1)adrianalimabikinibodyworkoutdietplan-140813113633-phpapp01 (1)
adrianalimabikinibodyworkoutdietplan-140813113633-phpapp01 (1)
 
4apachehadoop-0-23hadoopworld2011-111110151810-phpapp02
4apachehadoop-0-23hadoopworld2011-111110151810-phpapp024apachehadoop-0-23hadoopworld2011-111110151810-phpapp02
4apachehadoop-0-23hadoopworld2011-111110151810-phpapp02
 

Chinese hans

  • 2.  Gary Rosenzweig, 2008, “ActionScript 3.0 Game Programming”, Macmillan Computer Pub. 教材出處
  • 3. 這章會學到的…  用用 FlashFlash 製作遊戲需要的基本元素製作遊戲需要的基本元素  了解了解 ActionscriptActionscript 可以做到的效果可以做到的效果 特別注意特別注意 !!  本章範例程式很多個,回家記得複習本章範例程式很多個,回家記得複習
  • 4. 章節大綱  產生視覺化物件產生視覺化物件  接受使用者輸入接受使用者輸入  產生動畫產生動畫  撰寫使用者互動程式撰寫使用者互動程式  存取外部資料存取外部資料  各式各樣的遊戲元素各式各樣的遊戲元素
  • 5. 產生視覺化的物件 (page-42)  本章使用原始檔本章使用原始檔 (A3GPU02_GameElements.zip)(A3GPU02_GameElements.zip)  製作遊戲的第一步製作遊戲的第一步 ->-> 產生並控制螢幕上的物件產生並控制螢幕上的物件  使用元件庫的影片片段的兩種方式使用元件庫的影片片段的兩種方式  方式一:直接拖拉到場景當中方式一:直接拖拉到場景當中  在屬性視窗給予實體名稱在屬性視窗給予實體名稱 假如實體名稱為“假如實體名稱為“ myClipInstance””  使用 myClipInstance 來控制影片片段的屬性 myClipInstance.x = 300; myClipInstance.y = 200;
  • 6.  UsingMovieClips.flaUsingMovieClips.fla  方式二:完全用程式來產生方式二:完全用程式來產生  在元件庫內選取某個影片片段的元件在元件庫內選取某個影片片段的元件  設定連結名稱,讓程式可以存取影片片段設定連結名稱,讓程式可以存取影片片段  勾選 “勾選 “ Export for ActionScript”Export for ActionScript”  設定類別名稱設定類別名稱 (( 通常會設成和元件名稱相同通常會設成和元件名稱相同 )) (( 以下的例子類別名稱為以下的例子類別名稱為 MascotMascot ,大概是人名吧…,大概是人名吧… ?)?) (( 圖圖 2.2)2.2) 設定元件連結的對設定元件連結的對 話框
  • 7.  再利用以下的語法:再利用以下的語法: // 使用 var 宣告一個變數,名稱為 myMovieClip // 變數型態是 Mascot // 使用 new 替這個變數產生一個新的物件 // 實際上會呼叫 Mascot 的建構函式 ( 目前尚未定義… ) // 注意變數型態和新物件型態都是 Mascot var myMovieClip:Mascot = new Mascot(); // 把 myMovieClip 這個影片片段加入到場景當中 addChild(myMovieClip);  因為我們還沒有設定任何屬性,所以元件出現在因為我們還沒有設定任何屬性,所以元件出現在 (0,0)(0,0) 的位置的位置
  • 8.  修改成以下的語法:修改成以下的語法: // 一樣是宣告一個新的物件 var myMovieClip:Mascot = new Mascot(); myMovieClip.x = 275; // 修改物件 X 座標 myMovieClip.y = 150; // 修改物件 Y 座標 myMovieClip.rotation = 10; // 修改物件旋轉角度 // 一樣是把物件加入場景當中 addChild(myMovieClip);
  • 9.  前面的範例只會產生一個物件前面的範例只會產生一個物件  同一個元件在場景當中可以有很多份同一個元件在場景當中可以有很多份 copycopy  以下的程式碼會產生以下的程式碼會產生 1010 個個 MascotMascot 由左至右每次位移由左至右每次位移 5050 個像素個像素 元件比例為元件比例為 50%50% // 這個迴圈執行 10 次 ( 複習一下迴圈參數的用法… ) for(var i=0;i<10;i++) { // 宣告新的 Mascot 物件 var mascot:Mascot = new Mascot(); // X 座標以 50 為初始點 , 位置隨著迴圈參數向右每次移動 50 mascot.x = 50*i+50; // Y 座標固定在 300 mascot.y = 300; // X 方向比例設為 0.5, 就是 50% 的意思 mascot.scaleX = .5; // Y 方向的比例設為 50% mascot.scaleY = .5; // 加上這行物件才會顯示在場景當中 addChild(mascot); }
  • 10. (( 圖圖 2.3)2.3)  做出來的效果會像這樣…做出來的效果會像這樣…
  • 11.  製作按鈕製作按鈕 -- MakingButtons.flaMakingButtons.fla  元件類型可以是“影片片段”或“按鈕”元件類型可以是“影片片段”或“按鈕”  如果是“影片片段”,必須加入事件監聽器如果是“影片片段”,必須加入事件監聽器 (listener)(listener)  讓影片片段可以接受事件,像是“滑鼠點擊”事件讓影片片段可以接受事件,像是“滑鼠點擊”事件 // 和前面範例差不多的語法 var myMovieClip:Mascot = new Mascot(); myMovieClip.x = 100; myMovieClip.y = 150; addChild(myMovieClip);
  • 12.  替影片片段指定事件監聽器替影片片段指定事件監聽器  使用 “使用 “ addEventListener(addEventListener( 參數參數 1,1, 參數參數 2)”2)” 函函 式式  參數參數 11 :指定要接受何種輸入,例如::指定要接受何種輸入,例如: “ MouseEvent.CLICK” 代表按下滑鼠  參數 2 :指定一個函式名稱,當接受到事件時會:指定一個函式名稱,當接受到事件時會 執行這個函式執行這個函式 這邊是用“這邊是用“ clickMascot”…”… // 所以程式碼像這樣… myMovieClip.addEventListener(MouseEvent.CLICK, clickMascot);
  • 13.  接下來撰寫按下滑鼠會執行的函式 function clickMascot(event:MouseEvent) { // 按下滑鼠時輸出這段文字 trace(“You clicked the mascot!”); }  以下這行會讓滑鼠顯示成手指的圖案 // 直接把影片片段的 buttonMode 設為 true myMovieClip.buttonMode = true;
  • 14.  假如你的元件原本就是“按鈕”假如你的元件原本就是“按鈕” // 一樣的用法,不過類別型態是 LibraryButton var myButton:LibraryButton = new LibraryButton(); myButton.x = 450; // 設定 X 座標 myButton.y = 100; // 設定 Y 座標 addChild(myButton); // 加入場景  用“影片片段”和“按鈕”兩種元件製作按鈕不同的地方  按鈕元件的影格裡面可以直接設定四種按鈕狀態的圖示 Up( 原始狀態 ), Over( 滑鼠移入 ), Down( 按下滑鼠 ), Hit( 點擊範圍 ) (( 圖圖 2.4)2.4) 按鈕元件的時間軸影按鈕元件的時間軸影 格格 (( 圖圖 2.5)2.5) 按鈕四種狀態按鈕四種狀態
  • 15.  替按鈕元件加入事件監聽器替按鈕元件加入事件監聽器 // 先指定要監聽的事件類型是 MouseEvent.CLICK // 再指定事件發生時要執行的函式 clickLibraryButton myButton.addEventListener(MouseEvent.CLICK, clickLibraryButton); // 定義執行函式要做的事情 function clickLibraryButton(event:MouseEvent) { // 只輸出一段文字就好… trace(“You clicked the Library button!”); }
  • 16.  繪製圖形繪製圖形 -- DrawingShapes.flaDrawingShapes.fla  除了使用元件庫裡面的元件之外除了使用元件庫裡面的元件之外  也可以使用基本的線條和圖形繪圖也可以使用基本的線條和圖形繪圖  使用使用 graphicsgraphics 物件設定繪圖屬性物件設定繪圖屬性 // 設定線條樣式 , 線寬 2, 顏色為黑色 // 注意顏色的表示方法為 16 進位 (0,1,2,…,9,A,B,C,D,E,F) // 頭兩個 0x 不看剩餘 RGB 各用兩個數字代表 this.graphics.lineStyle(2,0x000000); // 開始繪圖 , 劃一條線 , 起點 (100,200) this.graphics.moveTo(100,200); // 畫到 (150,250 的位置 ) this.graphics.lineTo(150,250); ( 加分小問題 ) 請問 16 進位的色彩表示法當中,紅綠藍三色要怎麼 寫 ?
  • 18.  繪製文字繪製文字 -- DrawingText.flaDrawingText.fla  使用使用 TextFieldTextField 類別產生文字類別產生文字 // 產生 TextField 物件 var myText:TextField = new TextField(); // 使用 text 屬性設定文字內容 myText.text = “Check it out!”; // 設定位置 myText.x = 50; myText.y = 50; // 設定寬度和高度 myText.width = 200; myText.height = 30; // 設定是否顯示邊框 myText.border = true; // 設定文字是否可以選取 ,false 為不可選取 myText.selectable = false; // 還是要記得把文字加入場景當中 addChild(myText);
  • 19.  設定文字式樣設定文字式樣 // 宣告 TextFormat 物件 var myFormat:TextFormat = new TextFormat(); // 使用 font 屬性來設定字型 myFormat.font = “Arial”; // 使用 size 屬性設定字體大小 myFormat.size = 24; // 是否為粗體 , true 代表使用 myFormat.bold = true;  設定完文字式樣之後,要連結到文字物件 // 把 myText 的預設文字式樣設定為 myFormat myText.defaultTextFormat = myFormat; (( 圖圖 2.9)2.9) 設定完文字式樣的效設定完文字式樣的效 果果
  • 20.  以下內容略過,有興趣同學自行參考以下內容略過,有興趣同學自行參考  設定超連結文字設定超連結文字 (page-51)(page-51)  設定群組繪圖物件設定群組繪圖物件 (page-53)(page-53)  設定群組物件深度設定群組物件深度 (page-55)(page-55)
  • 21. 接受玩家的輸入 (page-55)  滑鼠輸入滑鼠輸入 -- MouseInput.flaMouseInput.fla  mouseX 和 mouseY 代表現在滑鼠座標 // 加入事件監聽器 , ENTER_FRAME 一進入影格就觸發 addEventListener(Event.ENTER_FRAME, showMouseLoc); // 觸發 ENTER_FRAME 事件時執行的函式 // 因為只有一個影格 , 所以以下的函式會一直在執行 function showMouseLoc(event:Event) { // 把滑鼠座標顯示在 mouseLocText 文字 mouseLocText.text = “X=”+mouseX+” Y=”+mouseY; }
  • 22.  滑鼠移入影片片段的效果滑鼠移入影片片段的效果 // 加入事件監聽器 , MouseEvent.ROLL_OVER 代表滑鼠移 入 mySprite.addEventListener(MouseEvent.ROLL_OVER, rolloverSprite); // 滑鼠移入時 , 影片片段透明度設為 1, 為完全不透明 function rolloverSprite(event:MouseEvent) { mySprite.alpha = 1; }  滑鼠移出影片片段的效果 // 和上面類似的寫法 , 事件改為 ROLL_OUT mySprite.addEventListener(MouseEvent.ROLL_OUT, rolloutSprite); function rolloutSprite(event:MouseEvent) { // 透明度變為 50% mySprite.alpha = .5; }
  • 23.  鍵盤輸入鍵盤輸入 -- KeyboardInput.flaKeyboardInput.fla  按下按鍵效果按下按鍵效果 // 事件監聽器監控 KEY_DOWN stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFunction); // 按下按鍵執行下列事情 function keyDownFunction(event:KeyboardEvent) { // event.charCode 代表按下的按鍵編碼 // 使用內建函式將按鍵碼轉為文字 keyboardText.text = “Key Pressed: +String.fromCharCode(event.charCode); } ( 加分小問題 ) 請問英文字母 A~Z 的按鍵碼範圍是多少 ?
  • 24.  修改成可以監控空白鍵是否有按下修改成可以監控空白鍵是否有按下 stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFunction); function keyDownFunction(event:KeyboardEvent) { // 空白鍵的按鍵碼是 32 // 如果有按下空白鍵 if (event.charCode == 32) { // 把這個變數設定為 true spacebarPressed = true; } }
  • 25.  在放開按鍵時,監控空白鍵是否放開 // 使用 KEY_UP stage.addEventListener(KeyboardEvent.KEY_UP, keyUpFunction); // 觸發 KEY_UP 事件時執行下列函式 function keyUpFunction(event:KeyboardEvent) { // 假如是放開空白鍵 if (event.charCode == 32) { // 這個變數設為 false spacebarPressed = false; } }
  • 26.  文字輸入文字輸入 -- TextInput.flaTextInput.fla  讓使用者可以在文字欄位輸入文字讓使用者可以在文字欄位輸入文字 // 一樣宣告一個文字物件 var myInput:TextField = new TextField(); // 使用 type 屬性來指定可以輸入文字 myInput.type = TextFieldType.INPUT; // 一樣把這個文字加到場景 addChild(myInput);
  • 27.  更詳細的程式碼更詳細的程式碼 // 宣告文字格式 var inputFormat:TextFormat = new TextFormat(); inputFormat.font = “Arial”; inputFormat.size = 12; // 宣告文字 var myInput:TextField = new TextField(); // 設定文字為可以輸入 myInput.type = TextFieldType.INPUT; // 設定文字格式 myInput.defaultTextFormat = inputFormat; // 設定位置 myInput.x = 10; myInput.y = 10; // 設定尺寸 myInput.height = 18; myInput.width = 200; // 設定邊框 myInput.border = true; // 文字加入場景 addChild(myInput); // 設定目前的輸入焦點在 myInput stage.focus = myInput;
  • 28.  最後修改成按下 “最後修改成按下 “ ENTER”ENTER” 鍵文字會消失鍵文字會消失 (( 確定輸入完畢的意思…確定輸入完畢的意思… )) // 事件監聽器監視 KEY_UP myInput.addEventListener(KeyboardEvent.KEY_UP, checkForReturn); // 下列函式檢查是否有按下 ENTER 鍵 function checkForReturn(event:KeyboardEvent) { // ENTER 的按鍵碼是 13 if (event.charCode == 13) { // 按下 ENTER 後執行下列函式 acceptInput(); } } // 按下 ENTER 實際上要做的事情 function acceptInput() { // 把輸入的文字存到 theInputText var theInputText:String = myInput.text; // 把 theInputText 儲存的內容印出來 trace(theInputText); // 把文字從場景中移除 removeChild(myInput); }
  • 29. 產生動畫 (page-59)  影片片段的移動影片片段的移動 -- SpriteMovement.flaSpriteMovement.fla  以影格為基礎的動畫以影格為基礎的動畫 (frame-based animation)(frame-based animation)  改變改變 XX 座標或座標或 YY 座標座標  以固定的速率移動以固定的速率移動  使用使用 ENTER_FRAMEENTER_FRAME 事件事件  以時間為基礎的動畫以時間為基礎的動畫 (time-based animation)(time-based animation)  稍後會看到…稍後會看到… (( 英文小提示英文小提示 )) something-based…something-based… 以某某東西為基礎的…以某某東西為基礎的…
  • 30.  程式碼範例 // 元件庫內已有 Hero 影片片段 // 新增一個 Hero 類別的物件 var hero:Hero = new Hero(); hero.x = 50; // 設定位置 hero.y = 100; addChild(hero); // 物件加入場景 // 加入 ENTER_FRAME 事件監聽器 // 遇到 ENTER_FRAME 時執行 animateHero() 這個函式 addEventListener(Event.ENTER_FRAME, animateHero); // 定義函式內要做的事情 function animateHero(event:Event) { hero.x++; // 每次把 hero 的位置往右加 1 像素 }
  • 31.  使用使用 ENTER_FRAMEENTER_FRAME 事件製作動畫事件製作動畫  物件移動的速度和影格速率有關物件移動的速度和影格速率有關  預設預設 12 fps12 fps ->-> 每秒跑每秒跑 1212 格格 -> 12-> 12 次次 ENTER_FRAMEENTER_FRAME 事件事件 ->-> 執行執行 1212 次次 animateHero()animateHero() 函式函式 ->-> 元件往右移動元件往右移動 1212 次次 (( 每次每次 11 像素像素 ))  如果要加快播放速度,增加影格速率,例如如果要加快播放速度,增加影格速率,例如 60fps60fps  預期每秒執行預期每秒執行 6060 次…但是會和電腦效能有關次…但是會和電腦效能有關  以影格為基礎的動畫以影格為基礎的動畫  簡單易用但是不穩定簡單易用但是不穩定  電腦速度很慢的話,無法達到預期的播放速度電腦速度很慢的話,無法達到預期的播放速度
  • 32.  進一步的修改,讓進一步的修改,讓 herohero 走路走路  herohero 內有內有 88 個影格個影格  影格影格 11 裡面裡面 stop()stop() 停止動作 – 站立狀態停止動作 – 站立狀態  影格影格 2~8 –2~8 – 走路循環動畫走路循環動畫 function animateHero(event:Event) { hero.x += 7; // 一樣向右移動 , 每次 7 像素 // 如果現在播放到影格 8 if (hero.currentFrame == 8) hero.gotoAndStop(2); // 回到影格 2 else // 往後播放一個影格 hero.gotoAndStop(hero.currentFrame+1); } (( 圖圖 2.14)2.14) 用用 77 個影格完成走路的個影格完成走路的
  • 33.  使用計時器使用計時器 (Timer) –(Timer) – UsingTimers.flaUsingTimers.fla  可以把可以把 timertimer 想成想成 ->-> 會送出訊息的時鐘會送出訊息的時鐘  產生時鐘、開始執行、開始計時、每隔一段時間送出訊息產生時鐘、開始執行、開始計時、每隔一段時間送出訊息  例如:讓某個函式每秒執行一次例如:讓某個函式每秒執行一次  使用使用 TimerTimer 物件產生計時器物件產生計時器  計時器可以設定編號計時器可以設定編號 (( 可有多個計時器同時執行可有多個計時器同時執行 ))  指定編號停止計時器指定編號停止計時器  用毫秒用毫秒 (( 千分之一秒千分之一秒 )) 為單位指定時間為單位指定時間  1000 milliseconds = 11000 milliseconds = 1 秒秒 // 使用 Timer 物件產生計時器 , 指定多久執行一次 ,1000 毫秒 =1 秒 var myTimer:Timer = new Timer(1000); // 替 Timer 加入事件監聽器 , 定期 (1000 毫秒 ) 執行 timeFunction 一次 myTimer.addEventListener(TimerEvent.TIMER, timerFunction); // 觸發事件時實際執行的函式 function timerFunction(event:TimerEvent) { // 設定繪圖顏色 this.graphics.beginFill(0x000000); // 每次在畫面上畫一個小圓 , 位置每次向右位移 10 // 其他細節用 google 自己查 this.graphics.drawCircle(event.target.currentCount*10,100,4); } myTimer.start(); // 開始執行 Timer( 沒有這行 ,Timer 不會執行 )
  • 34.  將將 TimerTimer 套入動畫 –套入動畫 – UsingTimers2.flaUsingTimers2.fla  和前面和前面 enterFrameenterFrame 事件的例子類似事件的例子類似  修改事件監聽器的程式修改事件監聽器的程式  一樣定期執行一樣定期執行 animateHero()animateHero() 函式函式 // 替動畫角色產生一個 Timer,80 毫秒執行一次 var heroTimer:Timer = new Timer(80); // 加入事件監聽器 , 定時執行 animateHero() 函式 heroTimer.addEventListener(TimerEvent.TIMER, animateHero); heroTimer.start(); // Timer 開始跑  其餘程式碼相同其餘程式碼相同  不管影格速率多少不管影格速率多少 (6,12,60…)(6,12,60…)  動畫執行大致速度相同動畫執行大致速度相同  速度慢的電腦就不一定相同速度慢的電腦就不一定相同
  • 35. 注意注意 !! 這邊的概念會有點難懂…這邊的概念會有點難懂…  以時間為基礎的動畫 –以時間為基礎的動畫 – TimeBasedAnimation.flaTimeBasedAnimation.fla  動畫步驟根據經過的時間來進行動畫步驟根據經過的時間來進行  計算步驟之間的時間計算步驟之間的時間  根據時間差來移動物體根據時間差來移動物體 移動距離移動距離 == 物體速度物體速度 xx 經過時間經過時間  首先用變數首先用變數 (( 整數型態整數型態 )) 來儲存經過的時間來儲存經過的時間 // getTimer()// getTimer() 傳回傳回 Flash playerFlash player 開始播放到現在的時間開始播放到現在的時間 (( 單位是毫秒單位是毫秒 )) var lastTime:int = getTimer();  再加入事件監聽器再加入事件監聽器 //// 監聽監聽 ENTER_FRAMEENTER_FRAME 事件事件 ,, 觸發執行觸發執行 animateBall()animateBall() 函式函式 addEventListener(Event.ENTER_FRAME, animateBall);
  • 36.  處理物體移動的函式處理物體移動的函式 function animateBall(event:Event) { // 計算經過的時間 // getTimer() 抓現在的時間 // lastTime 是上次存起來的時間 // 兩個相減代表現在和上一步的時間差 var timeDiff:int = getTimer()-lastTime; // 把時間差累加到 lastTime, 在下一步使用 lastTime += timeDiff; // 物體距離 = 時間差 * 速度 (0.1), // 速度 0.1 代表每毫秒移動 0.1 像素 , 一秒移動 100 像素 ball.x += timeDiff*.1; }  測試一下效果 , 影格速率 12 和 60 有何不同 ?  物體移動距離一樣 , 影格速率 60 跑的比較順暢
  • 37.  以物理為基礎的動畫 –以物理為基礎的動畫 – PhysicsBasedAnimation.flaPhysicsBasedAnimation.fla  增加物理屬性增加物理屬性  模擬真實世界的動畫效果模擬真實世界的動畫效果  真實重力加速度真實重力加速度 : 9.8 (: 9.8 ( 公尺平方公尺平方 // 秒秒 )) var gravity:Number = .00098; // 設定重力加速度 var dx:Number = .2; // 設定 X 方向速度 var dy:Number = -.8; // 設定 Y 方向速度 // 設定開始時間 var lastTime:int = getTimer(); // 監聽 ENTER_FRAME 事件 , 執行 animateBall() 函式 addEventListener(Event.ENTER_FRAME, animateBall); (( 圖圖 2.15)2.15) 影格速率影格速率 1212 的動畫的動畫
  • 38.  定義移動動畫函式 function animateBall(event:Event) { // 計算時間差 var timeDiff:int = getTimer()-lastTime; // 累加經過時間 lastTime += timeDiff; // 根據重力加速度修改 Y 方向速度 // 速度 = 加速度 x 時間 dy += gravity*timeDiff; // 距離 = 速度 x 時間 // 計算完的距離累加原本的位移 ball.x += timeDiff*dx; ball.y += timeDiff*dy; }
  • 39. 撰寫使用者互動程式 (page-65)  移動圖形:移動圖形: MovingSprites.flaMovingSprites.fla  使用方向鍵控制動畫移動方向使用方向鍵控制動畫移動方向  先使用先使用 BooleanBoolean 變數儲存按鍵狀態變數儲存按鍵狀態 (( 尚未按下:尚未按下: false)false) var leftArrow:Boolean = false; var rightArrow:Boolean = false; var upArrow:Boolean = false; var downArrow:Boolean = false; (( 圖圖 2.16)2.16) 方向鍵與按鍵方向鍵與按鍵
  • 40.  替按鍵加入事件監聽器替按鍵加入事件監聽器 // 按下按鍵的事件監聽器 stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown); // 放開按鍵的事件監聽器 stage.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp); // ENTER_FRAME 事件監聽器 stage.addEventListener(Event.ENTER_FRAME, moveMascot); // 觸發按下按鍵事件 , 實際執行的函式 function keyPressedDown(event:KeyboardEvent) { // 按下對應的按鍵 , 把按鍵狀態變數設為 true if (event.keyCode == 37) leftArrow = true; else if (event.keyCode == 39) rightArrow = true; else if (event.keyCode == 38) upArrow = true; else if (event.keyCode == 40) downArrow = true; }
  • 41.  觸發放開按鍵事件 , 實際執行的函式 function keyPressedUp(event:KeyboardEvent) { // 對應按鍵將狀態變數設為 true if (event.keyCode == 37) leftArrow = false; else if (event.keyCode == 39) rightArrow = false; else if (event.keyCode == 38) upArrow = false; else if (event.keyCode == 40) downArrow = false; }
  • 42.  觸發 ENTER_FRAME 事件 , 移動位置產生動畫 function moveMascot(event:Event) { var speed:Number = 5; // 設定速度 // 注意以下的判斷式寫法是每個獨立的 if 判斷 , 不是 if… else if // 代表以下四個狀態可以同時執行 // 對應方向鍵移動 X 或 Y 方向 if (leftArrow) mascot.x -= speed; if (rightArrow) mascot.x += speed; if (upArrow) mascot.y -= speed; if (downArrow) mascot.y += speed; }
  • 43.  拖拉圖形:拖拉圖形: DraggingSprites.flaDraggingSprites.fla  使用滑鼠點擊拖拉圖形使用滑鼠點擊拖拉圖形  加入滑鼠事件監聽器加入滑鼠事件監聽器 // 替影片片段加入按下滑鼠事件監聽器 mascot.addEventListener(MouseEvent.MOUSE_DOWN,mascot.addEventListener(MouseEvent.MOUSE_DOWN, startMascotDrag);startMascotDrag); // 替場景加入放開滑鼠事件監聽器 stage.addEventListener(MouseEvent.MOUSE_UP,stage.addEventListener(MouseEvent.MOUSE_UP, stopMascotDrag);stopMascotDrag); // 替影片片段加入 ENTER_FRAME 事件監聽器 mascot.addEventListener(Event.ENTER_FRAME,mascot.addEventListener(Event.ENTER_FRAME, dragMascot);dragMascot);
  • 44.  處理滑鼠拖拉距離處理滑鼠拖拉距離  紀錄按下滑鼠的位置紀錄按下滑鼠的位置 // 使用內建 Point 類別紀錄座標 , 預設還未儲存座標 var clickOffset:Point = null; // 觸發按下滑鼠事件的函式 function startMascotDrag(event:MouseEvent) { // 把觸發事件當時的座標儲存到 clickOffset clickOffset = new Point(event.localX, event.localY); } // 觸發放開滑鼠事件執行的函式 function stopMascotDrag(event:MouseEvent) { // 放開滑鼠後清除之前儲存的按下位置 clickOffset = null; }
  • 45. // ENTER_FRAME 事件觸發的函式 function dragMascot(event:Event) { // 如果已經有紀錄滑鼠按下位置 if (clickOffset != null) { // 計算現在滑鼠位置和儲存位置的距離差 mascot.x = mouseX - clickOffset.x; mascot.y = mouseY - clickOffset.y; } }
  • 46.  碰撞檢測:碰撞檢測: CollisionDetection.flaCollisionDetection.fla  遊戲內的物件常需要檢查是否有碰撞遊戲內的物件常需要檢查是否有碰撞  兩種用法:兩種用法: hitTestPoint()hitTestPoint() 檢查某個點座標是否有碰撞物體檢查某個點座標是否有碰撞物體 hitTestObject()hitTestObject() 碰撞兩個物件是否有碰撞碰撞兩個物件是否有碰撞 // 測試上列兩個函式的用法 // 加入 ENTER_FRAME 事件監聽器 addEventListener(Event.ENTER_FRAME, checkCollision); // 實際處理在觸發 ENTER_FRAME 事件的函式 function checkCollision(event:Event) { // 判斷現在的滑鼠座標是否有碰到影片片段 // 這個用法比較少用 if (crescent.hitTestPoint(mouseX, mouseY, true)) messageText1.text = “hitTestPoint: YES”; else messageText1.text = “hitTestPoint: NO”;
  • 47. // 根據滑鼠位置移動 star 影片片段 star.x = mouseX; star.y = mouseY; // 判斷兩個影片片段是否有碰撞 if (star.hitTestObject(crescent)) messageText2.text = “hitTestObject: YES”; else messageText2.text = “hitTestObject: NO”; }
  • 48. 存取外部資料 (page-69)  有時需要存取遊戲外部的資料,例如…有時需要存取遊戲外部的資料,例如…  從網頁或文字欄位載入遊戲參數從網頁或文字欄位載入遊戲參數  在本機端在本機端 (( 自己的電腦自己的電腦 )) 儲存或載入資訊儲存或載入資訊  使用外部變數:使用外部變數:  ExternalVariables.htmlExternalVariables.html  ExternalVariables.flaExternalVariables.fla  AC_RunActiveContent.jsAC_RunActiveContent.js  遊戲進行時會因為某些選項改變,例如…遊戲進行時會因為某些選項改變,例如…  拼圖遊戲會使用不同的圖片拼圖遊戲會使用不同的圖片  機台遊戲用不同的速度進行機台遊戲用不同的速度進行
  • 49.  注意注意 :: 資料夾內必須要有資料夾內必須要有 AC_RunActiveContent.jsAC_RunActiveContent.js  可以藉由可以藉由 HTMLHTML 網頁傳遞變數值給網頁傳遞變數值給 flashflash 影片影片  AC_FL_RunContent()AC_FL_RunContent() 函式函式  flashvars: Flashflashvars: Flash 變數變數 <script language=”javascript”> // javascript 開始 AC_FL_RunContent( ‘codebase’, ‘http://download.macromedia.com/pub/shockwave/cabs/flash/swfl ash.cab#version=9,0,0,0’, // flash 安裝檔網址 ‘width’, ‘550’, // flash 影片寬度 ‘height’, ‘400’, // flash 影片高度 ‘src’, ‘ExternalVariables’, // flash 影片名稱 ‘quality’, ‘high’, // flash 影片品質 ‘flashvars’, ‘puzzleFile=myfilename.jpg&difficultyLevel=7’ ); // javascript 結束 </script>
  • 50.  flashvarflashvar 的格式的格式  變數名稱變數名稱 == 變數值變數值  用“用“ &”&” 符號區隔符號區隔  所以 HTML 內這行的意思…  puzzleFile=myfilename.jpg&difficultyLevel=7  兩個變數 : puzzleFile, difficultyLevel  變數值為 : myfilename.jpg, 7
  • 51.  FlashFlash 裡面存取方式裡面存取方式  參數儲存在下列物件 var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters;  分開存取 paramObj 內的變數 var diffLevel:String = paramObj[“difficultyLevel”];  可以用上述方式傳遞遊戲參數,例如…  圖片名稱 , 開始關卡 , 速度 , 位置…
  • 52.  載入載入 XMLXML 資料用法:資料用法:  LoadingData.flaLoadingData.fla  LoadingData.xmlLoadingData.xml  結合結合 XMLXML 文字檔儲存資料,格式可自訂文字檔儲存資料,格式可自訂 <LoadingData> <question> <text>This is a test</text> <answers> <answer type=”correct”>Correct answer</answer> <answer type=”wrong”>Incorrect answer</answer> </answers> </question> </LoadingData>  XML 格式是以標籤自訂資料結構,以這樣的形式 <tag>…</tag>  標籤可設定屬性
  • 53.  讀取讀取 XMLXML 檔案在檔案在 FlashFlash 內需要兩個物件內需要兩個物件  URLRequestURLRequest  URLLoaderURLLoader  加入事件監聽器,當載入動作完成時執行函式加入事件監聽器,當載入動作完成時執行函式 // 使用 URLRequest 設定 XML 的載入路徑 ( 可以是網址 ) var xmlURL:URLRequest = new URLRequest(“LoadingData.xml”); // 使用 URLLoader 物件載入 XML 資料 , 並指定讀取網址 var xmlLoader:URLLoader = new URLLoader(xmlURL); // 加入載入完成事件監聽器 xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);  載入完成後執行下列函式 function xmlLoaded(event:Event) { // 將載入的資料存入區域物件 dataXML var dataXML = XML(event.target.data); // 以下為存取 XML 資料的用法 trace(dataXML.question.text); trace(dataXML.question.answers.answer[0]); // 存取 type 屬性 trace(dataXML.question.answers.answer[0].@type); }
  • 54.  使用使用 ShareObjectsShareObjects 儲存區域變數儲存區域變數  SavingLocalData.fla  可用來儲存像玩家分數,遊戲設定可用來儲存像玩家分數,遊戲設定  使用下列用法…使用下列用法… // 宣告 SharedObject 物件 , 名稱為 myLocalData // 再使用 getLocal() 函式設定變數 mygamedata var myLocalData:SharedObject = SharedObject.getLocal(“mygamedata”); // 把字串內容儲存到 SharedObject 的 gameinfo 變數 myLocalData.data.gameinfo = “Store this.”; // 測試是否有儲存成功 trace(“Found Data: “+myLocalData.data.gameinfo);
  • 55. 各式各樣的遊戲元素 (page-72)  以下內省略,有興趣同學自己研讀,包括…以下內省略,有興趣同學自己研讀,包括…  自訂鼠標自訂鼠標  播放聲音播放聲音  載入畫面載入畫面  產生亂數產生亂數  將陣列內容洗牌將陣列內容洗牌 (( 類似像樸克牌類似像樸克牌 ))  顯示時鐘時間顯示時鐘時間  系統設定資料系統設定資料  遊戲作弊與安全性問題遊戲作弊與安全性問題