2012年8月30日 星期四

[Linux] errno 訊號註解

[errno.h]linux api 錯誤訊號&註解

#define EPERM   1 /* Operation not permitted */
#define ENOENT   2 /* No such file or directory */
#define ESRCH   3 /* No such process */
#define EINTR   4 /* Interrupted system call */
#define EIO       5 /* I/O error */
#define ENXIO   6 /* No such device or address */
#define E2BIG   7 /* Arg list too long */
#define ENOEXEC   8 /* Exec format error */
#define EBADF   9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */

[strerror]
錯誤碼解釋函式
 char * ERROR_MSG(int error)/* errno.h -> #define errno   (*_errno()) */{
  //printf("Error no.%d\n",error); 
  char * msg = strerror(error);
  //printf("Error Message : %s\n",msg); 
  return msg;
 }

2012年8月29日 星期三

[Linux]Daemon 守護神程式

為什麼會需要『守護神程式』?
一般的程式通常都是『單次目的性』,像我常用的『cat』,這種程式都常就都是一次性使用。
那『守護神程式』呢?
沒接觸過『Linux』的人,恐怕不知道什麼是Daemon。Daemon功能相當於Windows的service,也就是常駐程式。
通常在系統啟動時就會運行,當系統關閉時結束。


#include <stdio.h>
#include <iostream>
#include <time.h>
#include <sys/timeb.h>
#include <locale>
int Daemon()
{
    static int Count =0;
    int status=0;
    pid_t pid=fork();
    if(pid < 0){//初始化失敗
        return -1;
    }
    else if(pid==0)
    {
        //主程式進行
    }else
    {
        pid_t p=waitpid(pid,&status,0);//等待程式退出
        Daemon();
    }
    return 1;
}
int main()
{
 if(Daemon()==-1){
  exit(0);
 }
 while(1){
 
 }
}

陽春的架構就是這樣,如此一來程式至系統關閉為止都會一直執行。 除非手動去把它『kill』掉。 想到再補..

2012年8月16日 星期四

[JavaScript]Cocos2d-x html5 試用 (五) TouchDispatcher & Scheduler

[TouchDispatcher]
這個類別算是[Cocos2d-x]裡的底層類別,主要管理『觸控事件』和『滑鼠事件』,
有興趣的可以看一下原始碼,這個我就不特別做解說。
 我們這裡以觸控面板為例 以當今觸控面板來說,分為『多點觸控』和『單點觸控』,而這個類別也提供了『多點觸控』和『單點觸控』,分別是:

註冊單點觸控事件的
[addTargetedDelegate]

    /**
     * @param {cc.TouchDelegate} delegate
     * @param {Number} priority
     * @param {Boolean} swallowsTouches
     */
    addTargetedDelegate:function (delegate, priority, swallowsTouches)
註冊一個『單點觸控事件』,第一個參數是想註冊的物件本身,第二個是優先權,第三個我試了很久看不出有甚麼差別,原始碼內也無地方也用到,所以暫時先略過。
    ccTouchBegan:function (pTouch, pEvent) {
        console.log(pTouch.locationInView().x + "," + pTouch.locationInView().y);
    },
    ccTouchMoved:function (pTouch, pEvent) {

    },
    ccTouchEnded:function (pTouch, pEvent) {

    },
在註冊『觸控事件』,前需要為物件加入以上函式,分別是『開始(按下)』、『移動』和『結束(放開)』。
因為『單點觸控』,所以當事件觸發時,會傳進點到的座標,如範例,可用『locationInView』函式得到座標。
cc.Director.sharedDirector().getTouchDispatcher().addTargetedDelegate(this,1);
當確認函式加入了之後,就可以註冊事件了。

接下來是,註冊多點觸控事件的
[addStandardDelegate]

    /**
     * Adds a standard touch delegate to the dispatcher's list.
     * See StandardTouchDelegate description.
     * IMPORTANT: The delegate will be retained.
     * @param {cc.TouchDelegate} delegate
     * @param {Number} priority
     */
    addStandardDelegate:function (delegate, priority)
註冊『多點觸控事件』跟『單點觸控事件』是一樣的,不一樣的在後面
    ccTouchesBegan:function (pTouch, pEvent) {
        for (var i = 0; i < pTouch.length; i++)
            console.log("Point[" + (i + 1) + "](" + pTouch[i].locationInView().x + "," + pTouch[i].locationInView().y + ")");
    },
    ccTouchesMoved:function (pTouch, pEvent) {

    },
    ccTouchesEnded:function (pTouch, pEvent) {

    },
