2

前言

  • 目的:是为了熟悉Egret引擎
  • 这款小游戏还是个半成品。

一些常用方法、技巧

*官网的一些常用方api版本多,隐藏的较深,比较不好找,所以总结下一些常用的。

描述
DisplayObject 显示对象基类,所有显示对象均继承自此类
Bitmap 位图,用来显示图片
Shape 用来显示矢量图,可以使用其中的方法绘制矢量图形
DisplayObjectContainer 显示对象容器接口,所有显示对象容器均实现此接口
Sprite 与DisplayObjectContainer类似,多一些功能
Stage 舞台类
TextField 文本类
TextInput 输入文本类

Bitmap

这应该是最常用到的

    //创建一个图片精灵
    let sky = new egret.Bitmap();
      sky.texture = RES.getRes("game_scene_bg"); //RES.getRes获取资源
      sky.width = 100;
      skt.height = 100;
      this.addChild(sky);
      
    //九宫格位图,改变长宽而不改变圆角处,见下图。
    let sky = new egret.Bitmap();
      sky.texture = RES.getRes("game_scene_bg"); //RES.getRes获取资源
      this.addChild(sky);
      let rect:egret.Rectangle = new egret.Rectangle(30,31,40,41);
      sky.scale9Grid = rect;

image

除了宽高还有许多属性,可以设置也可以获取,游戏中会有许多逻辑判断,都将会用到这些数据。

alpha:1
anchorOffsetX:0
anchorOffsetY:0
blendMode:"normal"
cacheAsBitmap:false
filters:null
hashCode:40
height:456
mask:null
matrix:Matrix
measuredHeight:456 
measuredWidth:326
name:""
numChildren:3
parent:Main
platingPage:
playingPage {$hashCode: 46, $EventDispatcher: {…}, $children: Array(0), $parent: null, $stage: null, …}
rotation:0
scaleX:1
scaleY:1
scrollRect:null
skewX:0
skewY:0
stage:Stage
touchChildren:true
touchEnabled:false
visible:true
width:326
x:0
y:0

Shape

  let shp:egret.Shape = new egret.Shape();
    shp.x = 100;
    shp.y = 100;
    shp.graphics.lineStyle( 10, 0x00ff00 );
    shp.graphics.beginFill( 0xff0000, 1);
    shp.graphics.drawCircle( 0, 0, 50 ); //圆 x,y,r
    //shp.graphics.drawRect( 0, 0, 100, 200 ); 矩形
    //shp.graphics.moveTo( 50, 50); 移动,不划线
    //shp.graphics.curveTo( 100,100, 200,50);  曲线
    //shp.graphics.lineTo( 100, 20 ); 直线
    shp.graphics.endFill();
    this.addChild( shp );

TextField

  let label:egret.TextField = new egret.TextField(); 
  label.text = "这是一个文本"; 
  label.textColor = 0xff0000; //颜色
  label.fontFamily = "KaiTi"; //字体
  label.textAlign = egret.HorizontalAlign.RIGHT; //布局默认LEFT
  //描边属性
  label.strokeColor = 0x0000ff;
  label.stroke = 2;

  this.addChild( label );

TextInput

  let txInput:egret.TextField = new egret.TextField;
  txInput.type = egret.TextFieldType.INPUT;
  txInput.width = 282;
  txInput.height = 43;
  txInput.x = 134;
  txInput.y = 592;
  txInput.textColor = 0x000000;
  /// 注意_container是事先建立好的一个显示容器,即 egret.Sprite,并且已经添加到显示列表中
  this._container.addChild(txInput);

Tween

let delay = 200, during = 100;
egret.Tween.get(sprite)
  .to({alpha: 0}, 1)  //动画类型常用的有alpha、ritation、scaleX、scaleY、
  .to({alpha: 1, y: during}, delay)
            ...
  .wait(400)
  .call(()=>{
    ...
  });

添加、移除精灵

  • parent.addChild(); //添加
  • parent.removeChild(); //单个对象
  • parent.removeChildren() ;//移除所有子对象
  • parent.numChildren //获取parent容器子对象的数量
  • parent.getChildIndex(); //获取精灵深度(叠放次序)
  • parent.getChildAt(); //通过index获取子对象(效率高)
  • parent.getChildByName(); //通过name属性获取子对象(效率低)
  • child.parent //获取父级对象

Demo 部分代码

/**
 *  结构Main - >startPage -> playingPage -> 结束页?
 *  还有一种方案就是编写自定义监听事件,在每个页面结束之后触发自定义事件,通知Main移除前页面进入下一个页面,结构:
 Main -> startPage, Main -> playingPage, Main -> 结束页
 */

Main.ts

    /**
     *  加载资源
     *  添加两个子对象:背景、游戏开始页
     */
    private startPage = new StartPage(); //游戏开始页
    private onResourceLoadComplete(event: RES.ResourceEvent) {
    if (event.groupName == "startPage") {
        ...
        ...
        ...
      //背景
      let sky = new egret.Bitmap();
      sky.texture = RES.getRes("game_scene_bg");
      this.addChild(sky);
      sky.width = this.stage.stageWidth;
      sky.height = this.stage.stageHeight;

      this.addChild(this.startPage);
    }
  }

