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