【翻譯】動手動腦玩轉Web遊戲之三:人物動起來、敵人出現、自定義視角

讓角色動起來

   當鍵盤上特定的按鍵被按下時,爲了讓我們創建的角色同步地動起來,需要讓Gamma來爲我們改變對象水平、垂直方向的位置狀態。在本章節,我們將實現如下功能:

·         鍵盤上向左的方向鍵控制角色往左移動

·         鍵盤上向右的方向鍵控制角色往右移動

·         鍵盤上的空格鍵控制角色跳躍

按鍵碼

    首先我們得知道這三個按鍵(左鍵,右鍵和空格鍵)分別對應的鍵碼(譯者注:就是我們所說的按鍵所對應的ASCII)。通過查閱鍵碼錶 我可以知道左鍵對應的ASCII碼值是37,右鍵是39,空格是32

移動角色的函數

    然後,我們得弄清楚Gamma提供了哪些函數可以用於改變角色的位置狀態。當遊戲開始後,一旦我們給角色下達了向右移動的按鍵指令,那麼角色就會以一個固定的速率動起來。本例中我們主要會用到Gamma提供的move jump 兩個API庫函數。調用move時爲其傳遞LEFT參數實現角色向左移動的功能,同理,讓角色向右移動時只要將move函數的參數改爲RIGHT即可。調用 jump就可以實現角色的跳躍動作。movejump函數都需要一個按鍵事件的對象作爲其輸入參數。

我們使用Gamma提供的register API爲按鍵註冊響應處理函數。響應處理函數被調用時系統會爲其傳遞一個鍵盤事件,用於區分是按鍵被按下還是按鍵彈起。

gma.keyHandler.register(37, function (keyEvent) {

    manager.character.move(gma.constants.LEFT, keyEvent);

});

 

gma.keyHandler.register(39, function (keyEvent) {

    manager.character.move(gma.constants.RIGHT, keyEvent);

});

 

gma.keyHandler.register(32, manager.character.jump);

 

    爲按鍵註冊消息處理功能的API包含gma.keyHandler包裏,所以在game.js開頭的require函數裏需要導入gma/events依賴包。

科裏化/閉包

    上面的代碼不是很優美,我們可以使用Javascript的科裏化功能。科裏化是一種根據輸入參數返回函數的函數,是閉包最偉大的應用之一(譯者注)。例如下面的(f1 f2)函數是等價的。創建f2時,根據其第一個輸入參數對其進行科裏化之後,就只需要一個按鍵事件作爲其輸入參數就可以了:

f1 = function (keyEvent) {

    manager.character.move(gma.constants.LEFT, keyEvent);

};

f2 = manager.character.move.curry(gma.constants.LEFT);

 

    所以,前面關於按鍵消息處理函數的註冊代碼可以簡化成:

gma.keyHandler.register(37, manager.character.move.curry(gma.constants.LEFT);

gma.keyHandler.register(39, manager.character.move.curry(gma.constants.RIGHT);

gma.keyHandler.register(32, manager.character.jump);

 

最終示範代碼

require([

    'gma/base',

    'gma/manager',

    'gma/entities/character',

    'gma/events'

],

    function(gma) {

        var manager = gma.manager({

            width : 600,

            height : 500

        });

        manager.character = gma.character({

            left     : 0,

            bottom   : 0,

            width    : 3,

            height   : 6,

            depth    : 3

        });

 

        var myLevel = {

            spawn : {

                main : [15, 24]

            },

            entities : [

                {top:0, left:0, width:30, height:3},

                {top:0, left:36, width:30, height:3}

            ]

        };

        manager.storeLevels(myLevel);

 

        gma.keyHandler.register(37, manager.character.move.curry(gma.constants.LEFT));

        gma.keyHandler.register(39, manager.character.move.curry(gma.constants.RIGHT));

        gma.keyHandler.register(32, manager.character.jump);

 

        manager.init();

    }

);

添加障礙

        Gamma也提供了一些用於定義障礙的對象,這些對象都有自己的行爲方式。如果要在遊戲關卡里添加障礙,必須將其放置在一個數組裏。

    在本篇中,我們會用gma.platformEnemy創建一個從一邊移動到另一邊的場景障礙,用gma.patrolEnemy創建一個在兩點之間移動的巡邏障礙,以及用gma.jumpingEnemy創建一些不斷跳躍的障礙物:

entities : [

    gma.platformEnemy({bottom:0, left:45, width:3, height:6}),

    gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),

    gma.jumpingEnemy ({bottom:0, left:7,  width:1, height:2}),

    gma.jumpingEnemy ({bottom:3, left:8,  width:1, height:2}),

    gma.jumpingEnemy ({bottom:6, left:9,  width:1, height:2})

]

    場景障礙和跳躍的障礙只需要限定其大小和位置即可,而巡邏障礙還需要設置它巡邏時的範圍,即最大左右邊界點limitLeft limitRight

類型

    如果以普通屬性來創建遊戲中的障礙物,可以將其設置成一個用戶自定義類型。在創建障礙時來引用該類型以降低代碼冗餘。我們用addCustomDefinitions來定義類型。例如:

manager.addCustomDefinitions({

    types : {

        jumpingJack: ['jumpingEnemy', {

            width    : 1,

            height   : 2

        }]

    }

});

    在定義障礙的類型時,需要將其放在數組裏,且數組的第一個元素是類名,用它來實例化一個具體的對象,例如我們所要創建gma.jumpingEnemy的跳躍障礙的對象;數組的第二個參數是一個對象,該對象裏包含了一些屬性值,這些屬性會被應用到所有實例化的對象上面。

    下面我們通過引用上面定義的jumpingJack類型來重新創建跳躍障礙:

// 此時,引用自定義類型junpingJack

entities : [

    gma.platformEnemy({bottom:0, left:45, width:3, height:6}),

    gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),

    {type:'jumpingJack', bottom:0, left:21},

    {type:'jumpingJack', bottom:3, left:24},

    {type:'jumpingJack', bottom:6, left:27}

]