startPage.ts

  public create(): void{
    //舞台宽高
    let stageW = this.stage.stageWidth;
    let stageH = this.stage.stageHeight;

    //开始按钮
    let starBtn = this.createBitmapByName("play_btn");
    this.addChild(starBtn);
    starBtn.width = 110;
    starBtn.height = 110;
    starBtn.anchorOffsetX = 55;
    starBtn.x = stageW * .5;
    starBtn.y = stageH * .6;
    starBtn.touchEnabled = true;
    starBtn.addEventListener(egret.TouchEvent.TOUCH_TAP, ()=> {
      this.removeChildren(); //移除所有子对象
      this.addChild(tip);  
    }, this);
    
    //游戏提示
    let tip = this.createBitmapByName("help_info");
    tip.width = stageW * .9;
    tip.height = stageH * .55;
    tip.x = stageW * .05;
    tip.y = 120;
    tip.touchEnabled = true;
    tip.addEventListener(egret.TouchEvent.TOUCH_TAP, ()=>{
      this.removeChild(tip);
      this.addChild(this.platingPage);  //添加游戏页
    }, this);
    
    //音乐按钮
    let sound = this.createBitmapByName("sound_on_btn");
    let soundSwitch = true;
    this.addChild(sound);
    sound.width = 60;
    sound.height = 60;
    sound.anchorOffsetX = 60;
    sound.x =  stageW - 12;
    sound.y =  17;
    sound.touchEnabled = true;
    //点击切换开关状态
    sound.addEventListener(egret.TouchEvent.TOUCH_BEGIN, ()=>{
      if(soundSwitch){
        egret.Tween.get(sound)
          .to({scaleY: 1.1, scaleX: 1.1}, 150)
          .to({scaleY: 1, scaleX: 1}, 150);
        sound.texture = RES.getRes("sound_off_btn"); //替换资源
        soundSwitch = !soundSwitch;
      }
      else{
        egret.Tween.get(sound)
          .to({scaleY: 1.1, scaleX: 1.1}, 150)
          .to({scaleY: 1, scaleX: 1}, 150);
        sound.texture = RES.getRes("sound_on_btn");
        soundSwitch = !soundSwitch;
      }
    }, this);
  }

playingPage.ts

  private createBlock():void{
    ...
    ...
    let matrix = []; //位置矩阵
    let Matrix = new egret.Sprite(); //新建一个容器,存放方块,方便整体操作
    //初始化9*8方块,
    this.addChild(Matrix);
    for(let j = 0; j<9; j++){
      matrix[j] = [];
      alreadyRet[j] = [], retrievalOk[j] = [];
      for(let i = 0; i<8; i++){
        let index = Math.floor(Math.random() * 5);
        let bl = this.createBitmapByName(`bl${index}`);
        matrix[j].push(bl);
        retrievalOk[j][i] = false;
        bl.name = index.toString();
        bl.width = 41;
        bl.height = 41;
        bl.x = 4 + 41 * j;
        bl.y = stageH - 3 - 41 * (i+1);
        Matrix.addChild(bl);
      }
    }
    //把点击事件绑定到背景层
    let bg = this.parent.parent.getChildAt(0); //获取背景精灵
    bg.touchEnabled = true;
    bg.addEventListener(egret.TouchEvent.TOUCH_BEGIN, click, this);
    function click(e) {
      position = this.getPosition(e); //通过点击坐标确定点击的方块,避免了对每个方块都绑定点击事件,提高效率
      ...
      ...
      //达到30分,进入下一关
      if(this.totalScore>=30){
        this.totalScore = 0;
        egret.Tween.get(Matrix)  //所有滑块,下滑出屏幕
          .to({y:stageH},500)
          .call(()=>{
            //移除点击事件,否则会造成重复绑定,后果很严重。
            bg.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, click ,this);
            this.removeChild(Matrix);
            this.createBlock();
          });
        }
    }
  }
    
  /**
   * 几乎每个游戏都要用到数字,复用率高,写一个创建数字的方法
   * num:要显示的数字
   * sprite:精灵(Sprite),把所有的数字都加入到他的子对象,方便整体 操作
   * width:单个数字的宽度
   * height:单个数字的宽度
   * x:数字x坐标,锚点为width/2,就是中间点横坐标。
   * y:最上方点的纵坐标,为了与其他元素保持一致,方便计算。
   */
  private createNumber(num: number, sprite, width: number, height: number, x: number, y: number) {
    let number = num.toString();
    let len = number.length;
    let anchorX = width / 2 * len;
    sprite.removeChildren();
    for(let i = 0; i<len; i++){
      let item;
      item = new egret.Bitmap();
      //数字图片使用官方Texture Merger合并。
      item.texture = RES.getRes(`number.${number.charAt(i)}`);
      item.width = width;
      item.height = height;
      item.anchorOffsetX = anchorX - width * i;
      item.x = x;
      item.y = y;
      sprite.addChild(item);
    }
  }

       以上代码都没有涉及逻辑部分并删除了许多相似内容,每个不同的游戏逻辑都不一样,参考价值不大,附上完整代码:https://gitee.com/zhangweiqin...


不快乐的程序员
393 声望13 粉丝