学习 PixiJS — 交互工具_weixin_33971205的博客-程序员宅基地

技术标签: ui  json  

说明

Pixi 内置一组功能有限的用于鼠标交互和触摸交互的方法,但是对于游戏和应用程序所需的丰富交互性,建议使用第三方库来简化操作,这篇文章介绍的是 Tink 库,它有通用的指针对象、拖放精灵、按钮对象、键盘控制 等一些有用的功能。

使用 Tink

要开始使用 Tink ,首先直接用 script 标签,引入 js 文件。

<script src="https://www.kkkk1000.com/js/tink.js"></script>
复制代码

然后创建它的实例,它的构造函数需要两个参数,一个是 PIXI,另一个是渲染器的 view 属性,也就是用作视图的 canvas 元素。

let t = new Tink(PIXI, renderer.view);
复制代码

变量 t 现在代表 Tink 实例,可以使用它来访问 Tink 的所有方法。

接下来,在游戏循环中调用 Tinkupdate 方法,来更新交互的对象,如下所示:

function gameLoop(){
	requestAnimationFrame(gameLoop);
	state();
	t.update();
	renderer.render(stage);
}
复制代码

scaleToWindow 函数

这里提供一个 scaleToWindow 函数,它可以将画布缩放到浏览器窗口的最大大小。

scaleToWindow 函数的源码在这,使用方法如下所示:

let scale = scaleToWindow(renderer.view, borderColor);
复制代码

它需要两个参数,一个是需要缩放的 canvas 元素,另一个参数是可选的,表示与画布相邻的浏览器背景的颜色,它可以是任何RGB,HSLA 或十六进制颜色值,以及任何 HTML 颜色字符串,例如 blue 或者 red 。

scaleToWindow 函数还返回画布缩放到的缩放值。

设置缩放比例

Tink 的构造函数还可以传入第三个参数,这个可选的参数用来确保 Tink 使用的坐标将匹配画布的缩放像素坐标。在创建实例的时候可以直接使用 scaleToWindow 函数的返回值,作为第三个参数。

let scale = scaleToWindow(renderer.view);
let t = new Tink(PIXI, renderer.view, scale);
复制代码

指针对象

使用 TinkmakePointer 方法可以创建指针对象,它可以自动确定用户是鼠标交互还是通过触摸进行交互。

let pointer = t.makePointer();
复制代码

通常,一个指针对象足以满足大多数游戏或应用程序的需求,但你也可以根据需要制作多个指针对象。

但是如果你的游戏或应用程序需要进行复杂的多点触控交互,可以考虑使用 Hammer 库。

指针对象有三种事件:

  • press:按下鼠标左键或用户将手指按到设备屏幕时触发
  • release:释放鼠标按键时或者用户将手指从屏幕上抬起时触发
  • tap:单击鼠标左键,或者用户点击屏幕时触发

用法:

pointer.press = () => console.log("触发 pressed 事件");
pointer.release = () => console.log("触发 released 事件");
pointer.tap = () => console.log("触发 tapped 事件");
复制代码

指针对象还有 xy 属性,表示它在画布上的位置。

pointer.x
pointer.y
复制代码

它还有三个 Boolean 属性,用于指示指针的当前状态:isUpisDowntapped

pointer.isUp
pointer.isDown
pointer.tapped
复制代码

查看示例

指针对象与精灵的交互

指针对象有一个 hitTestSprite 方法,可以使用它来检测指针是否正在接触精灵。

pointer.hitTestSprite(anySprite);
复制代码

如果指针位于精灵的矩形区域内,则 hitTestSprite 将返回 true 。

查看示例

hitTestSprite 方法也适用于圆形精灵。只需将精灵的 circular 属性设置为 true 即可。

anyCircularSprite.circular = true;
复制代码

这样 hitTestSprite 方法就使用圆形碰撞检测算法,而不是默认的矩形碰撞检测算法。

查看示例

如果需要指针位于精灵上时显示手形图标,可以将指针的 cursor 属性设置为 pointer。当指针离开精灵区域时将其设置为 auto 将显示默认箭头图标。

示例:

