Laya Base

开发环境

  • 操作系统:Windows10
  • 游戏引擎:LayaAir2.2.0beta4
  • Web服务器:Node.js的http-server
  • 编程语言:ES6

检查是否安装Node.js环境,若没有则进入 https://nodejs.org/en/ 下载安装。

$ npm -h

使用npm全局安装HTTP服务器

$ npm i -g http-server

进入项目目录运行HTTP服务器

$ cd laya_project_name
$ http-server ./

浏览器输入网址http://127.0.0.1:8080/bin/index.html运行


使用npm命令安装TypeScript环境

$ npm i -g typescript

缓存清理

$ npm cache clean --force

查看TypeScript编译环境版本(tsc, TypeScript Compiler)

$ tsc -v

快速入门

需求:创建项目新建舞台并向舞台中添加带样式的文本

实现
  1. 进入项目src目录下新建App.js
$ cd demo
$ http-server ./
$ vim ./src/App.js
  1. 进入项目根目录下的.laya文件夹,修改compile.js编译文件,重新设置项目默认的启动文件,设置前默认为src/Main.js
$ vim ./.laya/compile.js
input: workSpaceDir + '/src/App.js',//默认第33行

3.编辑默认启动文件实现功能

$ vim ./src/App.js
//创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
const width = 1136;
const height = 640;
Laya.init(width, height);
//设置舞台背景色,默认不设置时背景为黑色。
Laya.stage.bgColor = "#23238e";
//创建文本
const txt = new Laya.Text();
txt.text = "Hello World";//文本内容
txt.color = "#ff0000";//文本颜色
txt.fontSize = 66;//文本字体大小,单位像素。
txt.stroke = 5;//文本描边宽度,单位像素。
txt.strokeColor = "#ffffff";//文本描边颜色
txt.bold = true;//文本是否粗体显示
txt.pos(width/2 - txt.fontSize/2 * txt.text.length/2, height/2 - txt.Size);//文本位置,在舞台的二维坐标。
//将文本添加到舞台
Laya.stage.addChild(txt);
  1. 选择Chrome调试,F8编译文件后使用浏览器访问http://127.0.0.1:8080/bin/index.html,并使用Shift+F5强制刷新,查看效果。

文件结构

项目目录结构

  • .laya 项目运行配置文件夹,存放项目在开发运行中的配置信息。
  • bin 项目的输出目录,存放当前项目的输出文件。
  • laya 项目的UI项目目录,存放LayaAirIDE当前的UI项目。
  • libs .d.ts代码提供文件目录,是LayaAir引擎LayaAir.d.ts文件。用来代码提示,第三方类库相关的.d.ts文件存放位置。
  • src 项目代码目录

项目配置文件 项目名称.laya

项目名称.laya 项目配置文件,记录当前项目的项目名称、使用类库版本、项目类型。

{
    "proName":"myLaya",
    "engineType":0,
    "proType":2,
    "layaProType":0,
    "version":"2.1.0"
}

语言类型config.json 对应语言的工程配置文件,比如tsconfig.json

项目配置目录.laya

  • publish.js 文件时GULP针对项目发布的脚本文件
  • compile.js 文件是GULP自定义编译流程的脚本文件,若开发者对GULP熟悉可修改。
  • launch.json 文件保存项目调试的配置信息,分别是LayaAirIDE调试配置和Chrome浏览器调试配置。
# 表示使用LayaAirIDE内置的调试方式
"name": "layaAir",
# 表示使用Chrome浏览器调试
"name": "chrome调试",
# 表示项目以运行启动的入口文件路径
"file": "${workspaceRoot}/bin/index.html",
# 表示Chrome浏览器的路径
"runtimeExecutable": "${execPath}",
# 表示Chrome调试缓存的临时目录,默认为用户的临时目录,开发者可以更改设置。
"userDataDir": "${workspaceRoot}/.laya/chrome",
  • tasks.json 文件保存TS编译器相关配置信息

项目输出目录bin

