AdvancED Game Design with Flash-0

AdvancED Game Design with Flash 讀書筆記
這本書不知道要看多久…原文Orz...













p26.專案的資料夾結構

HelloWorld project folder專案資料夾
assets This folder contains the extra things that you use in your project, like images, video, and
sound. 其它需要在這個專案中用到的東西,像圖片、影像、聲音...
deploy This optional folder is used for the final published form that your game takes, such as
part of an HTML file.最後發佈時產生的檔案,例如HTML檔,這個資料不是必要的。
bin This is the destination folder for compiled SWFs. “bin” is short for “binary,” which is another
way of referring to finished, compiled programs. 發佈的SWF檔
src This is the location of your project-specific AS source files. If you’re using Flash Professional, it will
also be the location of your main FLA file.AS程式碼、FLA檔

p26.Flex metadata tag
ex:
[SWF(backgroundColor = "0xFFFFFF",
frameRate = "60", width = "550", height = "400")]
發佈swf時,為swf加入額外的訊息,像背景色、場景大小等...
也可嵌入字型、圖片、聲音等class會用到的元件。

p33.提昇Flash的一些方法
*Bit-block transfer:目前Flash有一個瓶頸,就是顯示物件和影片物件全都放在場景上,使用 bit-block transfer(或稱作blitting)方法,可以立即增進2~5倍的效能,而且不用改太多code (在第六章有相關的教學)
*Streamline your logic
*Use the Vector class for arrays that contain the same data types:若是一組資料的資料型態都相同,使用Vector class來取代 Array class ( Flash Player 10 以上才開始有Vector這個資料型別)
Use uint instead of Math.floor:使用uint取代Math.floor來取得整數,執行速度較快,但不能用在負數
Multiplication is almost twice as fast as division:乘法的執行速度比除法快兩倍(能用乘法就用乘法,ex:
x=x/2
可改寫成:
x=x*0.5
*Use lookup tables as much as possible:儘量使用lookup tables(查找表)(在第六章有相關的教學)
*Avoid creating and destroying objects unnecessarily:非必要時,不要建立或移除物件,如果有物件待會兒可能會再用到,寧願把它的visible設成false暫時先隱藏,而不要先移除,等到用時再新增。(對FlashPlayer而言,暫時隱藏會比重新建立一個物件的效能好)
*Consider object pooling:一開始就先建立好可能要用的物件,要用時再設初值給這些物件。
*Bitwise operations are sometimes faster:使用位元運算子(Bitwise operators) 通常執行速度會快一些。

Flash作品 拼圖2_新竹鄉鎮市地圖

這是一個簡單易的拼圖遊戲,最早的版本是大學時的期中作業,年代久遠啊~AS2.0
這支大概改了3次吧,
第一次是期中交作業時作的初版,
第二次是畢業後,心血來潮拿出來改,
第三次是剛好看到有人在知識+求檔,再拿出來改過後再發佈。
每隔一陣子,把舊的code拿出來再看一遍,再修改一下,
會發現自己以前怎麼會寫得這麼爛,邏輯怎麼這麼差,
然後就能發現自己在不知不覺進步了。

原始檔下載

Flash Player版本

寫好一個Project,測試時都沒問題,最討厭的就是正式上線Run時bug一堆,程式邏輯方面的bug還好,至少知道原因為何(不過這種東西通常在測試時就會被發現),最怕的就是為什麼A電腦可以正常執行,B電腦不行?碰到這種問題,什麼作業系統、FlashPlayer版本、瀏覽器、網路環境、使用者怎麽操作的,什麼雜七雜八的原因都要猜測,尤其一個project整合的環境愈複雜,要猜測的原因就更多了。

我常碰到的大概就 作業系統、FlashPlayer版本、瀏覽器 這三個原因佔大多數,所以來整理一下FlashPlayer、瀏覽器的安裝程式吧:
[[Flash Player]]
Flash Player 移除程式 http://kb2.adobe.com/cps/141/tn_14157.html
Flash Player 各種版本下載中心 http://www.adobe.com/support/flashplayer/downloads.html

[[火狐 Fire Fox]]
3.6.13 http://download.mozilla.org/?product=firefox-3.6.13&lang=zh-TW&os=win
(要其它版本的話把網址中的3.6.13改要的版本號碼)

JSON整理

JSON-AS3.0
檔案下載

import com.adobe.serialization.json.*;
trace(JSON.encode(obj_or_array));//編譯
trace(JSON.decode(string));//解譯
Category: 0 意見

Flash(AS3.0)與FMS(Flash Media Server)溝通(補充)

補充1.安裝完FMS後,C:\Program Files\Adobe\Flash Media Server 3.5\documentation 資料夾下有一些關於fms的pdf參考文件,其中 flashmediaserver_3.5_SSLR.pdf是關於FMS server端code的寫法,有詳細的寫法和一些function的用法,當然,全部是英文,網路上有翻譯好的,大家可以google "FMS 中文帮助" 看看。

補充2.
asc檔裡,client.call("fmsCallSWF", null,"fmsCallSWFEnable");
第二個參數在上一篇的範例是使用null,它可以帶一個變數進去,這個變數要定義onResul和onStatus兩個屬性,用來接收client return 的變數
例如:
asc檔:

var Handler = function(){
this.onResult = function(res){//成功接收Flash傳來的變數
trace("Random number: " + res);
}
this.onStatus = function(info){//呼叫Flash的function失敗時
trace("Failed with code:" + info.code);
}
};


application.onConnect = function(client,dd) {
trace("connect server");
application.acceptConnection(client); //接受這個client連線
//application.rejectConnection(client); //拒絕這個client連線
application.broadcastMsg("fmsCallSWF","DDDD");//呼叫SWF;所有有連線的client都會被呼叫
for(var i in client){
//trace("i="+i+","+client[i]);
}
client.call("fmsCallSWF", new Handler(),"fmsCallSWFEnable");
//client.call("fmsCallSWF",null,"fmsCallSWFEnable");//呼叫SWF;只有這個client會被呼叫
};

相對的,Flash的Responder物件,也是接收server return的變數
Category: 0 意見

Flash(AS3.0)與FMS(Flash Media Server)溝通

Flash檔下載
FMS的基礎筆記,若看懂範例檔的話,再加工一下就可以做一個簡易的線上聊天室了。
範例檔是AS3.0搭配FMS3.5
在本機安裝完FMS後,在C:\Program Files\Adobe\Flash Media Server 3.5\applications\下建立一個叫test01的資料夾下,然後把asc丟進test01資料夾下,就可以執行了。
Category: 0 意見

Facebook 連結

Facebook(1)
Category: 0 意見

Facebook(3-1 使用PHP API)

前面兩個步驟都準備好後,就是下載Facebook的API了。(此範例為PHP)
第1步:先到這個網址後,點"Downloads"進入下載頁面
http://github.com/facebook/php-sdk


第2步:目前看到最新版是v2.1.1,就下載這個版本的zip吧


第3步:解壓縮回來後,我們主要會用到的只有2個檔
src資料夾內的facebook.php <=這個是我們待會兒要用到的API
examples資料夾內的example.php <=這個是範例檔,待會兒會直接執行它做測試

第4步:把examples資料夾內的example.php,改名為index.php

第5步:如果你有裝appserv的話,把"src資料夾"和"examples資料夾" 丟到 C:\AppServ\www\下,資料夾的結構看起來會像這樣:
(沒有裝的話,請上傳到你的網頁空間)

第6步:回到應用程式設定,把Canvas URL由"http://localhost/"改成"http://localhost/examples/"
(沒有裝appserv,而是上傳到網頁空間的,改成:http://你的網址/examples/)


第7步:瀏覽器上的網址列上輸入Canvas Page的網址 也就是http://apps.facebook.com/你的Canvas page網址/

第8步:會出現
Fatal error: Uncaught CurlException: 60: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed thrown inC:\AppServ\www_class1\src\facebook.php on line 589
的錯誤訊息。

做到這,真的是令人感到很沮喪…範例居然跑起來會有error...

這個問題應該是跟SSL有關,但我不清楚這是什麼東西,直接上google找解決方法
解決方法:開啟src資料夾下的facebook.php,找到這一段:
...前面省略
protected function makeRequest($url, $params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}

$opts = self::$CURL_OPTS;
if ($this->useFileUploadSupport()) {
...後面省略
把它改成:
...前面省略
protected function makeRequest($url, $params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}
$opts = self::$CURL_OPTS;
$opts[CURLOPT_SSL_VERIFYPEER] = false;//加入這一行
if ($this->useFileUploadSupport()) {
...後面省略

第9步:再執行網頁一次,應該會跑出下面的圖片
恭禧你~你的第一個Facebook範例出來了。
Category: 0 意見

Facebook(2)

文章清單
第1步:按左邊的"Facebook整合"
填入Canvas Page及Canvas URL
Canvas Page的值是這個應用程式的網址
Canvas URL的值是這個應用程式的"真正"網址
什麼意思?就是連到Canvas Page後,它會內嵌一個iframe,這個iframe的網址就是Canvas URL
因為我要在本機直接測試,所以我的Canvas URL就填入 http://localhost/
我測了一下,發現Canvas URL不能指定某個html或php檔,它會自己找這個資料夾下的index.html或index.php

第2步:按左邊的"進階"
勾選"沙盒模式"
勾選這個的目的是只有建立這個程式的帳號才可進入測試,其它帳號不行。
因為我只是測試而已,並沒有要開放,所以我把它勾起來。

第3步:按下面的儲存,把設定儲存起來。
若是成功的話,就會看到下圖的字樣:

然後…我又出現error了…可能的失敗情況(我碰到的):
1.下面兩圖,都是說Canvas Page填入的值只能是小寫字母、底線



2.Canvas Page的值必需為唯一,會出現這個錯誤,代表已經有其它人用這個網址了,所以我們只好改別的啦!

3.這是我前面提到的,不能指定某個html或php檔,只能指定某個目錄,而它會自己找這個目錄下的index檔
Category: 0 意見

Facebook(1)

開始學著開發Facebook應用程式,順便就記錄一些開發過程吧。
文章清單
第1步:一定要有一個facebook帳號(這不是廢話嗎?)
申請帳號步驟就不講了。
第2步:進入Facebook的開發者頁面
還沒登入時,會先要求登入;已經登入了,會要求授權,按下同意
第3步:按下"現在就建立一個"


第4步:填入應用程式名稱、勾選同意、按下"建立應用程式"

第5步:成功的話,就會出現下圖


當然…我不是一次就建好了…可能的失敗情況(我碰到的):


1.應用程式的名稱不可以包含fb或FB





2.應用程式的名稱至少要三個字



Category: 0 意見

AS3與AS2做溝通-1(AS3呼叫AS2)

AS3已出來很久,但有時還是會碰到AS3呼叫AS2的狀況。
這個範例是使用LocalConnection去做溝通。
這個方法最大的限制是,傳送資料限定大小:40kb
範例檔下載
AS3檔案:
場景上做一個按鈕,實體名稱為mc,按下後,就會呼叫AS2中AS3call2_fun這支function

var conn:LocalConnection=new LocalConnection();

var loader:Loader=new Loader();//載AS2 SWF
loader.load(new URLRequest("AS2.swf"));
this.addChild(loader);
mc.addEventListener(MouseEvent.CLICK,function(e:Event){
var connObj:Object=new Object();
connObj.datas="connect Data!!!";
conn.send("connAS2", "AS3call2_fun", connObj);
//connAS2=>溝通的通訊名稱
//AS3call2_fun=>通訊的function名稱
//connObj=>要傳入的資料,有資料量限制,需在40 KB以下
});


AS2檔案

var conn:LocalConnection = new LocalConnection();
conn.AS3call2_fun=function(connObj:Object){//AS3call2_fun=>通訊的function名稱
trace("as2被呼叫:"+connObj.datas);//connObj=>接收的資料,有資料量限制,需在40 KB以下
}
conn.connect("connAS2");//connAS2=>溝通的通訊名稱

AS3 使用DataGrid組件 - 欄位文字變色(下)

範例檔下載

再加一個"是否大於0"的欄位,這個欄位的內容與顏色都會依照亂數值而改變。









1.先建立一支設定Style的as,檔名為CellRenderStyle2.as



package {
import fl.controls.listClasses.CellRenderer;

public class CellRenderStyle2 extends CellRenderer {
public function CellRenderStyle2() {
}
override protected function drawLayout():void {
//this.data["col2"]會取得與這個欄位同一Roll的值
//this.listData.label會取得目前這個欄位的值
//this.listData.column會取得目前是第幾個Column

if(parseInt(this.data["col2"])<0 && this.listData.column==1){
textField.textColor=0xFF0000;
}
if(parseInt(this.data["col2"])<0 && this.listData.column==2){
textField.textColor=0x00FF00;
}
super.drawLayout();
}
}
}



2.fla的主程式:

import fl.controls.DataGrid;
import fl.data.DataProvider;
import fl.controls.dataGridClasses.DataGridColumn;

//建立DataGrid(可把它想成大Table)
var dg:DataGrid = new DataGrid();
dg.width=500;
dg.height=300;
dg.x=20;
dg.y=30;
this.addChild(dg);
//建立Column
//第一個Column
var colA:DataGridColumn = new DataGridColumn("col1");
colA.headerText="序號";
dg.addColumn(colA);
//第二個Column
var colB:DataGridColumn = new DataGridColumn("col2");
colB.headerText="亂數";
//此格會變色,因此要設定cellRenderer
colB.cellRenderer = CellRenderStyle2;
dg.addColumn(colB);
//第三個Column
var colC:DataGridColumn = new DataGridColumn("col3");
colC.headerText="大於0?";
//此格會變色,因此要設定cellRenderer
colC.cellRenderer = CellRenderStyle2;
//此格的文字內容依Col2而變化,設定要出現的文字function
//labelFun會判斷col2的值大於0嗎,大於0顯示Y;小於0顯示n
colC.labelFunction=labelFun;
dg.addColumn(colC);

//建立DataProvider(Table的資料)
var dp:DataProvider = new DataProvider();
for (var i = 0; i < 20; i++) {
//col3的值依col2的值變化,可先不填
dp.addItem({col1:(i+1), col2:getRandomNumber()});
}
dg.dataProvider=dp;

function labelFun(item:Object):String {
trace(item["col2"]);
if(parseInt(item["col2"])>0){
return 'Y';
}else{
return 'N';
}
}

function getRandomNumber(){
return Math.floor(Math.random()*50)-25;
}

AS3 使用DataGrid組件 - 欄位文字變色(上)


範例檔下載
在AS2中,為DataGrid的欄位文字變色是很方便的事,但在AS3就無法用相同的方法了。
被它搞了很久,原本用的方法因為效能太差而被打回票,最近有同事找到了新方法塞值,就來試看看囉。

先看執行結果:欄位值小於0的,字會顯示紅色。






1.先建立一支設定Style的as,檔名為CellRenderStyle1.as



package {
import fl.controls.listClasses.CellRenderer;

public class CellRenderStyle1 extends CellRenderer {
public function CellRenderStyle1() {
}
override protected function drawLayout():void {
if(parseInt(this.listData.label)<0){
//this.listData.label會取得目前這個欄位的值
textField.textColor=0xFF0000;
}
super.drawLayout();
}
}
}




2.fla的主程式:

import fl.controls.DataGrid;
import fl.data.DataProvider;
import fl.controls.dataGridClasses.DataGridColumn;

//建立DataGrid(可把它想成大Table)
var dg:DataGrid = new DataGrid();
dg.width=500;
dg.height=300;
dg.x=20;
dg.y=30;
this.addChild(dg);
//建立Column
//第一個Column
var colA:DataGridColumn = new DataGridColumn("col1");
colA.headerText="序號";
dg.addColumn(colA);
//第二個Column
var colB:DataGridColumn = new DataGridColumn("col2");
colB.headerText="亂數";
colB.cellRenderer = CellRenderStyle1;
//此格會變色,因此要設定cellRenderer
dg.addColumn(colB);


//建立DataProvider(Table的資料)
var dp:DataProvider = new DataProvider();
for (var i = 0; i < 20; i++) {
dp.addItem({col1:(i+1), col2:getRandomNumber()});
}
dg.dataProvider=dp;


function getRandomNumber(){
return Math.floor(Math.random()*50)-25;
}

AS3.0 建立函數執行佇列




殿堂之路這本書有提到使用函數的技巧,忙裡偷閒來練習一下。
場景上有三個影片片段,依照按下按鈕的順序依續播放,一個播放完了之後,才會播放下一個。

var funAry:Array=new Array();
var quee:int=0;//剩餘要執行的工作數量
function enterFrameFun(e:Event){
e.target.currentFrame_txt.text=String(e.target.currentFrame);
if(e.target.currentFrame==e.target.totalFrames){
e.target.gotoAndStop(1);
e.target.currentFrame_txt.text="1";
e.target.removeEventListener(e.type,arguments.callee);
quee--;//一個播放完了,工作數量減1
playNow();//播放下一個
}
}
var funA:Function=function(){
mcA.gotoAndPlay(1);
mcA.addEventListener(Event.ENTER_FRAME,enterFrameFun);
}

var funB:Function=function(){
mcB.gotoAndPlay(1);
mcB.addEventListener(Event.ENTER_FRAME,enterFrameFun);
}
var funC:Function=function(){
mcC.gotoAndPlay(1);
mcC.addEventListener(Event.ENTER_FRAME,enterFrameFun);
}

btnA.addEventListener(MouseEvent.CLICK,function(e:Event){
addQuee(funA);
});
btnB.addEventListener(MouseEvent.CLICK,function(e:Event){
addQuee(funB);
});
btnC.addEventListener(MouseEvent.CLICK,function(e:Event){
addQuee(funC);
});
function addQuee(fun:Function){//將工作排入序列中
quee++;
funAry.push(fun);
if(quee==1){//工作數量=1,表示目前沒有播放
playNow();//立即播放
}
}
function playNow(){//把存在序列的工作取出,並且執行
if(funAry.length>=1){
var fun=funAry.shift();
fun();
}
}


原檔下載

AS3.0 把JS語法寫在AS裡

懶得改兩邊程式碼的懶人做法…

先宣告XML變數存JS語法

public static var alertFun:XML = new XML(
< script >
< ![CDATA[
function () {
alert("only Test");
}
]] >
< /script >
);



利用ExternalInterface.call呼叫JS:
(使用ExternalInterface要先 import flash.external.ExternalInterface;)

ExternalInterface.call(alertFun);//呼叫JS Function


範例下載(使用FD建立)

用JS控制CSS時,發生的問題

今天用JS控制Div的出現或隱藏,卻發生了神秘事件,幸有高人提醒,不然我又不知道搞多久。
事情是這樣的:畫面一開始要隱藏DIV,按了按鈕以後,再顯示DIV。

所以我先設了隱藏DIV的CSS(div的id是mydiv):

< style >
#mydiv{
display:none;
}
< /style >

JS要去顯示它,所以就寫了:

< script >
function showDiv(){
var divObj=document.getElementById('mydiv');
divObj.style.display='';
}
< /script >


我HTML的body

< body >
< div id="mydiv">This is div< /div >
< input onclick="showDiv();" value="Click Me To Show Div" type="button" >


結果…JS一點作用都沒有。

解決辦法就是:
把< style >拿掉,CSS直接下在DIV標籤上:

< div id="mydiv" style="display:none" >

雖然問題解決了,但我還是搞不懂為什麼會發生這種事=.=
註:以上為IE語法
Category: , 0 意見

PV3D-1初探Flash3D 建立平面物件、材質

PV3D文件網址
安裝設定
範例 MainPV3D001 :材質使用WireframeMaterial(內建材質)

package
{
import flash.display.Sprite;
import flash.events.Event;

import org.papervision3d.view.BasicView;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.materials.WireframeMaterial;
/**
* ...
* @author Ercrta 嵐
*/
public class MainPV3D001 extends Sprite {
//BasicView(寬:Number = 640, 高:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
private var basicView:BasicView= new BasicView();; //3D環境
private var material:WireframeMaterial; //材質
private var plane:Plane; //建立3d物件-平面
public function MainPV3D001():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
initPV3D();
}
private function initPV3D():void {

//WireframeMaterial(顏色:Number = 0xFF00FF, 透明度:Number = 100, 線框厚度:Number = 0)
material = new WireframeMaterial(0xFF6655,50,5);
material.doubleSided = true;//材質是否用在正反兩面
//primitive = new Plane(材質:MaterialObject3D = null, 寬:Number = 0, 高:Number = 0, 寬分割數:Number = 0, 高分割數:Number = 0);//分割數愈少,愈省效能
plane = new Plane(material, 200, 200, 1, 1);
basicView.scene.addChild(plane);//把3D物件加進3D環境中
basicView.startRendering();//開始渲染
this.addChild(basicView);//場景加入3D
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
plane.localRotationY++;
}
}
}

範例 Mainpv3D002:材質使用ColorMaterial(內建材質)

package {
import flash.display.Sprite;
import flash.events.Event;

import org.papervision3d.view.BasicView;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.materials.ColorMaterial;
/**
* ...
* @author Ercrta 嵐
* @date: 2010/4/29 下午 10:19
*/
public class Mainpv3D002 extends Sprite {
//BasicView(寬:Number = 640, 高:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
private var basicView:BasicView = new BasicView(); //3D環境
private var material:ColorMaterial; //材質
private var plane:Plane; //建立3d物件-平面
public function Mainpv3D002() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init():void{
removeEventListener(Event.ADDED_TO_STAGE, init);
initPV3D();
}
private function initPV3D():void{
//ColorMaterial(顏色:Number = 0xFF00FF, 透明度:Number = 1, interactive:Boolean = false)
material = new ColorMaterial(0xFF6655,50);
material.doubleSided = true;//材質是否用在正反兩面
//primitive = new Plane(材質:MaterialObject3D = null, 寬:Number = 0, 高:Number = 0, 寬分割數:Number = 0, 高分割數:Number = 0);//分割數愈少,愈省效能
plane = new Plane(material, 200, 200, 1, 1);
basicView.scene.addChild(plane);//把3D物件加進3D環境中
basicView.startRendering();//開始渲染
this.addChild(basicView);//場景加入3D
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
plane.localRotationY++;
}
}

}

範例 Mainpv3D003:材質使用BitmapMaterial(使用自己的jpg圖片)

package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;

import org.papervision3d.view.BasicView;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.materials.BitmapMaterial;
/**
* ...
* @author Ercrta 嵐
* @date: 2010/4/29 下午 10:19
*/
public class MainPV3D003 extends Sprite {
//BasicView(寬:Number = 640, 高:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
private var basicView:BasicView = new BasicView(); //3D環境
private var material:BitmapMaterial; //材質
private var plane:Plane; //建立3d物件-平面
[Embed(source="../asset/material.jpg")]
private static var imgClass:Class;
private var img:Bitmap = new imgClass();
public function MainPV3D003() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init():void{
removeEventListener(Event.ADDED_TO_STAGE, init);
initPV3D();
}
private function initPV3D():void {
//BitmapMaterial(材質來源:BitmapData = null, precise:Boolean = false)
material = new BitmapMaterial(img.bitmapData);
material.doubleSided = true;//材質是否用在正反兩面
//primitive = new Plane(材質:MaterialObject3D = null, 寬:Number = 0, 高:Number = 0, 寬分割數:Number = 0, 高分割數:Number = 0);//分割數愈少,愈省效能
plane = new Plane(material, 200, 200, 1, 1);
basicView.scene.addChild(plane);//把3D物件加進3D環境中
basicView.startRendering();//開始渲染
this.addChild(basicView);//場景加入3D
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
plane.localRotationY++;
}
}
}


材質部份,基本上都劃分在 org.papervision3d.materials下。
範例檔下載
Category: 0 意見

Flash 右鍵選單 2--自訂選單

AS2.0
在主時間軸貼上:

var myMenu:ContextMenu=new ContextMenu();
//隱藏其它選項
myMenu.hideBuiltInItems();
//建立一個自訂選項,並且為自訂選項加入按下時執行的function
var myItem:ContextMenuItem=new ContextMenuItem("顯示1", fun1);
//將自訂選項加入選單
myMenu.customItems.push(myItem);
this.menu=myMenu;

function fun1(){
trace("顯示1被按下了");
}

AS3.0
在主時間軸貼上:

var myMenu:ContextMenu=new ContextMenu();
//隱藏其它選項
myMenu.hideBuiltInItems();
//建立一個自訂選項
var myItem:ContextMenuItem=new ContextMenuItem("顯示1");
//為自訂選項加入按下時執行的function
myItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,fun1);
//將自訂選項加入選單
myMenu.customItems.push(myItem);
this.contextMenu=myMenu;
function fun1(e:Event){
trace("顯示1被按下了");
}