if (pointer.hitTestSprite(anySprite)) {
    //当指针在精灵上时显示一个手形图标
    pointer.cursor = "pointer";
} else {
    //当指针移出精灵区域时显示默认箭头图标
    pointer.cursor = "auto";
}
复制代码

pointer.cursor 只是引用 canvas 元素的 style.cursor 属性来实现这一点。你也可以手动设置任何你喜欢的光标样式值。方法如下:

renderer.view.style.cursor  = "cursorStyle"
复制代码

不过,这些光标样式仅适用于基于鼠标的界面,在触摸界面上,不会起作用。

示例:

在示例中可以看到将指针移到方形和圆形精灵上,光标是变化的。文本还会根据指针接触的内容显示 矩形!圆形!没有接触到精灵!。因为圆形精灵的 circular 属性设置为 true,你能看到圆形的形状会被准确检测到。以下是实现效果的关键代码:

if (pointer.hitTestSprite(rectangle)) {
    message.text = "矩形!";
    pointer.cursor = "pointer";
} else if (pointer.hitTestSprite(circle)) {
    message.text = "圆形!";
    pointer.cursor = "pointer";
} else {
    message.text = "没有接触到精灵!";
    pointer.cursor = "auto";
}
复制代码

查看示例

拖放精灵

你可以使用 TinkmakeDraggable 方法向精灵添加拖放功能,它的参数是一个想要可以拖动的精灵或精灵列表。

示例:

t.makeDraggable(sprite1, sprite2, sprite3);
复制代码

选择可拖动的精灵时,其堆叠顺序会发生变化,拖动的精灵会显示在其他精灵上方。鼠标箭头图标在可拖动的精灵上时也会变为手形。

查看示例

可拖动的精灵有一个名为 draggable 的 Boolean 属性,默认值为 true 。要禁用拖动,将draggable 设置为 false 即可。

anySprite.draggable = false;
复制代码

将其设置为 true 将再次启用拖动。

要从拖放系统中完全删除精灵或精灵列表,需要使用 makeUndraggable 方法,如下所示:

t.makeUndraggable(sprite1, sprite2, sprite3);
复制代码

按钮

按钮是一个重要的用户界面(UI)组件。Tink 有一个 button 方法,用来创建按钮。在这之前让我们先来了解下什么是按钮。

什么是按钮?

你可以将按钮理解为可点击或者可触摸的精灵。它们具有状态和动作。状态定义按钮的外观,动作定义它的作用。

大多数按钮具有以下三种状态:

  • up:指针未触摸按钮时的状态
  • over:当指针在按钮上时的状态
  • down:当指针按下按钮时的状态

如下图所示

基于触摸的界面的按钮只有两种状态: updown

你可以通过按钮的 state 属性访问这些状态,如下所示:

playButton.state
复制代码

state 属性可能有 upoverdown 这三个字符串值,你可以在游戏逻辑中使用它。

按钮的动作,如下所示:

  • press:当指针按下按钮时
  • release:指针从按钮释放时
  • over:当指针移动到按钮区域时
  • out:当指针移出按钮区域时
  • tap:点击按钮时

你可以为这些动作定义一个函数,当执行了相应操作时,会触发这个函数,如下所示。

playButton.press = () => console.log("pressed");
playButton.release = () => console.log("released");
playButton.over = () => console.log("over");
playButton.out = () => console.log("out");
playButton.tap = () => console.log("tapped");
复制代码

在按钮对象中,使用 action 属性可以知道当前是 pressed 操作还是 released 操作。

playButton.action
复制代码

制作按钮

首先,从定义三个按钮状态的三个图像开始。三个图像分别是 up.png,over.png 和 down.png 。然后将这三个图像做成纹理贴图集 ,你可以使用 Texture Packer 这个工具来制作。

接下来,加载纹理图集到程序中。

//加载纹理贴图集,加载完后执行 setup 函数
loader.add("images/button.json").load(setup);
复制代码

然后,在初始化精灵的 setup 函数中,创建一个数组,该数组有个三个成员,按顺序分别对应按钮的 up, over, 和 down 的状态。