bin目录是项目输出文件夹,存放当前项目输出的JS、HTML、游戏资源等项目运行文件,以及小游戏项目文件。默认LayaAir调试或Chrome调试,就是运行该目录下的文件。

  • index.html 项目入口文件,所有LayaAir引擎库或第三方类库的JS都需从这里引入。
  • bin\libs 文件夹存放的是LayaAir引擎各模块的JS文件

bin\libs 引擎库文件夹存放是LayaAir引擎各模块的JS文件,在项目中需要使用哪个模块就需要在index.html文件中引入对应的模块包JS文件。

  • laya.core 核心包,封装了显示显示对象渲染、事件、时间管理、时间轴动画、缓动、消息互动、Socket、本地存储、鼠标触摸、声音、加载、颜色滤镜、位图字体等。
  • laya.webgl 包封装了WebGL渲染管线,使用WebGL渲染可在初始化时调用Laya.init(1000, 800, laya.webgl.WebGL)
  • laya.ani.js 动画模块包括SWF动画、骨骼动画等
  • laya.filter.js WebGL滤镜
  • laya.html.js 封装了HTML动态排版功能
  • laya.ui.js 提供制作UI的各种组件实现
  • laya.tilemap.js 提供TileMap解析支持

项目资源目录 laya

laya用于存放UI项目的文件夹

  • .laya文件是LayaAirIDE的UI项目配置文件
  • laya\assets文件夹用于存放UI页面、粒子等组件所需的图片、音频等资源
  • laya\pages文件夹用于存放LayaAirIDE创建原页面布局比如场景、动画、预设等生成的配置文件

代码提示目录 libs

libs文件夹是LayaAir引擎LayaAir.d.ts文件,用于代码提示,若存在第三方类库使用,相关的.d.ts文件会保存在文件夹下。

项目开发源代码目录 src

src/ui/目录是IDE自动生成的,

基础概念

舞台Stage

  • 舞台stage是显示游戏元素的平台,在游戏视觉编程中,一切游戏的元素必须添加到舞台才能被显示。因此,舞台是放置对象的最终容器。
  • 舞台自身也是一种可以显示的对象,从编程角度来讲,任何对象都具有属性和行为。
  • 舞台类,可通过Laya.stage单例访,是显示列表的根节点,所有显示对象都在舞台上显示。
  • 舞台提供适配模式,不同适配模式产生不同大小的画布,画布越大渲染压力越大。
  • 舞台提供不同的帧率模式,帧率越高渲染压力越大,也越耗电。

显示对象

一切在舞台上可见的东西都可以称为显示对象,显示对象即包括可见的图形、文字、图片 、视频,也包括不可见的音频、显示对象容器等。

显示列表

显示对象在舞台上显示之前,还需一个过程,就是先添加到显示列表中。

显示列表的作用就是将显示对象进行数据索引,用于层级的显示顺序,然后在舞台上显示。

场景Scene

  • Laya游戏开发中是由一个个的场景所组成的
  • Laya引擎加载运行显示场景
  • 场景中由一个个物体
  • 新建场景需设置场景尺寸和名字
  • 层级视图用来查看场景中的节点
  • 视图中的每个图标表示不一样的类型
  • 场景文件保存在/laya/pages/文件夹下
  • 场景文件的后缀为.scene

创建场景

  1. 新建场景
  2. 配置设计分辨率
  3. 场景大小与设计分辨率保持一致
  4. 配置适配策略

设计分辨率

设计分辨率是内容产生者在制作场景时使用的分辨率蓝本,而屏幕 分辨率则是游戏在设备上运行时的实际屏幕显示分辨率。通常设计分辨率会采用市场目标群体中使用率最高的设备的屏幕分辨率,比如目前在Android设备中 800 x 4001280 x 720两种屏幕分辨率,或iOS设备中1136 x 640960 x640两种屏幕分辨率。

适配策略

  • 策略:横屏horizontal、固定高度fixedheight、设计宽度1136、设计高度640
  • 注意:场景适配模式选择固定高度fixedheight,设计宽度与设计高度与场景的的宽度和高度保持一致。
  • 操作:使用快捷键 F9打开 项目设置 ,也可选择菜单中 文件 > 项目设置
