zoukankan      html  css  js  c++  java
  • PIXI 太空玉兔游戏(6)

    想法来源 

    出于练习看到这篇文章   没有什么难度  效果如下,接下来会用pixijs讲解如何实现

     

    创建应用及舞台

    HTML部分只创建标签引入 pixi.min.js  即可:

    <script src="pixi.min.js"></script>

    javascript:

     let app = new PIXI.Application({
         350,
        height: 526
      })
      document.body.appendChild(app.view); 
    

      

    运行后,页面是一个黑色区域,没错这是正常的。接下来添加精灵

    创建精灵

       

    首先加载图片使用PIXI自带loader,来实现图片预加载,图片全部加载完毕后再执行其它操作

    定义图片列表:

      var imgList = [
        "img/bg.jpg",
        "img/bg1.jpg",
        "img/food21.png",
        "img/food2.png",
        "img/icon.png",
        "img/player.png",
        "img/heart.png",
      ]
    

      

    是用loader预加载图片,也可以监听加载进度onprogress:

       PIXI.loader
          .add(imgList)
           .load(function () {
    // 图片素在记载完毕后,创建精灵 bgimg = new PIXI.Sprite(PIXI.loader.resources["img/bg.jpg"].texture); })

      

    把精灵添加到舞台

    app.stage.addChild(bgimg);
    

      

    背景图片滚动效果

      原理如图,创建两个精灵,一个在可见区域,一个在可见区域上边或者下边,操作背景移动 ,当背景移动区域大于背景图片高度,重新绘制。

    可以见图,方向是从上往下运动的

    通过中间变量:

    var bgDistance = 0; // 获取移动y值大小

    var bgHeight = 背景图片高度; // 获取背景图片高度来 判断bgDistance移动大小是否,超过背景图片高度,超过重新渲染


    背景图片移动向下飞船向前行驶,使用PIXI ticker

    tips:bgDistance 变量在上边已声明默认:0
    app.ticker.add(function (delta) {
               // 背景图片1位置
              bgimg.x = 0;
              bgimg.y = bgDistance - bgHeight;
               // 背景图片2位置
              bgimg1.x = 0;
              bgimg1.y = bgDistance;
    
              if(bgDistance >= bgHeight){
                bgloop = 0;
              }
              bgDistance  = ++bgloop;
            })
    

      

    会看到背景在移动,接下来在页面添加飞船,操作跟添加背景图片一样,创建一个精灵添加到舞台中:

    这时会看到飞船出现在太空中,飞船有些怪怪的,接下来大小及位置修改

            player.scale.x = 0.5;
            player.scale.y = 0.5;
    
            player.x = (app.view.width - player.width)/2;
            player.y = app.view.height - player.height -100;
    

      

    scale 进行缩放

    app.view.width/height 获取舞台的宽高,

    player.width/height  获取当前容器或是精灵所占的大小

     接下来,让飞船移动,通过键盘   上下左右来控制 及监听事件 keydown 

    document.addEventListener("keydown", function (event) {
    //    alert(event.keyCode)
        switch (event.keyCode) {
          case 37:
    
            player.vx = -5;
            break;
          case 38:
            player.vy = -5;
            break;
          case 39:
            player.vx = 5;
            break;
          case 40:
            player.vy = 5;
            break;
        }
    
      }, false)
    
    
      document.addEventListener("keyup", function () {
        player.vx = 0;
        player.vy = 0;
      })
    

      

    键盘事件写完后,在ticker控制改变飞船位置

    player.x += player.vx;
    player.y += player.vy;

    这时会发现,飞船 飞出舞台之外了 ,接下来,检测是否到舞台边缘 有两种方式可以检测
    1、自定义一个容器的宽高,来判断是否到该容器边缘
    2、直接判该该精灵是否到舞台边缘

    直接就用第二种了,
       // 判断是否到舞台边缘
              if(player.x<=0){
                player.x = 0;
              }else if( player.x >= bgimg.width- player.width){
                player.x = bgimg.width- player.width;
              }
               // 同理, y的判断 也是一样的。。。
    

      

    靠近边缘,不会出舞台外边;

    接下来考虑,随机掉月饼有两种类型的月饼

     function randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
      }
    

      

    每个随机玉兔位置应该为:

    var randomType = Math.floor(Math.random()*2 +1);
        return {
          rabbitType : randomInt(1, 2),
          x: randomInt(1,app.view.width),
          y: 0,
    speed:randomInt(1,4), // 向下移动速度
    isHas: false // 是否存在舞台中
    }
    }

      

    在舞台中,显示玉兔,创建精灵并把精灵放到舞台上 ,让精灵从上往下移动使用ticker 对y ++操作 ,当玉兔跟月饼相碰是,

    精灵销毁 ,销毁,销毁! 当精灵到屏幕最下方是,也要做销毁处理。

    月饼下实际上就是对数组操作,当到底部在数组中移除操作

    定义存放数组


    var ybArry = []; // 存放月饼
    var imgOjbArry = []; // 存放图片对象,把每个创建的精灵添加的舞台上

    在ticker随机调用数组函数 ,数组里边最多存放五个元素。

    // 处理月饼下路 假定 一直值显示五个 月饼
    if(Math.random() > 0.9 && ybArry && ybArry.length < 5){
    var randPoint = randomRabbit();
    ybArry.push(randPoint);
    }

    对每个随机生成的坐标y ,进行++ 操作,数组中每个元素都会有下路效果

      for(var i = 0; i < ybArry.length; i++){
                ybArry[i].y += ybArry[i].speed;
              }
    

      

    跟随机月饼数,创建图片精灵,让图片运动

              // 根据随机数组创建精灵
              for(var j = 0; j< ybArry.length; j++){
                if(ybArry[j].isHas == false){
                  var sprite = new PIXI.Sprite(
                      PIXI.loader.resources["img/food"+ybArry[j].rabbitType+".png"].texture
                  );
                  ybArry[j].isHas = true;
                  imgOjbArry.push(sprite);
                  app.stage.addChild(sprite);
    
                }
              }
    

      

    把数组月饼中的y 赋值给图片精灵坐标

       for(var k  = 0; k < imgOjbArry.length; k++){
                imgOjbArry[k].x = ybArry[k].x;
                imgOjbArry[k].y =  ybArry[k].y;
    
                if(imgOjbArry[k].y >= app.view.height){
                  imgOjbArry[k].destroy();
                  ybArry.splice(k, 1);
                  imgOjbArry.splice(k, 1);
    
                }
              }
    

      

    舞台就会显示精灵运动,细心会看到,随机产生不一样的图。根据不同图片,碰撞那个加分那个结束。自己定义;

    碰撞检测实现:(官网的函数copy)

    //The `hitTestRectangle` function
    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 occuring. 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;
    };
    

      

    碰撞后的月饼透明度降低,是带花的,五仁的无变化。

              for(var k  = 0; k < imgOjbArry.length; k++){
                imgOjbArry[k].x = ybArry[k].x;
                imgOjbArry[k].y =  ybArry[k].y;
                imgOjbArry[k].rabbitType = ybArry[k].rabbitType;
    
    
                // 碰撞检测
                var hitStatus = hitTestRectangle(player, imgOjbArry[k]);
                //  console.log(imgOjbArry[k].rabbitType )
                if(hitStatus){
                  if(imgOjbArry[k].rabbitType == 2){
                    imgOjbArry[k].alpha = 0.5;
                  }
                }
    
    
                if(imgOjbArry[k].y >= app.view.height){
                  imgOjbArry[k].destroy();
                  ybArry.splice(k, 1);
                  imgOjbArry.splice(k, 1);
    
                }
    
              }
    

      

    其它操作根据需要添加,记录分数或或是关数。

    代码如下:勉强看吧,没整理。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>天空</title>
      <script src="lib/pixi.min.js"></script>
    </head>
    <body>
    
    
    <script>
      var bgDistance = 0;
      var bgHeight;  // 背景图片高度
      var bgloop = 0;
    
    
      var ybArry = [];  // 存放月饼
      var imgOjbArry = [];  // 存放图片对象,把每个创建的精灵添加的舞台上
    
    
      let app = new PIXI.Application({
         350,
        height: 526
      });
      document.body.appendChild(app.view);
    
      // 随机创建玉兔(有两种根据类型来区分)
      //randomRabbit();
      function randomRabbit(){
        var randomType = Math.floor(Math.random()*2 +1);
        return {
          rabbitType : randomInt(1, 2),
          x: randomInt(1,app.view.width),
          y: 0,
          speed:randomInt(1,4), // 向下移动速度
          isHas: false // 是否存在舞台中
        }
      }
    
       console.log(randomRabbit())
    
      function randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
      }
    
      var imgList = [
        "img/bg.jpg",
        "img/food1.png",
        "img/food2.png",
        "img/icon.png",
        "img/player.png",
      ]
    
      PIXI.loader
          .add(imgList)
          .load(function () {          // 图片素在记载完毕后,创建精灵
            bgimg = new PIXI.Sprite(PIXI.loader.resources["img/bg.jpg"].texture);
            bgimg1 = new PIXI.Sprite(PIXI.loader.resources["img/bg.jpg"].texture);
            player = new PIXI.Sprite(PIXI.loader.resources["img/player.png"].texture);
    
            player.scale.x = 0.5;
            player.scale.y = 0.5;
    
            player.x = (app.view.width - player.width) / 2;
            player.y = app.view.height - player.height - 100;
    
            player.vx = 0;
            player.vy = 0;
    
    
            bgHeight = bgimg.height;
    
    
            app.stage.addChild(bgimg);
            app.stage.addChild(bgimg1);
            app.stage.addChild(player);
    
    
            app.ticker.add(function (delta) {
    
              bgimg.x = 0;
              bgimg.y = bgDistance - bgHeight;
    
              bgimg1.x = 0;
              bgimg1.y = bgDistance;
    
              if (bgDistance >= bgHeight) {
                bgloop = 0;
              }
              bgDistance = ++bgloop;
    
    
              player.x += player.vx;
              player.y += player.vy;
    
              // 判断是否到舞台边缘
              if(player.x<=0){
                player.x = 0;
              }else if( player.x >= bgimg.width- player.width){
                player.x = bgimg.width- player.width;
              }
               // 同理, y的判断 也是一样的。。。
    
    
              // 处理月饼下路 假定 一直值显示五个 月饼
              if(Math.random() > 0.9 && ybArry && ybArry.length < 5){
                var randPoint = randomRabbit();
                ybArry.push(randPoint);
              }
    
              for(var i = 0; i < ybArry.length; i++){
                ybArry[i].y += ybArry[i].speed;
              }
    
              // 根据随机数组创建精灵
              for(var j = 0; j< ybArry.length; j++){
                if(ybArry[j].isHas == false){
                  var sprite = new PIXI.Sprite(
                      PIXI.loader.resources["img/food"+ybArry[j].rabbitType+".png"].texture
                  );
                  ybArry[j].isHas = true;
                  imgOjbArry.push(sprite);
                  app.stage.addChild(sprite);
    
                }
              }
    
              for(var k  = 0; k < imgOjbArry.length; k++){
                imgOjbArry[k].x = ybArry[k].x;
                imgOjbArry[k].y =  ybArry[k].y;
                imgOjbArry[k].rabbitType = ybArry[k].rabbitType;
    
    
                // 碰撞检测
                var hitStatus = hitTestRectangle(player, imgOjbArry[k]);
                //  console.log(imgOjbArry[k].rabbitType )
                if(hitStatus){
                  if(imgOjbArry[k].rabbitType == 2){
                    imgOjbArry[k].alpha = 0.5;
                  }
                }
    
    
                if(imgOjbArry[k].y >= app.view.height){
                  imgOjbArry[k].destroy();
                  ybArry.splice(k, 1);
                  imgOjbArry.splice(k, 1);
    
                }
    
              }
    
            })
          });
    
    
      document.addEventListener("keydown", function (event) {
    //    alert(event.keyCode)
        switch (event.keyCode) {
          case 37:
    
            player.vx = -5;
            break;
          case 38:
            player.vy = -5;
            break;
          case 39:
            player.vx = 5;
            break;
          case 40:
            player.vy = 5;
            break;
        }
    
      }, false)
    
    
      document.addEventListener("keyup", function () {
        player.vx = 0;
        player.vy = 0;
      })
    
    
      //The `hitTestRectangle` function
      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 occuring. 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;
      };
    
    
    </script>
    </body>
    </html>
    

      


























  • 相关阅读:
    java变量类型
    java基本数据类型
    java对象和类
    java认识
    vue-随笔-transition
    vue-随笔-class-style
    vue-随笔-form-elements
    Constructing Roads*
    hdu3371 Connect the Cities
    hdu1879浙大计算机研究生复试上机(2008)继续畅通工程
  • 原文地址:https://www.cnblogs.com/congxueda/p/9356291.html
Copyright © 2011-2022 走看看