游戏说明
一个用pixi.js编写的h5塔防游戏,可以用electron打包为exe,支持移动端,也可以用webview控件打包为app在移动端使用
环境说明
cnpm@6.2.0
npm@6.14.13
node@12.22.7
npminstall@3.28.0
yarn@1.22.10
npm config list
electron_mirror = "https://npm.taobao.org/mirrors/electron/"
home = "https://www.npmjs.org"
registry = "https://registry.npmmirror.com/"
plist说明:
plist在应用中其实是一个多张静态图片打包为一张图片的功能。
主要作用是减少浏览器的请求。多次请求比较耗时间,打包为一张图片,一个xml文件,这样就可以实现多个图片的少加载。
plist主要是在cocos中使用的比较多在pixi中很少见到,并且pixi中的相关加载库也不完善。
pixi实现加载plist思路:
在pixi.js的6.x.x版本中Loader支持registerPlugin可以注册插件。(注意这里的registerPlugin方法在高版本不支持)
registerPlugin传入一个有use方法的对象就可以对加载的资源进行相关处理。
use方法
use(lSou:LoaderResource, next:any) {}
参数一 lSou 是加载的资源
参数二 next 告诉pixi的loader对象我们这一个资源已经加载完成 需要加载下一个资源
use方法主要思路:
第一步.先读取 lSou参数的对象为xml
第二步.获取xml文件里面的图片地址信息
第三步.加载图片等待图片加载完成
第四步.将xml转化为json对象这样可以方便我们循环加载资源因为js对xml的循环不太好
第五步.解析完毕了我们就可以调用next方法进行下一个资源的加载
第一步:
先判断我们获取的资源是否是plist对象的资源,下面是判断是否是plist的方法
function isPlist(lSou:LoaderResource) {
if (lSou.xhr && lSou.xhr.responseText && lSou.xhr.responseText.indexOf("DOCTYPE plist") !== -1) {
return true
} else {
return false
}
}
如果不是plist直接调用next加载下一个资源。
第二步:
根据浏览器的URL对象来拼接获取图片地址
第三步:
通过浏览器的Image对象加载图片
第四步:
读取xml方法:
function readXml(xml:string) {
let o:any = {}
const parser = new DOMParser()
const xmlDoc = parser.parseFromString(xml, "text/xml")
o = loopXmlDom(xmlDoc.firstElementChild, o)
return o
}
调用浏览器的原生对象DOMParser格式化xml文件获取一个dom对象这样方便我们循环xml对象。
循环xml对象将xml转换为json
下面是loopXmlDom的方法
function loopXmlDom(p:Element, o:any) {
if (p.firstElementChild) {
if (p.nodeName === "dict") {
loopXmlDom(p.firstElementChild, o)
} else {
o[p.nodeName] = {}
loopXmlDom(p.firstElementChild, o[p.nodeName])
}
} else {
// o[p.nodeName] = p.textContent
let first = p
let next = first.nextElementSibling
while (first && next) {
if (first.nodeName.toLocaleLowerCase() === "key") {
if (next.firstElementChild) {
if (p.nodeName === "dict") {
loopXmlDom(next, o)
} else {
o[first.textContent] = {}
loopXmlDom(next, o[first.textContent])
}
} else {
o[first.textContent] = next.textContent || next.nodeName
o[first.textContent] = o[first.textContent].replace(/[\{]/g, "[").replace(/[\}]/g, "]")
try {
o[first.textContent] = JSON.parse(o[first.textContent])
} catch (e) {
console.warn(e.toString())
}
}
first = next.nextElementSibling
if (first) {
next = first.nextElementSibling
}
}
}
}
return o
}
在获取到图片和plist储存的文件信息数据我们就可以将图片写入到pixi的纹理对象中
下面是方法
async function loadPlistTexture(json:any, img:any, call:any, opt?:any) {
opt = opt || {}
opt.name = opt.name || "plist_"
const endName = []
for (const i in json) {
const name = opt.name + i
const txture = await Texture.fromLoader(img, "", opt.name + i)
endName.push(name)
try {
if (json[i].rotated) {
txture.frame = new Rectangle(json[i].frame[0][0] + json[i].offset[0], json[i].frame[0][1] + json[i].offset[1], json[i].frame[1][1], json[i].frame[1][0])
txture.orig = new Rectangle(json[i].frame[0][0] + json[i].offset[0], json[i].frame[0][1] + json[i].offset[1], json[i].frame[1][0], json[i].frame[1][1])
txture.rotate = groupD8.S
} else {
txture.frame = new Rectangle(json[i].frame[0][0] + json[i].offset[0], json[i].frame[0][1] + json[i].offset[1], json[i].frame[1][0], json[i].frame[1][1])
txture.orig = new Rectangle(json[i].frame[0][0] + json[i].offset[0], json[i].frame[0][1] + json[i].offset[1], json[i].frame[1][0], json[i].frame[1][1])
}
} catch (e) {
debugger
}
}
call && call(endName)
}
这里我们根据json的数据来写入纹理对象
第五步
这里调用next即可
这是我们要做的目标:
项目开源地址:
GitHub - yinhui1129754/towerDefense: 一个使用pixi.js编写的类似保卫萝卜的塔防游戏。