总要有人来改变世界的,为什么不能是你呢

pixi之动画

一、循环动画

let sprite;
Loader.add("images/imgs.json").load(setup);
function setup() {
    //利用orange图片贴图生成精灵
    let texture = TextureCache["orange.png"];
    sprite = new PIXI.Sprite(texture);
    //在渲染之前替换纹理贴图
    sprite.texture = TextureCache['gakki.jpg'];
    sprite.x = 50;
    sprite.y = 50;
    //将精灵实例添加到场景
    app.stage.addChild(sprite);
    //为pixi循环添加事件
    app.ticker.add(delta => gameLoop(delta));
}

function gameLoop(delta){
  sprite.x += 1+delta;
}

应该很好理解吧,delta参数值代表帧的部分的延迟。你可以把它添加到元素的位置,让元素移动的速度和帧率无关,就像上面代码所示一样;

是否加进去这个delta的值其实是一种审美的选择。它往往只在你的动画没法跟上60帧的速率时候出现(比如你的游戏运行在很老旧的机器上)。

如果你不需要这个参数的话,你的代码可以简化成这样:

let sprite;
Loader.add("images/imgs.json").load(setup);
function setup() {
    //利用orange图片贴图生成精灵
    let texture = TextureCache["orange.png"];
    sprite = new PIXI.Sprite(texture);
    //在渲染之前替换纹理贴图
    sprite.texture = TextureCache['gakki.jpg'];
    sprite.x = 50;
    sprite.y = 50;
    //将精灵实例添加到场景
    app.stage.addChild(sprite);
    //为pixi循环添加事件
    app.ticker.add(gameLoop);
}

function gameLoop(){
  sprite.x += 1;
}

我们再来谈谈app.tick.add()的原理:

通过该方法,会将事件逐个添加到了一个事件队列,然后通过requestAnimationFrame()来执行这些方法,该方法类似于setInterval(),只不过比他更为流畅,该API是以帧为单位的,一般1s==60帧,所以每一帧这些函数都会跑一次,1秒跑60次,所以肉眼看起来就会流畅很多了。

二、按键动画

动画,始终是要由人操控的,所以我们卡可以通过键盘的key相关事件来处理,动画的移动

首先,我们利用工厂模式,新建一个keyboard工厂类来实现键盘事件的监听(这里通过函数的方式新建工厂类):

function keyboard(keyCode) {
  let key = {
    code : keyCode,
    isDown : false,
    isUp : true,
    press : undefined,
    release : undefined
  };
  
  //The `downHandler`
  key.downHandler = event => {
    if (event.keyCode === key.code) {
      if (key.isUp && key.press) key.press();
      key.isDown = true;
      key.isUp = false;
    }
    event.preventDefault();
  };

  //The `upHandler`
  key.upHandler = event => {
    if (event.keyCode === key.code) {
      if (key.isDown && key.release) key.release();
      key.isDown = false;
      key.isUp = true;
    }
    event.preventDefault();
  };

  //Attach event listeners
  window.addEventListener(
    "keydown", key.downHandler.bind(key), false
  );
  window.addEventListener(
    "keyup", key.upHandler.bind(key), false
  );
  return key;
}

虽然代码简单,但是还是要提一下,首先初始化按键状态:keyCode、按键是Up状态的、down的回调key.press和up的回调key.release;

按下键盘时,如果按下的键盘的keyCode和我们定义的按键code一致并且该按键状态为up,那么执行该按键的presss事件;

松开键盘,同理。

let left = keyboard(37),
    up = keyboard(38),
    right = keyboard(39),
    down = keyboard(40);

left.press = () => {
    sprite.vx = -5;
    sprite.vy = 0;
  };
left.release = () => {
  if (!right.isDown && sprite.vy === 0) {
    sprite.vx = 0;
  }
};

right.press = () => {
    sprite.vx = 5;
    sprite.vy = 0;
  };
right.release = () => {
  if (!left.isDown && sprite.vy === 0) {
    sprite.vx = 0;
  }
};

上述代码我们定义了上下左右四个键(对应ASCII码值分别为37~40),并且:

left键按下时触发的press事件为精灵x轴速度为-5,也就是向左走,left键松开的时候触发的release事件中如果right键没有按下并且上下键没有按(vy==0),那么精灵的x轴速度变为0(停止)。

其余同理。

在这里提一下,因为循环动画一旦开启那就会一直执行,页面按着一定的规律逐帧渲染,所以,我们只有通过改变元素的移动速度来间接地使其运动/停止。

 

posted @ 2019-03-27 22:41  桔子桑  阅读(1252)  评论(0编辑  收藏  举报