预习下官网的知识。 及字母消除接上文
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();