以下是学习learn PIXI.js这本书的学习笔记,也是对我前一篇文章的补充——pixi的使用之创建和操作精灵,主要是个人读书笔记性质,为以后参考之用。本文是本人阅读并翻译原版书籍而来,原著虽短且浅,但翻译终归枯燥,断断续续花了我不少时间,如有对读者有所帮助,幸甚至哉。
我也是一个比较懒的人,基本要求是自己看得懂就行,所以本文几乎在细节方面无任何打磨,翻译、代码等几乎处于原生态状态,错误毫无疑问是处处都有,请各位包涵。
-
Sprite.fromImag()
方法不推荐使用,最好还是在创造精灵之前就加载图片生成材质,建议使用PIXI.loader.add
的办法,否则可能会遇到问题。 -
anySprite.destroy()
几乎不会被用到,除非发现不寻常的GPU高占用,通常情况下用visible就可以。 -
参考上条,材质也有destroy方法。
-
可以将任何Image对象和Canvas对象制作成精灵。
let base=new BaseTexture(anyIamgeObject), //let base=BaseTexture.fromCanvas(anyCanvasElement); texture=new Texture(base), sprite=new Sprite(texture); 复制代码
-
使用
PIXI.loader.reset()
来重置loader。 -
pixi中的一切,无论是container还是sprite,默认的旋转中心都是左上角,如果要把旋转中心设置成中心点,可以使用
anySprite.anchor.set(0.5,0.5)
。 -
与anchor类似的是pivot,不同的是pivot的参数填的是像素单位。
-
frame的用法。
//tileSet是一张精灵图 let texture=TextureCache["images/tileSet.png"]; let rectangle=new Rectangle(160,260,32,32); texture.frame=rectangle; let adventures=new Sprite(texture); 复制代码
-
封装一个截取精灵图的方法。
function frame(source,x,y,width,height){ let texture,imageFrame; //if the source is a string, it's either a texture in the cache or an image file if(typeof source==="string"){ if(TextureCache[source]){ texture=new Texture(TextureCache[source]); } }else if(source instanceof Texture){//if the `source` is a texture,use it texture=new Texture(source); } if(!texture){ console.log(`please load the ${source} texture into the cache.`) }else{ imageFrame=new Rectangle(x,y,width,height); texture.frame=imageFrame; return texture; } } 复制代码
-
阻止从精灵图上截取的精灵不够精确的现象发生(所谓的texture bleed)
//精确模式 texture.baseTexture.scaleMode=PIXI.SCALE_MODES.NEAREST //默认模式 texture.baseTexture.scaleMode=PIXI.SCALE_MODES.LINEAR 复制代码
-
推荐使用精灵图打包工具——Texture Packer, 或者使用
Shoebox(renderhjs.net/shoebox)
或者Spritesheet.js(github.com/krzysztof-o/spritesheet.js)
1,第一种方式,只加载json文件
//json格式如下,meta指向了精灵图位置 { "meta": { "image": "atlas.png" }, "frames": { "icon_1.png": { "frame": {"x":0, "y":0, "w":32, "h":32}, "sourceSize": {"w": 32, "h": 32} }, "icon_2.png": { "frame": {"x":32, "y":0, "w":64, "h":64}, "sourceSize":{"w": 64, "h": 64} }, ... } } PIXI.loader .add('atlas', 'atlas.json') .load(onAssetsLoaded); //似乎只有通过loader.add方式加载的图片,才能在PIXI.resourses里被找到(未验证) function onAssetsLoaded() { ... } 复制代码
2,第二种方式,用spritesheet
//加载精灵图制作材质 const baseTexture = PXBaseTexture.from(iconsImg, null, 1); //加载json文件对材质进行裁剪,制作sheet const spritesheet = new PXSpritesheet(baseTexture, iconsJson); spritesheet.parse(textures => { this.isLoaded = true; }); 复制代码
-
根舞台(root stage)的宽高通常跟它包含的最大的sprite的宽高是一致的,但并非永远如此,如果你想知道renderer的精确宽高,用
renderer.view.width
和renderer.view.width
-
封装一个判断元素是否触及render边界的方法
function contain(sprite,container){ var collision=new Set(); if(sprite.x<container.x){ sprite.x=container.x; collison.add("left"); } if(sprite.y<container.y){ sprite.y=container.y; collison.add("top"); } if(sprite.x+sprite.width<container.width){ sprite.x=container.width-sprite.width; collison.add("right"); } if(sprite.x+sprite.height<container.height){ sprite.x=container.height-sprite.height; collison.add("bottom"); } if(collison.size===0){ collison=undefined; } return collison; } 复制代码
-
如果用webGlRender制作图元,图元的边缘可能会有参差不齐的情况,为了修复,可以进一步将图元制作成sprite,注意用的是
generateTextutre
let circle=new Graphics(); circle.beginFill(0xFF9933); circle.lineStyle(4,0x006600,1); circle.drawCircle(0,0,48); circle.endFill(); let circleTexture=circle.generateTextutre(); let circleSprite=new Sprite(circleTexture); circleSprite.x=212; circleSprite.y=64; stage.addChild(circleSprite); 复制代码
-
sprite相对于其container的坐标被称为local position,而相对于root container(一般是stage)的坐标叫global position
-
所有的sprite都可以通过设置它的tint属性来改变其颜色,默认tint是0xFFFFFFF,也就是无tint
-
PIXI可以做幻灯片效果(movieclip),引入SpriteUtilities
-
做烟雾、爆炸等效果时,可以引入第三方库dust
-
平铺效果
let tilingSrpite = new TilingSprite( //texture,width,height TextureCache["images/tile.png",192,192] ); 复制代码
-
通过已存在的精灵来制作材质
//triangle为已存在的精灵 let trangleTexture=triangle.generateTexture(); let triangleSprite=new Sprite(trangleTexture) 复制代码
-
cacheAsBitmap
——跟generateTexture类似的属性是cacheAsBitmap,想象一下,你有一个container或者sprite,里面包含了几千个子sprites,我们只需要让它整体以一张image的形式展示,而不必渲染其中的每一个部分。你只需要将父sprite或者container的cacheAsBitmap属性设置为truesprite.cacheAsBitmap=true; 复制代码
如果子sprite正处于运动状态,它们将会马上静止。将cacheAsBitmap回复成false将会让父级入场render,并且解封子sprites。
-
renderTexture……待补充
-
mask,遮罩,只显示选定区域
let cat=new Sprite(id["cat.png"]); let rectangle=new Graphics(); cat.mask=rectangle; 复制代码
以下内容看得不仔细,工作中暂时用不到,简单记录下,以后用到再来查。
-
sprite的曲线运动,可以使用Rope Mesh
-
sprite的移动,除了可以使用keyframe,也可以使用tweening and transitions,考虑引入第三方库,Tween.js,Dynamic以及Charm.js。
-
PIXI的鼠标和触碰事件引入第三方库,Tink, 多点触控可以考虑另一个插件hammer.js
let t=new Tink(PIXI,renderer.view); //三个事件 pointer.press=()=>console.log("the pointer was pressed"); pointer.release=()=>console.log("the pointer was released"); pointer.tap=()=>console.log("the pointer was tapped"); //触发点坐标 pointer.x pointer.y //三种状态 pointer.isUp pointer.isDown pointer.tapped //判断是否接触到了某个sprite pointer.hitTestSprite(anySprite); //如果是环形的sprite,比如说空心的,也可以判断,但是要给sprite加一个属性 anyCircularSprite.circular=true; //鼠标(手指)接触元素时设置pointer if(pinter.hitTestSprite(anySprite)){ pointer.cursor="pointer"; }else{ pointer.cursor="auto" } //拖拽事件 t.makeDraggable(sprite1,sprite2...) //禁止拖动 anySprite.draggable=false; //彻底将元素移出拖拽体系 t.makeUndraggable(sprite1,sprite2...) //可以用tink制作可交互的button let playButton=t.button(buttonFrames,32,96); stage.addChild(playButton); //制作可交互的sprites t.makeInteractive(anySprite); anySprite.press=()=>{ //do sth } anySprite.release=()={ //do sth } 复制代码