Laya air 之實現按鈕控制人物驅動模塊

國際慣例,先上效果圖:

一、場景佈置:

ok,下面將介紹如果實現搖桿操作物體,在這裏我會創建一個res的文件夾用來存放這三張圖:

創建一個but節點掛到場景節點下,分別將內圓和外圓的圖片掛載到該節點下,更名爲out_cricle和in_cricle,再將飛機的圖片掛到與but節點同級的節點下並更名爲obj,然後全部轉換類型爲image類型,並全部設置錨點爲0.5的位置:

Ok,場景基礎就這樣:

 

  • 編寫代碼組件:

去到代碼編輯器界面,在src下創建一個scprit的文件夾,再創建一個名爲but的typescript代碼模板,將組件掛到but節點下:

在but.ts中分別創建四個屬性:max_r(搖桿移動最大範圍)、min_r(搖桿移動最小範圍)、but(搖桿節點)、obj(移動的物體):

/** @prop {name:max_r, tips:"按鈕最大範圍", type:Int, default:90}*/

public max_r: number = 78;



/** @prop {name:min_r, tips:"按鈕最小範圍", type:Int, default:30}*/

public min_r: number = 40;



/** @prop {name:but, tips:"按鈕", type:Node, default:null}*/

public but: Laya.Node;



/** @prop {name:obj, tips:"物體", type:Node, default:null}*/

public obj: Laya.Node;



我這裏自己調整了下圖片大小,最大範圍設爲78,最小範圍爲40,接下來再定義三個變量:

private is_start:boolean = false;

private speed:number = 200;

private v:Laya.Point = Laya.Point.create();

(1)Is_start用於標識按鈕是否按下觸發了Laya.Event.MOUSE_DOWN事件,如果按鈕按下再(2)is_sart設置爲true.

(3)speed用來設置物體移動的速度

v用來存儲搖桿移動的位置信息,後面要賦給物體使用。

可能有的讀者有疑問:當物體觸發MOUSE_DOWN事件之後應該自動會切換到MOUSE_MOVE事件,爲什麼還要特地聲明一個變量來標記?

其實是因爲我們平時在操控搖桿的時候,搖桿必然會移動到搖桿的範圍之外去,但是如果觸碰到了外面,搖桿節點就會一直卡死在最後的位置,導致物體不停按最後給的觸碰信息進行移動:

所以爲了解決這個問題,我們將MOUSE_MOVE和MOUSE_UP事件全用Laya.stage來監聽,搖桿本身來監聽MOUSE_DOWN:

this.but.on(Laya.Event.MOUSE_DOWN,this,this.but_down);

Laya.stage.on(Laya.Event.MOUSE_MOVE,this,this.but_move);

Laya.stage.on(Laya.Event.MOUSE_UP,this,this.but_up);

然後分別創建三個監聽返回的回調用函數:but_down、but_move、but_up,接下來就是寫組件的基本邏輯:

  1. 按鈕按下:is_start標記爲true,表示開始移動。
  2. 按鈕移動:將移動返回的觸碰信息保存到變量,後面用來驅動物體移動,判斷搖桿是否超出規定範圍,如果超過再限定在圈內。
  3. 按鈕彈起:關閉is_start,按鈕返回原點位置。
  4. 重寫onUpdate()方法,將保存的變量拿出來做相關速度運算再賦給物體,之後通過Math.atan2()算出旋轉的信息,將弧度轉成角度賦給物體。

下面是全部代碼,註釋有詳細說明:

export default class but extends Laya.Script {

/** @prop {name:max_r, tips:"按鈕最大範圍", type:Int, default:90}*/

public max_r: number = 78;



/** @prop {name:min_r, tips:"按鈕最小範圍", type:Int, default:30}*/

public min_r: number = 40;



/** @prop {name:but, tips:"按鈕", type:Node, default:null}*/

public but: Laya.Node;



/** @prop {name:obj, tips:"物體", type:Node, default:null}*/

public obj: Laya.Node;



private is_start:boolean = false;

private speed:number = 200;

private v:Laya.Point = Laya.Point.create();



constructor() { super(); }

onAwake(){



this.but.on(Laya.Event.MOUSE_DOWN,this,this.but_down);

Laya.stage.on(Laya.Event.MOUSE_MOVE,this,this.but_move);

Laya.stage.on(Laya.Event.MOUSE_UP,this,this.but_up);

}



but_down(e){

if(this.is_start == true){

return;

}



this.is_start = true;

}



but_move(e){

if(this.is_start ==false){

return;

}



//因爲要使用x、y座標相關方法,將搖桿節點和but節點轉爲Laya.Sprite

var node:Laya.Sprite = this.owner as Laya.Sprite;

var but_node:Laya.Sprite = this.but as Laya.Sprite;



//創建一個Laya.Point的變量存儲在鼠標移動後全局返回的x、y座標,將這個座標轉到組件所在節點的局部座標系下

var mouse_pos:Laya.Point = Laya.Point.create();

mouse_pos.x = Laya.MouseManager.instance.mouseX;

mouse_pos.y = Laya.MouseManager.instance.mouseY;

node.globalToLocal(mouse_pos);



//算出x、y到原點的距離,算出sin(x)和cos(y)的比例係數

//得到一個固定值,再使用上面聲明的變量v來存儲轉完後的信息:

var length = mouse_pos.distance(0,0);

this.v.x = mouse_pos.x / length;

this.v.y = mouse_pos.y / length;



//判斷是否超出搖桿最大範圍

if(length > this.max_r){

mouse_pos.x = mouse_pos.x * this.max_r / length;

mouse_pos.y = mouse_pos.y * this.max_r / length;

}//判斷是否超出搖桿最小範圍

else if(length < this.min_r){

but_node.pos(mouse_pos.x,mouse_pos.y);

return;

}



but_node.pos(mouse_pos.x,mouse_pos.y);



}



but_up(e){

if(this.is_start == false){

return;

}

var but_node:Laya.Sprite = this.but as Laya.Sprite;

var obj_node:Laya.Sprite = this.obj as Laya.Sprite;

but_node.pos(0,0); //搖桿彈起返回原點位置



this.is_start = false; //關閉監聽狀態

this.v.x = 0;

this.v.y = 0;

}



onUpdate(){

if(this.v.x == 0 && this.v.y == 0){

return;

}

var dt = Laya.timer.delta / 1000;

var obj_node:Laya.Sprite = this.obj as Laya.Sprite;



//給物體賦x、y的移動信息

obj_node.x += (this.v.x * this.speed) * dt;

obj_node.y += (this.v.y * this.speed) * dt;



var rot:number = 180 / Math.PI;

var deg:number = Math.atan2(this.v.y,this.v.x);

//給物體賦x、y的旋轉信息

obj_node.rotation = rot * deg + 90 ;

}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章