Egret(白鹭引擎) 入门

2023-01-05  本文已影响0人  brave_wu

入门首先看文档,然后是一些攻略,当然不可避免的还是碰到一些坑,我习惯首先自己想办法,实在不行请教大神,最后一步步学习开发第一个小游戏,以下是一些干货(代码)。

1.egret build 遇到http://localhost/打不开

我是按照文档一步步新建了个HelloWorld项目,但是就是build后在浏览器中打不开,此前不知道什么原因,但是看了新手入门文章知道了可以自己启动一个http服务,特别是Mac OS X自带了Apache,就按照web项目的方法启动了服务,并把egret build编译的东西放到

/资源库/WebServer/Documents/

目录下面,果然曲线救国了。
请教大神才知道实际上是端口和新编译模式的问题,解决办法:

第一步 动态端口号

//./launch.json 没有就新建
{
    "configurations": [
        {
            "type": "Egret",
            "request": "launch",
            "name": "Egret Debugger",
            "url": "http://localhost:${command:WebsitePort}",
            "webRoot": "${workspaceFolder}",
            "sourceMaps": true,
            "userDataDir": "${tmpdir}",
            "preLaunchTask": "egret: build"
        }
    ],
    "version": "0.2.0"
}
第二步 把新编译改为普通编译
// ./scripts/config.ts
        if (command == 'build') {
            const outputDir = 'bin-debug';
            return {
                outputDir,
                commands: [
                    // new EmitResConfigFilePlugin({
                    //     output: "resource/default.res.json",
                    //     typeSelector: config.typeSelector,
                    //     nameSelector: p => path.basename(p).replace(/\./gi, "_"),
                    //     groupSelector: p => "preload"
                    // }),
                    new ExmlPlugin('debug'), // 非 EUI 项目关闭此设置
                    new IncrementCompilePlugin(),
                ]
            }
        }

2.显示对象和显示容器

了解添加显示对像,以及显示对象的坐标、锚点等

    var shape: egret.Shape = new egret.Shape();
    // shape.scaleX = 0.5;
    // shape.scaleY = 0.5;
    // shape.alpha = 0.5;
    // shape.rotation = 30;
    // shape.visible = true;
    shape.graphics.beginFill(0x00ff00);
    shape.graphics.drawRect(50, 0, 100, 100);
    shape.graphics.endFill();
    //锚点偏移
    shape.anchorOffsetX = 100;
    shape.x = 50;
    shape.y = 175;
    this.addChild(shape);

    //文本
    var txInfo: egret.TextField = new egret.TextField();
    txInfo = new egret.TextField();
    this.addChild(txInfo);
    txInfo.text = "2222221";
    txInfo.size = 28;
    txInfo.x = 0;
    txInfo.y = 150;
    txInfo.textAlign = egret.HorizontalAlign.LEFT;
    txInfo.textColor = 0x000000;
    txInfo.type = egret.TextFieldType.DYNAMIC;
    txInfo.lineSpacing = 6;
    txInfo.multiline = true;

    //自定义
    const _mycell: MyCell = new MyCell();
    this.addChild(_mycell);

    //相对坐标
    let offsetx: number;
    let offsety: number;
    const container: egret.DisplayObjectContainer =
      new egret.DisplayObjectContainer();
    container.x = 50;
    container.y = 50;
    this.addChild(container);
    //画个圆
    const circle: egret.Shape = new egret.Shape();
    circle.graphics.beginFill(0xff0000);
    circle.graphics.drawCircle(75, 75, 25);
    circle.graphics.endFill();
    container.addChild(circle);

显示对象可以添加事件

  //添加点击事件
    circle.touchEnabled = true;
    circle.addEventListener(egret.TouchEvent.TOUCH_TAP, on_click, this);
    circle.addEventListener(egret.TouchEvent.TOUCH_BEGIN, starMove, this);
    circle.addEventListener(egret.TouchEvent.TOUCH_END, endMove, this);
    function on_click(): void {
      const targetPoint: egret.Point = container.globalToLocal(0, 0);
      circle.x = targetPoint.x;
      circle.y = targetPoint.y;
    }
    function starMove(e: egret.TouchEvent): void {
      offsetx = e.stageX - circle.x;
      offsety = e.stageY - circle.y;
      //手指在屏幕上移动,会触发 onMove 方法
      this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, onMove, this);
    }
    function endMove(e: egret.TouchEvent): void {
      //手指离开屏幕,移除手指移动的监听
      this.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE, onMove, this);
    }
    function onMove(e: egret.TouchEvent): void {
      //通过计算手指在屏幕上的位置,计算当前对象的坐标,达到跟随手指移动的效果
      circle.x = e.stageX - offsetx;
      circle.y = e.stageY - offsety;
    }

