Pixi基本概念

基本概念

  • Application

    Application可以自动在HTML中创建<canvas>元素,并且控制在canvas上显示图像。

    //Create a Pixi Application
    let app = new PIXI.Application({width: 256, height: 256});
    
    //Add the canvas that Pixi automatically created for you to the HTML document
    document.body.appendChild(app.view);
    
  • renderer

    Application中有渲染器renderer,通过它可以对画布的形状、分辨率、颜色等进行调节。pixi的渲染默认是WebGL,但也可以通过配置,强制为forceCanvas。

    app.renderer.backgroundColor = 0x061639;
    app.renderer.autoResize = true;
    app.renderer.resize(512, 512);
    
  • stage

    stage是Pixi的 根Container,持有所有要在pixi上显示的对象。

  • sprites

    sprites就是在stage中存储的要显示的对象。我们可与控制它的position、size等等属性。它代表了在canvas上的一个image,有3种创建方式:

    • image file

    • tileset(图集)所谓tileset就是图标图集,一张图上有多个小图片

      tileset
    • texture atlas(纹理图集)

      texture是一种更方便的tileset使用的方式,通过一个json说明各个图片在tileset中的位置,然后用名字可以直接加载它。

sprite基础

创建

  • texture

    texture以一种webgl友好方式来存储图片,方便pixi的renderer高效的渲染。

    let texture = PIXI.utils.TextureCache["images/anySpriteImage.png"];
    let sprite = new PIXI.Sprite(texture);
    
  • loader

    loader用于加载image,并将其转变成texture。使用如下:

    PIXI.loader
      .add("images/anyImage.png")
      .load(setup);
    
    function setup() {
      //This code will run when the loader has finished loading the image
    }
    

    当加载完成之后执行setup函数。

    图像加载之后,需要转变成sprite,通过loader.resources对象来引用对应的texture。

    PIXI.loader
      .add("images/anyImage.png")
      .load(setup);
    
    function setup() {
      let sprite = new PIXI.Sprite(
        PIXI.loader.resources["images/anyImage.png"].texture
      );
    }
    

属性

  • sprites的显示

    只需要将sprite加入到stage中即可,如下:

    app.stage.addChild(cat);
    
  • spirte的位置与形状

    position有(x,y)属性;

    形状上有绝对值的width, height属性,以及成比例的scale属性

    cat.x = 24;
    cat.y = 24;
    cat.position.set(24, 24)
    
    cat.width = 80;
    cat.height = 120;
    
    cat.scale.x = 0.5;
    cat.scale.y = 0.5;
    
  • sprite的rotation属性

    旋转有两个属性:旋转的角度、旋转的中心点。

    cat.ratation = 0.5
    

    0.5是弧度制;

    旋转是根据sprite的左上角旋转的;

    左上角是默认的锚点(anchor),这个锚点是可以设置的

    cat.anchor.x = 0.5;
    cat.anchor.y = 0.5;
    
    cat.anchor.set(x, y)
    

    anchor的值也是比例值,以上代码是设置到中心点。

    另外有一个privot的属性,可以直接它的旋转点。

    cat.privot.set(32, 32)
    

keybord事件

move sprite

自动移动是通过Pixi提供的时钟回调(ticker)来完成的。ticker中的代码会被1秒执行60次。

app.ticker.add(delta => gameLoop(delta))
function gameLoop(delta){
    cat.x += 1;
  }

​ 每秒移动60次,每次1个像素。

可以设置两个移动速度:vx、vy,vx是x轴移动速度,vy是y轴移动速度,然后在移动时进行增加。

通过定义一个keybord,来辅助创建各个keyObject,keyObject指的是对某个按键的操作。然后提供了press与relealse两个接口,通过它两个进行具体的操作。

function keyboard(value) {
  let key = {};
  key.value = value;
  key.isDown = false;
  key.isUp = true;
  key.press = undefined;
  key.release = undefined;
  //The `downHandler`
  key.downHandler = event => {
    if (event.key === key.value) {
      if (key.isUp && key.press) key.press();
      key.isDown = true;
      key.isUp = false;
      event.preventDefault();
    }
  };

  //The `upHandler`
  key.upHandler = event => {
    if (event.key === key.value) {
      if (key.isDown && key.release) key.release();
      key.isDown = false;
      key.isUp = true;
      event.preventDefault();
    }
  };

  //Attach event listeners
  const downListener = key.downHandler.bind(key);
  const upListener = key.upHandler.bind(key);
  
  window.addEventListener(
    "keydown", downListener, false
  );
  window.addEventListener(
    "keyup", upListener, false
  );
  
  // Detach event listeners
  key.unsubscribe = () => {
    window.removeEventListener("keydown", downListener);
    window.removeEventListener("keyup", upListener);
  };
  
  return key;
}

这个代码挺漂亮的。