『多點觸控事件』需要加入的函式,名稱與『單點觸控事件』的函式名稱不一樣,但是功能還是一樣的。
而因為是『多點觸控』,所以傳回的座標是以陣列的方式回傳,預設的最大觸控點是4個。
cc.Director.sharedDirector().getTouchDispatcher().addStandardDelegate(this,1);

註冊方式除了名子和『單點觸控事件』不一樣外,大概就是參數少一個吧。
 如果有多點觸控裝置的話,觸碰複數點,就會回傳碰到的所有座標。 

只能偵測到表面事件,是Canvas的缺點之一。
 所以我們必須要自行判斷及規劃『Canvas』裏頭的所有事件響應與否。
 而這部分,算是比較進階的了,所以暫時先不提。

[Scheduler]
    /**
     * *    Schedules the 'update' selector for a given target with a given priority.

     *    The 'update' selector will be called every frame.

     *    The lower the priority, the earlier it is called.
     * 


     * @param {cc.Class} target
     * @param {Number} priority
     * @param {Boolean} paused
     * @example
     * //register this object to scheduler
     * cc.Director.sharedDirector().getScheduler().scheduleUpdateForTarget(this, priority, !this._isRunning);
     */
    scheduleUpdateForTarget:function (target, priority, paused)

物件在註冊[Scheduler]前需要注意的事項如下:
1. 物件本身必須要擁有[update],可供呼叫。
    update:function () {
        //The 'update' selector will be called every frame.
    }

運作原理,就類似Flash裏頭的『onEnterframe』,他會在每一次frame更新時被呼叫。
2. 注意優先順序,程式會依優先權進入[update]狀態。
以上也是第一和第個個參數的介紹。最後第三個參數,代表是否再直接進入偵聽狀態,可視程式目的決定。
    cc.Director.sharedDirector().getScheduler().scheduleUpdateForTarget(this, 0, false);
註冊方法與[TouchDispatcher]一樣。
最後,這兩大類類別,需要在物件的初始化完畢後,才可進行註冊。

2012年8月15日 星期三

[JavaScript]Cocos2d-x html5 試用 (四) Action

Cocos2d-x 的[Action]裡,定義了一些基本的『動畫動作類別』和『動作管理類別』。
那在眾多『動作類別』裡,我們該如何分辨它是什麼樣的類別?
我們先從基本的『動畫動作類別』開始講解,
每一個 『動畫動作類別』 都會有一個『xxxTo』、『xxxBy』。基本上只要看到這兩種結尾的Function,就不用懷疑,他就是一個 『動畫動作類別』。

[Action] + [To]
代表會從現在的的狀態,隨時間轉換到指定狀態。
Ex:
/**
 * @param {Number} duration duration in seconds
 * @param {cc.Point} position
 * @return {cc.MoveTo}
 * @example
 * // example
 * var actionTo = cc.MoveTo.create(2, cc.PointMake(windowSize.width - 40, windowSize.height - 40));
 */
cc.MoveTo.create = function (duration, position) 
就跟字面上的意思一樣,這個『動畫動作類別』會讓綁定的宿主,『在指定的時間內,從目前的位置,移動到指定位置』。
接下來就直接使用看看吧!

var actionMoveTo = cc.MoveTo.create(1,cc.ccp(128,128));
sprite.runAction(actionMoveTo);

我們接著用上次[cc.Sprite],在宣告[sprite]之後,加上以上程式碼。
執行了程式後,[sprite]會在一秒內,從本來的位置移動到(128 , 128)位置。

var actionRotateTo = cc.RotateTo.create(1,720);
sprite.runAction(actionRotateTo);

執行了這段程式碼後,[sprite]會在一秒內,改變角度至[720]度,初始值是0,也就是轉兩圈。

var actionScaleTo = cc.ScaleTo.create(1,0.5);
sprite.runAction(actionScaleTo);

執行了這段程式碼後,[sprite]會在一秒內,縮放至[0.5]倍,初始值是1,也就是變成一半大小。

var actionFadeTo = cc.FadeTo.create(1,128);
sprite.runAction(actionFadeTo);

執行了這段程式碼後,[sprite]會在一秒內,改變透明度至[128],初始值是255,也就是變為一半的透明度。