场景适配参数

节点

  • 场景中的元素都叫做节点
  • 节点在场景内,节点按照树型关系来进行组织。
  • Laya定义的节点类型和预先定义的特定功能的节点类型,在Basics下面。
  • 父节点与子节点

编辑器

  • 位置平移:x/y相对坐标,相对于父节点坐标,场景的原点位于左上角。
  • 大小改变:width/height
  • 节点旋转:rotation 子节点会跟着父节点一起旋转
  • 节点缩放:scaleX/scaleY 子节点也会跟着父节点一起缩放
  • 节点的中心位置:pivotX/pivotY 2D物体的中心点,子节点以父节点的左上角为原点。
  • 节点的锚点 anchorX/anchorY 锚点的左上角坐标为(0,0),锚点的右下角坐标为(1,1)。
  • 节点的透明度:alpha
  • 扭曲:skewX/skewY
旋转缩放

脚本

Laya2.0 IDE采用挂载组件脚本与场景管理的方式进行开发,在IDE中编辑场景和页面组件,通过添加脚本的方式,使项目开发更利于程序、美术、策划的协同工作,并对初次接触Laya的开发者更易于上手且开发方式更加友好。

  • 组件化开发

创建脚本

  1. 新建组件类
  2. 创建组件类实例到节点,一个节点可添加多个组件实例。
  3. 脚本的注册

操作流程

  1. 打开LayAir2,新建项目选择空项目,编程语言选择JavaScript。
  2. 选择编辑模式,新建场景命名为Game,宽度设置为1136,高度设置为940。
  3. 点击快捷键F9打开项目设置,选择预览设置,选择场景适配模式为fixedheight,设计宽度设置为1136,设计高度设置为940。
  4. 选择代码模式,选择src右键新建模板文件,选中新建脚本文件,命名为GameMgr.js
  • 创建脚本组件类的模板,继承自Laya.Script类。
  • 为节点添加组件并找个定义的脚本类,编辑器会创建类的实例到节点上。
  • 在游戏配置GameConfig.js中注册定义的组件类
export default class GameMgr extends Laya.Script {

    constructor() { 
        super(); 
        /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
        let intType = 1000;
        /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
        let numType = 1000;
        /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
        let strType = "hello laya";
        /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
        let boolType = true;
        // 更多参数说明请访问: https://ldc2.layabox.com/doc/?nav=zh-as-2-4-0
    }
    
    onEnable() {
    }

    onDisable() {
    }
}

5.进入编辑模式,在场景中添加精灵Sprite,为精灵添加组件中code中的GameMgr
6.进入代码模式,选择src目录下的GameConfig.js游戏配置文件,在配置文件中注册刚才创建的GameMgr组件。

import GameMgr from "./GameMgr"
export default class GameConfig {
    static init() {
        //注册Script或者Runtime引用
        let reg = Laya.ClassUtils.regClass;
        reg("GameMgr.js",GameMgr);
    }
}

挂脚本的原则

  1. 脚本要控制哪个节点,就挂在哪个节点上。
  2. 如果是全局的管理类,一般都会挂到根节点上。

runtime的作用

LayaAir IDE的资源面板中所有组件均带有runtime属性,runtime属性是组件运行时的逻辑类,相同组件可使用同一个runtime类来实现相同的功能。需要注意的是组件的runtime逻辑类如果不继承组件自身,若继承的对象中没有该组件的属性时,runtime属性则会失效,另外runtime不支持在view页面 和dialog对话框场景中使用。

组件固定入口

引擎的运行过程

  1. 引擎加载场景
  2. 引擎获取场景中的每个节点
  3. 由节点获取每个组件实例
  4. 特定时机引擎调用组件实例特定入口

