zoukankan      html  css  js  c++  java
  • 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({
             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();


  • 相关阅读:
    Redis-持久化
    Redis-Sort命令
    Redis-ZSet常用命令
    Redis-Hash
    Redis-Set常用命令
    Redis-List常用命令
    Redis-String常用命令
    访问控制
    c++之旅:多态
    c++之旅:类型的强制转换
  • 原文地址:https://www.cnblogs.com/congxueda/p/9343121.html
Copyright © 2011-2022 走看看