PIXI 精靈及文本加載(4)


預習下官網的知識。 及字母消除接上文

 

Pixi 精靈

Pixi擁有一個精靈類來創建游戲精靈。有三種主要的方法來創建它:

  • 用一個單圖像文件創建。
  • 用一個 雪碧圖 來創建。雪碧圖是一個放入了你游戲所需的所有圖像的大圖。
  • 從一個紋理貼圖集中創建。(紋理貼圖集就是用JSON定義了圖像大小和位置的雪碧圖)

你將要學習這三種方式,但是在開始之前,你得弄明白圖片怎么用Pixi顯示。

將圖片加載到紋理緩存中

因為Pixi用WebGL和GPU去渲染圖像,所以圖像需要轉化成GPU可以處理的版本。可以被GPU處理的圖像被稱作 紋理 。在你讓精靈顯示圖片之前,需要將普通的圖片轉化成WebGL紋理。為了讓所有工作執行的快速有效率,Pixi使用 紋理緩存 來存儲和引用所有你的精靈需要的紋理。紋理的名稱字符串就是圖像的地址。這意味着如果你有從"images/cat.png"加載的圖像,你可以在紋理緩存中這樣找到他:

PIXI.utils.TextureCache["images/cat.png"];

紋理被以WEBGL兼容的格式存儲起來,它可以使Pixi的渲染有效率的進行。你現在可以使用Pixi的精靈類來創建一個新的精靈,讓它使用紋理。

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

但是你該怎么加載圖像並將它轉化成紋理?答案是用Pixi已經構建好的loader對象。

Pixi強大的loader對象可以加載任何你需要種類的圖像資源。這里展示了怎么加載一個圖像並在加載完成時用一個叫做setup的方法來使用它。

 

這里是一個完整的加載圖像的代碼。調用setup方法,並未加載的圖像創建一個精靈。

PIXI.loader
  .add("images/anyImage.png")
  .load(setup);

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

  

從精靈圖(雪碧圖)中創建精靈

你現在已經知道了怎么從一個單文件內加載圖像。但是作為一個游戲設計師,你沒准更經常使用 雪碧圖(也被稱之為 精靈圖)。Pixi封裝了一些方便的方式來處理這種情況。所謂雪碧圖就是用一個單文件包含你游戲中需要的所有文件,這里就是一個包含了游戲對象和游戲角色的雪碧圖。

 

 

 下面是提取火箭,創建精靈

 

function setup() {

  //Create the `tileset` sprite from the texture
  let texture = TextureCache["images/tileset.png"];

  //Create a rectangle object that defines the position and
  //size of the sub-image you want to extract from the texture
  //(`Rectangle` is an alias for `PIXI.Rectangle`)
  let rectangle = new Rectangle(192, 128, 64, 64);

  //Tell the texture to use that rectangular section
  texture.frame = rectangle;

  //Create the sprite from the texture
  let rocket = new Sprite(texture);

  //Position the rocket sprite on the canvas
  rocket.x = 32;
  rocket.y = 32;

  //Add the rocket to the stage
  app.stage.addChild(rocket);

  //Render the stage   
  renderer.render(stage);
}

  

 

使用一個紋理貼圖集

紋理貼圖集 就會顯得很有用處,一個紋理貼圖集就是一個JSON數據文件,它包含了匹配的PNG雪碧圖的子圖像的大小和位置。如果你使用了紋理貼圖集,那么想要顯示一個子圖像只需要知道它的名字就行了。你可以任意的排序你的排版,JSON文件會保持他們的大小和位置不變。這非常方便,因為這意味着圖片的位置和大小不必寫在你的代碼里。如果你想要改變紋理貼圖集的排版,類似增加圖片,修改圖片大小和刪除圖片這些操作,只需要修改那個JSON數據文件就行了,你的游戲會自動給程序內的所有數據應用新的紋理貼圖集。你沒必要在所有用到它代碼的地方修改它。

 

Pixi兼容著名軟件Texture Packer輸出的標准紋理貼圖集格式。

"blob.png":
{
	"frame": {"x":55,"y":2,"w":32,"h":24},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":24},
	"sourceSize": {"w":32,"h":24},
	"pivot": {"x":0.5,"y":0.5}
},

  

顯示文本

let message = new PIXI.Text("Hello Pixi!"); 

app.stage.addChild(message);
message.position.set(54, 96);

 

編寫完簡陋的效果圖:代碼往下看。。。。。。。。。。。。。。。。

效果圖:

 

 

 文字下落代碼優化修改:

 1、過程改成對象形式編程

 2、添加圖片預加載

3、落下文字替換成圖片

4、添加得分及關數,達到目標分后進行下一關

5、添加血條字母下落而減少

 6、每過一關,目標分數增加,下落速度增加

 

未完善

 1、字母消除,添加爆炸效果

 2、圖片底邊添加炮台,炮彈打擊字母消失。(炮台根據字母坐標移動 ,炮台角度)

 

代碼如下:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>test2</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="pixi.min.js"></script>
</head>
<body>