组件实例的固定入口被引擎调用

  • onAwake虚方法,组件被激活后执行,此时所有节点和组件均已创建完毕。此方法只会执行一次,使用时需重写覆盖即可。
  • onDestroy虚方法,手动调用节点销毁时执行,使用时重写覆盖即可。
  • onDisable虚方法,组件被禁用时执行,比如节点从舞台移除后触发,使用时重写覆盖即可。
  • onEnable 虚方法,组件被启用后执行,比如节点被添加到舞台后触发,使用时重写覆盖即可。
  • onStart 虚方法,组件第一次执行update之前时执行,只会执行一次,使用时重写覆盖即可。
  • onUpdate 每帧更新时执行,使用时重写覆盖即可。
  • onLateUpdate每帧更新时执行,在update之后执行,使用时重写覆盖即可。

例如:

$ vim GameMgr.js
export default class GameMgr extends Laya.Script {

    constructor() { 
        super(); 
        /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
        let intType = 1000;
        /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
        let numType = 1000;
        /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
        let strType = "hello laya";
        /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
        let boolType = true;
    }
    
    onEnable() {
    }

    onDisable() {
    }
    
    //虚方法,仅执行一次,组件被激活后执行此时所有节点和组件均已创建完毕。
    onAwake(){        
        //需设置组件的name属性
        console.log(this.owner.name);
        console.log("onAwake");
    }
    //虚方法,手动调用节点销毁时执行。
    onDestroy(){
        console.log("onDestroy");
    }
    //虚方法,仅执行一次,第一次执行update之前执行。
    //所有节点的onAwake调用完毕后才会调用onStart。
    onStart(){
        console.log("onStart");
    }
    //虚方法,每次刷新时调用
    onUpdate(){
        //console.log("onUpdate");
    }
    //虚方法,每次刷新发生在Update之后。
    onLateUpdate(){
        //console.log("onLateUpdate");
    }
}
组件固定入口

帮助文档

  • 代码中查看引擎类的接口

使用快捷键F12代码模式中查看类的定义

F12转到定义

例如:laya.components.Script继承自Laya.components.Component

  • API文档中查看接口说明

接口文档地址:http://layaair2.ldc2.layabox.com/api/

API文档中查看接口说明
  • 通过查看代码API找到组件实例所依附的节点

ES6新特性

  • import/export导入导出代码模块
export default class GameMgr extends Laya.Script {}
import GameMgr from "./GameMgr"
  • pakcage代码包的概念
    不同开发者之间编写代码,可能会发生命令冲突,定义包可以以包名.类名的形式确定其类型。
declare module laya.components {
  class Script extends laya.components.Component  {}
}

日志输出

  • 打印输入日志使用console.log
  • Laya游戏配置文件中开启调试
$ vim src/GameConfig.js
GameConfig.debug = true

当游戏配置开启调试后,Laya会开启调试视图。

$ vim src/Main.js
//打开调试面板(通过IDE设置调试模式,或者url地址增加debug=true参数,均可打开调试面板)
if (GameConfig.debug || Laya.Utils.getQueryString("debug") == "true") Laya.enableDebugPanel();

点击F5调试

出问题了
  • Laya场景背后的节点树分布
    舞台:所有场景的根节点
    root:场景的父节点
    场景:场景节点,场景中的物体都是场景的子节点。

显示对象

Laya显示对象在laya.display类中

Laya的显示对象可分为

  • 节点:laya.display.Node
  • 精灵:laya.display.Sprite 继承自 laya.display.Node
  • 场景:laya.display.Scene 继承自 laya.display.Sprite
  • 舞台:laya.display.Stage 继承自 laya.display.Sprite
  • 文本:laya.display.Text 继承自 laya.display.Sprite

游戏配置

  • GameConfig.js编译时会自动生成,无需人为修改。
  • 编写的脚本文件可放在src中的下级目录中,编译时可自动在GameConfig.js中注册脚本。
$ vim src/GameConfig.jsj
import GameMgr from "./game/GameMgr";
export default class GameConfig {
    static init() {
        //注册Script或者Runtime引用
        let reg = Laya.ClassUtils.regClass;
        reg("game/GameMgr.js", GameMgr);
    }
}
  • 调试窗口的显示可使用F9项目设置中的选项来控制
