基于vue的小demo
拖动拼图块,组成拼图
<!-- 多余类名可去掉 -->
<canvas ref="canvasDom" class="lcter scene-canvas" id="canvas"></canvas>
我的vue文件里面引入的东西
import * as PIXI from 'pixi.js'
import { onMounted, ref } from 'vue'
相关逻辑代码,有部分代码涉及到pixi的loader问题。
我是提前使用loader加载项目所有用到的切图后存起来的,然后使用进度条的方式展现在最高层,这样用户进入页面时候会先提示进度条,代表资源加载进度。
const app = ref()
// 这一块是我们项目中已经有对项目的静态资源统一进行了加载,这里我就不做加载模块的展示啦
// 你们自行百度一下pixi加载静态资源 自行根据资源加载和取名
// 你们自行去用pixi的load对资源进行加载即可 不懂的话 百度有
const textureList = PIXI.utils.TextureCache;
const canvasDom = ref(null);
// 定义碎片的信息数组
const puzzleArr = [
{
id: 0,
name: 'puzzle_item01.png',
x: 620,
y: 470,
correct: false,
},
{
id: 1,
name: 'puzzle_item02.png',
x: 660,
y: 280,
correct: false,
},
{
id: 2,
name: 'puzzle_item03.png',
x: 980,
y: 480,
correct: false,
},
{
id: 3,
name: 'puzzle_item04.png',
x: 960,
y: 300,
correct: false,
},
]
// 定义正确的位置
const correctPosition = [
{
x2: 812,
y2: 284
},
{
x2: 864,
y2: 458
},
{
x2: 760,
y2: 460
},
{
x2: 811,
y2: 572
},
]
// 等页面初始化完成后才能获取到dom
onMounted(() => {
app.value = new PIXI.Application({
view: canvasDom.value,
width: 1624,
height: 750,
backgroundColor: 0xb2b2b2,
resolution: window.devicePixelRatio || 1,
antialias: true, //抗锯齿
});
});
// 这里我直接全部写进一个函数 方便进入页面直接调用即可
const puzzleDemo = () => {
// 定义碎片的信息数组
const puzzleArr = [
{
id: 0,
//图片名称 这里取名就是对应了加载模块的
name: 'puzzle_item01.png',
// 初始化碎片一开始的定位
x: 620,
y: 470,
//是否已经在正确位置
correct: false,
},
{
id: 1,
name: 'puzzle_item02.png',
x: 660,
y: 280,
correct: false,
},
{
id: 2,
name: 'puzzle_item03.png',
x: 980,
y: 480,
correct: false,
},
{
id: 3,
name: 'puzzle_item04.png',
x: 960,
y: 300,
correct: false,
},
]
// 定义正确的位置
const correctPosition = [
{
x2: 812,
y2: 284
},
{
x2: 864,
y2: 458
},
{
x2: 760,
y2: 460
},
{
x2: 811,
y2: 572
},
]
// app容器
let content = app.value.stage;
//当前选择的精灵
let dragTarget = null;
// 拖动到正确位置的差值(越大范围越大就是不需要贴得那么贴合就自动判断为正确)
let correctRange = 25;
// 当前的下标
let currentIndex;
// 创建一个拼图的容器
const puzzleContainer: any = new PIXI.Container();
// 开启事件功能
puzzleContainer.interactive = true;
puzzleContainer.eventMode = 'static';
// 添加到主父容器
content.addChild(puzzleContainer)
// 添加完整的拼图样子展示在页面
let contentSprite = new PIXI.Sprite(textureList['puzzle_content.png']);
// 设置中心点
contentSprite.anchor.set(0.5);
// 居中显示
contentSprite.position.set(app.value.screen.width / 2, app.value.screen.height / 2);
// 添加到拼图容器里
puzzleContainer.addChild(contentSprite)
// 循环创建碎片精灵
for (let i = 0; i < puzzleArr.length; i++) {
createPuzzle(puzzleArr[i])
}
// 创建精灵
function createPuzzle(item) {
let { id, name, x, y } = item
// 创建碎片精灵。 这里用到的textlist 在上面已经做过解释啦
const puzzle: any = new PIXI.Sprite(textureList[name]);
// 提前设置好定位
puzzle.position.set(x, y);
puzzle.anchor.set(0.5);
puzzle.eventMode = "static";
puzzle.interactive = true;
// 添加按下事件
puzzle.on("pointerdown", onPuzzleDown, puzzle)
puzzle['puzzleIndex'] = id
puzzleContainer.addChild(puzzle);
}
// 当前选择的第几个的下标
function onPuzzleDown(e) {
currentIndex = this.puzzleIndex;
// 把当前选择的定义给赋值出去
dragTarget = this;
// 这里让层级在最上面
puzzleContainer.setChildIndex(this, puzzleContainer.children.length - 1)
puzzleContainer.on("pointermove", onPuzzleMove);
}
// 鼠标移动函数
function onPuzzleMove(e) {
if (dragTarget) {
// console.log('移动看看e.data.global', e.data.global);
dragTarget.parent.toLocal(e.data.global, null, dragTarget.position);
}
}
// 鼠标按键松开函数
function onPuzzleUp(e) {
if (dragTarget) {
console.log('看看起来的定位', dragTarget.position);
let { x, y } = dragTarget.position;
let { x2, y2 } = correctPosition[currentIndex];
// 相差正负12以内
if (x > x2 - correctRange && x < x2 + correctRange && y > y2 - correctRange && y < y2 + correctRange) {
dragTarget.position.set(x2, y2)
puzzleArr[currentIndex].correct = true;
// 对精灵是否在正确位置进行修改
let identifyArr = puzzleArr.map(item => {
return item.correct === true
})
// 数组判断找不到false说明全部拼到正确位置啦
if (identifyArr.indexOf(false) === -1) {
// 执行相关拼图逻辑
puzzleSuccess()
}
} else {
// let { x, y } = puzzleArr[currentIndex];
// 回到原位
// dragTarget.position.set(x, y);
// 状态重新改为false
puzzleArr[currentIndex].correct = false;
}
puzzleContainer.off('pointermove', onPuzzleMove);
dragTarget = null;
}
}
function puzzleSuccess () {
console.log('拼图成功呀--执行逻辑');
// 这里可以执行拼图成功后的相关逻辑
}
puzzleContainer.on('pointerup', onPuzzleUp);
puzzleContainer.on('pointerupoutside', onPuzzleUp);
}
如果有不懂可以问我,亦或者下期出加载的相关逻辑代码和有什么优点
(此demo是一年前学习pixi的时候写的,如有不足请谅解)