緊接著我們介紹
[Action] + [By]
我們看一下其中一段原始碼
/**
 * @param {Number} duration duration in seconds
 * @param {cc.Point} position
 * @return {cc.MoveBy}
 * @example
 * // example
 * var actionBy = cc.MoveBy.create(2, cc.PointMake(80, 80));
 */
cc.MoveBy.create = function (duration, position)
這個看起來和[Action] + [To]沒什麼不一樣,其實還是有差的,
依照原始碼給的範例,這個『動作類別』會讓綁定的宿主,從原本的座標個別累加至80。
而這類型的『動作類別』還有一個[reverse]函式,可以讓目標物件返回原本的狀態。

使用上與[Action] + [To]是一樣的,只是使用單這個『動作類別』,其實沒有很明顯的效果。
所以我們必須搭配『動作管理類別』一起使用。
『動作管理類別』總共有三種,分別是[cc.Sequence]、[cc.Spawn]和[cc.RepeatForever]。

[cc.Sequence]
/** helper constructor to create an array of sequenceable actions
 * @param {Array|cc.FiniteTimeAction} tempArray
* @return {cc.FiniteTimeAction}
* @example
    * // example
    * // create sequence with actions
* var seq = cc.Sequence.create(act1, act2);
* // create sequence with array
* var seq = cc.Sequence.create(actArray);
*/
    cc.Sequence.create = function (/*Multiple Arguments*/tempArray)

[cc.Sequence]這個類別會依照,傳入的『動作類別』以Queue的方式,依序執行動作,
以下以程式碼進行解說,

    var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
    var actionSequence = cc.Sequence.create(actionMoveBy,actionMoveBy.reverse());
    sprite.runAction(actionSequence);
執行了上面這段程式碼後,[sprite]會先移動到自己座標(+80,+80)的位置,然後再移回原本的位置。

然而,依[cc.Sequence]的註解行上的說明,他是允許複數動作進行排程進行的。
所以我們也可以多定義幾個動作,再把它們排入[cc.Sequence]的行程裏,讓他依序去執行。
    var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
    var actionSequence = cc.Sequence.create(actionMoveBy,actionMoveBy.reverse());
    sprite.runAction(actionSequence);

以上原始碼裏,我讓[cc.Sequence]進行四個動作行程,效果我就不多做解釋了!執行看看吧!

[cc.Spawn]
/**
 * @param {Array|cc.FiniteTimeAction}tempArray
 * @return {cc.FiniteTimeAction}
 * @example
 * // example
 * var action = cc.Spawn.create(cc.JumpBy.create(2, cc.PointMake(300, 0), 50, 4), cc.RotateBy.create(2, 720));
 */
cc.Spawn.create = function (/*Multiple Arguments*/tempArray)
[cc.Spawn]這個類別不同於[cc.Sequence]的地方是它會讓加進來的所動作,同時進行。 看一段程式碼吧!
    var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
    var actionRotateBy = cc.RotateBy.create(0.5,360);
    var actionSpawn = cc.Spawn.create(actionMoveBy,actionRotateBy);
    sprite.runAction(actionSpawn);

運行了程式碼後,會看到[sprite]一邊移動,一邊旋轉。
但是因為旋轉的時間比較短,所以旋轉會比較早結束。
 跟[cc.Sequence]一樣,他也是允許複數的動作同時進行,所以你也可以讓[sprite]一邊移動、旋轉、縮放…等動作,這些就自由發揮吧。

[cc. RepeatForever ]

[cc.RepeatForever],跟字面上的意思一樣,他會一直重複動作。上前兩個不同的地方是,它只能接受一組動作,但是可以傳入的動作也包含[cc.Sequence]和[cc.Spawn]。
這樣說好了,其實所有的『動作管理類別』,都是一個『動作類別』,所以理所當然的,也可以互相加入彼此。
比如說,我想讓物體一邊放大、然後旋轉並移動到目的地,完畢之後再讓物體回到原本的位置,並且恢復原本大小,然後重複以上動作。
這些都是可以靠『動作管理類別』達成的。
我們就來實現以上的動作吧!
    var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
    var actionRotateBy = cc.RotateBy.create(0.5,360);
    var actionScaleBy = cc.ScaleBy.create(0.5,2);
    var actionSpawn = cc.Spawn.create(actionMoveBy,actionRotateBy,actionScaleBy);
    var actionSequence = cc.Sequence.create(actionSpawn,actionSpawn.reverse());
    var actionRepeat = cc.RepeatForever.create(actionSequence);
    sprite.runAction(actionRepeat);
以上的程式碼,就實現了上述的動作要求。

