天天看點

遊戲開發:Html5 虛拟搖杆控制人物移動

這邊想再單獨和大家分享一下有關虛拟搖杆的開發經驗,因為覺得這個功能還是很實用和用途廣泛的!

效果:

遊戲開發:Html5 虛拟搖杆控制人物移動

運作位址:

http://h5demo.yyfuncdn.com/res/gameDemo/Pokemon/game.html

搖杆顯示:

因為制作該遊戲使用了 pixi 架構,是以需要利用 PIXI.Graphics() 方法繪制兩個圓就可以了,一大一小,大圓為移動背景,給與一個顔色和透明度,預設隐藏即可,下面是繪制一個按鈕移動背景圓的代碼:

var rockerbg = new PIXI.Graphics();//繪制搖杆背景
    rockerbg.lineStyle(0);//外邊框寬度為0
    rockerbg.beginFill(0x000000, 0.3);//背景色 透明度
    var radius = 0;//半徑
    if(phoneWidth > phoneHeight)radius = phoneWidth/10;
    else radius = phoneHeight/10;
    rockerbg.drawCircle(0,0,radius);//設定半徑
    rockerbg.endFill();//結束繪畫
    parent.addChild(rockerbg);//添加到舞台,parent為傳進來的舞台參數
           

控制按鈕同理,隻不過小一點就可以了。當然如果小夥伴們圖省事或不使用架構,找兩個圓的圖檔也可以,但是要注意設定錨點為中心

搖杆功能:

接下來就要具體說明一下他是如何将被操作的人或物捆綁到一起的了,在該寶可夢遊戲中主要為了提供給角色一個速度,這個速度是一個 json 資料,裡面存放了 x 軸與 y 軸的速度

如何實作觸摸螢幕給與速度相應資料呢,這就要用到開啟舞台互動事件中的“滑鼠按下”、“滑鼠擡起”、“滑鼠移動”三個事件

其中“滑鼠按下”事件中控制擷取目前滑鼠位置,以及按鈕的顯示

app.stage.on("pointerdown",function(event){//在滑鼠按下位置顯示控制器
        var pos = event.data.getLocalPosition(app.stage);
        rockerbg.x = pos.x;
        rockerbg.y = pos.y;
        rockerbg.visible = true;
    })
           

“滑鼠擡起”事件中控制控制器隐藏以及速度歸零

app.stage.on("pointerup",function(){//滑鼠擡起時控制器隐藏,速度歸零
        rocker.x = 0;
        rocker.y = 0;
        rockerbg.visible = false;
        speed = {x:0,y:0};
    })
           

“滑鼠移動”事件是整個控制的關鍵,他将控制按鈕的移動,利用大圓與小圓的圓心位置獲得角色所需的移動方向,因為角色隻能四個方向移動,是以隻需要先判斷小圓圓心據原點的X軸與Y軸絕對值的最大值,再判斷最大值為正值或負值即可得出角色的移動方向

遊戲開發:Html5 虛拟搖杆控制人物移動
rocker.on("pointermove",function(event){//利用判斷控制器在控制器背景原點的方向進行設定角色移動方向
        var pos = event.data.getLocalPosition(app.stage);
        var A = rockerbg.x-pos.x;//搖杆起始點與滑鼠X軸距離
        var B = rockerbg.y-pos.y;//搖杆起始點與滑鼠Y軸距離
        var Z = radius;//控制器背景的半徑
        var X = pos.x-rockerbg.x;//擷取滑鼠X軸位置
        var Y = pos.y-rockerbg.y;//擷取滑鼠Y軸位置
        if(Z*Z<A*A+B*B){//判斷滑鼠位置是否超出搖杆移動範圍
            var angle = Math.atan((pos.y-rockerbg.y)/(pos.x-rockerbg.x));//計算滑鼠與搖杆起始點角度
            if(pos.x<rockerbg.x){//判斷滑鼠是否在搖杆左側
                X = -Z*Math.cos(angle);
                Y = -Z*Math.sin(angle);
            }else{//判斷滑鼠是否在搖杆右側
                X = Z*Math.cos(angle);
                Y = Z*Math.sin(angle);
            }
        }
        speed = {x:0,y:0};
        var movescope = rockerbg.width/6;//設定控制器移動的最小範圍(當超過這個值時則可設定方向與速度)
        if(Math.abs(X) > Math.abs(Y) && Math.abs(X) > movescope){
            if(X < 0){
                obj.moveState = true;
                obj.direction = "a";//人物動畫
                speed.x = -3;//設定x軸速度
            }else if(X > 0){
                obj.moveState = true;
                obj.direction = "d";//人物動畫
                speed.x = 3;//設定x軸速度
            }
        }else if(Math.abs(X) < Math.abs(Y) && Math.abs(Y) > movescope){
            if(Y < 0){
                obj.moveState = true;
                obj.direction = "w";//人物動畫
                speed.y = -3;//設定y軸速度
            }else if(Y > 0){
                obj.moveState = true;
                obj.direction = "s";//人物動畫
                speed.y = 3;//設定y軸速度
            }
        }
        rocker.x = X;//設定按鈕x坐标
        rocker.y = Y;//設定按鈕y坐标
    })
           

