laya入门,这一篇应该够了

欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

作者|王小强

来源|https://my.oschina.net/wxqdoit

简述

LayaAir 是基于HTML5开源引擎,所开发的游戏既可以网页运行,也可以打包Android & ios app运行,目前更到1.7.19.1 beta版本,本次使用1.7.18稳定版。 本文介绍laya的下载安装,项目创建,目录结构,环境配置与es6+的支持,及具体开发知识,网页端发布等等方面。

下载安装

官网传送门:www.layabox.com

进入首页看到如下两个下载按钮:

此刻就让人有点懵逼了,layaAir Engine可以理解为引擎内核(源码),IDE就是集成开发工具了,直接下载IDE就好,因为下载下来的已经集成对应版本的源码包了(你会发现,每一个版本的源码都有对应版本的IDE。截止目前更到1.7.19.1 beta版本,为了稳定还是使用1.7.18版本。如下(对,你没看错,蓝色那个,点...点...点它:

下载完成之后是一个zip压缩包,不用安装的,直接解压到你想放的位置,完事儿之后就可以使用了:

就是他了(.exe文件,双击吧,看到如下界面你就完成第一步了!

项目创建与目录结构

点击新建项目,弹出如下框:

选择默认的UI示例项目,类型选择JavaScript项目,如果你会as或者ts也可以选它,然后点击创建,创建完成进入代码模式,简单标注了一下:

接下来什么将调试器选择chrome调试,点击三角按钮或者按f5运行,你会看到如下一个巨丑的页面弹出来emmmm(真的很丑,但是只要正常看到,这一步就算完成了)。

接下来是目录结构,传送门:https://ldc.layabox.com/doc/?nav=zh-js-1-0-0,不过这个里面说的hin多hin杂,在这里简单说重点:

项目运行配置文件(.laya文件夹)。

  1. launch.json,当你将项目移动或拷贝到别处的时候需要修改,什么路径统统要改。
  2. 如果你用chrome运行项目,会有一个chrome文件夹,不用管他,垃圾东西。

项目的输出目录(bin文件夹)。项目编译后的东西都在里面,什么动画,图集,你的源码等等,最后项目发布也是从这个目录发布

  1. lib,全是引擎的源码包,不用的可以删除
  2. res,资源文件,图片图集,音频文件都可以在里面
  3. index.html,点进去看看,里面说的很清楚了

UI项目目录(laya)。其实这些都看自己的喜好,没有规定的话,只要合理爱咋咋地吧。

  1. laya/assets目录用来存放UI页面、粒子等组件所需的图片资源。
  2. laya/pages目录用来存放LayaAirIDE创建页面布局生成的文件。

代码提供文件目录(libs),不用管他。

项目代码目录(src)。

这个就比较牛逼了,全是你的代码,不过后面我们不在里面开发。

目录结构也介绍完了,这一节大概就是这些,下一节讲解配置我们真正的而开发环境。

环境配置

既然是属于h5前端开发,自然要配置一系列的工具。webpack,babel,gulp等等。(如果大家不想使用这些工具,直接用项目默认的开发模式也可以,前面也足够了)

  • 安装Node.js,推荐稳定版本8.x吧(不会问度娘。
  • 在项目根目录新建文件夹www(其实开发文件夹应该叫做src的,无奈被默认的目录占用了,src这个文件夹不能动他,因为构建的ui文件类会在里面,稍后我们输出webpack的main.js也会放在里面。然后项目编译时会用到src)。
  • 接下来切换到下方的终端(没有看到的话f5一下吧),用npm安装如下一堆依赖的东西(你可以直接建一个package.json文件,将下面的考进去,然后npm install,谢谢赶紧我~~)。完了之后www会有一个node_modules文件夹,全是刚才装的b:
  • { "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack" }, "author": "wxq", "license": "ISC", "dependencies": { "babel-cli": "^6.26.0", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", "dateformat": "^3.0.3", "gulp": "^3.9.1", "gulp-babel": "^7.0.1", "gulp-less": "^3.4.0", "gulp-util": "^3.0.8", "webpack": "^3.10.0", "webpack-stream": "^4.0.0" } } 创建.babelrc文件,里面是babel的预设集配置等,如果你不想懂,可以直接copy进去: { "presets": ["env"], "plugins": [[ "transform-runtime", { "helpers": false, "polyfill": false, "regenerator": true, "moduleName": "babel-runtime" } ]] }
  • 创建webpack.config.js文件,这个是webpack的配置文件,主要配置webpack打包的入口文件口和输出文件,之后会时候gulp的自动任务执行webpack打包,同时会将es6(es7、es8)通过bable转译为es5。
  • 创建gulpfile.js文件,这个是gulp的配置文件,如果你不想懂,也可以直接copy进去: const gulp = require("gulp"); //转译JavaScript gulp.task("webpack",()=>{ const webpack = require("webpack-stream"); const config = require("./webpack.config"); gulp.src("./src/**/*.js") .pipe(webpack(config)) .pipe(gulp.dest("../src/")) }); gulp.task("watch",function(){ gulp.watch("./src/**/*.js",['webpack']); }); gulp.task("default",["webpack",'watch']); 解释一下吧,引入依赖gulp,创建三个任务,第一个是打包任务,webpack执行,第二个是watch任务监听文件变化自动执行第一个任务,这样就不需要每次修改文件都去执行gulp命令了,美滋滋~~,第三个默认任务,就是去执行上面两个咯。
  • 执行npm install gulp -g 安装gulp到全局(必须安装到全局 全局 -g),不然会报错。

上述步骤完成且没有问题之后,成功之后再去执行gulp命令吧,如图我将www下面的src文件夹下面的所有东西都打包到了根目录下的src文件夹的mian.js文件里面:

然后打开你的www-->src-->main.js:

就长这样啦,然后去把index.html里面的代码改改吧,噢啦,环境搭建完成。

<!--IDE生成的UI文件-->
	<script src="../src/ui/layaUI.max.all.js"></script>
	<!--jsfile--startTag-->
	<script src="../src/main.js"></script>
	<!--jsfile--endTag-->

如果到这里,你没有如遇到什么难题,那我们就可以准备进入正题了,emmmm。

开发入门

舞台搭建与适配

开发目录下新建的main.js文件全部代码删除,然后不用管它,接下来:

GameMain.js:

export class GameMain {
    constructor() {
    }
    static init() {
        Laya.MiniAdpter.init();
        Laya.init(768, 1366, Laya.WebGL);
        Laya.stage.bgColor = "#5a7b9a";
        //水平对齐方式,水平居中
        Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
        //垂直对齐方式,垂直居中
        Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
        //按照宽度
        Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
        //屏幕适配,横屏还是竖屏,默认不改变
        Laya.stage.screenMode = Laya.Stage.SCREEN_NONE;
        //禁用多点触控
        Laya.MouseManager.multiTouchEnabled = false;
    }
}

如果es6不懂的可以先去补一下,创建一个静态的方法init()。

Laya.MiniAdpter.init();//如果不考虑微信小游戏可以不加,当然加上也不会怎样。

Laya.init(768, 1366, Laya.WebGL);//初始化舞台大小,记住这个尺寸是设计大佬给的,她们的图都按照这个尺寸来做的。宽、高、渲染方式。

Laya.stage.bgColor = "#5a7b9a";//这个舞台背景,爱咋咋地吧。

接下来的全是做是配的,copy贴上去就对了。还有其他的适配方式,以及参数,自己去官网看吧,反正我怎么不用。

关于图集打包与资源加载策略

在进入main文件之前讲一讲这两点:图集打包与资源加载。

图集打包:

进入编辑模式,你懂我意思吧:

看图的时候不要问我拿来那么多文件,看重点:在这个界面,当你按下f12的时候,会发布代码,并将红色框里的文件夹里面的图片,按分文夹的方式打包成图集,这些文件就是在www/laya/assets下面,发布完成之后,你在bin/res/atlas下面看到图集的.png与.atlas(json)文件,这两个文件都是一一对应的。

注意:在编辑模式按f9可以进行设置,包括图集的大小,当然,这里主要也是设置图集大小。

这图集打包就这样咯,接下来是资源加载↓↓↓↓↓

资源加载:

关于资源加载如果做过游戏都知道,有一个载入界面,载入界面用到的所有资源最好是放在游戏包里面,进行第一次加载。第一次加载完成之后就是加载游戏需要的其它大部分资源,这里面的资源有可能是在本地,也有可能加载网络资源,一般需要写一个资源加载类。

简单介绍laya里面的资源加载类该如何写:

主要使用Laya.loader.load()方法进行加载,该方法有三个参数:

Laya.loader.load(this.resources, Laya.Handler.create(this, loaded), Laya.Handler.create(this, loading, null, false));

第一个,资源,如果单个加载,可以写字符串路径,如果批量加载,写成数组对象:

let res = [
  {url: "res/atlas/start.atlas"},
  {url: "res/atlas/activity.atlas"},
  {url: "res/atlas/popup.atlas"},
  {url: "res/atlas/comp.atlas"},
  {url: "res/atlas/part.atlas"},
  {url: "res/atlas/shareMask.atlas"},
  {url: "res/atlas/common.atlas"},
  {
     url: "res/sound/btn_click.mp3",
     name: "btn_click",
     type: Laya.Loader.SOUND
  },
  {
     url: "res/sound/btnShowSound.mp3",
     name: "btnShowSound",
     type: Laya.Loader.SOUND
  }
]

name可以作为名字调用资源,如果不写,用的时候只能通过字符串路径调用资源;

type是资源类型,也可以不写,但最好写上

第二个:加载完成的回调,只返回true或者false,

第三个:加载过程的回调,返回的是数字,从0-100。

上一下完整的代码:

import {GameMain} from './base/GameMain.js'
import {ResLoader} from './utils/ResLoader.js'
import {MainBoard} from "./base/MainBoard";
import {UserUtils} from "./utils/UserUtils";
import {GlobalData} from "./base/GlobalData";
import {GameEvent} from "./utils/GameEvent";
import {LayoutUtils} from "./utils/LayoutUtils";

GameMain.init();
Laya.loader.load("res/atlas/loading.atlas", Laya.Handler.create(this, function (e) {
    let resManager = ResLoader.getInstance();
    let loading = new ui.view.gameLoadingUI();
    Laya.stage.addChild(loading);
    let sp_mask = loading.sp_mask;
    sp_mask.optimizeScrollRect = true;
    resManager.loaded((e) => {
        let mainBoard = MainBoard.getInstance();
        let user = UserUtils.getInstance();
        user.getWxUser({
            sucFn: () => {
                console.log('登陆成功v1.0.0');
                Laya.stage.addChild(LayoutUtils.getInstance().map.get("gameStartUI"));
                Laya.stage.removeChild(loading);
                mainBoard.initMainBoard();
                GameEvent.getInstance().bindListenEvent();
                GameEvent.getInstance().remarkGameTime();  
            }, errFn: () => {
                alert('登陆失败');
            }
        });

    }, (e) => {
        let process = parseInt(e * 100);
        loading.progress_text.text = process + '%';
        sp_mask.scrollRect = new Laya.Rectangle(0, 0, 5.2 * process, 24);
    });
}));

resManager是我自己写的资源加载管理器,做统一资源管理,其实跟这加载一样,只是资源多,封装了一下。

多说一句:单例模式

因为这里基于es6的类,常常需要实例化类,像资源加载这种只需要实例化一次的就需要用到js的单例模式,具体实现如下:

export class ResLoader {

    static getInstance() {
        return ResLoader.instance ? ResLoader.instance : ResLoader.instance = new ResLoader();
    }

    constructor() {}
}

UI创建

如果你不想通过它的编辑器创建界面也是可以的,只不过全部用代码来实现比较麻烦,看看他的ui有哪些组件吧,传送门:https://layaair.ldc.layabox.com/api/?category=UI&class=laya.ui.AsynDialog

什么Image,Text,Button,Sprite全部自己写也很不爽。不过你可以试试用自己写代码的方式来进行游戏布局,比如我写的一些:

diyPopup(btnImgs) {
        let length = btnImgs.length;
        let btnArr=[];
        let popupUI = this.map.get('gamePopupUI');
       for (let i = 0; i < 3; i++) {
          popupUI.removeChildByName(`btn${i===0?'':i}`)
       }
        if (length === 1) {
            let btn = new Laya.Image().size(262, 116).pos(250, 678);
            btn.skin = btnImgs[0];
            btn.name = 'btn';
            btnArr.push(btn);
            popupUI.addChild(btn);
        } else if (length === 2) {
            let btn1 = new Laya.Image().size(262, 116).pos(67, 678);
            btn1.name = 'btn1';
            btn1.skin = btnImgs[0];
            let btn2 = new Laya.Image().size(262, 116).pos(443, 678);
            btn2.name = 'btn2';
            btn2.skin = btnImgs[1];
            btnArr.push(btn1,btn2);
            popupUI.addChild(btn1);
            popupUI.addChild(btn2);
        }
        //遮罩
        popupUI.bg_wrap.graphics.clear();
        popupUI.bg_wrap.graphics.drawRect(0, 0, Laya.stage.width, Laya.stage.height, "#000000");
        return {popupUI:popupUI,btnArr:btnArr}
    }

    //自定义
    diyIcon(iconArr) {
        let length = iconArr.length;
        let mainUI = this.map.get('gameMainUI');
        mainUI.icon_wrap.destroyChildren();
        let iconUI = [];
        if (length === 1) {
            let icon = new Laya.Image().size(77, 68).pos(258, 0);
            icon.skin = iconArr[0];
            mainUI.icon_wrap.addChild(icon);
            iconUI.push(icon)
        } else if (length === 2) {
           for (let i = 0;i < length;i++){
               let icon = new Laya.Image().size(77, 68).pos(207+i*(30+77), 0);
               icon.skin = iconArr[i];
               mainUI.icon_wrap.addChild(icon);
               iconUI.push(icon)
           }
        } else {
            for (let i = 0;i < length;i++){
                let icon = new Laya.Image().size(77, 68).pos(169+i*(15+77), 0);
                icon.skin = iconArr[i];
                mainUI.icon_wrap.addChild(icon);
                iconUI.push(icon)
            }
        }
        return iconUI;
    }

还是用编辑器拖拖拉拉舒服,点击view新建页面/场景,最好把逻辑类勾,本人当时没有勾上,就全部发布到一个文件里面去了,下面会说的。然后直接往上怼:

做完之后按f12发布,就会发布到src/ui下面的layaUI.max.all.js里面。

接下来在代码里面引用:

let gameMain= new ui.view.gameMainUI();
Laya.stage.addChild(gameMain);//添加到舞台,removeChild()你懂吧

如此,页面场景也可以自己搭建好了。其实还有一部分是粒子和动画,但是我觉得这个可以看看官网给的教程(我司有做粒子和动画的,我不会),传送门:https://ldc.layabox.com/doc/?nav=zh-js-2-1-10。

这一入门部分也就告一段落,基本上可自己写出一个demo。下一篇准备讲讲使用laya的API以及其中遇到的巨坑。laya系列完了之后准备再写一个egret入门与坑的系列。如果有错误的地方,还请多多指教。

拓展阅读:

深入理解遗传算法(一)

深入理解遗传算法(二)

从1到100求和学算法思维(一)

从1到100求和学算法思维(二)

从1到100求和学算法思维(三)

从1到100求和学算法思维(四)

从1到100求和学算法思维(五)

从1到100求和学算法思维(六)

where2go 团队

微信号:算法与编程之美

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!

原文发布于微信公众号 - 算法与编程之美(algo_coding)

原文发表时间:2019-05-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券