项目设置

组件访问节点属性

  • 代码组件中的this指的是组件实例
$ vim src/GameMgr.js
export default class GameMgr extends Laya.Script {

    constructor() { 
        super(); 
        /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
        let intType = 1000;
        /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
        let numType = 1000;
        /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
        let strType = "hello laya";
        /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
        let boolType = true;
    }
    
    onEnable() {
    }

    onDisable() {
    }
    
    //虚方法,仅执行一次,组件被激活后执行此时所有节点和组件均已创建完毕。
    onAwake(){
        console.log(this.owner.name);
        console.log("onAwake");
    }
    //虚方法,手动调用节点销毁时执行。
    onDestroy(){
        console.log("onDestroy");
    }
    //虚方法,仅执行一次,第一次执行update之前执行。
    //所有节点的onAwake调用完毕后才会调用onStart。
    onStart(){
        //this表示当前组件实例,this.owner是组件实例所在的节点对象。
        console.log("onStart", this.owner);
    }
    //虚方法,每次刷新时调用
    onUpdate(){
        //console.log("onUpdate");
    }
    //虚方法,每次刷新发生在Update之后。
    onLateUpdate(){
        //console.log("onLateUpdate");
    }
}
  • 根据当前组件实例可以找到对应的节点,也可在代码中使用组件实例.owner来获取。
  • 组件实例.ownerlaya.display.Node节点对象
  • 所有场景中的节点对象都继承自laya.display.Node,所有场景中的元素继承自laya.display.Sprite

节点属性

所有场景组件都继承自Sprite,所以组件的属性都会在Sprite对象中。

  • 名字:this.owner.name获取节点名字,属于laya.display.Node类的成员。
  • 位置:this.owner.xthis.owner.y属于laya.display.Sprite类的成员。
  • 大小:this.owner.widththis.owner.height属于laya.display.Sprite类的成员。
  • 旋转:this.owner.rotation旋转的单位是度,属于laya.display.Sprite类成员。
  • 缩放:this.owner.scaleXthis.owner.scaleY属于laya.display.Sprite类成员。
  • 扭曲:this.owner.skewXthis.owner.skewY属于laya.display.Sprite类成员。
  • 可见度:this.owner.visible属于laya.display.Sprite类成员。
  • 透明度:this.owner.alpha属于laya.display.Sprite类成员。
  • 中心点:this.owner.pivotXthis.owner.pivotY属于laya.display.Sprite类成员。
$ vim src/GameMgr.js
export default class GameMgr extends Laya.Script {

    constructor() { 
        super(); 
        /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
        let intType = 1000;
        /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
        let numType = 1000;
        /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
        let strType = "hello laya";
        /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
        let boolType = true;
    }
    
    onEnable() {
    }

    onDisable() {
    }
    
    //虚方法,仅执行一次,组件被激活后执行此时所有节点和组件均已创建完毕。
    onAwake(){
        console.log(this.owner.name);
        console.log("onAwake");
    }
    //虚方法,手动调用节点销毁时执行。
    onDestroy(){
        console.log("onDestroy");
    }
    //虚方法,仅执行一次,第一次执行update之前执行。
    //所有节点的onAwake调用完毕后才会调用onStart。
    onStart(){
        //this表示当前组件实例,this.owner是组件实例所在的节点对象。
        console.log("onStart", this.owner);
        //节点属性
        var owner = this.owner;
        //节点名称
        console.log(owner.name); 
        //节点位置
        console.log(owner.x, owner.y);
        //节点大小
        console.log(owner.width, owner.height);
    }
    //虚方法,每次刷新时调用
    onUpdate(){
        //console.log("onUpdate");
    }
    //虚方法,每次刷新发生在Update之后。
    onLateUpdate(){
        //console.log("onLateUpdate");
    }
}

通过节点获取组件

  • getComponent(class:any)获取组件实例
$ vim GameMgr.js

定义GameMgr和PlayerMgr脚本,均添加到同一个节点组件上作为代码组件。在GameMgr代码节点上通过getComponent方法获取指定的代码组件。