可以把显示对象从显示列表里删除、更换层级,还可以获取显示对象

    //删除显示
    var mySprite: egret.Sprite = new egret.Sprite();
    mySprite.graphics.beginFill(0x0000ff);
    mySprite.graphics.drawRect(10, 200, 100, 100);
    mySprite.graphics.endFill();
    this.addChild(mySprite);
    if (mySprite.parent) {
      mySprite.parent.removeChild(mySprite);
    }
    //层级
    this.addChildAt(mySprite, this.numChildren - 4);
    this.removeChildAt(this.numChildren - 4);
    this.removeChildren();

    this.addChild(shape);
    this.addChild(mySprite);
    //层级互换
    this.swapChildren(shape, mySprite);
    //设置层级
    this.setChildIndex(mySprite, this.numChildren);

    //名字
    mySprite.name = "my";
    const spr: egret.DisplayObject = this.getChildByName("my");
    spr.alpha = 0.6;

    //推荐
    this.addChild(_mycell);
    const spr1: egret.DisplayObject = this.getChildAt(2);
    spr1.alpha = 0.5;
    this.removeChildren();

    //zIndex
    let superView = new egret.Sprite();
    superView.sortableChildren = true; //注意,一定要设置为true
    this.addChild(superView);
    let b1 = new egret.Shape();
    b1.graphics.beginFill(0x00ff00);
    b1.graphics.drawRect(0, 0, 200, 100);
    b1.graphics.endFill();
    b1.x = 0;
    superView.addChild(b1);
    let b2 = new egret.Shape();
    b2.graphics.beginFill(0xff0000);
    b2.graphics.drawRect(0, 20, 200, 100);
    b2.graphics.endFill();
    b2.x = 70;
    superView.addChild(b2);
    let b3 = new egret.Shape();
    b3.graphics.lineStyle(10, 0xff0000);
    b3.graphics.beginFill(0x0000ff);
    b3.graphics.drawRect(0, 40, 200, 100);
    b3.graphics.endFill();
    b3.x = 140;
    superView.addChild(b3);
    //设置到顶部
    b1.zIndex = 3;

绘图、遮罩、富文本

    //贝塞尔曲线
    let b4 = new egret.Shape();
    b4.graphics.lineStyle(2, 0xff0000);
    b4.graphics.moveTo(50, 200);
    b4.graphics.curveTo(100, 300, 300, 200);
    b4.graphics.endFill();
    superView.addChild(b4);

    //圆弧
    let b5 = new egret.Shape();
    // b5.graphics.beginFill(0xff0000);
    b5.graphics.lineStyle(3, 0xff0000);
    b5.graphics.drawArc(100, 400, 100, 0, 1.5 * Math.PI, false);
    b5.graphics.endFill();
    superView.addChild(b5);

    //遮罩
    let b6 = new egret.Shape();
    b6.graphics.beginFill(0xff0000);
    b6.graphics.drawCircle(50, 50, 50);
    b6.graphics.endFill();
    b6.x = 0;
    superView.addChild(b6);
    b6.zIndex = 4;
    const rect: egret.Rectangle = new egret.Rectangle(0, 0, 100, 100);
    b1.mask = rect;

    //文本
    this.removeChildren();
    this.addChild(txInfo);
    // txInfo.type = egret.TextFieldType.INPUT;
    // txInfo.inputType = egret.TextFieldInputType.PASSWORD;
    txInfo.fontFamily = "Impact";
    txInfo.strokeColor = 0xff0000;
    txInfo.stroke = 2;
    txInfo.text = "1 2 3 4 5";
    txInfo.bold = true;
    //斜体
    txInfo.italic = true;
    //富文本
    txInfo.width = 400;
    txInfo.height = 600;
    txInfo.textFlow = <Array<egret.ITextElement>>[
      { text: "Text in ", style: { size: 20 } },
      {
        text: "Egret",
        style: {
          href: "event:ttttt",
          textColor: 0x336699,
          size: 60,
          strokeColor: 0x6699cc,
          stroke: 2,
        },
      },
      { text: " can ", style: { fontFamily: "Impact" } },
      { text: "be set ", style: { fontFamily: "Times New Roman" } },
      { text: "to a ", style: { textColor: 0xff0000 } },
      { text: "\n" },
      { text: "variety ", style: { textColor: 0x00ff00 } },
      { text: "of ", style: { textColor: 0xf000f0 } },
      { text: "styles ", style: { textColor: 0x00ffff } },
      { text: "with", style: { href: "https://www.egret.com/", size: 56 } },
      { text: "different ", style: { size: 16 } },
      { text: "colors, ", style: { size: 26 } },
      { text: "\n" },
      { text: "fonts ", style: { italic: true, textColor: 0x00ff00 } },
      {
        text: "and ",
        style: { size: 26, textColor: 0xf000f0, fontfamily: "Quaver" },
      },
      { text: "sizes", style: { italic: true, textColor: 0xf06f00 } },
    ];
    txInfo.touchEnabled = true;
    txInfo.addEventListener(
      egret.TextEvent.LINK,
      function (evt: egret.TextEvent) {
        console.log(evt.text);
      },
      this
    );