this可以改成在場景上的MovieClip(或TextField)實體名稱,那選單就只會針對這個MovieClip做反應。

Flash 右鍵選單 1--隱藏選單

在Flash的swf上按右鍵,會出現選單,正常的狀態會出現下圖這些選項:

想隱藏嗎?可以,可惜無法全部隱藏,
左邊的選單最後還是會出現"顯示重繪區域"和"設定"兩個選項。
右上的選單可以新增選項,但無法隱藏其它選項。
右下的選單更是完全無法修改。
若swf是放在瀏覽器上觀看的話,倒是可以試著用js控制,強制把選單全部關閉(這方法大家自己找網路吧)。
AS2.0
在主時間軸貼上:

var myMenu:ContextMenu=new ContextMenu();
myMenu.hideBuiltInItems();
this.menu=myMenu;

AS3.0
在主時間軸貼上:

var myMenu:ContextMenu=new ContextMenu();
myMenu.hideBuiltInItems();
this.contextMenu=myMenu;

Flash作品 簡易的鋼琴2

這一版試著不用Flash CS,只用FlashDevelop去做,圖片外載。
感覺好累喔,聲音、圖片都要自己去Embed,位置要寫code自己調整。
反正這次是為了熟悉Embed語法而試做,就點到為止,不做auto了。
(因為是使用Embed,編譯成swf需要FlashDevelop,或是Flash CS4 + Flex SDK)