let keyObject = keyboard("ArrowLeft");
  //Left arrow key `press` method
  left.press = () => {
    //Change the cat's velocity when the key is pressed
    cat.vx = -5;
    cat.vy = 0;
  };
  
  //Left arrow key `release` method
  left.release = () => {
    //If the left arrow has been released, and the right arrow isn't down,
    //and the cat isn't moving vertically:
    //Stop the cat
    if (!right.isDown && cat.vy === 0) {
      cat.vx = 0;
    }
  };

Sprite Group

图元一定是一个组合模式,最外层的stage已经说明了这个问题,在这里sprite goup其实就是用的Container.

Container是有位置、尺寸等属性的,但不能有自己的Texture。

//The cat
let cat = new Sprite(id["cat.png"]);
cat.position.set(16, 16);

//The hedgehog
let hedgehog = new Sprite(id["hedgehog.png"]);
hedgehog.position.set(32, 32);

//The tiger
let tiger = new Sprite(id["tiger.png"]);
tiger.position.set(64, 64);

let animals = new PIXI.Container();
animals.addChild(cat);
animals.addChild(hedgehog);
animals.addChild(tiger);

app.stage.addChild(animals);

在位置上,这里就有了相对的概念,子的位置相对于父的位置而来的。

parentSprite.toGlobal(childSprite.position),子sprite的位置是相对于其父container的。可以通过:

parentSprite.toGlobal(childSprite.postion),来计算其绝对位置,即使就是求和;

也可以直接使用 childSprite.getGlobalPostion()来获取其位置。

与此相对,也有一个toLocal来获取其相对父Sprite的位置。

PIXI还提供了一个ParticleContainer的Group,它比普通的Group刷新的快2-5倍。

几何图形

终于到了我们这的焦点了。除了用image texture来创建sprite,pixi可以使用Grpahic来创建,包括 Retangle、line、polygons、text等,api与canvas相同。

  • rectangle

    let rectangle = new Graphics();
    rectangle.lineStyle(4, 0xFF3300, 1);		// 边线
    rectangle.beginFill(0x66CCFF);					// 内部颜色
    rectangle.drawRect(0, 0, 64, 64);
    rectangle.endFill();
    rectangle.x = 170;
    rectangle.y = 170;
    app.stage.addChild(rectangle);
    
  • circle

    let circle = new Graphics();
    circle.beginFill(0x9966FF);
    circle.drawCircle(0, 0, 32);
    circle.endFill();
    circle.x = 64;
    circle.y = 130;
    app.stage.addChild(circle);
    
  • ellipses

    ellipse.drawEllipse(0, 0, 50, 20);
    
  • 圆矩形角

    drawRoundedRect(x, y, width, height, cornerRadius)
    
  • 直线

    let line = new Graphics();
    line.lineStyle(4, 0xFFFFFF, 1);
    line.moveTo(0, 0);
    line.lineTo(80, 50);
    line.x = 32;
    line.y = 32;
    app.stage.addChild(line);
    
  • 多边形

    
    let path = [
      point1X, point1Y,
      point2X, point2Y,
      point3X, point3Y
    ];
    graphicsObject.drawPolygon(path);
    
  • 字体

    let message = new Text("Hello Pixi!");
    app.stage.addChild(message);
    

碰撞检测

PIXI没有直接提供碰撞检测的函数,需要根据图形,自己进行判断。

对于常用的矩形,官网提供了一个实现。通过两个图形中心点的位置,与尺寸的关系判断是否冲突。

function hitTestRectangle(r1, r2) {

  //Define the variables we'll need to calculate
  let hit, combinedHalfWidths, combinedHalfHeights, vx, vy;

  //hit will determine whether there's a collision
  hit = false;

  //Find the center points of each sprite
  r1.centerX = r1.x + r1.width / 2;
  r1.centerY = r1.y + r1.height / 2;
  r2.centerX = r2.x + r2.width / 2;
  r2.centerY = r2.y + r2.height / 2;

  //Find the half-widths and half-heights of each sprite
  r1.halfWidth = r1.width / 2;
  r1.halfHeight = r1.height / 2;
  r2.halfWidth = r2.width / 2;
  r2.halfHeight = r2.height / 2;

  //Calculate the distance vector between the sprites
  vx = r1.centerX - r2.centerX;
  vy = r1.centerY - r2.centerY;

  //Figure out the combined half-widths and half-heights
  combinedHalfWidths = r1.halfWidth + r2.halfWidth;
  combinedHalfHeights = r1.halfHeight + r2.halfHeight;

  //Check for a collision on the x axis
  if (Math.abs(vx) < combinedHalfWidths) {

    //A collision might be occurring. Check for a collision on the y axis
    if (Math.abs(vy) < combinedHalfHeights) {

      //There's definitely a collision happening
      hit = true;
    } else {

      //There's no collision on the y axis
      hit = false;
    }
  } else {

    //There's no collision on the x axis
    hit = false;
  }

  //`hit` will be either `true` or `false`
  return hit;
};

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×