上面代碼中各行都有詳細的功能注釋說明,希望對大家的了解有所幫助,最後的最後是調用目前對象中的 getSpeed 方法即可擷取該對象中的 json 資料 speed

this.getSpeed = function(){
        return speed;
    }
           

下面的是整個虛拟控制器的完整代碼

function Fsvjoy(parent){//虛拟控制器
    var self = this;
    var rockerbg = new PIXI.Graphics();//繪制搖杆背景
    rockerbg.lineStyle(0);
    rockerbg.beginFill(0x000000, 0.3);
    var radius = 0;
    if(phoneWidth > phoneHeight)radius = phoneWidth/10;
    else radius = phoneHeight/10;
    rockerbg.drawCircle(0,0,radius);
    rockerbg.endFill();
    parent.addChild(rockerbg);
    var rocker = new PIXI.Graphics();//繪制搖杆
    rocker.lineStyle(0);
    rocker.beginFill(0xf0f0f0,0.7);
    rocker.drawCircle(0,0,rockerbg.height/8);
    rocker.endFill();
    rockerbg.addChild(rocker);
    rockerbg.visible = false;

    var obj = null;
    this.setobj = function(role){
        obj = role;
    }
    var speed = {x:0,y:0};

    app.stage.interactive = true;//開啟舞台互動
    app.stage.on("pointerdown",function(event){//在滑鼠按下位置顯示控制器
        var pos = event.data.getLocalPosition(app.stage);
        rockerbg.x = pos.x;
        rockerbg.y = pos.y;
        rockerbg.visible = true;
    })

    app.stage.on("pointerup",function(){//滑鼠擡起時控制器隐藏,速度歸零
        rocker.x = 0;
        rocker.y = 0;
        rockerbg.visible = false;
        speed = {x:0,y:0};
    })
    rocker.interactive = true;//開啟搖杆互動
    rocker.on("pointermove",function(event){//利用判斷控制器在控制器背景原點的方向進行設定角色移動方向
        var pos = event.data.getLocalPosition(app.stage);
        var A = rockerbg.x-pos.x;//搖杆起始點與滑鼠X軸距離
        var B = rockerbg.y-pos.y;//搖杆起始點與滑鼠Y軸距離
        var Z = radius;//控制器背景的半徑
        var X = pos.x-rockerbg.x;//擷取滑鼠X軸位置
        var Y = pos.y-rockerbg.y;//擷取滑鼠Y軸位置
        if(Z*Z<A*A+B*B){//判斷滑鼠位置是否超出搖杆移動範圍
            var angle = Math.atan((pos.y-rockerbg.y)/(pos.x-rockerbg.x));//計算滑鼠與搖杆起始點角度
            if(pos.x<rockerbg.x){//判斷滑鼠是否在搖杆左側
                X = -Z*Math.cos(angle);
                Y = -Z*Math.sin(angle);
            }else{//判斷滑鼠是否在搖杆左側
                X = Z*Math.cos(angle);
                Y = Z*Math.sin(angle);
            }
        }
        speed = {x:0,y:0};
        var movescope = rockerbg.width/6;//設定控制器移動的最小範圍(當超過這個值時則可設定方向與速度)
        if(Math.abs(X) > Math.abs(Y) && Math.abs(X) > movescope){
            if(X < 0){
                obj.moveState = true;
                obj.direction = "a";
                speed.x = -3;
            }else if(X > 0){
                obj.moveState = true;
                obj.direction = "d";
                speed.x = 3;
            }
        }else if(Math.abs(X) < Math.abs(Y) && Math.abs(Y) > movescope){
            if(Y < 0){
                obj.moveState = true;
                obj.direction = "w";
                speed.y = -3;
            }else if(Y > 0){
                obj.moveState = true;
                obj.direction = "s";
                speed.y = 3;
            }
        }
        rocker.x = X;
        rocker.y = Y;
    })

    this.getSpeed = function(){
        return speed;
    }
}
           

繼續閱讀