想要做网页游戏怎么办 ?PixiJs 篇(三)
序
好久没记录过博客了,本来想五一写一下的,结果太忙了
本文是继上一次断章的《想要做网页游戏怎么办 ?PixiJs 篇(二)》后续篇
正文开始
上一篇中实现的效果是动画精灵出现了,但是还没有将动画精灵和键盘行走结合起来
在动画精灵生成之后,可以为精灵添加状态属性,因为精灵是由 4x4 的雪碧图构成的,所以按照雪碧图进行分析,精灵可以分为 4 种状态,分别是向下、向左、向右、向上。
关于精灵的状态可以通过中文网进行简单了解:Pixi.js中文网
也可以看这篇文章:https://blog.csdn.net/FE_dev/article/details/86483753
在雪碧图中,其实包含了 4 种静态状态和 4 种动态状态
精灵的静态状态定义精灵在不移动时的四个位置
精灵的动画状态定义了精灵移动时的四个动作序列
下面使用 states 去定义这些状态
// 设置一个states对象字面量属性
jujin.states = {
down: 0,
left: 4,
right: 8,
up: 12,
walkDown: [0, 3],
walkLeft: [4, 7],
walkRight: [8, 11],
walkUp: [12, 15]
};
使用sprite.show(sprite.states.静止状态);
可以只显示精灵某一静止状态使用sprite.playAnimation(sprite.states.动作状态);
语句可以将只显示精灵某一动作状态
比如使用以下代码测试:
// 设置一个states对象字面量属性
jujin.states = {
down: 0,
left: 4,
right: 8,
up: 12,
walkDown: [0, 3],
walkLeft: [4, 7],
walkRight: [8, 11],
walkUp: [12, 15]
};
// jujin.show(jujin.states.left);
jujin.playAnimation(jujin.states.walkUp);
效果:
目前已经将精灵的动作效果告一段落
接下来将键盘事件添加进入
关于键盘移动的方法我使用的是中文网提供的 keyboard 方法
此方法可以监听并捕获键盘事件。
使用起来也很方便:let keyObject = keyboard(keyValue);
可以为 keyboard 对象定义 press 和 release 方法
keyObject.press = () => {
//key object pressed
};
keyObject.release = () => {
//key object released
};
使用 unsubscribe 方法删除事件监听器keyObject.unsubscribe();
下面是 keyboard 方法代码
// 键盘函数
function keyboard(value) {
let key = {};
key.value = value;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
//The `downHandler`
key.downHandler = event => {
if (event.key === key.value) {
if (key.isUp && key.press) key.press();
key.isDown = true;
key.isUp = false;
event.preventDefault();
}
};
//The `upHandler`
key.upHandler = event => {
if (event.key === key.value) {
if (key.isDown && key.release) key.release();
key.isDown = false;
key.isUp = true;
event.preventDefault();
}
};
//Attach event listeners
const downListener = key.downHandler.bind(key);
const upListener = key.upHandler.bind(key);
window.addEventListener(
"keydown", downListener, false
);
window.addEventListener(
"keyup", upListener, false
);
// Detach event listeners
key.unsubscribe = () => {
window.removeEventListener("keydown", downListener);
window.removeEventListener("keyup", upListener);
};
return key;
}
接下来需要多添加一个按键判断方法 keyMove,使用键盘上面的 asdw 控制:
this.keyMove(jujin)
// 键盘控制移动
keyMove(person) {
let left = keyboard('a'), up = keyboard('w'), right = keyboard('d'), down = keyboard('s');
left.press = () => {
// 按键按下使用动作状态
person.playAnimation(person.states.walkLeft);
person.vx = -2;
person.vy = 0;
};
left.release = () => {
// 停止动作状态
person.stopAnimation();
// 每次按键抬起时使用静止状态
person.show(person.states.left);
person.vx = 0;
person.vy = 0;
};
right.press = () => {
person.playAnimation(person.states.walkRight);
person.vx = 2;
person.vy = 0;
};
right.release = () => {
person.stopAnimation();
person.show(person.states.right);
person.vx = 0;
person.vy = 0;
};
up.press = () => {
person.playAnimation(person.states.walkUp);
// person.show(person.states.up);
person.vx = 0;
person.vy = -2;
};
up.release = () => {
person.stopAnimation();
person.show(person.states.up);
person.vx = 0;
person.vy = 0;
};
down.press = () => {
person.playAnimation(person.states.walkDown);
// person.show(person.states.down);
person.vx = 0;
person.vy = 2;
};
down.release = () => {
person.stopAnimation();
person.show(person.states.down);
person.vx = 0;
person.vy = 0;
};
},
对了,在使用时要记得加上精灵的运动
this.app.ticker.add(()=> this.gameLoop(jujin ));
gameLoop(person){
person.x += person.vx;
person.y += person.vy;
},
这样操作之后,就可以达到键盘控制精灵运动的效果了
完整代码
<template>
<div id="animation"></div>
</template>
<script>
import * as pixi from 'pixi.js'
// 键盘函数
function keyboard(value) {
let key = {};
key.value = value;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
//The `downHandler`
key.downHandler = event => {
if (event.key === key.value) {
if (key.isUp && key.press) key.press();
key.isDown = true;
key.isUp = false;
event.preventDefault();
}
};
//The `upHandler`
key.upHandler = event => {
if (event.key === key.value) {
if (key.isDown && key.release) key.release();
key.isDown = false;
key.isUp = true;
event.preventDefault();
}
};
//Attach event listeners
const downListener = key.downHandler.bind(key);
const upListener = key.upHandler.bind(key);
window.addEventListener(
"keydown", downListener, false
);
window.addEventListener(
"keyup", upListener, false
);
// Detach event listeners
key.unsubscribe = () => {
window.removeEventListener("keydown", downListener);
window.removeEventListener("keyup", upListener);
};
return key;
}
export default {
name:'animation',
components: {},
props: {},
data() {
return {
loader: null,
app:null,
player: null,
};
},
created() {},
mounted() {
this.initState();
this.players();
},
watch: {},
computed: {},
methods: {
initState() {
this.loader = new pixi.Loader();
//Create a Pixi Application 创建一个pixi应用
this.app = new pixi.Application({
width: 735, // default: 800 宽度
height: 640, // default: 600 高度
antialias: true, // default: false 反锯齿
transparent: true, // default: false 透明度
resolution: 1 , // default: 1 分辨率
backgroundAlpha: 1 // 设置背景颜色透明度 0是透明
});
//其实上面已经设置透明了,这就没必要设置背景颜色了
this.app.renderer.backgroundColor = 0x000000;
document.getElementById('animation').appendChild(this.app.view)
this.app.renderer.view.style.display = "block";
this.app.renderer.view.style.marginLeft = "30px"; //设置canvas的左外边距
this.app.renderer.autoResize = true;
this.app.renderer.view.style.border = "1px dashed black"; //设置边框
},
players() {
let stage = this.app.stage, Container = pixi.Container, Graphics = pixi.Graphics, player = this.player, TextureCache = pixi.utils.TextureCache,
Texture = pixi.Texture, Rectangle = pixi.Rectangle, AnimatedSprite = pixi.AnimatedSprite;
/******************* 加载纹理贴图,创造精灵,并将精灵添加到stage舞台上 *******************/
let jujinPng = './baoke/an3.png'
this.loader.add([{name:'jujin', url: jujinPng}]).load(()=>{
// 使用SpriteUtilities
let animate = new SpriteUtilities(pixi);
// console.log(animate)
//创建纹理数组 将雪碧图变成纹理数组 66,48
let frames = animate.filmstrip(jujinPng, 84, 81);
// 创建纹理数组 只使用雪碧图中的一部分
// let frames = animate.frames(jujinPng,[[0,0],[66,0],[132,0],[198,0]], 66, 48);
// console.log(frames)
let jujin = animate.sprite(frames); //使用SpriteUtilities创建精灵
// let jujin = this.setTexture(frames); //使用之前的方法创建精灵
stage.addChild(jujin);
jujin.animationSpeed=0.08;
jujin.vx = 0;
jujin.vy = 0;
// jujin.play();
// 设置一个states对象字面量属性
jujin.states = {
down: 0,
left: 4,
right: 8,
up: 12,
walkDown: [0, 3],
walkLeft: [4, 7],
walkRight: [8, 11],
walkUp: [12, 15]
};
this.keyMove(jujin)
this.app.ticker.add(()=> this.gameLoop(jujin ));
})
},
// 键盘控制移动
keyMove(person) {
let left = keyboard('a'), up = keyboard('w'), right = keyboard('d'), down = keyboard('s');
left.press = () => {
// person.show(person.states.left);
person.playAnimation(person.states.walkLeft);
person.vx = -2;
person.vy = 0;
};
left.release = () => {
person.stopAnimation();
person.show(person.states.left);
person.vx = 0;
person.vy = 0;
};
right.press = () => {
person.playAnimation(person.states.walkRight);
person.vx = 2;
person.vy = 0;
};
right.release = () => {
person.stopAnimation();
person.show(person.states.right);
person.vx = 0;
person.vy = 0;
};
up.press = () => {
person.playAnimation(person.states.walkUp);
// person.show(person.states.up);
person.vx = 0;
person.vy = -2;
};
up.release = () => {
person.stopAnimation();
person.show(person.states.up);
person.vx = 0;
person.vy = 0;
};
down.press = () => {
person.playAnimation(person.states.walkDown);
// person.show(person.states.down);
person.vx = 0;
person.vy = 2;
};
down.release = () => {
person.stopAnimation();
person.show(person.states.down);
person.vx = 0;
person.vy = 0;
};
},
gameLoop(person){
person.x += person.vx;
person.y += person.vy;
},
setTexture (texture) {
// console.log(texture)
let sprite = new pixi.AnimatedSprite(texture);
return sprite;
},
},
};
</script>
<style scoped>
</style>
版权声明: 本文为 InfoQ 作者【空城机】的原创文章。
原文链接:【http://xie.infoq.cn/article/9bec5553d98dcb9df69c26d6d】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
空城机
曾经沧海难为水,只是当时已惘然 2021.03.22 加入
业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步
评论