<script>
  var imgList = [
    'bg.png',
    'img/A.png',
    'img/B.png',
    'img/C.png',
    'img/D.png',
    'img/E.png',
    'img/F.png',
    'img/G.png',
    'img/H.png',
    'img/I.png',
    'img/J.png',
    'img/K.png',
    'img/L.png',
    'img/M.png',
    'img/N.png',
    'img/O.png',
    'img/P.png',
    'img/Q.png',
    'img/R.png',
    'img/S.png',
    'img/T.png',
    'img/U.png',
    'img/V.png',
    'img/W.png',
    'img/X.png',
    'img/Y.png',
    'img/Z.png',
  ];

  var dropDown = function () {
    this.app = null;
    this.letterArr = []; // 存放字母
    this.textObjArr = []; // 存放text對象
    this.txtStyle = '';
    this.loader = '';
    this.endFlag = false;
    this.speedVal = 0.3;
    this.scoreNum = 0; // 得分
    this.winScroe = 5; // 目標分
    this.isTimeDownIng = false;
    this.currentLevel = 1;

  }

  dropDown.prototype = {
    init: function () {
      this.keyDown();
      this.createAppStage();
    },
    //  創建血條
    createHealthBar: function(){
      var _this = this;
      gameOver = new PIXI.Container();
      // 來是官網copy
      healthBar = new PIXI.Container();

      healthBar.position.set(_this.app.view.width - 140, 10);

      this.app.stage.addChild(healthBar);

      // 游戲結束提示
      gameOver.visible = false;
      gameOver.width = _this.app.view.width;
      gameOver.height = _this.app.view.height;
      this.app.stage.addChild(gameOver);

      this.scoreNumFun();


      let style = new PIXI.TextStyle({
        fontFamily: "Futura",
        fontSize: 64,
        fill: "white"
      });
      message = new PIXI.Text("You lost!", style);
       // 120
      message.x = _this.app.view.width / 2 -110;
      message.y = _this.app.view.height / 2 - 32;

      gameOver.addChild(message);

      innerBar = new PIXI.Graphics();
      innerBar.beginFill(0x000000);
      innerBar.drawRect(0, 0, 128, 8);
      innerBar.endFill();
      healthBar.addChild(innerBar);


      outerBar = new PIXI.Graphics();
      outerBar.beginFill(0xFF3300);
      outerBar.drawRect(0, 0, 128, 8);
      outerBar.endFill();
      healthBar.addChild(outerBar);
      healthBar.outer = outerBar;
    },
    // 得分
    scoreNumFun: function(){
      var _this = this;
      scroe = new PIXI.Text("得分:0" , _this.txtStyle);
      scroe.x = 10;
      scroe.y = 10;
      _this.app.stage.addChild(scroe);

      // 目標分數
      winScroe = new PIXI.Text("目標分:"+_this.winScroe , _this.txtStyle);
      winScroe.x = 10;
      winScroe.y = 40;
      _this.app.stage.addChild(winScroe);

      currentlevel = new PIXI.Text("關數:"+_this.currentLevel , _this.txtStyle);
      currentlevel.x = 10;
      currentlevel.y = 100;
      _this.app.stage.addChild(currentlevel);

    },
    // 創建舞台
    createAppStage: function () {
      var _this = this;
      this.app = new PIXI.Application({
        width: 700,
        height: 556
      });
      document.body.appendChild(this.app.view);

      PIXI.loader
          .add(imgList)
          .load(function () {
            var bgimg = new PIXI.Sprite(PIXI.loader.resources["bg.png"].texture);
            _this.app.stage.addChild(bgimg);
            // 創建字母
              _this.createTxtStyle();

            _this.createHealthBar();
//            setInterval(function () {
//              _this.createTxtObj(_this.speedVal);
//            }, 10);


            _this.app.ticker.add(function(delta ){
              _this.createTxtObj(_this.speedVal);
            })
          });
    },

    // 字體樣式
    createTxtStyle: function () {
      this.txtStyle = new PIXI.TextStyle({
        fontFamily: "Arial",
        fontSize: 18,
        fill: "white",
        stroke: '#ff3300',
        strokeThickness: 4,
        dropShadow: true,
        dropShadowColor: "#000000",
        dropShadowBlur: 4,
        dropShadowAngle: Math.PI / 6,
        dropShadowDistance: 6
      });
    },
    // 隨機顯示字母
    randomLetter: function () {
      var _this = this;
      var charCode = 97 + Math.floor(Math.random() * 26);
      var speed = Math.ceil(Math.random() * 4);
      return {
        code: String.fromCharCode(charCode).toLocaleUpperCase(),
        speed: speed,
        y: 0,
        x: Math.floor(Math.random() * _this.app.view.width - 100 + 70),
        isHas: false
      }
    },
    // 隨機字母創建文本對象
    createTxtObj: function (delta) {
      var _this = this;
      // 隨機創建10 個字母,字母消除隨機一個不重復字母,有一個碰到底部結束
      var getLetterObj = this.randomLetter();
      // console.log(getLetterObj)
      var randomHas = false; // 隨機數是否與現有數組元素相同
      if (_this.letterArr) {
        for (var i = 0; i < _this.letterArr.length; i++) {
          if (getLetterObj.code == _this.letterArr[i].code) {
            randomHas = true;
          }
        }
      }
      if (randomHas == false) {
        if(_this.letterArr && _this.letterArr.length < 10){
          _this.letterArr.push(getLetterObj);
//          console.log(_this.letterArr)
        }
      }
      _this.speedLetter(delta);
    },
    // 精靈移動
    speedLetter: function (delta) {
      var _this = this;
      for (var i = 0; i < _this.letterArr.length; i++) {
//        _this.letterArr[i].y += _this.letterArr[i].speed;
        _this.letterArr[i].y += _this.letterArr[i].speed * delta;
      }

      // 創建元素
      for (var i = 0; i < _this.letterArr.length; i++) {
        if (_this.letterArr[i].isHas == false) {
//          var txtObj = new PIXI.Text("Hello Pixi!", _this.txtStyle);
          var letterSprite = new PIXI.Sprite(PIXI.loader.resources["img/"+_this.letterArr[i].code+".png"].texture);

          _this.letterArr[i].isHas = true;
//          _this.textObjArr.push(txtObj);
          _this.textObjArr.push(letterSprite);
          // console.log(_this.textObjArr)
        }
      }
      for (var j = 0; j < _this.textObjArr.length; j++) {
//            console.log(_this.textObjArr[j])
        _this.app.stage.addChild(_this.textObjArr[j]);
      }
      // 舞台文本對象指定位置
      for (var i = 0; i < _this.textObjArr.length; i++) {
        _this.textObjArr[i].x = _this.letterArr[i].x;
        _this.textObjArr[i].y = _this.letterArr[i].y;
        _this.textObjArr[i].scale.set(0.5, 0.5);
      //  _this.textObjArr[i].text = _this.letterArr[i].code;

        // 銷毀對象
        if (_this.textObjArr[i].y >= this.app.view.height) {
          _this.textObjArr[i].alpha = 0;
          _this.textObjArr.splice(i, 1);
          _this.letterArr.splice(i, 1); // 移除數組中元素


          if(_this.endFlag == false && _this.scoreNum < _this.winScroe){
            healthBar.outer.width -= 5;
          }
//          outerBar.alpha = 0.5

        }
        if (healthBar.outer.width <= 0) {
          healthBar.outer.width = 0;
          gameOver.visible = true;
          _this.endFlag = true;
//          message.text = "You lost!";
        }

        if(_this.endFlag == true){
          gameOver.visible = true;
          _this.endFlag = true;
        }
      }
    },
    // 鍵盤按下事件
    keyDown: function () {
      var _this = this;
      window.addEventListener("keydown", function (evt) {
        var currKey = 0, e = e || event;
        currKey = e.keyCode || e.which || e.charCode;
//        alert(currKey)
//        _this.clearLetter(currKey);
//        var letterKey  = String.fromCharCode(currKey).toLowerCase();
        var letterKey = String.fromCharCode(currKey);
        // 是否結束
        if(_this.endFlag == false && _this.scoreNum <= _this.winScroe){
          _this.clearLetter(letterKey);
        }
        // 下一關
        if(_this.scoreNum >= _this.winScroe){
          if(_this.isTimeDownIng == true){
            return;
          }
          _this.scoreNum = 0;
          _this.winScroe += 10;
          _this.currentLevel++;
          scroe.text = "得分:"+_this.scoreNum;
          winScroe.text = "目標分:"+_this.winScroe;
          currentlevel.text = "關數:"+_this.currentLevel;

          gameOver.visible = true;
          message.text = "下一關";
          var numv = 3;
          var num3 =setInterval(function(){
            _this.isTimeDownIng =  true;
            numv--;
            message.text = numv;
            if(numv < 0){

              clearInterval(num3);
              _this.isTimeDownIng = false;
              _this.gameContinue();
            }

          },1000);
        }
      });
    },
    gameContinue: function(){
      var _this = this;

      _this.endFlag = false;
      healthBar.outer.width = 128;
      _this.speedVal += 0.3;
      gameOver.visible = false;
      message.text = "You lost!";
    },
    clearLetter: function (key) {
      var _this = this;
      for (var i = 0; i < _this.letterArr.length; i++) {
        if (_this.letterArr[i].code == key) {
          var sNum = ++_this.scoreNum;
          scroe.text = "得分:"+sNum;
//          console.log(sNum)
          //_this.textObjArr[i].text = '';
           _this.textObjArr[i].alpha = 0;
          _this.textObjArr.splice(i, 1);
          _this.letterArr.splice(i, 1);
        }
      }
    },
  };

  var dDown = new dropDown();
  dDown.init();

</script>
</body>
</html>

  

 

代碼下載地址

 

 

 結構

 1、創建類函數

   var dropDown = function(){

     // code init

   }

dropDown.prototype = {
init: function(){ // 初始化
},
createHealthBar: function(){
// 創建血條
},
.....
}
var dDown = new dropDown();
dDown.init();


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM