PIXI 太空玉兔游戏(6)
阅读原文时间:2023年07月13日阅读:2

想法来源

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

创建应用及舞台

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

javascript:

let app = new PIXI.Application({
width: 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);

        }

      }

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

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





天空





手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章