原始檔下載

ps.前一版有錯,先拿掉了。

Flash Develop Flash開發工具2-樣版設定

開新檔時,FlashDevelop會很貼心地幫我們填入一些程式,但…格式不是我習慣的。
我寫程式碼的習慣,大括號是右上左下,而不是左上左下,但Flash Develop偏偏是左上左下,怎麼辦?只好找辦法改了。
參考網址catfacegames.com(英文)

Tools / Application Files /開啟FlashDevelop安裝位置的資料
進入Template / 會看到跟樣版有關的檔案 ,修改AS3.fdt
它本來長這樣:

package $(CSLB){
/**
$(CBI)* ...
$(CBI)* @author $(DefaultUser)
$(CBI)*/
public class $(EntryPoint) $(CSLB){
}
}

稍微解釋一下$()裡的東西是什麼意思,詳細的可以參考catfacegames.com(英文)
$(CSLB) 換行
$(DefaultUser) 讀取FlashDevelope裡DefaultUser的參數(這個參數可以新增、修改)從[工具列]/[Tools]/[Customer Arguments]做設定
$(EntryPoint) 利用這個樣版建立新檔時,指標所在的位置

改成:


package {
/**
$(CBI)* ...
$(CBI)* @author $(DefaultUser)
$(CBI)* @date: $(Timestamp)
$(CBI)* @date: $$(#DateTime#=yyyy-MM-dd)
$(CBI)*/
public class $(EntryPoint) {
}
}