其他比較重要的,還有一個[cc.CallFunc]的動作類別,我們先來看看他的原始碼
/** creates the action with the callback
 * @param {object} selectorTarget
 * @param {function|Null} selector
 * @param {*|Null} data data for function, it accepts all data types.
 * @return {cc.CallFunc}
 * @example
 * // example
 * // CallFunc without data
 * var finish = cc.CallFunc.create(this, this.removeSprite);
 *
 * // CallFunc with data
 * var finish = cc.CallFunc.create(this._grossini, this.removeFromParentAndCleanup, true),
 */

cc.CallFunc.create = function (selectorTarget, selector, data)

[cc.CallFunc]這個動作,是作為程式的『Callback』用,因此若將它加在[cc.Sequence]的尾端,它就會在最後執行,依此類推。
[cc.CallFunc]的第一個參數,一般來說都是傳入『物件』本身(即動作的宿主)。
第二個參數則是想要呼叫的函式。
第三個參數是想傳遞的值,如範例,它傳入一個『true』的值,在『Callback』條件達成時就會一起被傳進去。
我們來看一段程式碼, 宣告
    var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
    var callback = cc.CallFunc.create(sprite, Main.callback, true);
    sprite.runAction(cc.Sequence.create(actionMoveBy, actionMoveBy.reverse(), 
Main.callback));
Callback函式
Main.callback = function (sprite, data) {
    var actionRotateBy = cc.RotateBy.create(0.05, 5);
    var callback = cc.CallFunc.create(sprite, Main.callback, true);
    sprite.runAction(cc.Sequence.create(actionRotateBy,actionRotateBy.reverse(), Main.callback));
};

效果就自己執行看看吧!

2012年8月13日 星期一

[JavaScript]Cocos2d-x html5 試用 (三) Sprite

在介紹Sprite前,我們有必要先了解一下Sprite的建構式
    /**
     * Constructor
     * @param {String|cc.SpriteFrame|cc.SpriteBatchNode|HTMLImageElement|cc.Texture2D} fileName sprite construct parameter
     */
    ctor:function (fileName) {
        this._super();
        this._shouldBeHidden = false;
        this._offsetPosition = new cc.Point(0, 0);
        this._unflippedOffsetPositionFromCenter = new cc.Point(0, 0);

        if (fileName) {
            if (typeof(fileName) == "string") {
                var frame = cc.SpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName(fileName);
                this.initWithSpriteFrame(frame);
            } else if (typeof(fileName) == "object") {
                if (fileName instanceof cc.SpriteFrame) {
                    this.initWithSpriteFrame(fileName);
                } else if (fileName instanceof cc.SpriteBatchNode) {
                    if (arguments.length > 1) {
                        var rect = arguments[1];
                        if (rect instanceof cc.Rect) {
                            this.initWithBatchNode(fileName, rect);
                        }
                    }
                } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
                    this.initWithTexture(fileName)
                } else if (fileName instanceof cc.Texture2D) {
                    this.initWithTexture(fileName)
                }
            }
        }
    },
從以上程式碼,得知cc.Sprite 的建構條件有
String|cc.SpriteFrame|cc.SpriteBatchNode|HTMLImageElement|cc.Texture2D 
其中String,並不是代表著一個FileName,要以String方式宣告一個Sprite的條件是,必須要有[SpriteFrame],且有在[cc.SpriteFrameCache]做[Cache],String代表著[SpriteFrame]的[Key]值。
要以建構式宣告一個Sprite的話,還是必須宣告一些介質來達成,
如果我們想要直接以路徑來宣告,就必須只用其他的初始化方法。

    /**
     * Initializes a sprite with a texture and a rect in texture
     * @param {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture
     * @param {cc.Rect} rect
     * @return {Boolean}
     * @example
     * var img =cc.TextureCache.sharedTextureCache().addImage("HelloWorld.png");
     * var mySprite = new cc.Sprite();
     * mySprite.initWithTexture(img,new cc.Rect(0,0,480,320));
     */
    initWithTexture:function (texture, rect, rotated)
    /**
     * Initializes a sprite with a texture's filename and a rect in texture
     * @param {String} filename
     * @param {cc.Rect} rect
     * @return {Boolean}
     * @example
     * var mySprite = new cc.Sprite();
     * mySprite.initWithFile("HelloWorld.png",new cc.Rect(0,0,480,320));
     */
    initWithFile:function (filename, rect)
    /**
     * Initializes a sprite with a sprite frame.
     * @param {cc.SpriteFrame} spriteFrame
     * @return {Boolean}
     * @example
     * var spriteFrame = cc.SpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName("grossini_dance_01.png");
     * var sprite = new cc.Sprite();
     * sprite.initWithSpriteFrame(spriteFrame);
     */
    initWithSpriteFrame:function (spriteFrame)
    /**
     * Initializes a sprite with a sprite frame name. 

     * A cc.SpriteFrame will be fetched from the cc.SpriteFrameCache by name.  

     * If the cc.SpriteFrame doesn't exist it will raise an exception. 

     * @param {String} spriteFrameName
     * @return {Boolean}
     * @example
     * var sprite = new cc.Sprite();
     * sprite.initWithSpriteFrameName("grossini_dance_01.png");
     */
    initWithSpriteFrameName:function (spriteFrameName) 