3.加载资源RES

本地资源放在./resource下,而且需要关注default.res.json文件,然后就可以在游戏中加载资源了

    RES.addEventListener(
      RES.ResourceEvent.GROUP_COMPLETE,
      this.onGroupComplete,
      this
    );
    await RES.loadConfig("resource/default.res.json", "resource/");
    await RES.loadGroup("preload");

在onGroupComplete方法中使用加载好的资源

  private onGroupComplete() {
    //图片
    let bgimg: egret.Bitmap = new egret.Bitmap();
    bgimg.texture = RES.getRes("bg_jpg");
    bgimg.y = 0;
    this.addChild(bgimg);
  }

4.滤镜效果

可以使用本身自带一些属性设置滤镜

    //设置滤镜
    let color: number = 0xff0000; /// 光晕的颜色,十六进制,不包含透明度
    let alpha: number = 0.8; /// 光晕的颜色透明度,是对 color 参数的透明度设定。有效值为 0.0 到 1.0。例如,0.8 设置透明度值为 80%。
    let blurX: number = 35; /// 水平模糊量。有效值为 0 到 255.0(浮点)
    let blurY: number = 35; /// 垂直模糊量。有效值为 0 到 255.0(浮点)
    let strength: number = 2; /// 压印的强度,值越大,压印的颜色越深,而且发光与背景之间的对比度也越强。有效值为 0 到 255。暂未实现
    let quality: number = egret.BitmapFilterQuality.HIGH; /// 应用滤镜的次数,建议用 BitmapFilterQuality 类的常量来体现
    let inner: boolean = false; /// 指定发光是否为内侧发光,暂未实现
    let knockout: boolean = false; /// 指定对象是否具有挖空效果,暂未实现
    const glowFilter: egret.GlowFilter = new egret.GlowFilter(
      color,
      alpha,
      blurX,
      blurY,
      strength,
      quality,
      inner,
      knockout
    );
    img.filters = [glowFilter];

也可以使用颜色矩阵

    //灰化
    let colorMatrix = [
      0.3, 0.6, 0, 0, 0, 0.3, 0.6, 0, 0, 0, 0.3, 0.6, 0, 0, 0, 0, 0, 0, 1, 0,
    ];
    let colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
    img.filters = [colorFlilter];
    //红化
    colorMatrix = [
      1, 0, 0, 0, 100, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
    ];
    colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
    img.filters = [colorFlilter];
    //绿化
    colorMatrix = [1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
    colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
    img.filters = [colorFlilter];
    //蓝换红
    colorMatrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0];
    colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
    img.filters = [colorFlilter];
    //亮起来
    colorMatrix = [
      1, 0, 0, 0, 100, 0, 1, 0, 0, 100, 0, 0, 1, 0, 100, 0, 0, 0, 1, 0,
    ];
    colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
    img.filters = [colorFlilter];

模糊和阴影效果

    //模糊
    const blurFliter = new egret.BlurFilter(9, 10);
    img.filters = [blurFliter, colorFlilter];
    //阴影
    const distance: number = 20; /// 阴影的偏移距离,以像素为单位
    const angle: number = 30; /// 阴影的角度,0 到 360 度
    color = 0xff0000; /// 阴影的颜色,不包含透明度
    alpha = 0.7; /// 光晕的颜色透明度,是对 color 参数的透明度设定
    blurX = 16; /// 水平模糊量。有效值为 0 到 255.0(浮点)
    blurY = 16; /// 垂直模糊量。有效值为 0 到 255.0(浮点)
    strength = 0.65; /// 压印的强度,值越大,压印的颜色越深,而且阴影与背景之间的对比度也越强。有效值为 0 到 255。暂未实现
    quality = egret.BitmapFilterQuality.LOW; /// 应用滤镜的次数,暂无实现
    inner = false; /// 指定发光是否为内侧发光
    knockout = false; /// 指定对象是否具有挖空效果
    const dropShadowFilter: egret.DropShadowFilter = new egret.DropShadowFilter(
      distance,
      angle,
      color,
      alpha,
      blurX,
      blurY,
      strength,
      quality,
      inner,
      knockout
    );
    img.filters = [dropShadowFilter];

5.使用插件(比如p2物理引擎)

