使用Pixi.js编写JavaScript网页小游戏

Pixi.js中文网https://pixijs.huashengweilai.com/PixiJSOfficial site for PixiJS, The HTML Creation Engine.https://pixijs.com/Pixi是一个非常快的2D sprite渲染引擎,基于它可以轻松地使用JavaScript和其他HTML5技术制作游戏和应用程序。

一. 使用Pixi.js创建一个项目


(1)在开始编写代码之前,为项目创建一个文件夹,并在项目的根目录中启动一个web服务。不运行web服务,Pixi将无法工作。

(2)下载 pixi.min.js 文件,并放在一个名为pixi的文件夹中。

(3)在项目根目录文件夹中创建一个用于编写游戏实现代码的js文件,命名为index.js。

(4)创建一个基本的HTML页面,命名为index.html。使用一个

注意:以下代码编写均在index.js文件中进行!

二. Pixi.js基础语法


1. 创建舞台

//新建一个宽500,高500的舞台
var app = new PIXI.Application(500,500);
document.body.appendChild(app.view);

2. 创建图片元素

//新建一个飞机图片
var plane = new PIXI.Sprite.fromImage("res/plane/main/img_plane_enemy_04.png");
app.stage.addChild(plane1);
//设置x、y坐标
plane.x = 300;
plane.y = 300;
//设置宽高
plane.width = 100;
plane.height = 80;
//设置缩放比例
plane.scale.x = 2;//将图片x方向缩放到原来的2倍    
plane.scale.y = 2;//将图片y方向缩放到原来的2倍
//plane.scale.x = -1; //图片沿y轴水平翻转
//设置旋转
plane.rotation = Math.PI / 2;//顺时针旋转90度
//设置元素是否可见 
//plane.visible=false;
//设置元素的透明度    
//plane.alpha=0.6;
//设置图片锚点  btn.anchor.set(0.5,0.5);
plane.anchor.x = 0.5;
plane.anchor.y = 0.5;

3. 创建文字元素

//新建分数文字
var score = new PIXI.Text("得分:10000");
app.stage.addChild(score);     
score.text = “飞机大战真好玩!”;//设置显示内容    
app.stage.addChild(score);    
var score = new PIXI.Text("得分:10000");    
score.style.fill = 0xffffff;//设置字体颜色    
score.style.fontSize = 50;//设置字体大小    
score.style.fontWeight = "bold";//加粗    
score.style.fontStyle = "italic";//斜体    
score.style.fontFamily = "隶书";//设置字体    

4. 元素的鼠标点击事件

//新建背景图片
var bg = new PIXI.Sprite.fromImage("res/plane/main/img_plane_enemy_04.png");
app.stage.addChild(bg);
//允许bg图片,可以被鼠标点击
bg.interactive = true;
//bg图片当被点击时,通知执行 move 函数
bg.on("click",move);
function move() {
    plane.y += 10;
}

/*
其他鼠标事件
bg.on(“mousemove”,函数名);  
bg.on(“mousedown”,函数名);   
bg.on(“mouseup”,函数名); 
bg.on(“mouseover”,函数名);
bg.on(“mouseout”,函数名);
bg.on(“touchstart”,函数名);  
bg.on(“touchend”,函数名);
bg.on(“touchmove”,函数名);
*/

5. 实现元素跟随鼠标移动

bg.interactive = true;
//不管把 mousemove 事件添加给舞台上哪一个显示元素,最终都是由应用程序窗口,响应该事件。
bg.on("mousemove", movePlane);
function movePlane(event) {
    var pos = event.data.getLocalPosition(app.stage);
    plane.x = pos.x;
    plane.y = pos.y;
}
bg.buttonMode = true; //鼠标移入按扭时,变成小手样式

6. 为元素添加子元素(跟随)

//右侧僚机
var planeRight = new PIXI.Sprite.fromImage("res/plane/liaoji_01_11.png");
planeRight.anchor.set(0.5,0.5)
planeRight.x = 100;
planeRight.y = 60;
plane.addChild(planeRight);

//左侧僚机
var planeLeft = new PIXI.Sprite.fromImage("res/plane/liaoji_01_11.png");
planeLeft.anchor.set(0.5,0.5);
planeLeft.x = -100;
planeLeft.y = 60;
plane.addChild(planeLeft);  

7. 取消显示某元素

app.stage.removeChild(显示元素);
父显示元素.removeChild(子显示元素);

8. 实现动画效果

//动画效果
//帧频函数是new PIXI.Application()提供的功能,用于实现补间动画的效果。 
//1、帧频函数添加后,由系统自动调用    2、帧频函数每秒钟被调用60次    