以上截至cc.Sprite的原始碼,在註解行裡有簡單的使用方法,所以我就不做解釋。
其中 [initWithFile]這個 Function ,就是可以以檔案路徑初始化一個Sprite的方法。
接下來,我們就直接來用看看,
    var sprite = new cc.Sprite();
    sprite.initWithFile("Image/HelloSprite.png");
    sprite.setPosition(cc.ccp(size.width / 2, size.height / 2));//將[sprite]的位置至於正中間
    sprite.setAnchorPoint(cc.ccp(0.5, 0.5));//設定對齊點為中間
    this.addChild(sprite);//將[sprite]加到[Layer]上顯示
現在我們宣告了一個『cc.Sprite』,並把他加到[Layer]上。
直接把以上程式碼,加到『Main.js』的[initLayer]裡,就可以看到,除了背景圖和Hello World,還顯示了一張圖片在[Canvas]正中央。
如下圖

成功貼出一個『cc.Sprite』後,接下來能做什麼呢?
這裡簡單的介紹一下『cc.Sprite』裡,所定義的Function
1   . [setTexture] : 將目前顯示的[Texture]替換成目標。
2   . [addChild] :將目標物件設為子項,物件必須是[cc.Sprite]或繼承於[cc.Sprite]。
    /**
     * Add child to sprite (override cc.Node )
     * @param {cc.Sprite} child
     * @param {Number} zOrder  child's zOrder
     * @param {String} tag child's tag
     * @override
     */
    addChild:function (child, zOrder, tag)
3   . [removeChild] :將目標物件成子項中移除。
4   . [removeAllChildrenWithCleanup] : 將所有子項移除。
5   . [setPosition] :設定Sprite的座標位置。傳入值必須為[cc.Ponit]。
6   . [setRotation] :設定角度。
7   . [setSkewX]&[setSkewY] :設定橫向、垂直斜度。
8   . [setScaleX]&[setScaleY] :設定橫向、垂直放大倍率。(0~1為縮小,1以後為放大)。
9   . [setScale] :整體放大倍率,同上述。
10 . [setFlipX]&[setFlipY] :設定橫向、垂直反轉,[true or false]。
11 . [setAnchorPoint] :設定對齊位置,傳入值必須為[cc.Ponit]。
12 . [setVisible] :設定是否顯示,[true or false]。
13 . [setOpacity] :設定透明度,[0~255]。
14 . [setColor] :設定顏色,[cc.Color3B]。
上述皆為[setter],[getter]屬性的 Function 只要呼叫就會回傳與[setter]相對應的值,所以我只列出以下幾項做說明。
1   . [getParent]  :取得父項目。
2   . [getContentSize]  :取得[Sprite]寬度和高度。
3   . [getChildByTag]  :依標籤取得子項,子項必須在加入時定義標籤名稱。
以上是比較常用到的 Function ,比較不常用的像是[draw]和[visit]這兩個屬於底層的 Function ,應用上並不會使用到,所以就不多做解釋。

[JavaScript]Cocos2d-x html5 試用 (二) 模板建置

Cocos2d-html5 環境設置

首先下載底下的檔案
https://github.com/locke12456/Cocos2dTemplate

打開下載下來的文件後,我們會發現,在『index.html』裡面只有宣告一個『cocos2d.js』的'script' TAG。
『cocos2d.js』裡,
這裡頭的重點就是『cc.loadjs』的函式,他包含了『Preloader』,代替'script'這個TAG。
使用方法我就不贅述了,這個文件裡頭到處都有它的存在,直接看程式碼:

