PIXI 太空玉兔遊戲(6)

想法來源 javascript

出於練習看到這篇文章   沒有什麼難度  效果以下,接下來會用pixijs講解如何實現html

 

 

 

 

建立應用及舞臺java

 

HTML部分只建立標籤引入 pixi.min.js  便可:數組

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

 

javascript:app

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

  

運行後,頁面是一個黑色區域,沒錯這是正常的。接下來添加精靈dom

 

建立精靈函數

   

首先加載圖片使用PIXI自帶loader,來實現圖片預加載,圖片所有加載完畢後再執行其它操做oop

定義圖片列表:spa

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:code

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;

這時會發現,飛船 飛出舞臺以外了 ,接下來,檢測是否到舞臺邊緣 有兩種方式能夠檢測
一、自定義一個容器的寬高,來判斷是否到該容器邊緣
二、直接判該該精靈是否到舞臺邊緣

直接就用第二種了,
// 判斷是否到舞臺邊緣
          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({
    width: 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>
相關文章
相關標籤/搜索