写点什么

想要做网页游戏怎么办 ?PixiJs 篇(四)

用户头像
空城机
关注
发布于: 2021 年 05 月 16 日
想要做网页游戏怎么办 ?PixiJs 篇(四)

在之前学了一部分的 pixi 之后,还是希望稍微写点和别人不一样的东西,有关碰撞检测之类的文章先略过不写了

现在小游戏中的拳皇因为是 flash 的原因,在我电脑上面已经玩不了了。那我能做一个仿制的么,想想看还是挺有趣的。真的是太年轻了

(脑子:我会了          手:不,你不会!!!)

不会去自己想


使用 pixi.js 做一个拳皇游戏,我逐步发现需要的东西有好多呀!


目前就做出一个最简单的实验品 no1,只有最简单的前进、后退、跳、蹲、跑,轻拳,重拳,轻脚,重脚这几个动作

下面是目前有的效果:

因为上传图片大小限制,所以将 gif 图分开进行展示

初始化和前进


初始化和前进

后退和跳跃


后退和跳跃

下蹲和跑动


下蹲和跑

轻拳和重拳


轻拳和重拳

轻脚和重脚


轻脚和重脚

 

正文开始

素材来源


素材来源依旧是爱给网,当然我在爱给网下载下来的是 gif 图,通过将 GIF 分解成帧图片,然后使用纹理打包器TexturePacker制作为雪碧图


下面是我的 vue 页面和处理好的素材,如果要使用的话,还需要各位网友自己配置好文件和相对位置

链接:https://pan.baidu.com/s/1zYaLQTRdt_4P7J6vAMZb6g 

提取码:7fbd 


雪碧图


基础布局添加

这部分和之前的《想要做网页游戏怎么办 ?PixiJs 篇(二)》较像

首先,先创建好 pixi.Application 场景

