learn PIXI.js之补充

以下是学习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.widthrenderer.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属性设置为true

    sprite.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
    }
    复制代码

转载于:https://juejin.im/post/5d1f1942e51d45109725fee2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值