let id = PIXI.loader.resources["images/button.json"].textures;
let buttonFrames = [
    id["up.png"],
    id["over.png"],
    id["down.png"]
];
复制代码

数组中的成员其实不必非要是纹理贴图集中的帧,如果你愿意,也可以使用任何单个图像纹理。

最后,使用 Tinkbutton 方法创建按钮。使用 buttonFrames 数组作为第一个参数。

第二个和第三个参数是按钮的 x 和 y 坐标,默认值都是0 。

let playButton = t.button(buttonFrames, 32, 96);
复制代码

千万不要忘记将按钮添加到舞台上!

stage.addChild(playButton);
复制代码

示例:

在示例中可以看到将指针移到按钮上时,光标变为手形图标。而且在视图中还会根据按钮状态和动作显示相应的文本。

查看示例

从本质上讲,按钮只是一个普通的 Pixi 动画精灵,因此你可以像对待其他动画精灵一样对待它。

制作交互式精灵

Tink 有另一个名为 makeInteractive 的方法,它允许你向任何普通精灵添加按钮属性和方法。

t.makeInteractive(anySprite);
复制代码

这可以将任何精灵转换为类似按钮的对象,然后你可以为精灵添加 pressrelease 事件方法。并且可以访问它的 stateaction 属性,如下所示:

anySprite.press = () => {
    //当指针按下精灵时执行某些操作
};
anySprite.release = () => {
    //按下精灵后释放指针时执行某些操作
};

function play() {
    stateMessage.text = `State: ${anySprite.state}`;
    actionMessage.text = `Action: ${anySprite.action}`;
}
复制代码

查看示例

键盘控制

keyboard 是一种监听和捕获键盘事件的方法。它实际上只是将原生的 keyup 和 keydown 事件封装起来而已,以下是如何使用 keyboard 方法。创建一个新的键盘对象(keyObject ):

let keyObject = t.keyboard(asciiKeyCodeNumber);
复制代码

它的参数是你要监听的键盘键编码,你可以在这里查看每个键对应的编码。然后你就可以为返回值(keyObject)定义 pressrelease 方法,如下所示:

keyObject.press = () => {
    //按键按下时执行某些操作
};
keyObject.release = () => {
    //按键释放时执行某些操作
};
复制代码

keyObject 还具有 isDownisUp 布尔属性,你可以使用它们来检查每个键的状态。

Tink 还有另一个方便的方法 arrowControl ,可以让你使用键盘方向键快速为精灵创建一个4个方向的控制器。这个方法需要两个参数,第一个是需要控制的精灵,第二个是移动速度。

示例:

t.arrowControl(anySprite, 5);
anySprite.vx = 0;
anySprite.vy = 0;
复制代码

因为 arrowControl 方法能让精灵移动,用到了精灵的速度属性(vx,vy),所以需要给这两个属性一个初始值,然后在游戏循环中需要更新精灵的位置,如下所示:

function play() {
    anySprite.x += anySprite.vx;
    anySprite.y += anySprite.vy;
}
复制代码

最后,就可以使用箭头键在四个方向上移动精灵了。

查看示例

注意:
使用高于 4.2.1 版本的 Pixi 时,需要将 tink.js 文件中的 extras.MovieClip 改为 extras.AnimatedSprite

上一篇 学习 PixiJS — 碰撞检测

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33971205/article/details/88216994

智能推荐

bootstrap 分页行数选择按钮失效_weixin_30619101的博客-程序员宅基地

原因是bootstrap.js重复加载,button点击作用两次,导致没效果转载于:https://www.cnblogs.com/codeDevotee/p/9895147.html

P3366 【模板】最小生成树_qq_34593871的博客-程序员宅基地

题目描述如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz输入输出格式输入格式: 第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi输出格式: 输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz输入输出样例输入样例#1:

php-5.4.,安装PHPphp-5.4.4_weixin_39538451的博客-程序员宅基地

一、下载PHPphp-5.4.4[[emailprotected] software]# pwd/software[[emailprotected] software]# wget http://mirrors.sohu.com/php/php-5.4.44.tar.gz二、解压php-5.4.44.tar.gz[[emailprotected] software]# tar -xzvf p...