initState() {  this.loader = new pixi.Loader();  //Create a Pixi Application   创建一个pixi应用  this.app = new pixi.Application({    width: window.innerWidth,         // default: 800 宽度    height: window.innerHeight,        // default: 600 高度    antialias: true,    // default: false 反锯齿    // transparent: true, // default: false 透明度    resolution: 1 ,      // default: 1 分辨率    backgroundAlpha: 0   // 设置背景颜色透明度   0是透明  });  this.app.renderer.backgroundColor = 0x000000;  document.getElementById('game1').appendChild(this.app.view)  this.app.renderer.view.style.display = "block";  this.app.renderer.view.style.marginLeft = "30px";  this.app.renderer.autoResize = true;    this.bumpInit();  //碰撞检测  // 画布全屏    后面加一个参数可以设置背景色  scaleToWindow(this.app.renderer.view);}
复制代码


然后创建一个添加精灵方法

let bg = './gameImg/bg.png', start = './gameImg/start.png', stand = './gameImg/stand.png', walkqian = './gameImg/walkqian.png', walkhou = './gameImg/walkhou.png', setdown = './gameImg/setdown.png', jump = './gameImg/jump.png', run = './gameImg/run.png', attack = './gameImg/attack.png';this.loader.add([{name:'bg', url: bg}, {name:'start', url: start},{ name:'stand', url: stand },{ name:'walkqian', url: walkqian } ,{ name:'walkhou', url: walkhou }, { name:'setdown', url: setdown }, { name:'jump', url: jump }, { name:'run', url: run } , { name:'attack', url: attack }]).load(()=>{      //具体的添加事件    // 先定义一个SpriteUtilities,这里的this.$SpriteUtilities是在main.js导入的原因    let sput = new this.$SpriteUtilities(pixi); })
复制代码


在 main.js 当中添加 spriteUtilities 全局,这里我已经在 spriteUtilities.js 添加了 export default SpriteUtilities;

import SpriteUtilities from './assets/spriteUtilities'Vue.prototype.$SpriteUtilities = SpriteUtilities   //将SpriteUtilities放入全局
复制代码


战斗场景添加

场景精灵的创建也较为简单,这里注意将场景精灵的宽高设置为屏幕相同即可

并且使用 animationSpeed 去调节精灵的运动速度,注意启动精灵的 play()方法让精灵动起来

//创建纹理数组  将雪碧图变成纹理数组  624, 384// 创建战斗场景let bgframes = sput.filmstrip(bg, 624, 384);let bgsprite = sput.sprite(bgframes);bgsprite.width = window.innerWidth;  //场景精灵的宽高和屏幕相同bgsprite.height = window.innerHeight;bgsprite.animationSpeed = 0.1;  //调节速度bgsprite.play();  // 让精灵运动起来// 精灵加入场景this.addSprite(stage, [bgsprite])
复制代码


场景效果 


人物精灵

人物精灵的添加因为有许多雪碧图,如果像添加战斗场景一样写,那重复语句会很多。

所以这里可以封装一个创建人物精灵的方法

// 封装创建精灵方法createSprite(sput, spng, pwidth, pheight, width, height, animationSpeed, isshow, name, wheight) {    let playerframes = sput.filmstrip(spng, pwidth, pheight);  //解析雪碧图    let sprite = sput.sprite(playerframes);    sprite.width = width;   //设置精灵的宽高    sprite.height = height;    sprite.animationSpeed=animationSpeed; //精灵的运动速度    sprite.position.set(82, wheight * 0.93 - sprite.height)  //精灵初始位置    sprite.visible = isshow;  //精灵是否显示    sprite.name = name   //精灵的别名    return sprite;}
复制代码


这样就可以使用像下面这样的方式大量创建精灵了

因为并不是一副完整的雪碧图,各个动作之间都是存在差别的。所以精灵的大小需要注意,这个可能要自己调试一下,差别比较明显

// 人物前进let walkqiansprite = this.createSprite(sput, walkqian, 68, 104, 210, 288, 0.2, false, 'walkqian', wheight)// 人物后退let walkhousprite = this.createSprite(sput, walkhou, 70, 107, 210, 288, 0.2, false, 'walkhou', wheight)// 人物下蹲let setdownsprite = this.createSprite(sput, setdown, 65, 64, 200, 195, 0.2, false, 'setdown', wheight)// 人物跳动let jumpsprite = this.createSprite(sput, jump, 68, 190, 210, 570, 0.3, false, 'jump', wheight)// 人物跑动let runsprite = this.createSprite(sput, run, 123, 90, 350, 270, 0.3, false, 'run', wheight)playersCont.addChild(walkqiansprite);playersCont.addChild(walkhousprite);playersCont.addChild(setdownsprite);playersCont.addChild(jumpsprite);playersCont.addChild(runsprite);
复制代码


动作精灵的切换

因为是不同的精灵,所以通过玩家操控人物的动作会需要进行的不同切换。我将人物精灵都添加入一个 Container()集合当中

通过控制 Container()中的精灵的 visible 显隐来显示不同的人物动作。


这里要介绍一下 pixi.js 的 API 中的内容,如何去判断精灵动画的结束和开始,正在运行当前动画的哪一帧。通过这样的方式去判断切换不同的动作

PIXI.AnimatedSprite动作状态

这里的运动状态方法和属性还是比较多的,可以进行参考



例子:人物一开始出场动作消失后,在 onComplete 动画结束事件中改变动画精灵。注意要设置出场动画不循环  playersprite.loop = false;

// 初始化动画结束后,显示人物站立动作 
playersprite.onComplete = () => {
playersCont.removeChild(playersprite);
playersCont.addChild(standsprite);
this.currIndex = 'stand'
standsprite.play();
this.keyMove(playersCont);
}
复制代码

 

按键切换

之后在使用按键切换动作时也是类似的原理,关于按键控制动作可以参考:

《想要做网页游戏怎么办 ?PixiJs 篇(三)》

《学习 PixiJS — 精灵状态》


keyboard 方法判断按下的是什么按键

let left = keyboard('a'), up = keyboard('w'), right = keyboard('d'), down = keyboard('s'), quanattack1 = keyboard('u'), jiaoattack1 = keyboard('i'), quanattack2 = keyboard('j'), jiaoattack2 = keyboard('k');
复制代码


例子: 按下键盘 A 键,人物从站立状态变成向后走的状态。  使用 getChildByName 来获取当前的精灵,使用 visible 改变显隐


调整 vx 来改变 Container 的位置

// 按键A按下left.press = () => {    playersCont.getChildByName(this.currIndex).visible = false;    playersCont.getChildByName('walkhou').visible = true    playersCont.getChildByName('walkhou').play();    this.currIndex = 'walkhou';    playersCont.vx = -4;};// 按键松开left.release = () => {    playersCont.vx = 0;    playersCont.getChildByName(this.currIndex).visible = false;    playersCont.getChildByName('stand').visible = true;    this.currIndex = 'stand';};
复制代码


当然在按键切换中,有许多判断还是比较麻烦的

比如说跑动动画的切换,其实是连续按两下 D 键实现的,所以这里就需要我判断按键连续点击。

在两次按下 D 键之间的时间间隔大于 0 和小于 600ms 即可

let ot = 0;right.press = () => {    // getChildAt通过index索引  getChildByName通过name    playersCont.getChildByName(this.currIndex).visible = false;    playersCont.getChildByName('walkqian').visible = true    playersCont.getChildByName('walkqian').play();    this.currIndex = 'walkqian';    playersCont.vx = 4;    // 判断是否双击    let nt = new Date().getTime();    let ct = nt - ot;    if (ct > 0 && ct < 600) {        playersCont.getChildByName(this.currIndex).visible = false;        playersCont.getChildByName('run').visible = true        playersCont.getChildByName('run').play();        this.currIndex = 'run';        playersCont.vx = 12;    }    ot = nt;};
复制代码


还有像跳跃动作,需要这一次跳跃动作结束后,才可以进行下一次跳跃动作,不然就会变得十分鬼畜

 

正常动作:

正常动作

鬼畜动作:

鬼畜动作


其实在按键这一块切换判断时,需要做的判断还有很多,比如说攻击判断等等,当前只是完成了最基础的部分,毕竟 Pixi 虽说性能比较高,但是开发成本一些方法需要自己完善。

 

小节

真的是路漫漫其修远兮,不过关于做前端游戏,我学习 pixi.js 其实也只是自己慢慢练手,毕竟真的去做,还是 Cocos Creator Unity 方便。

如果说接下来我把自己的学习计划完成,去真正学前端游戏的话,目标应该会是 Cocos Creator

发布于: 2021 年 05 月 16 日阅读数: 34
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
想要做网页游戏怎么办 ?PixiJs 篇(四)