官方提供了一些第三方库,可以直接下载,下载之后把对应的文件放到./libs下

1.png

PS:不用放到modules中。
然后在egretProperties.json中添加,重新编译后即可使用

{
  "engineVersion": "5.4.1",
  "compilerVersion": "5.4.1",
  "template": {},
  "target": {
    "current": "web"
  },
  "modules": [
    {
      "name": "egret"
    },
    {
      "name": "game"
    },
    {
      "name": "tween"
    },
    {
      "name": "assetsmanager"
    },
    {
      "name": "promise"
    },
    {
      "name":"physics",
      "path":"./libs/physics"
    }
  ],
  "vivo": {
    "usePlugin": true
  }
}

此时可以使用p2物理引擎开发一个点球小游戏了

//PlayBall.ts
/**
 * @create 2023-01-05 16:25:46
 */
class PlayBall extends egret.Sprite {
  private factor: number = 50;
  private world: p2.World;
  private boxBody: p2.Body;
  private planeBody: p2.Body;
  public constructor() {
    super();
    //图片
    let bgimg: egret.Bitmap = new egret.Bitmap();
    bgimg.texture = RES.getRes("bg_jpg");
    bgimg.y = 0;
    this.addChild(bgimg);
    this.createGameScene();
  }

  /**
   * 创建游戏场景
   */
  private createGameScene(): void {
    this.world = new p2.World();
    this.world.sleepMode = p2.World.BODY_SLEEPING;
    //创建plane
    var planeShape: p2.Plane = new p2.Plane();
    var planeBody: p2.Body = new p2.Body();
    planeBody.addShape(planeShape);
    planeBody.displays = [];
    this.world.addBody(planeBody);

    egret.Ticker.getInstance().register(function (dt) {
      if (dt < 10) {
        return;
      }
      if (dt > 1000) {
        return;
      }
      this.world.step(dt / 1000);

      var stageHeight: number = egret.MainContext.instance.stage.stageHeight;
      var l = this.world.bodies.length;
      for (var i: number = 0; i < l; i++) {
        var boxBody: p2.Body = this.world.bodies[i];
        var box: egret.DisplayObject = boxBody.displays[0];
        if (box) {
          box.x = boxBody.position[0] * this.factor;
          box.y = stageHeight - boxBody.position[1] * this.factor;
          box.rotation =
            360 - ((boxBody.angle + boxBody.shapes[0].angle) * 180) / Math.PI;
          if (boxBody.sleepState == p2.Body.SLEEPING) {
            box.alpha = 0.5;
          } else {
            box.alpha = 1;
          }
        }
      }
    }, this);
    this.touchEnabled = true;
    //鼠标点击添加刚体
    this.addEventListener(egret.TouchEvent.TOUCH_TAP, this.addOneBox, this);
  }

  private addOneBox(e: egret.TouchEvent): void {
    var positionX: number = Math.floor(e.stageX / this.factor);
    var positionY: number = Math.floor(
      (egret.MainContext.instance.stage.stageHeight - e.stageY) / this.factor
    );
    var display: egret.DisplayObject;
    if (Math.random() > 0.9) {
      //添加方形刚体
      var boxShape: p2.Shape = new p2.Box({ width: 2, height: 1 });
      var boxBody: p2.Body = new p2.Body({
        mass: 1,
        position: [positionX, positionY],
        angularVelocity: 1,
      });
      boxBody.addShape(boxShape);
      this.world.addBody(boxBody);

      display = this.createBitmapByName("rect");
      display.width = (<p2.Box>boxShape).width * this.factor;
      display.height = (<p2.Box>boxShape).height * this.factor;
    } else {
      //添加圆形刚体
      var boxShape: p2.Shape = new p2.Circle({ radius: 1 });
      var boxBody: p2.Body = new p2.Body({
        mass: 1,
        position: [positionX, positionY],
      });
      boxBody.addShape(boxShape);
      this.world.addBody(boxBody);

      display = this.createBitmapByName("circle");

      display.width = (<p2.Circle>boxShape).radius * 2 * this.factor;
      display.height = (<p2.Circle>boxShape).radius * 2 * this.factor;
    }

    display.anchorOffsetX = display.width / 2;
    display.anchorOffsetY = display.height / 2;

    boxBody.displays = [display];
    this.addChild(display);
  }
  /**
   * 根据name关键字创建一个Bitmap
   */
  private createBitmapByName(name: string): egret.Bitmap {
    var result: egret.Bitmap = new egret.Bitmap();
    var texture: egret.Texture = RES.getRes(name);
    result.texture = texture;
    return result;
  }
}

自此,第一个入门小游戏可以玩一会儿了。

上一篇下一篇

猜你喜欢

热点阅读