把package和class的" $(CBI) "拿掉,再開檔案時,就會多出一行建立日期,而且大括號的格式也是我要的~
以後只要按File / New / AS3 Document 就行了。

但有人會習慣在專案面版上 按右鍵 / Add / new Class / 來建立新檔
這時就是改
Template /AS3Project / Class.as.fdt.wizard 這支檔案了。
另外,在這個資料夾上建立新的fdt檔,會自動出現在右鍵選單。

! 、%的小技巧

我唸書時,印象最深刻的就是老師教我使用!與%,非常簡單,但沒人指點,還真的會不知道。

! 的技巧,用在Boolean


最常用的就是開關了,當變數現在true時,要把它變成false;當變數現在是false時,要把它變成true。
一般的寫法,寫了四行:

if(booleanVariable==true){
booleanVariable=false;
}else{
booleanVariable=true;
}


修改後的寫法,一行就可以解決:

booleanVariable=!booleanVariable;


% 的技巧,用在數值循環


假設_mc這個MovieClip有四個Frame,你每點一下,它就要往下一個Frame,到第四個時,要回到第一個Frame。
一般寫法:

if(_mc.currentFrame==_mc.totalFrame){
_mc.gotoAndStop(1);
}else{
_mc.gotoAndStop(_mc.currentFrame+1);
}


