Laya Stage
舞臺是顯示游戲元素的平臺,在游戲視覺編程中,一切游戲的元素必須添加到舞臺才能被顯示。因此,舞臺是放置對象的最終容器。舞臺自身也是一種可以顯示的對象,從編程角度來講,任何對象都具有屬性和行為。
- 舞臺提供適配模式,不同適配模式產生不同大小的畫布,畫布越大渲染壓力越大。
- 舞臺提供不同的幀率模式,幀率越高渲染壓力越大,也越耗電。
環境
- 操作系統:Windows10
- 引擎版本:LayaAir2.2.0beta4
- 編程語言:ES6
舞臺
Laya是全局對象的引入入口類,Laya類引用常用全局對象。舞臺可通過 Laya 類的 stage 屬性 Laya.stage 單例訪問。
| Laya.stage | 單例訪問,獲取舞臺 laya.display.Stage 對象的引用。 |
Laya.stage 是 Laya 全局類的屬性,是使用單例訪問 laya.display.Stage 舞臺類的對象,舞臺類是顯示列表的根節點,所有顯示對象都在舞臺上顯示。
| Package | laya.display |
| Class | Laya.Stage |
| Inheritance | Stage / Sprite / Node / EventDispatcher / Object |
初始化引擎
Laya.init()初始化引擎,使用引擎前需要先初始化引擎,否則可能會報錯。
$ vim ./libs/LayaAir.d.ts /* * 初始化引擎。使用引擎需要先初始化引擎,否則可能會報錯。 * @param width 初始化的游戲窗口寬度,又稱設計寬度。 * @param height 初始化的游戲窗口高度,又稱設計高度。 * @param plugins 插件列表,比如 WebGL(使用WebGL方式渲染)。 * @return 返回原生canvas引用,方便對canvas屬性進行修改 */ static init(width:number,height:number,...plugins:any[]):any;例如:根據IDE設置初始化引擎
if (window["Laya3D"]){Laya3D.init(GameConfig.width, GameConfig.height); }else{Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]); }例如:使用默認的Canvas渲染引擎
//創建舞臺,尺寸以iPhone5寬高1136x640為基準,16:9標準。 const width = 1136; const height = 640; const canvas = Laya.init(width, height); console.log(Laya.stage.width, Laya.stage.height);//1136 640 console.log(convas);// <canvas id="layaCanvas" width="1136" height="640" style="position: absolute; left: 0px; top: 0px; background: rgb(35, 35, 142); transform-origin: 0px 0px 0px; transform: matrix(0.5, 0, 0, 0.5, 0, 0);"></canvas>例如:使用WebGL渲染引擎
注意使用WebGL渲染引擎時,需要在項目中提前將laya.webgl.js類庫導入,在編輯模式下使用【F9】打開項目設置,勾選類庫設置中的laya.webgl.js。
//創建舞臺,尺寸以iPhone5寬高1136x640為基準,16:9標準。 const width = 1136; const height = 640; const webgl = Laya.init(width, height, Laya.WebGL); console.log(webgl);寬高
LayaAir中的寬高可以分為以下幾種類型:
| Laya.Stage.width / Laya.Stage.height | 舞臺實際寬高 |
| Laya.Stage.designWidth / Laya.Stage.designHeight | 舞臺設計寬高 |
| Laya.Browser.clientWidth / Laya.Browser.clientHeight | 設備屏幕寬高 |
| Laya.Browser.width / Laya.Browser.height | 設備物理寬高 |
設計寬高
設計分辨率是內容產生者在制作場景時使用的分辨率藍本,屏幕分辨率則是游戲在設備上運行時的實際屏幕顯示分辨率。通常設計分辨率會采用市場目標群體中使用率最高的設備的屏幕分辨率,比如目前在Android設備中 800 x 400和1280 x 720兩種屏幕分辨率,或iOS設備中1136 x 640和960 x640兩種屏幕分辨率。
設計寬高是LayaAir引擎初始化時設置的寬高
//引擎初始化 Laya.init(designWidth, designHeight); //獲取設計寬高 console.log(Laya.Stage.designWidth); console.log(Laya.Stage.designHeight);舞臺寬高
游戲舞臺實際大小的寬高
Laya.stage.width;Laya.stage.height;適配寬高
通過引擎適配模式scaleMode對設計寬高縮放后的寬高。
畫布寬高
HTML5中Canvas節點的寬高,游戲中所有可見內容都在畫布區域內。
早期的移動設備中,屏幕分辨率較低,比如iPhone3的分辨率為320 x 480,此時一個“像素”等于一個屏幕物理像素。隨著設備屏幕像素密度越來越高,從iPhone4開始Apple開始推出Retina屏,分辨率提高到了640 x 960,也就是說分辨率提高了一倍,但設備屏幕尺寸并沒有變化,這就意味著同樣面積大小的屏幕上,像素卻多了一倍,這提高的也就是設備像素比devicePixelRatio。
在LayaAir中可以通過Laya.Browser.pixelRatio獲取設備像素比。
//獲取設備像素比 const pixelRatio = Laya.Browser.pixelRatio;屏幕寬高
手機瀏覽器屏幕的寬高即設備像素分辨率 ,比如iPhone6豎屏寬高為376x667。
//獲取手機瀏覽器屏幕寬高 const clientWidth = laya.utils.Browser.clientWidth; //const clientWidth = Laya.Browser.clientWidth;const clientHeight = laya.utils.Browser.clientHeight; //const clientHeight = Laya.Browser.clientHeight;默認從Browser瀏覽器上獲得clientWidth和clientHeight并不是像素分辨率,而是經過縮放后的分辨率。如果想要獲得正確的像素分辨率,則需要在HTML文件中設置視區的寬度為設備寬度且不縮放。
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scale=no" />物理寬高
手機屏幕窗口的實際寬高,平時比較常用的一般是設備物理分辨率,它代表著瀏覽器窗口的實際分辨率。
//獲取手機屏幕窗口的實際寬高 //const browserWidth = laya.utils.Browser.width; const deviceWidth = Laya.Browser.width;//const browserHeight = laya.utils.Browser.height; const deviceHeight = Laya.Browser.height;例如:
//創建舞臺,尺寸以iPhone5寬高1136x640為基準,16:9標準。 const designWidth = 1136;//設計寬度 const designHeight = 640;//設計高度 const canvas = Laya.init(designWidth, designHeight); //設置縮放模式 //Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//最小比例縮放,縮放后全部都在屏幕內,但可能會出現黑邊。 Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;//最大比例縮放,縮放后全屏幕顯示無黑邊,但可能有部分顯示在屏幕外邊。//獲取設備像素比 const pixelRatio = Laya.Browser.pixelRatio; console.log(`pixelRatio = ${pixelRatio}`);//pixelRatio = 2 //獲取設備像素分辨率即屏幕寬高 const clientWidth = Laya.Browser.clientWidth; const clientHeight = Laya.Browser.clientHeight; console.log(`clientWidth = ${clientWidth}`, `clientHeight = ${clientHeight}`);//clientWidth = 667 clientHeight = 375 //獲取設備物理分辨率即物理寬高 const width = Laya.Browser.width; const height = Laya.Browser.height; console.log(`width = ${width}`, `height = ${height}`);//width = 1334 height = 750 LayaAir中的寬高對齊模式
| Laya.stage.alignH | 橫向水平對齊 |
| Laya.stage.alignV | 縱向垂直對齊 |
Laya.stage.alignH 舞臺橫向對齊 分為左中右
| Laya.stage.alignH = Laya.Stage.ALIGN_LEFT; | 設置舞臺水平居左對齊 |
| Laya.stage.alignH = Laya.Stage.ALIGN_CENTER; | 設置舞臺水平居中對齊 |
| Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT; | 設置舞臺水平居右對齊 |
Laya.stage.alignV 舞臺縱向對齊 分為上中下
| Laya.stage.alignV= Laya.Stage.ALIGN_TOP; | 設置舞臺垂直居上對齊 |
| Laya.stage.alignV= Laya.Stage.ALIGN_MIDDLE; | 設置舞臺垂直居中對齊 |
| Laya.stage.alignV= Laya.Stage.ALIGN_BOTTOM; | 設置舞臺垂直居下對齊 |
例如:設置舞臺或畫布水平居中顯示
class Test {constructor() {Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);this.initStage();this.run();}initStage(){this.setStageAlign("center", "middle");Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;Laya.stage.bgColor = "#000000";}setStageAlign(h, v){h = h.toLowerCase();if(h == "left"){Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;}else if(h == "center"){Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;}else if(h == "right"){Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;}v = v.toLowerCase();if(v == "top"){Laya.stage.alignV = Laya.Stage.ALIGN_TOP;}else if(v == "middle"){Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;}else if(v == "bottom"){Laya.stage.alignV = Laya.Stage.ALIGN_BOTTOM;}}run(){console.log(Laya.stage.width, Laya.stage.height);//414 736console.log(Laya.stage.clientWidth, Laya.stage.clientHeight);//undefined undefinedconsole.log(Laya.Browser.width, Laya.Browser.height);//1242 2208console.log(Laya.Browser.clientWidth, Laya.Browser.clientHeight);//414 736} } //啟動 new Test();屏幕模式
LayaAir可以根據瀏覽器顯示的比例設置自動橫屏或豎屏,不會受到鎖屏而影響。簡單來說,LayaAir的屏幕方向是智能適配設置的。改變LayaAir的屏幕方向并不會改變操作系統的的屏幕方向,因此LayaAir的屏幕方向不會受到操作系統屏幕方向的影響。
| Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL; | 自動橫屏 |
| Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL; | 自動豎屏 |
- 設置自動橫屏后,游戲的方向會始終與舞臺較長的邊保持垂直。
- 設置自動豎屏后,游戲的方向會始終與舞臺較短的邊保持垂直。
例如:使用新窗口打開,拖動改變瀏覽器尺寸查看自動橫屏效果。
class Test {constructor() {//初始化引擎Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);//初始化舞臺this.initStage();//運行this.run();}/**初始化舞臺*/initStage(){//設置舞臺對齊方式this.setStageAlign("center", "middle");//設置舞臺屏幕模式this.setStageScreen("horizontal");//設置舞臺縮放模式Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;Laya.stage.bgColor = "#000000";}/**設置舞臺屏幕模式 */setStageScreen(mode = "horizontal"){mode = mode.toLowerCase();if(mode == "horizontal"){Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;}else if(mode == "vertical"){Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL;}}/**設置舞臺對齊方式 */setStageAlign(h, v){h = h.toLowerCase();if(h == "left"){Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;}else if(h == "center"){Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;}else if(h == "right"){Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;}v = v.toLowerCase();if(v == "top"){Laya.stage.alignV = Laya.Stage.ALIGN_TOP;}else if(v == "middle"){Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;}else if(v == "bottom"){Laya.stage.alignV = Laya.Stage.ALIGN_BOTTOM;}}run(){console.log(Laya.stage.width, Laya.stage.height);//414 736console.log(Laya.stage.clientWidth, Laya.stage.clientHeight);//undefined undefinedconsole.log(Laya.Browser.width, Laya.Browser.height);//1242 2208console.log(Laya.Browser.clientWidth, Laya.Browser.clientHeight);//414 736console.log(Laya.stage.alignH, Laya.stage.alignV);//center middleconsole.log(Laya.stage.screenMode);//horizontal} } //啟動 new Test();縮放模式
舞臺提供不同的適配模式scaleMode,不同縮放模式下會產生不同的畫布大小,畫布越大,渲染壓力也就越大。
| Laya.stage.scaleMode = Laya.Stage.NOSCALE; | noscale | 不縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL; | showall | 最小比例縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_EXACTFIT; | exactfit | 全屏不等比縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER; | noborder | 無框縮放 最大比例縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_FULL; | full | 全屏縮放 舞臺寬高等于屏幕寬高 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_WIDTH; | fixedwidth | 寬度固定 寬度不變 高度根據屏幕比縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_HEIGHT; | fixedheight | 高度固定 高度不變 寬度根據屏幕比縮放 |
| Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_AUTO; | fixedauto | 自動選擇 根據寬高比自動使用fixedwidth或fixedheight |
例如:舞臺中心添加精靈圖,查看不同縮放模式下的效果。
//創建舞臺 const designWidth = 400;//設計寬度 const designHeight = 300;//設計高度 const canvas = Laya.init(designWidth, designHeight); //設置舞臺背景顏色 Laya.stage.bgColor = "black"; //設置舞臺水平對齊 Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;//水平居中 //設置舞臺垂直對齊 Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;//垂直居中 //設置舞臺縮放模式 Laya.stage.scaleMode = Laya.Stage.SCALE_EXACTFIT;//縮放顯示所有 //設置舞臺屏幕模式 Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;//自動橫屏//創建精靈 let sprite = new Laya.Sprite(); //精靈圖繪制黃色矩形 sprite.graphics.drawRect(-100, -100, 200, 200, "gray"); //向舞臺中添加精靈節點 Laya.stage.addChild(sprite); //設置精靈在舞臺中的坐標位置 sprite.x = Laya.stage.width >> 1; sprite.y = Laya.stage.height >> 1;- SCALE_EXACTFIT 伸縮適應
Exact Fix模式是不考慮內容的原始比例,直接通過非等比縮放填滿整個瀏覽器屏幕的模式。在此種模式下,畫布寬高與舞臺寬高都等同于設計寬高,而且不會發生改變。但當物理寬高與設計寬高不相同時,這種非等比的縮放可能會導致原有設計明顯缺陷。
整個應用程序在指定區域中可見,但不嘗試保持原始寬高比,可能會發生扭曲,應用程序可能會拉伸或壓縮顯示。
SCALE_EXACTFIT
- SCALE_NOBORDER 無邊框
No Border無邊框模式下,畫布寬高等同于設計寬高。當縮放時,按照屏幕寬高與設計寬高最大比率的一方進行縮放。
比如設計尺寸為1136x640,屏幕物理寬高為750x1334,經過計算得到寬的比例為750/1136=0.66,高的比例1334/640=2.08,按照最大比例一方將適配拉伸至物理高度的1334,適配寬度等比拉升 1334/640*1136=2368,此時超出屏幕寬度的部分將會被自動裁剪掉。
整個應用程序填滿指定區域,不會發生扭曲,但有可能進行一些裁剪,同時保持應用程序的原始寬高比。
- SCALE_NOSCALE 不縮放
No Scale不縮放模式下,畫布與舞臺的寬高等同于設計寬高,并在保持1:1原始設計比例的基礎上,將舞臺與瀏覽器屏幕左上角對齊。當屏幕寬高小于內容時將進行裁切,當屏幕寬高大于內容時則會出現黑邊。
整個應用程序大小固定,即使播放器窗口大小更改,應用程序也會保持不變。如果播放器窗口比內容小,則可能進行裁剪。
- SCALE_SHOWALL 顯示所有
Show All顯示所有模式下,舞臺與畫布的寬高等同于縮放后的適配寬高,縮放按照屏幕寬高與設計寬高最小比率一方進行等比縮放。
比如設計尺寸為1136x640,屏幕物理寬高為750 x 1334,通過計算得到寬的比率為 750 / 1136 = 0.66,高的比率為 1334 / 640 = 2.08。按照最小比率一方即寬為基準,畫布寬高會被縮放為屏幕的物理寬度750,適配高度經過等比縮放 750 / 1136 * 640 = 423,由于423遠遠小于屏幕物理高度1134,因此會出現大量留黑的空屏。
整個應用程序在指定區域中可見,不會發生扭曲,同時保持應用程序的原始寬高比,應用程序兩側可能會顯示邊框。
查看默認縮放模式
//創建舞臺,尺寸以iPhone5寬高1136x640為基準,16:9標準。 const width = 1136; const height = 640; const canvas = Laya.init(width, height); console.log(Laya.stage.scaleMode);//noscale設置縮放模式
//創建舞臺,尺寸以iPhone5寬高1136x640為基準,16:9標準。 const designWidth = 1136;//設計寬度 const designHeight = 640;//設計高度 const canvas = Laya.init(designWidth, designHeight); //設置縮放模式 Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//最小比例縮放,縮放后全部都在屏幕內,但可能會出現黑邊。 //Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;//最大比例縮放,縮放后全屏幕顯示無黑邊,但可能有部分顯示在屏幕外邊。 console.log(Laya.stage.scaleMode);//showall自動計算
Laya.stage.autoSize = false;由于Stage舞臺類繼承自Sprite精靈類,Sprite精靈類提供了autoSize屬性,用于指定是否自動計算寬高數據,默認為 false。默認Sprite精靈寬高為0,不會隨著繪制內容的變化而變化。如果想要根據繪制內容獲取寬高,可以設置autoSize=true,或者通過getBounds()方法獲取。不過開啟autoSize后會對性能有一定影響。
幀率類型
Laya.stage.frameRate = Laya.Stage.FRAME_SLOW;Laya 的 Stage 舞臺類提供了 frameRate 存取器,用于獲取和設置舞臺的幀率類型。
| Laya.Stage.FRAME_FAST | string | fase | 全速模式,以60FPS的幀率運行。 |
| Laya.Stage.FRAME_SLOW | string | slow | 慢速模式,以30FPS的幀率運行。 |
| Laya.Stage.FRAME_MOUSE | string | mouse | 自動模式,以30FPS的幀率運行,鼠標活動后會自動加速到60FPS,鼠標不動2秒后降低為30FPS,以節省性能。 |
| Laya.Stage.FRAME_SLEEP | string | sleep | 休眠模式,以1FPS的幀率運行。 |
FPS是畫面每秒傳輸幀數(Frames Per Second),是指動畫或視頻的畫面數(幀數)。FPS是用測量用于保存、顯示動態視頻的信息數量,秒條幀數越多所顯示的動作就越流暢。通常要避免動作不流程的最低FPS是30。
FPS可理解為刷新率,單位Hz,比如裝機選購顯卡和顯示器時默認刷新率都在75Hz以上,75Hz的刷新率表示屏幕1秒內掃描75次。當刷新率太低時肉眼會感覺到屏幕閃爍且不連貫,對圖像顯示效果和視覺感觀不好。
電影以每秒24張畫面的速度播放,一秒內在屏幕上連續投射出24張靜止畫面。游戲中一般人能接受的最低FPS為30Hz,基本流暢等級則需要高于50Hz。
常見媒體的FPS幀率
| 電影 | 24FPS |
| 電視 PAL | 25FPS |
| 電視 NTSC | 30FPS |
| CRT 顯示器 | 75Hz |
| 液晶顯示器 | 60Hz |
顯示分辨率不變的情況下,FPS刷新率越高對顯卡的處理能力要求越高,計算機中所顯示的畫面都是由顯卡輸出的,屏幕上每個像素的填充都是由顯卡計算輸出的,當畫面的分辨率為1024 x 768 時,畫面的刷新率達到 24FPS,顯卡在一秒鐘內需要處理的像素就需要達到 1024 x 768 x24 = 18874368。FPS與分辨率和顯卡處理能力的關系:顯卡處理能力 = 分辨率 x 刷新率。
當前PC與手機等移動設備的滿幀為60幀,如果游戲對畫面的流暢度要求不高可采用Laya引擎的幀數限制方法Laya.Stage.FRAME_SLOW將FPS幀數限制為最高30幀。
Laya項目由于實際運行環境是在瀏覽器中,所以性能還取決于JavaScript解釋器的效率,對此同一款游戲的FPS在不同的瀏覽器中可能會存在不同的差異。這部分不是開發者能夠決定的,開發者能作的盡可能使用更好的引擎和游戲項目,爭取在低端設備和低性能瀏覽器中提升FPS幀率。
Laya引擎支持Canvas和WebGL兩種渲染模式,因此在查看FPS幀率時需要注意當前引擎在哪種渲染模式下。
封裝
TypeScript封裝舞臺工具類
/*** 舞臺工具類*/ export default class Stage{//單例模式private static _instance:Stage;public static getInstance():Stage{if(!this._instance){this._instance = new Stage();}return this._instance;}private constructor(){}/*** 舞臺初始化*/init(width:number=1334, height:number=750, isWebGL:boolean=false, isStat:boolean=false):void{//引擎渲染方式if(isWebGL){Laya.init(width, height, Laya.WebGL);//指定WebGL}else{Laya.init(width, height);//默認Canvas}//是否顯示統計信息if(isStat){Laya.Stat.show();}//自動計算Laya.stage.autoSize = false;//開啟后影響性能//幀率類型Laya.stage.frameRate = Laya.Stage.FRAME_SLOW;//30幀//對齊方式Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;//水平居中Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;//垂直居中//屏幕模式Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;//橫屏//縮放模式Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_AUTO;//背景顏色Laya.stage.bgColor = "#808080";} }總結
以上是生活随笔為你收集整理的Laya Stage的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: acdream 1725 哗啦啦的小彭玉
- 下一篇: 外贸企业邮箱如何撤回已发送的邮件,发错的