cc.loadjs = function (filename) {
    //add the file to the que
    var script = cc.$new('script');
    script.src = cc.Dir + filename;
    script.order = cc.loadQue.length;
    cc.loadQue.push(script);


    script.onload = function () {
        //file have finished loading,
        //if there is more file to load, we should put the next file on the head
        if (this.order + 1 < cc.loadQue.length) {
            cc.$('head').appendChild(cc.loadQue[this.order + 1]);
            //console.log(this.order);
        }
        else {
            cc.setup("gameCanvas");//選取『index.html』裡的『canvas』TAG的 id,可自行修改
            //we are ready to run the game
            cc.Loader.shareLoader().onloading = function () {
                cc.LoaderScene.shareLoaderScene().draw();//Preloader進度條
            };
            cc.Loader.shareLoader().onload = function () {
                cc.AppController.shareAppController().didFinishLaunchingWithOptions();
            };
            //preload ressources
            cc.Loader.shareLoader().preload([

                {type:"image", src:"Image/HelloWorld.png"}//遊戲資源文件
            ]);
        }
    };
    if (script.order === 0)//if the first file to load, then we put it on the head
    {
        cc.$('head').appendChild(script);
    }
};
我們看到函式裡,有一個onload的狀態偵聽,主要功能在判斷js文件是否全部都已經加載完畢。
加載完畢後,初始化『Canvas』,並開始加載遊戲資源文件,
完成後,運行『cc.AppController.shareAppController().didFinishLaunchingWithOptions()』。
運行這個函式後遊戲就會開始初始化。
其構造相當於『C#』的『Program.cs』,有興趣的人可以開啟一個C#專案看看,其實就是應用程式及視窗的初始化。
而這裡用於遊戲程式的初始化。

接下來,看文件最後兩行
cc.loadjs('Main.js');
cc.loadjs('Classes/AppDelegate.js');
會發現預載了『AppDelegate.js』這個文件。
有開發過IOS APP的人應該對這文件名稱不陌生,他同樣是負責程式的生命週期,文件加載完畢後即會運行這個程式。
我們會修改到的地方如下
applicationDidFinishLaunching:function () {
        // initialize director
        var director = cc.Director.sharedDirector();

        // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
        //     director->enableRetinaDisplay(true);

        // turn on display FPS
        director.setDisplayStats(true);

        //cc.SPRITE_DEBUG_DRAW = 1;

        // director->setDeviceOrientation(CCDEVICE_ORIENTATION_LANDSCAPE_LEFT);

        // set FPS. the default value is 1.0/60 if you don't call this
        director.setAnimationInterval(1.0 / 60);

        // create a scene. it's an autorelease object
        var scene = new Main.scene();

        // run
        director.runWithScene(scene);

        return true;
    },
會修改到的部分大改只有『director.setDisplayStats(true)』、『director.setAnimationInterval(1.0 / 60)』和『var scene = new Main.scene()』。
『director.setDisplayStats』這裡是設定是否顯示FPS,方便Debug用。
『director.setAnimationInterval(1.0 / 60)』這裡是設定Framerate,但是不知道為什麼設定了依然不會改變,所以暫時略過。
『var scene = new Main.scene()』這段就是我們先前寫的『Hallo World』了,名稱沒限制一定要是『Main』,所以自行修改吧。

最後就是『Main.js』這個文件了。
需要注意的地方,如下:

Main.scene = function () {
    // 'scene' is an autorelease object
    var scene = cc.Scene.create();
    // 'layer' is an autorelease object
    var layer = Main.node();
    scene.addChild(layer);
    return scene;
};

// implement the "static node()" method manually
Main.node = function () {
    var pRet = new Main();

    // Init the Main display layer.
    if (pRet && pRet.init()) {
        main = pRet;
        return pRet;
    }

    return null;
};
這段程式碼,用於整個遊戲程式的初始化,所以除了Class名稱可以自由修改外,其他如無特別的需要,可不必修改。

至此『cocos2d-html5』的模板就建置完成了。
程式流程圖如下
'index.html' → 'cocos2d.js'                         →   'AppDelegate.js'        →    'Main.js'
                    ↓(cc.loadjs) part 1 程式加載                ↓(初始化Main.js)          ↓(遊戲執行)
                '引擎相關Class'                                 next step                 end
                'Main.js'
                'AppDelegate.js' 
                    ↓(cc.loadjs) part 2 影音加載
                'cc.Loader.shareLoader().preload'
                    ↓(cc.loadjs) part 3 初始化
                    next step