修改後的寫法:

_mc.gotoAndStop((_mc.currentFrame%_mc.totalFrame)+1);

Flash Develop Flash開發工具1-安裝

Flash Develop 下載位置:
http://www.flashdevelop.org/community/viewtopic.php?f=11&t=4041

Flash SDK 下載位置:(選擇Latest Milestone Release Builds 的 Open Source Flex SDK):
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3

Flash Player 下載位置:(為了讓Flash Develop顯示trace的內容,要使用debug版)
http://www.flashdevelop.org/wikidocs/index.php?title=Getting_Started

Vizzy Flash Tracer 下載位置:
http://code.google.com/p/flash-tracer/downloads/list?can=1&q=&colspec=Filename+Summary+Uploaded+ReleaseDate+Size+DownloadCount

Flash Develop常用外掛介紹:
http://milkmidi.blogspot.com/2009/08/flashdevelopplugin.html

Flash Develop 安裝詳細教學
http://milkmidi.blogspot.com/2008/12/flashdevelop300rc1.html

Flash Develop 快速安裝設定(底下是我個人快速備忘,詳細的內容參上面網址)
1.Tools/global Classpaths/設定類別的程式碼提示
2.Tools/Progrom settings/左方 AS3Context/右方 Flex SDK Location /設定剛下載的SDK檔案路徑
3.Tools/Progrom settings/Flash Develope / 右方 Misc / Default CodePage / 選擇utf8 /避免中文顯示亂碼的問題
4.Tools ->program settings->FlashViewer->Extermal Player Path / 選擇剛下載Flash Player(debug版本)
5.project/new Project / 選擇AS3,empty project /建立新專案
6.Project面版/專案上按右鍵/Properties/Output file/輸入匯出swf時,swf的名稱