提示

    後面我們不再顯式的調用gma.jumpingEnemy函數來創建跳躍障礙,而是通過設置其寬、高屬性來定義它們。因爲我們已經有了類型這個神奇的法寶(譯者注)

模板

    默認情況下,所有被創建出來的障礙都是一個藍色的方形柱體結構,這是由對象的模板屬性決定的。對象的缺省模板是一個立方體,可以用下面的方法來設置其模板屬性(雖然這一步操作顯得多此一舉)

manager.addCustomDefinitions({

    types : {

        jumpingJack: ['jumpingEnemy', {

            width    : 1,

            height   : 2

            template : 'cube'

        }

    }

});

    如果需要自定義障礙的外觀,就必須通過創建模板來實現。下面的代碼中,我們用模板助手gma.meshTemplate創建了一個綠色的方柱體的模板:

manager.addCustomDefinitions({,

    templates : {

        greencube : ['meshTemplate', {

            mesh : gma.unitCubeInfo.mesh,

            material : {color : "#090"}   // 非常的綠

        }

    }

});

    讓後將這個模板應用到前面定義的jumpingJack類型裏:

manager.addCustomDefinitions({

    types : {

        jumpingJack: ['jumpingEnemy', {

            width    : 1,

            height   : 2

            template : 'greencube'

        }

    }

});

提示

    默認情況下,Gamma已經提供了藍色紅色模板,可以使我們很方便的就創建紅色和藍色立方體。在外觀 章節的目錄裏,有模板對象類型的詳細介紹,以及它們的用法。

    另外,Gamma中的遊戲障礙缺省情況下都有一個默認的類型,使用藍色模板定義的一個平臺障礙gma.platform

最終示範代碼

require([

    'gma/base',

    'gma/manager',

    'gma/entities/character',

    'gma/events',

    'gma/entities/enemy'

], function(gma) {

        var manager = gma.manager({

            width : 600,

            height : 500

        });

        manager.character = gma.character({

            left     : 0,

            bottom   : 0,

            width    : 3,

            height   : 6,

            depth    : 3

        });

        manager.addCustomDefinitions({

            templates : {

                greencube : ['meshTemplate', {

                    mesh : gma.unitCubeInfo.mesh,

                    material : {color : "#090"}

                }]

            },

            types : {

                jumpingJack: ['jumpingEnemy', {

                    width    : 1,

                    height   : 2,

                    template : 'greencube'

                }]

            }

        });

        var myLevel = {

            spawn : {

                main : [15, 24]

            },

            entities : [

                {top:0, left:0, width:30, height:3},

                {top:0, left:39, width:30, height:3},

                gma.platformEnemy({bottom:0, left:45, width:3, height:6}),

                gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),

                {type:'jumpingJack', bottom:0, left:21},

                {type:'jumpingJack', bottom:3, left:24},

                {type:'jumpingJack', bottom:6, left:27}

            ]

        };

        manager.storeLevels(myLevel);

        gma.keyHandler.register(37, manager.character.move.curry(gma.constants.LEFT));

        gma.keyHandler.register(39, manager.character.move.curry(gma.constants.RIGHT));

        gma.keyHandler.register(32, manager.character.jump);

        manager.init();

    }

);

自定義視角

        Gamma創建的默認視角是跟隨角色一起移動的,位於角色前50個單位,z座標也是50

    在關卡里我們可以在camera標籤裏設置其屬性值來改變視角。在每個關卡里只需設置一個視角。注意:如果在你的關卡里提供了新視角,那麼Gamma提供的默認視角將會被覆蓋。

    下面這段代碼的效果和缺省視角的效果是等效的:

var myLevel = {

     camera : {

         locZ : 50,

         attached : ['character']

     }

 };

 

    接下來,我們設置一個距離角色稍微遠一點點,並且總是比角色只高那麼一丁點的視角:

var myLevel = {

     camera : {

         locZ : 60,

         attached : ['character',0, 6]

     }

 };

 

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
閱讀(1546) | 評論(0) | 轉發(0) |
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章