import PlayerMgr from "./PlayerMgr";

export default class GameMgr extends Laya.Script {

    constructor() { 
        super(); 
        /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
        let intType = 1000;
        /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
        let numType = 1000;
        /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
        let strType = "hello laya";
        /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
        let boolType = true;
    }
    
    onEnable() {
    }

    onDisable() {
    }
    //虚方法,仅执行一次,组件被激活后执行此时所有节点和组件均已创建完毕。
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    //虚方法,仅执行一次,第一次执行update之前执行。
    //所有节点的onAwake调用完毕后才会调用onStart。
    onStart(){
        //this表示当前组件实例,this.owner是组件实例所在的节点对象。
        console.log("onStart: "+this.owner.name);
        //获取当前节点上的代码组件,代码组件必须首先绑定到节点上,否则返回null。
        var player = this.owner.getComponent(PlayerMgr);
        console.log(player);//PlayerMgr {_id: 11, _indexInList: -1, _enabled: true, _awaked: true, owner: Scene, …}
        //调用对应代码组件的自定义方法
        player.test();//player manager test method
    }
}

如果同一个节点上具有多个相同类的组件实例则会返回最先查找到的

  • getComponents(class:any)获取满足条件的组件实例数组
onStart(){
    //this表示当前组件实例,this.owner是组件实例所在的节点对象。
    console.log("onStart: "+this.owner.name);
    //获取当前节点上的代码组件,代码组件必须首先绑定到节点上,否则返回null。
    var players = this.owner.getComponents(PlayerMgr);
    console.log(players);//Array(1) [PlayerMgr]
}
  • addComponent(type:new()=>any)使用代码添加组件到节点
onStart(){
    //this表示当前组件实例,this.owner是组件实例所在的节点对象。
    console.log("onStart: "+this.owner.name);
    //添加代码组件到当前组件
    var player = this.owner.addComponent(PlayerMgr);
    console.log(player)//PlayerMgr {_id: 14, _indexInList: -1, _enabled: true, _awaked: true, owner: Scene, …}
    player.test();//player manager run test method
}

编辑器绑定

  • 编辑器绑定对于脚本代码而言是注释/** */
  • 编辑器会解析注释中@prop并提取变量绑定到编辑器
/** @prop {name:“名字”, tip:"提示信息", type:数据类型, default:默认值}*/
  • 绑定到编辑器上的变量会称为类的数据成员
  • 编辑器绑定变量的数据类型支持两种分别是基本数据类型和场景节点类型,场景节点类型无需携带包名。

操作流程

  1. 创建标准空Laya项目
  • 创建Game.scene场景
  • 配置项目设置 编辑模式F9:固定高度 设计宽高与场景保持一致
  1. 创建标准Laya组件类并实例化组件到节点
  • src目录下创建game文件夹并添加脚本Game.js
  • 在游戏配置文件src/GameConfig.js中检查是否注册成功
  • 挂脚本 创建类的实例到节点并选择脚本需要控制的节点
  • 引擎运行时首先会加载场景获取场景树,通过场景树得到节点,通过遍历节点获取每个节点上的每个组件实例。
  • 根据场景的树形结构搭建场景,场景中节点具有父子关系。
  1. 组件代码如何绑定数据成员到编辑器
$ vim src/game/SceneMgr.js
constructor() { 
    super(); 
    /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
    let intType = 1000;
    /** @prop {name:numType, tips:"数字类型示例", type:Number, default:1000}*/
    let numType = 1000;
    /** @prop {name:strType, tips:"字符串类型示例", type:String, default:"hello laya"}*/
    let strType = "hello laya";
    /** @prop {name:boolType, tips:"布尔类型示例", type:Bool, default:true}*/
    let boolType = true;
}
编辑器绑定规则

编辑器绑定规则

/** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/

引擎运行时编辑器会去识别注释中的参数变量,找到@prop描述会将其绑定到编辑器。当加载场景运行时,会将组件实例的属性信息添加到组件实例的成员中。

通过注释@prop定义成员会绑定到编辑器,注意它不是 JS语法只是运行时的注释,因此是可以调整位置的。

$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    /** @prop {name:intType, tips:"整数类型示例", type:Int, default:1000}*/
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
    }
    onEnable() {
    }
    onDisable() {
    }
}
编辑器绑定规则

编辑器绑定的数据类型

  • 基本数据类型:IntNumberStringBool
  • 场景节点类型(无需带包名):NodeSpriteButton
$ vim game/Scene.js
export default class SceneMgr extends Laya.Script {
    /** @prop {name:speed, tips:"速度", type:Int, default:1000}*/
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        console.log("speed: "+this.speed);//200
    }
    onEnable() {
    }
    onDisable() {
    }
}

设置组件上的speed数值,若不设置值则输出值为 undeifned

设置组件上的数值

调试运行查看打印输出


打印输出

绑定场景节点类型

$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    /** @prop {name:speed, tips:"速度", type:Int, default:1000}*/
    /** @prop {name:btnStart,  tips:"开始按钮", type:Node, default:null}*/
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        console.log("speed: "+this.speed);//200
        console.log("btnStart: "+this.btnStart+" buttonName:"+this.btnStart.name);//btnStart: [object Object] buttonName:start
    }
    onEnable() {
    }
    onDisable() {
    }
}
绑定

运行调试查看输出

调试

编辑器绑定常用类型

查找节点

  1. 组件代码中如何查找节点
  • 根据脚本的固定入口,引擎的场景会从节点获取到组件实例,在特定时机执行组件实例的固定入口方法。
  • 在固定入口方法中的this表示当前组件实例所依附的节点

场景中查找节点

  • laya.display.Nodescene可获取节点所在的场景
  • laya.display.Nodeparent查找子节点的父节点
  • laya.display.NodenumChildren可获取子节点的数量
  • laya.display.Node_children可获取子节点的数组
  • laya.display.NodegetChildByName()根据节点名称获取场景中的子节点
  • laya.display.NodegetChildByAt(index)根据索引查找节点
  • laya.display.NodegetChildIndex()获取节点的索引值
$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        //当前当前自己的代码组件所在的节点
        console.log(this.owner);//Scene {_bits: 70, _children: Array(2), _extUIChild: Array(0), _parent: Sprite, name: "scene", …}
        //获取当前节点所在场景
        console.log(this.owner.scene);//Scene {_bits: 70, _children: Array(2), _extUIChild: Array(0), _parent: Sprite, name: "scene", …}
        //获取当前节点的父节点
        console.log(this.owner.parent);//Sprite {_bits: 70, _children: Array(1), _extUIChild: Array(0), _parent: Stage, name: "root", …}
        //获取子节点数量
        console.log(this.owner.numChildren);//2
        //根据子节点名称获取当前节点的子节点
        var player = this.owner.getChildByName("player");
        console.log(player);//Image {_bits: 6, _children: Array(1), _extUIChild: Array(0), _parent: Scene, name: "player", …}
        //获取子节点数组
        console.log(this.owner._children);//Array(2) [Image, Button]
        //根据子节点所在的索引查找
        console.log(this.owner.getChildAt(0));//Image {_bits: 6, _children: Array(1), _extUIChild: Array(0), _parent: Scene, name: "player", …}
        console.log(this.owner.getChildAt(1));//Button {_bits: 70, _children: Array(1), _extUIChild: Array(0), _parent: Scene, name: "start", …}
    }
    onEnable() {
    }
    onDisable() {
    }
}
  1. 代码中如何添加节点
  • laya.display.NodeaddChild添加单个子节点
  • laya.display.NodeaddChildren添加多个子节点

例如:在当前节点 下添加子节点

$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        //添加文本节点到当前节点下
        var txt = new Laya.Text();
        txt.color = "#ff0000";
        txt.label = "测试文本";
        txt.fontSize = 32;
        txt.text = "Blank";
        this.owner.addChild(txt);
    }
    onEnable() {
    }
    onDisable() {
    }
}