其它:
有空時看看這個,開發Flash的觀念文章
http://blog.frogiology.com/2009/07/17/flash-development-guide/
在AS3中使用元件庫的兩種方法(使用swc或embed)
http://tonycube.blogspot.com/2010/01/as3.html

TortoiseSVN 版本控制

最近寫程式,突然感覺版本控制的重要性,平常我手邊只有一個版本的code,有什麼要新加的功能,也是改這份code,但…

凡事總有意外:
程式改到掛了,想恢復原本穩定的版本。
功能不加了,想復原。
客人突然要測試,總不能拿改到一半的code給客人=.=
等等....
這時…沒有做好版本控制,當下只能唉嘆…

上網找一下,發現有TortoiseSVN這個東西,免費的,試用了一下,感覺還滿方便的。
這裡有詳細的介紹:
TortoiseSVN使用簡介
有空的話,可以了解一下資料夾的命名意義(上面的網址介紹的比較詳細):
Trunk==>程式主幹
Branch==>分支
Release==>發佈
Tag==>某一個里程碑

除了程式之外,我覺得像word、excel等這些東西都可以用版本控制,看到這個軟體之後,真是感到相見恨晚啊~~令我想到大學時大家共同做一個專案時,你改了檔我卻沒更新,拿到舊的版本卻繼續改下去的窘況...這種事,大家都發生過吧?XD

