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。使用一个<script>标记来链接pixi.min.js文件,并使用一个<script>标记。
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Plane vs Enemy</title>
</head>
<script src="pixi/pixi.min.js"></script>
<script type='text/javascript' src='index.js'></script>
<body>
</body>
</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<arr.length;i++){
arr[i].y += 2;
}
}
删除数组中的值:
//删除数组中的值
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<arr.length;i++){
arr[i].y -= 8;
}
//如果子弹的超出边界,将子弹删除
for(var i=arr.length-1;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<bulletList.length;i++) {
var bullet = bulletList[i];
//循环敌机数组
for(var j=0;j<enemyList.length;j++) {
var enemy = enemyList[j];
var pos = (bullet.x - enemy.x) * (bullet.x - enemy.x) + (bullet.y - enemy.y) * (bullet.y - enemy.y);
//判断是否发生碰撞
if(pos < 60 * 60) {
//爆炸动画
enemyBoom(enemy);
//得分:每销毁一架敌机,得分增加200
scoreTxt+=200;
score.text = "得分:"+scoreTxt; //得分
//销毁子弹
app.stage.removeChild(bullet);
bulletList.splice(i, 1);
//销毁敌机
app.stage.removeChild(enemy);
enemyList.splice(j, 1);
break;
}
}
}
}
//主机与Exp碰撞
function crashExp(){
var pos = (plane.x - exp.x) * (plane.x - exp.x) + (plane.y - exp.y) * (plane.y - exp.y);
var c = plane.height/2 + exp.height/2;
//判断是否发生碰撞
if(pos < c * c) {
exp.x = Math.random()*512;
exp.y = -50;
bulletSpeed++;
bulletAddSpeed--;
}
}
//爆炸动画
//创建图片数组,用于充当帧频动画的纹理
var boomList = [];
for(var i=1;i<=7;i++){
boomList.push("res/texiao/bao0"+i+".png")
}
//创建逐帧动画,将boomList中所有图片作为动画切换的纹理
var boom = PIXI.extras.AnimatedSprite.fromImages(boomList);
boom.anchor.set(0.5,0.5);
app.stage.addChild(boom);
boom.visible=false;
boom.animationSpeed = 0.3;//设置动画播放速度(值为0到1之间的小数,0最慢,1最快)
boom.loop = false;//loop属性,用于控制是否循环播放动画
function enemyBoom(enemy) {
boom.visible=true;
boom.x = enemy.x;
boom.y = enemy.y;
boom.gotoAndPlay(0);
}
四. 参考文档
【教程】使用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
4080

被折叠的 条评论
为什么被折叠?