例如:同时添加多个节点

$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        //添加文本节点到当前节点下
        var txt = new Laya.Text();
        txt.color = "#ff0000";
        txt.fontSize = 32;
        txt.text = "测试文本";
        txt.x = 100;
        txt.y = 100;

        var text = new Laya.Text();
        text.color = "#ffffff";
        text.fontSize = 32;
        text.text = "测试文本2";
        text.x = 1000;
        text.y = 500;

        this.owner.addChildren(txt, text);
    }
    onEnable() {
    }
    onDisable() {
    }
}

Sprite

  • Laya中laya.display.Node处理的是场景树关系的对象,所有的Laya显示对象都继承自它。
  • Laya中laya.display.Sprite处理的场景中的位置、大小、缩放等信息,所有的Laya显示对象也都继承自它。
  • laya.display.Sprite是所有显示对象的基类
Sprite

Sprite显示图片

  • Sprite中的texture属性可指定需要显示的图片,若没有则什么都不显示。
  • Sprite的缩放参数scaleXscaleY,若scale为负数则会被镜像。
  • Sprite的大小改变图片也会跟着缩放
Sprite图片

Image

Image九宫格模式sizeGrid

  • 编辑图片资源设置九宫格,其实是指定拉升区域,大小改变时只在指定的拉升区域里拉升图片。
  • 设置完九宫格后根据指定区域拉升
  • 九宫格能节省图片大小并保持物体的边角形状
  • 九宫格需使用laya.ui.Image对象来显示,laya.ui.Image继承自Sprite
九宫格模式
九宫格拉升

Handler

  • 创建Handler对象使用Laya.Handler.create()静态方法
/*
* 从对象池内创建一个Handler,默认会执行一次并立即回收,如果不需要自动回收,设置once参数为false。
* @param caller 执行域(this)。
* @param method 回调方法。
* @param args 携带的参数。
* @param once 是否只执行一次,如果为true,回调后执行recover()进行回收,默认为true。
* @return 返回创建的handler实例。
*/
static create(caller:any,method:Function,args?:any[],once?:boolean):Handler;
  • Handler对象不直接使用new而使用create方法从对象池中创建
  • 运行run()方法将直接触发一个Handler对象
  • 运行runWith()方法携带参数触发,参数可以是单个对象或数组。
  • Handler主要用于通知和回调,可以先创建一个Handler并告知管理模块,当有某事件发生时可使用runrunWith触发已定义的Handler。
$ vim src/game/SceneMgr.js
export default class SceneMgr extends Laya.Script {
    constructor() { 
        super(); 
    }
    onAwake(){
        console.log("onAwake: "+this.owner.name);
    }
    onStart(){
        console.log("onStart: "+this.owner.name);
        //创建处理器
        var handler = Laya.Handler.create(this, function(id,name,pid){
            console.log(this);//SceneMgr {_id: 4, _indexInList: -1, _enabled: true, _awaked: true, owner: Scene, …}
            console.log(id);//1
            console.log(name);//junchow
            console.log(pid);//undefined
        }, [1,"juncow"], true);
        //触发处理器
        handler.run();

        //手动回收
        var handler = Laya.Handler.create(this, function(id,name,pid){
            console.log(this);//SceneMgr {_id: 4, _indexInList: -1, _enabled: true, _awaked: true, owner: Scene, …}
            console.log(id);//1
            console.log(name);//junchow
            console.log(pid);//2
        }, [1,"juncow"], false);
        handler.runWith(2);
        handler.recover();

        //传递多个参数
        var handler = Laya.Handler.create(this, function(id,name,pid){
            console.log(this);//SceneMgr {_id: 4, _indexInList: -1, _enabled: true, _awaked: true, owner: Scene, …}
            console.log(id);//1
            console.log(name);//junchow
            console.log(pid);//10
        }, [1,"juncow"], false);
        handler.runWith([10, 100, 1000]);
        handler.recover();
    }
    onEnable() {
    }
    onDisable() {
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345