Flash 關於圓




以前對於圓總是有莫名的恐懼… 原因就是三角函式還有角度和弧度的關係我一直弄不太懂。
拖了好久,總算花一點時間去理解它一下。
角度與弧度的關系:
radians(弧度)
degrees(角度)
一般程式三角函式所帶的參數都是帶入弧度,而我們計算通常都是直接拿角度計算,所以要轉換一下:

radians = degrees * Math.PI/180
degrees = radians * 180/Math.PI

知道弧度(radians)與半徑(r)後,就可以計算x、y位置:
x位置=r*Math.cos(radians);
y位置=r*Math.sin(radians);

知道這些,大部份的問題就都可以解決啦!

簡單的範例:


範例檔下載

AS 呼叫 JS 與 JS 呼叫AS

[[AS 呼叫 JS]]
AS

import flash.external.ExternalInterface;

_btn.addEventListener(MouseEvent.CLICK,function(e:Event){
ExternalInterface.call("AScallJS");
});
val_btn.addEventListener(MouseEvent.CLICK,function(e:Event){
ExternalInterface.call("AScallJSVal","我是參數");
});

JS

function AScallJS(){
alert("AS call JS");
}
function AScallJSVal(val){
alert("AS call JS,val="+val);
}

Flash arguments類別 (AS3.0)