//指定应用 app 的帧频函数是 animate
app.ticker.add(animate);
//定义一个名叫 animate 的函数,实现补间动画    
function animate() {
    plane1.y += 1;//
    plane2.x += 1;
}
//帧频函数中不仅可以控制显示元素x、y坐标的变化,也可以控制显示元素的大小、透明度、显示内容等的变化。  

//如何控制帧频函数的调用频率?可以通过变量计数的功能,来控制帧频函数的调用频率。
/*
var time = 0;
app.ticker.add(animate);
function animate() {
    if(time == 60){ //每 1 秒调用 1 次
        //相关代码 
        ......
        time = 0;
     }
     time++;
}
*/

9. 利用数组快速创建多个元素

//存储飞机的数组
var arr = [];
//通过循环创建6架飞机
for(var i=0;i<6;i++){
    var plane = new PIXI.Sprite.fromImage("res/enemy_04.png");
    app.stage.addChild(plane);
    plane.x = i * 80;
    //将飞机plane,存入arr数组中
    arr.push(plane);
}
//更改arr数组中1、5下标对应飞机的坐标
arr[1].y = 100;
arr[5].y = 100;
//帧频函数,控制arr数组中所有飞机移动
app.ticker.add(animate);
function animate() {
    for(var i=0;i

删除数组中的值:

//删除数组中的值    
var arr = [10,20,"上海",3.14];
arr.splice(2,1);//删除名称为arr数组中的值,从2下标开始删除,向后,一共删除一个值
console.log(arr.length);    

菱形排列元素(小算法问题):

//菱形排列飞机
function Plane(x,y){
    var plane = PIXI.Sprite.fromImage("res/plane/main/img_plane_main_09.png");
    plane.x = x;
    plane.y = y;
    plane.scale.x = 0.8;
    plane.scale.y = 0.8;
    app.stage.addChild(plane);
}
//代码编写区域   五行五列,拆成两半看
function Rhombus() {
    for (var i=-2;i<=2;i++){
        for (var k=-2;k<=2;k++){
            if(Math.abs(i)+Math.abs(k)<=2){
                Plane((k+2)*100,(i+2)*100);
            }    
        }    
    }
}
Rhombus();

10. JS常用API

10.1 随机数

//随机数
//1、0到1之间的随机小数    
var a = Math.random();    
//2、0到500之间的随机小数    
var a = Math.random() * 500;      
//4、指定范围的随机小数    
var a = Math.random() * (大-小) + 小;  
//四舍五入取整
var a = Math.round(3.14);//对3.14进行四舍五入取整,返回结果为:3
//圆周率
var a = Math.PI;//返回圆周率的值约等于:3.141592653589793
plane.rotation = Math.PI / 4;//通过数学中弧度和角度的转换关系可以得知,圆周率对应的角度为180度角。所以 Math.PI / 4 对应的角度为45度角

10.2 时间

//时间
app.ticker.add(animate);
function animate(){
    //获得日期,Date对象常用API
    var d = new Date();
    var year = d.getFullYear();//用本地时间表示的年份值
    var month = d.getMonth()+1;//用本地时间表示的月份值
    var day = d.getDate();//用本地时间表示的一个月中的日期值
    var hour = d.getHours();//用本地时间表示的小时值
    var minute = d.getMinutes();//用本地时间表示的分钟值
    var second = d.getSeconds();//用本地时间表示的秒钟值
    //getDay()  用本地时间表示的一周中的日期值
    //getMilliseconds()  用本地时间表示的毫秒值
    //getTime()  返回 Date 对象中的时间值(时间戳)
    //toString() 返回对象的字符串表示
    
    //拼接日期字符串
    var dt = year+"-"+month+"-"+day+"  "+hour+":"+minute+":"+second;
    
    //通过文本显示日期
    txt.text = dt;
}

10.3 String对象

//String对象
var 变量 = "内容";
/*
length        返回字符串的长度
indexOf()     返回字符串中子字符串首次出现的位置
lastIndexOf() 返回字符串中子字符串最后出现的位置
replace()     返回文字替换后的字符串
split()       将字符串分割为子字符串,返回结果为数组
substr()      返回从指定位置开始的指定长度的子字符串
substring()   返回字符串指定位置的子字符串
toLowerCase() 将字符串中的所有字母都转换为小写字母
toUpperCase() 将字符串中的所有字母都转化为大写字母
*/

10.4 Array对象

//Array对象
var 变量 = [ ];
var 变量 = [值,值,值...];
/*
length    返回数组的长度
pop()     移除数组中的最后一个元素并返回该元素
reverse() 返回元素顺序被反转的 Array 对象
shift()   移除数组中的第一个元素并返回该元素
slice()   返回数组的一段
sort()    返回元素已经进行了排序的 Array 对象
splice()  从数组中移除一个或多个元素
unshift() 将指定元素插入数组开始位置
toString()返回对象的字符串表示
*/

10.5 数据类型转换

/*
变量,既可以存储基本类型的数据,也可以存储对象类型的数据。
基本类型变量:变量中存储的是基本类型的数据。例如:数字,布尔等。
对象类型变量:变量中存储的是对象类型的数据。例如:应用程序对象、图片对象、文本对象等。

同样的道理,属性也是既可以存储基本类型的数据,也可以存储对象类型的数据。
基本类型属性:属性中存储的是基本类型的数据。
对象类型属性:属性中存储的是对象类型的数据。
*/

//查看数据类型
typeof(变量/数据值);
//基本类型转换成字符串类型
var n = 100;
console.log(typeof(n)); // Number
var sn1 = n.toString();//通过 toString() 方法将数据转换成字符串类型
var sn2 = String(n);//通过 String(参数) 方法将数据转换成字符串类型 
//字符串类型转成数字类型
var sn = "3.1415926";
var n1 = parseInt(sn);	// 3
var n2 = parseFloat(sn);  // 3.1415926
var n3 = Number(sn);	// 3.1415926
//布尔类型转换为数字类型
var a = Number(true);// 1
//数字、字符串转换为布尔类型
console.log(Boolean(0));
console.log(Boolean(''));
console.log(Boolean("Hello"));
//字符串自动类型转换
var s2 = 'hello' + 100 + 200;//"Hello100200"

11. 碰撞判断

//存储子弹的数组
var arr = [];


app.ticker.add(animate);
function animate() {
    addBullet();//创建子弹
    moveBullet();//移动子弹
    crash();//碰撞判断
}

//创建子弹
var time = 0;
function addBullet() {
	if(time == 10) {
        var bullet = PIXI.Sprite.fromImage("res/plane/bullet_01.png");
        bullet.anchor.set(0.5,0.5);
        bullet.x = plane.x;
        bullet.y = plane.y;
        app.stage.addChild(bullet);
        //将子弹存入arr数组
        arr.push(bullet);

        time = 0;
    } 
	time++;
}

//移动子弹
function moveBullet(){
    //移动arr数组中的子弹
    for(var i=0;i=0;i--){
        if(arr[i].y < -100) {
            app.stage.removeChild(arr[i]);
            arr.splice(i,1);
        }
    }
}


//敌机与子弹碰撞
function crash(){
    var pos = (bullet.x - enemy.x) * (bullet.x - enemy.x) + (bullet.y - enemy.y) * (bullet.y - enemy.y);
    //判断是否发生碰撞
    if(pos < 60 * 60) {
        enemy.y -= 5;
        bullet.y = 400;
    }
}
/*
碰撞,指的是窗口中两张图片是否有交集。如果有交集,则认为两张图片发生碰撞。    
判断两张图片是否有交集,似乎不太好做,所以为了判断方便,    
我们把每张图片都看做一个圆,这个圆,就是我们通常所说的假想圆。   
这个假想圆,非常类似于我们在数学课中所学到的三角形外接圆的概念。
在判断碰撞时,我们只需要判断两个假想圆是否有交集就可以了。
当A、B两张图片中心点距离小于A、B两个假想圆的半径之和时,我们就认为两张图片发生了碰撞。        
*/

12. 逐帧动画

//逐帧动画
/*
切换图片纹理,就是更改图片显示内容
var texture = new PIXI.Texture.fromImage('res/plane_blue_01.png'); //用于创建一个纹理
plane.texture = texture; //将飞机plane图片的纹理,更改为texture所指定的纹理内容    
*/

/*
通过图片纹理,创建图片显示元素
var texture = new PIXI.Texture.fromImage("res/plane_blue_01.png");
var plane = new PIXI.Sprite(texture);  //通过己创建好的纹理,来创建一个图片显示元素
*/

//快速实现逐帧动画

//创建图片数组,用于充当帧频动画的纹理
var imageList = [];
for(var i=1;i<=11;i++){
    imageList.push("res/plane/plays/planplay_"+i+".png")
}

//创建逐帧动画,将imageList中所有图片作为动画切换的纹理
var as = PIXI.extras.AnimatedSprite.fromImages(imageList);
as.anchor.set(0.5,0.5);
as.x = 200;
as.y = 200;
app.stage.addChild(as);

as.animationSpeed = 0.2;//设置动画播放速度(值为0到1之间的小数,0最慢,1最快)
as.loop = false;//loop属性,用于控制是否循环播放动画
//as.gotoAndPlay(5);//指定从第5帧,开始播放as动画
as.play();//播放动画

//如果想要使用onComplete属性,那么loop属性必须设置为false
as.onComplete = complete;//指定一个函数,当动画播放完毕时执行该函数
function complete() {
    txt.text = "is completed";
}

三. 一个简单的飞机大战小游戏


// index.js 文件完整源码

var app = new PIXI.Application(512,768);
document.body.appendChild(app.view);

//存储敌机的数组
var enemyList = [];
//存储子弹的数组
var bulletList = [];
//得分
var scoreTxt=0;

var bg = new PIXI.Sprite.fromImage("res/plane/bg/img_bg_level_3.jpg");//背景
var yun = new PIXI.Sprite.fromImage("res/texiao/yun02.png");//云
yun.x=15;
yun.y=150;

// var plane = new PIXI.Sprite.fromImage("res/plane/plane_blue_01.png");//蓝色飞机
// plane.x=200;
// plane.y=650;
// plane.anchor.set(0.5,0.5);
//创建飞机图片数组,用于充当帧频动画的纹理
var imageList = [];
for(var i=1;i<=11;i++){
    imageList.push("res/plane/plays/planplay_"+i+".png")
}
//创建逐帧动画,将imageList中所有图片作为动画切换的纹理
var plane = PIXI.extras.AnimatedSprite.fromImages(imageList);
plane.anchor.set(0.5,0.5);
plane.x = 200;
plane.y = 650;
app.stage.addChild(plane);
plane.animationSpeed = 0.2;
plane.play();

var ui1 = new PIXI.Sprite.fromImage("res/plane/ui/2_03.png");//HP条黑底
ui1.x=10;
ui1.y=5;
var ui2 = new PIXI.Sprite.fromImage("res/plane/ui/3_03.png");//HP条红条
ui2.x=10;
ui2.y=5;
var hp = new PIXI.Sprite.fromImage("res/plane/ui/img_ui_16.png");//HP条文字
hp.x=5;
hp.y=5;
var exp = new PIXI.Sprite.fromImage("res/plane/item/img_plane_item_15.png");//EXP浮标
exp.x = 200;
exp.y = 400;
var score = new PIXI.Text("得分:00000"); //得分
score.style.fill = 0xffffff;//设置字体颜色    
score.x=300;
score.y=5;

app.stage.addChild(bg);
app.stage.addChild(yun);
app.stage.addChild(plane);
app.stage.addChild(ui1);
app.stage.addChild(ui2);
app.stage.addChild(hp);
app.stage.addChild(score); 
app.stage.addChild(exp);

//右侧僚机
var planeRight = new PIXI.Sprite.fromImage("res/plane/liaoji_02_11.png");
planeRight.anchor.set(0.5,0.5)
planeRight.x = 80;
planeRight.y = 60;
plane.addChild(planeRight);
//左侧僚机
var planeLeft = new PIXI.Sprite.fromImage("res/plane/liaoji_02_11.png");
planeLeft.anchor.set(0.5,0.5);
planeLeft.x = -80;
planeLeft.y = 60;
plane.addChild(planeLeft); 

//开始按钮
var start = new PIXI.Sprite.fromImage("res/plane/ui/start.png");
start.anchor.set(0.5,0.5);
start.x=250;
start.y=400;
app.stage.addChild(start);
//暂停按钮
var stop = new PIXI.Sprite.fromImage("res/plane/ui/ui_new_btn_png_03.png");
stop.anchor.set(0.5,0.5);
stop.x=470;
stop.y=50;
app.stage.addChild(stop);
stop.visible=false;

var startFlag=0;
start.interactive = true;
start.on("click", startGame);
function startGame() {
    start.visible=false;
    stop.visible=true;
    startFlag=1;
}
stop.interactive = true;
stop.on("click", stopGame);
function stopGame() {
    start.visible=true;
    stop.visible=false;
    startFlag=0;
}



bg.interactive = true;
//不管把 mousemove 事件添加给舞台上哪一个显示元素,最终都是由应用程序窗口,响应该事件。
bg.on("mousemove", movePlane);
function movePlane(event) {
    if(startFlag==1){
        var pos = event.data.getLocalPosition(app.stage);
        plane.x = pos.x;
        plane.y = pos.y;
    }
}



app.ticker.add(animate);
//定义一个名叫 animate 的函数,实现补间动画    
function animate() {
    if(startFlag==1){
        bgMove();
        expMove();
        
        addEnemy();//添加敌机
        enemyMove();//敌机移动
        
        addBullet();//添加子弹
        bullletMove();//移动子弹
        
        crash();//敌机与子弹碰撞
        crashExp();//主机与Exp碰撞
    }
}

//背景图片和云移动
function bgMove() {
    bg.y += 1;
    if(bg.y > 0){
        bg.y = -772;
    }
    
    yun.y += 2;
    if(yun.y > 780){
        yun.y = -600;
    }
}

//exp移动
function expMove() {
    exp.x+=1;
    exp.y+=1;
    if(exp.x>512||exp.y>768){
        exp.x = Math.random()*512;
        exp.y = Math.random()*100;
    }
}

//添加敌机
var a = 0;
function addEnemy() {
    if(a == 30) {
         //创建敌机
        var enemy = PIXI.Sprite.fromImage("res/plane/enemy_04.png");
        enemy.anchor.set(0.5,0.5);
        enemy.x = Math.random() * 400;
        app.stage.addChild(enemy);
        
        //将敌机添加到数组
        enemyList.push(enemy);
        
        a = 0;
    }
    a++;
}

//敌机移动
function enemyMove() {
    for(var i=enemyList.length-1;i>=0;i--) {
        var enemy = enemyList[i];
        enemy.y += 4;
        //敌机是否超出边界
        if(enemy.y > 600) {
            //销毁敌机
            app.stage.removeChild(enemy);
            enemyList.splice(i,1);
        }
    }
}

var bulletAddSpeed=20;//子弹默认发射速度,越小越快
//添加子弹
var b = 0;
function addBullet() {
    if(b == bulletAddSpeed) {
        //创建子弹
        var bullet = PIXI.Sprite.fromImage("res/plane/bullet_02.png");
        bullet.anchor.set(0.5,0.5);
        bullet.y = plane.y;
        bullet.x = plane.x;
        app.stage.addChild(bullet);
        
        //将子弹图片添加到子弹数组中
        bulletList.push(bullet);

        b = 0;
    } 
    b++;
}

var bulletSpeed=10;//子弹默认移动速度,越大越快
//子弹移动
function bullletMove() {
    for(var i=bulletList.length-1;i>=0;i--) {
        var bullet = bulletList[i];
        bullet.y -= bulletSpeed;
        //子弹是否超出边界
        if(bullet.y < -100) {
            //销毁子弹
            app.stage.removeChild(bullet);
            bulletList.splice(i,1);
        }
    }
}

//敌机与子弹的碰撞
function crash(){
    //循环子弹数组
    for(var i=0;i

四. 参考文档

【教程】使用webpack搭建pixi.js开发环境 - SegmentFault 思否本文介绍怎么使用webpack4搭建pixi.js游戏的开发环境,怎么配置babel优化代码(tree shake)、混淆代码、合并代码、并最终将ES6+转换为ES5,怎么优化图片资源并最终发布项目。这篇文章也被pixi.js官方收录为教程 Webpack tutorial with pixihttps://segmentfault.com/a/1190000021724296?_ea=31872857【教程】pixi.js拼图游戏教程 - SegmentFault 思否教程面向已经能简单使用pixi.js的开发者,通过创建一个拼图游戏,来演示怎么完整的开发一款pixi游戏并最终发布。 此教程也被pixi.js官方收录为教程 How to make jigsaw game此项目中你可以学会怎么使用ES6+开发,怎么划分模块,怎么提前加载资源,怎么进行屏幕自适应,怎么播放音频和视频,怎么分层,怎么通过继承pixi类...https://segmentfault.com/a/1190000021726866 

使用Pixi.js编写飞机大战小游戏_潘鹏i的博客-CSDN博客使用Pixi.js编写飞机大战小游戏此小游戏前端使用Pixi.Js+tweenMax.js编写,后端使用express.js+mysql编写。试玩游戏预览地址源码查看Github链接游戏内截图https://blog.csdn.net/panchuanpeng/article/details/109596380如何使用pixi.js制作'打飞机'小游戏 - 简书什么是pixi.js Pixi.js使用WebGL,是一个超快的HTML5 2D渲染引擎。作为一个Javascript的2D渲染器,Pixi.js的目标是提供一个快速的、轻量...https://www.jianshu.com/p/0475cd430fdb

你可能感兴趣的:(Javascript,javascript)