【Python之路——基础回顾90列】_AA8j的博客-程序员宅基地

一、Python基础Python基础主要总结Python常用内置函数;Python独有的语法特性、关键词nonlocal,global 等;内置数据结构包括:列表(list),字典(dict),集合(set),元组(tuple) 以及相关的高级模块 collections 中的 Counter,namedtuple,defaultdict,heapq 模块。目前共有 90 个小例子。1 求绝对值求绝对值或复数的模&gt;&gt;&gt; abs(-6)62 元素都为真接受一个迭代器,如果迭代

Exchange Server 2010 部署全攻略(一)_weixin_33885676的博客-程序员宅基地

 Exchange Server 2010    部署全攻略数据可用性组配置、NLB实现、Exchange迁移最新版本的 Exchange 可以控制部署、管理和合规性成本,从而帮助您提升业绩。Exchange 提供最广泛的部署选项、集成的信息泄露保护和高级符合性功能,共同组成当前最佳的消息传递和协作解决方案。王缘2010/01/20  概述  由于您...

虚拟服务器拷贝数据,虚拟云服务器拷贝数据_花嫁wsh的博客-程序员宅基地

虚拟云服务器拷贝数据 内容精选换一换华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档,帮助您快速上手使用华为云服务。当我们部署在裸金属服务器上的系统出现外部病毒入侵、人为误操作、业务软件Bug等故障场景时,可以通过云服务器备份服务(Cloud Server Backup Service,CSBS)为裸金属服务器创建定期自动备份(备...

随便推点

Apache Beam发布第一个稳定版本_weixin_34244102的博客-程序员宅基地

Apache Beam在官方博客上正式发布了Beam 2.0.0。这是Beam有史以来的第一个稳定版本,根据Beam社区的声明,Beam意欲为未来版本发布保持API的稳定性,并让Beam适用于企业的部署。Beam的第一个稳定版本是Beam社区发布的第三个重要里程碑。Beam在2016年2月成为Apache孵化器项目,并在同年12月升级成为Apache基...

初探Java设计模式4:JDK中的设计模式_黄小斜的博客-程序员宅基地

JDK中设计模式本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图。首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK和设计模式有所帮助。一、设计模式是什么(1)反复出现问题的解决方案(2)增强软件的灵活性(3)适应软件不断变化二、学习JDK中设计模式的好处(1)借鉴优秀代码的设计,有助于提高代码设计能力(2)JDK的设计中体现了大多数设计模式,是学...

校招--深度学习面经记录_hi我是大嘴巴的博客-程序员宅基地

1、Embedding作用Embedding能够用低维向量对物体进行编码仍保留其含义特点Embedding性质: 1)若两物体相似,则其对应向量的距离较近 2)其从另一个空间表达物体,揭示了物体间的前年在联系用途:常常 大体量数据 其 One- hot encoding 维度过高(数据分布过于离散和稀疏化,稀疏不...

Linux信号专题FAQ_weixin_34194317的博客-程序员宅基地

信号: 基本概念可重入、线程安全以及异步信号安全的区别?​   参考可重入、线程安全和异步信号安全,需要强调的是异步信号安全,这个概念知道的人不多,平常大家在编写代码的时候也很少考虑这个因素,也不清楚哪些函数是异步信号安全的,哪些不是,典型的像printf就不是异步信号安全的,内部会加锁,但是平时很多人都喜欢在信号处理函数中调用。大多数情况下都不会出...

PowerMock和Mockito来mock_weixin_34228617的博客-程序员宅基地

2019独角兽企业重金招聘Python工程师标准&gt;&gt;&gt; ...

Android 8.0 内部升级失败_duke_knight的博客-程序员宅基地

其中部分参照 网络大神的文章,自己整理了一下android 8.0 系统,app内部升级失败,因为,Android 8.0 系统内部升级时需要 申请   安装权限 具体步骤如下:1. 在 AndroidManifest 中 添加 以下权限&amp;lt;uses-permission android:name=&quot;android.permission.REQUEST_INSTALL_PACKAG...

推荐文章

热门文章

相关标签