arguments類別是function 在用的,看help文件只有兩個屬性:

callee : Function 目前正在執行之函數的參照。
length : Number 傳遞給函數的引數數目。

Flash addFrameScript方法 (AS3.0)

我 不習慣把程式碼寫在元件中,但有偏偏會碰到非要某個元件某個影格時執行的程式。
例如:1個MovieClip有20個影格,我要在它跑到第10個影格時先暫停。
很直覺的寫法是在它第10個影格下stop();語法。
最近我是完全不寫程式碼在影格甚至主時間軸中,全部抽到.as檔

之前會用監聽EnterFrame事件來抓影格編號:

_mc.addEventListener(Event.ENTER_FRAME,function(e:Event){
if(_mc.currentFrame==10){
_mc.stop();
e.target.removeEventListener(e.type,arguments.callee);
}
});

我覺得很麻煩,又要監聽又要移除 =.=
倒不如使用

_mc.addFrameScript( 9,stopFun);//第10個影格,參數填9;第1個影格則參數填0,類推...
function stopFun(){
_mc.stop();
}

可簡化成:

_mc.addFrameScript( 9,_mc.stop);


若是要帶參數,就改成:

function myFun(str:String):Function {
var my_fun:Function = function (){
trace("參數值="+str);
}
return my_fun;
}

_mc.addFrameScript(9,myFun("我是參數"));


但有幾點要注意
1.使用這種方式,只要播放到這個影格,就會執行程式。
例如:
_mc.gotoAndStop(10)//執行
_mc.nextFrame();//下一個影格剛好是影格10,執行
_mc.prevFrame();//上一個影格剛好是影格10,執行
_mc.play()//影格播放經過影格10,執行
2.影格不存在,不會出現錯誤,但也沒作用
例如我_mc.totalFrames只到5,那_mc.addFrameScript( 9,_mc.stop);就沒作用
3.已經為指定的影格加程式碼了(不論是下在影格或是使用addFrameScript),又再加一次,新的會覆蓋掉舊的。
ex:
同時下了這兩行:
_mc2.addFrameScript(9,myFun("我是參數2"));
_mc2.addFrameScript(9,myFun("我是參數3"));
只會執行_mc2.addFrameScript(9,myFun("我是參數3"));