注意:本文代码使用的Pixi.js版本为PixiJS 5.3.3

pixi中常用的鼠标交互事件:

//兼容鼠标和触摸屏的共同触发
type InteractionPointerEvents = "pointerdown" | "pointercancel" | "pointerup" | "pointertap" | "pointerupoutside" | "pointermove" | "pointerover" | "pointerout";
//触摸屏触发事件
type InteractionTouchEvents = "touchstart" | "touchcancel" | "touchend" | "touchendoutside" | "touchmove" | "tap";
//鼠标触发事件
type InteractionMouseEvents = "rightdown" | "mousedown" | "rightup" | "mouseup" | "rightclick" | "click" | "rightupoutside" | "mouseupoutside" | "mousemove" | "mouseover" | "mouseout";

点击事件

首先,我们再Stage中添加一个圆形按钮,将其interactive属性设置为true,并给它绑定一个点击事件。

const point = new Graphics();
point.beginFill(0x0bef47)
point.drawCircle(300, 300, 50)
point.endFill()
point.interactive = true;//响应交互
point.buttonMode = true;//鼠标变手型
point.on("pointerdown", (event: PIXI.InteractionEvent) => {
    console.log("graphics")
})
app.stage.addChild(point)

同样的还可以给舞台stage也添加一个点击事件,因为stage其实就是一个特殊的Container

app.stage.interactive = true;//这个不能忘记
app.stage.on("pointerdown", (event: PIXI.InteractionEvent) => {
    console.log("stage")
})

先测试下,上面的点击事件。

  • 点击point按钮,控制台输出graphics -> stage。由于点击事件传递,触发了按钮和舞台的点击事件。
  • 点击stage空白处,控制台无输出。 这个原因其实是因为Container本身是无法被点击的,需要有一个hitAreagraphics继承于Container,在设定了图形范围后,其实就是确定了hitArea。或者可以直接设定点击区域app.stage.hitArea = new PIXI.Rectangle(0, 0, 300, 300);

还可以在renderer上添加点击事件,这个就可以直接响应在stage空白处的点击事件。

app.renderer.plugins.interaction.on("pointerdown", (event: PIXI.InteractionEvent) => {
    console.log("renderer", event)
})

当然最外面还可以用window的点击事件。

window.addEventListener("pointerdown", (event: any) => {
    console.log("window")
})

最后,点击point按钮就可以看到控制台依次输出的graphics -> stage -> renderer -> window

平移事件(拖拽)

知道了全屏的点击事件后,拖拽平移就简单了。通过dragFlag判断当前是否处于拖拽状态,绑定mousemove事件,移动后修改stageposition即可。

let dragFlag = false;
let startPoint: any;
app.renderer.plugins.interaction.on("mousedown", (event: PIXI.InteractionEvent) => {
    dragFlag = true
    startPoint = { x: event.data.global.x, y: event.data.global.y }
})

app.renderer.plugins.interaction.on("mousemove", (event: PIXI.InteractionEvent) => {
    if (dragFlag) {
        const dx = event.data.global.x - startPoint.x;
        const dy = event.data.global.y - startPoint.y;
        app.stage.position.x += dx;
        app.stage.position.y += dy;
        startPoint = { x: event.data.global.x, y: event.data.global.y }
    }
})

app.renderer.plugins.interaction.on("mouseup", (event: PIXI.InteractionEvent) => {
    dragFlag = false
})

缩放事件

缩放就直接绑定到window上,每次鼠标滚动修改stagescale即可。

window.addEventListener("mousewheel", (event: any) => {
    const step = event.wheelDelta > 0 ? 0.1 : -0.1
    if (app.stage.scale.x + step >= 0.1) {
        app.stage.scale.x += step
        app.stage.scale.y += step
    }
})

总结

总的来说pixi内置的交互方法还是比较简单的,只能满足一些简单使用场景,更多使用样例,可以到 https://pixijs.io/examples/#/interaction/dragging.js 进行预览。
更复杂的使用场景可以引入第三方库Tink来实现。

下面列举一些好用的pixi第三方插件

  • Bump: 一个为了游戏准备的完整的2D碰撞函数集.
  • Tink: 拖放, 按钮, 一个通用的指针和其他有用的交互工具集。
  • Charm: 给Pixi精灵准备的简单易用的缓动动画效果。
  • Dust: 创建像爆炸,火焰和魔法等粒子效果。
  • Sprite Utilities: 创建和使用Pixi精灵的一个更容易和更直观的做法,包括添加状态机和动画播放器。让Pixi的工作变得更有趣。
  • Sound.js:一个加载,控制和生成声音和音乐效果的微型库。包含了一切你需要添加到游戏的声音。
  • Smoothie: 使用真正的时间增量插值实现的超平滑精灵动画。它也允许为你的运行的游戏和应用指定 fps (帧率) ,并且把你的精灵图循环渲染完全从你的应用逻辑循环中分离出去。
12-24 22:41