Chap_16 纹理切换与帧频动画

一、概念

[wm_notice]

  • 纹理 :图片元素中显示的内容
  • 纹理切换:更换图片中显示的内容,可以让元素中的内容产生变化

[/wm_notice]

二、元素与纹理

元素与纹理通常一起创建

//  图片元素				 纹理
var plane = new PIXI.Sprite.fromImage("img/plane1.png");

plane就是图片元素 而 "img/plane.png" 就是纹理

创建纹理

语法

var 变量名 =  new PIXI.Texture.fromImage("路径");

var texture = new PIXI.Texture.fromImage("img/plane1.png");

创建图片元素并添加纹理

语法

var 变量名 = new PIXI.Sprite(纹理变量)

var plane = new PIXI.Sprite(texture);

修改图片元素中的纹理

语法

元素名.texture = 新纹理;

//创建纹理1
var t1 = new PIXI.Texture.fromImage("img/plane1.png");
var t2 = new PIXI.Texture.fromImage("img/plane2.png");
//创建图片元素并添加纹理 t1
var plane = new PIXI.Sprite( t1 );
//将plane元素中的纹理更改为t2
plane.texture  = t2;

三、通过快速切换纹理实现帧频动画

[wm_notice]PIXI中提供了一些可以通过快速切换纹理实现帧频动画的方法[/wm_notice]

运行效果

如下图所示

第一步 :准备一个存放所有纹理路径的数组

//用于保存所有纹理路径的数组
var ts = [];
//向数组中添加纹理路径
ts.push("img/planplay_1.png");
ts.push("img/planplay_2.png");
ts.push("img/planplay_3.png");
ts.push("img/planplay_4.png");
ts.push("img/planplay_5.png");
ts.push("img/planplay_6.png");
//略.....

第二步:创建纹理播放器

语法
var 变量名 = PIXI.extras.AnimatedSprite.fromImages( 纹理数组 );

var as = new PIXI.extras.AnimatedSprite.fromImages( ts );

第三步:调整属性并在应用中添加播放器

//创建纹理播放器
var as = new PIXI.extras.AnimatedSprite.fromImages( ts );
//设置播放器位置
as.x = 200;
as.y = 200;
//在应用中添加播放器
app.stage.addChild( as );

第四步:设置播放速度

播放速度0~1,数值越小速度越慢

语法

纹理播放器.animationSpeed = 播放速度;

//设置动画播放速度
as.animationSpeed = 0.15;

第五步:播放动画

语法

纹理播放器.play();

as.play();

完整代码

var app = new PIXI.Application(500,700);
document.body.appendChild( app.view );
			
//用于保存所有纹理路径的数组
var ts = [];
//向数组中添加纹理路径
ts.push("img/planplay_1.png");
ts.push("img/planplay_2.png");
ts.push("img/planplay_3.png");
ts.push("img/planplay_4.png");
ts.push("img/planplay_5.png");
ts.push("img/planplay_6.png");
ts.push("img/planplay_7.png");
ts.push("img/planplay_8.png");
ts.push("img/planplay_9.png");
ts.push("img/planplay_10.png");
ts.push("img/planplay_11.png");
			
//创建纹理播放器
var as = new PIXI.extras.AnimatedSprite.fromImages( ts );
//设置播放器位置
as.x = 200;
as.y = 200;
//在应用中添加播放器
app.stage.addChild( as );
//设置动画播放速度
as.animationSpeed = 0.15;
//播放动画
as.play();

 

Chap14_碰撞的判断及利用勾股定理计算出距离

[wm_tips]概念: 碰撞,指的是窗口中两张图片是否有交集。如果有交集,则认为两张图片发生碰撞。[/wm_tips]

一 、假想圆

因为图片形状各异,判断两张图片是否有交集,似乎不太好做,所以为了判断方便, 我们把每张图片都看做一个圆,这个圆,就是我们通常所说的假想圆。

二、碰撞距离

有了假想圆,在判断碰撞时就容易多了,我们只需要判断两个假想圆是否有交集就可以了。

通过上图可以看出,当A、B两张图片中心点距离小于A、B两个假想圆的半径之和时

我们就认为两张图片发生了碰撞。

可问题是:两个假想圆的半径是固定的,但AB中心点的距离如何获得呢?

三、利用勾股定理计算距离

如果我们想要获得AB两个中心点距离,那么必须要用上勾股定理了。

[wm_tips]勾股定理:在直角三角形中,两条直角边的平方和,等于斜边的平方[/wm_tips]

  • 虽然现在c边的距离我们不知道,但a边和b边的距离我们是能求出来的
  • a 边的距离长度 = 子弹的y坐标 – 飞机的y坐标
  • b 边的距离长度 = 子弹的x坐标 – 飞机的x坐标
  • 所以通过勾股定理,我们同样可以求出 c 边长度的平方值

计算公式如下

  • 如果两元素距离 小于等于 碰撞距离,则视为两元素发生碰撞
  • 如果两元素距离的平方值 小于等于 碰撞距离的平方值,则视为两元素发生碰撞

四、碰撞判断步骤总结

  1. 根据元素宽高特点划定假想圆,元素锚点为中心,作为假想圆的圆心位置
  2. 计算碰撞距离:两个元素假想圆半径之和,如果两元素间距小于或等于碰撞距离,则视为发生碰撞
  3. 计算两个元素x轴距离与y轴距离(距离既边长)
  4. 计算两个元素间距:根据勾股定理,得出x轴距离平方+y轴距离平方==间距平方
  5. 如果间距的平方<=碰撞距离的平方(间距<=碰撞距离,由于得到的间距是平方值,所以碰撞距离 也要用平方值)

五、多元素碰撞

示例代码

var app = new PIXI.Application(500,700);
document.body.appendChild( app.view );
			
//添加图片元素(飞机)
var plane = new PIXI.Sprite.fromImage("img/plane.png");
plane.x  = 250;
plane.y  = 650;
//设置飞机图片锚点为中心
plane.anchor.set(0.5,0.5);
app.stage.addChild( plane );
			
//定义变量,敌机计时器
var escount = 0;
//定义变量,子弹计时器
var bscount = 0;
			
//定义数组用于存储敌机元素
var es = [];
			
//定义数组用于存储子弹元素
var bs = [];
			
//自定义帧频函数
function animate(){
	//如果帧频函数执行次数等于60,证明时间过了1秒
	if(escount == 60){
		//添加图片元素(敌机图片)
		var enemy =  new  PIXI.Sprite.fromImage("img/enemy.png");
		//Math.random() * n 获取0~n-1之间的随机数
		enemy.x = Math.random() *(500 - 104 +1);
		//将创建的每个敌机元素添加到数组中
		es.push( enemy );
		app.stage.addChild( enemy );	
		//重置count变量,重新计时
		escount=0;
	}
				
//如果帧频函数执行次数等于120,证明时间过了2秒
	if(bscount == 120 ){
		//添加图片元素(子弹图片)
		var bullet = new PIXI.Sprite.fromImage("img/bullet.png");
		//位置与飞机一致
		bullet.x = plane.x;
		bullet.y = plane.y;
		//设置锚点为中心
		bullet.anchor.set(0.5,0.5);
		//添加到数组中
		bs.push( bullet );
		//添加到应用窗口
		app.stage.addChild( bullet );
					
		//计数器归零
		bscount  = 0;
	}
				
	//遍历数组获取每颗子弹元素,添加动画效果 
	for(var i=0; i<bs.length; i++){
		//子弹向上移动
		bs[i].y-=5;
		//如果敌机移出边界,从数组中移除该元素
		if(bs[i].y<=0){
			//将子弹从应用窗口中移除
			app.stage.removeChild( bs[i] );
			//将子弹从数组中移除
			bs.splice(i,1);
		}	
	}
				
				
	//遍历数组获取每架敌机元素,添加动画效果
	for(var i=0;  i<es.length; i++){ //敌机向下移动 es[i].y+=3; //如果敌机移出边界,从数组中移除该元素 if(es[i].y>=700){
			//将敌机从应用窗口中移除
			app.stage.removeChild( es[i] );
			//将敌机从数组中移除
			es.splice(i,1);				
		}			
	}
				
	//帧频函数执行一次,计数变量+1
	escount++;
	bscount++;
}
//添加帧频函数
app.ticker.add( animate );

敌机数组如下图所示

子弹数组如下图所示

多飞机与多子弹碰撞,必须用每一个子弹元素与每一个飞机分别做碰撞判断

原理如下所示

核心代码

//遍历bs数组获取每颗子弹
for(var i = 0; i<bs.length; i++){
    //获取子弹元素
	var bullet  =  bs[i];
    
	//与每架敌机 碰撞判断
	//遍历es数组获取每架敌机
	for(var j=0; j<es.length; j++){
        //获取敌机元素 
		var enemy = es[j];
		//判断 bullet 是否与 enemy 发生碰撞
		//1、根据元素宽高及特点划定假想圆 
		//敌机元素宽度 104  ,假想圆半径 52
		//子弹元素宽度 50   ,假想圆半径 25
        
		//2、计算碰撞距离:两个元素假想圆半径之和
		var pos =  52+25;
        
		//3、计算元素x,y间距
		//获取x轴间距(边长)
		var xl = bullet.x - enemy.x;
		
        //获取y轴间距(边长)
		var yl = bullet.y - enemy.y;
						
        //4、计算两元素间距
		//xl、yl等于两个直角边的边长,根据勾股定理计算
		//xl*xl + yl*yl 等于 两个元素 间距的平方
						
        //5、如果两元素间距平方<=碰撞距离平方,则视为两元素发生碰撞
		if(xl*xl + yl*yl <= pos*pos){
			//从应用窗口中移除子弹元素
			app.stage.removeChild( bullet );
			//从数中移除子弹元素
			bs.splice(i,1);
			//从应用窗口中移除敌机元素 
			app.stage.removeChild( enemy );
			//从数中移除敌机元素
			es.splice(j,1);
		
		}
    }
}

获取/修改图层编号

  •  页面中每个图片都有自己所对应的图层以及编号,编号从0开始,编号越大图层越高
  • 可以通过修改图层编号设置图片的图层
  • 通过修改图层,可以让子弹一直处于飞机图层的下级

获取图层编号

app.stage.getChildIndex(classify3);

设置图层编号

//将元素的图层设置为指定编号级别 
app.stage.setChildIndex(元素,图层编号);

[wm_warn]注意:如果两元素图层一致,后添加的元素会置于制定编号位置,先添加的元素会自动提高一级。[/wm_warn]

Chap12_数组与集中处理方法

一 、数组概念

[wm_notice]用来存储多个数据(变量)的容器,存储在数组中的数据称为数组的元素。【水彩笔】【月饼盒】 特点:便于集中统一管理某些数据[/wm_notice]

例:定义多个变量表示学生的成绩,不便于同一维护

var stu1 = 59;
var stu2 = 60;
var stu3 = 70;
var stu4 = 80;
var stu5 = 45;
var stu6 = 50;
var stu7 = 55;
var stu8 = 61;
//.....100名学生就要定义 100个变量
			
//如何同时为每位同学的成绩加十分?
//如何计算班级平均分?
//如何将不及格的学生成绩改为及格?

[wm_warn]生活中的统一操作:军训(稍息,立正),打仗。反例:《让子弹飞》[/wm_warn]

二、定义数组

1、定义数组语法

【对比变量】

var 数组名称 = [];

var as = [];

2、创建数组时添加数据语法

var as = [数据1,数据2,数据3...];

var as = [59 , 60 , 70 , 80 , 45 , 50 , 55 , 61];
//在控制台输出as中的内容
console.log( as );

此时 as 就表示了一组数据

三、数组存取与删除

[wm_notice]有些时候数组由系统创建 或 无法在创建时得到数据并存入数据 此时必须通过数组提供的函数,当得到数据时再存入数组中[/wm_notice]

1、添加元素(数据 )

语法

数组名称.push( 数据 );

例:向数组中添加数据

var as = [];
//向数组中添加一个元素10
as.push(  10 );
//向数组中添加一个元素20
as.push(  30 );
as.push(  40 );
as.push(  50 );

//在控制台中输出  as
console.log( as);

数组中可以存储任何类型的数据与元素

2、获取元素(数据)

【数据存进去了,怎么用?之前用变量还有个名字,现在每个元素叫什么】

【数组叫什么?as,as[],中括号里写下标,as[下标 ],这就是元素的名字】

数组为每个元素都进行了编号,编号表示该元素在数组中的位置 在程序中我们称该编号为数组的下标 下标从0开始到数组长度-1结束,通过下标可以获取数组中的元素

语法

数组名称[下标];

var as = [50,10,800];
as[0];//数组中的第 1 个元素【第一个变量,名为as[0]】
as[1];//数组中的第 2 个元素【第二个变量,名为as[1]】
as[2];//数组中的第 3 个元素

var a1 = as[0];//提取数组中的第 1 个元素【提取变量,a1可以表示as[0]但不属于数组】
var a2 = as[1];//提取数组中的第 2 个元素【如a = 10, b =  a; b变化不会影响a】
var a3 = as[2];//提取数组中的第 3 个元素
			
//输出数组中的第 1 个元素
console.log( as[0]  );
//输出数组中的第 2 个元素
console.log( as[1]  );
//输出数组中的第 3 个元素
console.log( as[2]  );

使用循环遍历数组【重点】

[wm_tips]遍历数组:获取数组中的每一个元素[/wm_tips]

例:当数组元素很多时不便于统一操作

var as = [50,10,800];			
//输出数组中的第 1 个元素
console.log( as[0]  );
//输出数组中的第 2 个元素
console.log( as[1]  );
//输出数组中的第 3 个元素
console.log( as[2]  );

(重复的步骤放到循环中,不重复的步骤放到循环之外,有规律的变量想办法用循环变量替代)

例:使用循环遍历【重点】

var as = [50,10,800];
//已知as数组长度为3,下标范围0~2
//使用循环变量i充当下标,控制下标范围区间在0~2
//每次循环可以获取数组中的一个元素,直到最后一个元素
for(var i=0; i<3; i++){
    //输出数组中的某个元素
    console.log( as[i]  );
}

【遍历失败案例】例:数组长度改变,遍历失败(准备一个长度为4的数组)

3、获取数组长度

[wm_notice]数组的长度等于数组中的元素个数 在程序中可以动态的获取数组长度,以便在数组元素个数改变时,依然能够正确遍历[/wm_notice]

动态获取数组长度

数组名.length;
例如
var as = [10,20,30];
as.length;//获取as数组长度

使用数组长度增强遍历

//遍历数组
for( var i = 0; i<数组名.length; i++){
    //获取数组中的某个数据
	var a = as[i]);
    //输出到控制台中
	console.log( a );
}

4、删除元素(数据 )

语法

数组名称.splice(下标 , 个数);
个数:从下标位置开始(含下标位置的元素)删除几个元素

例:删除数组中的某一个元素

var as = [100,200,300,400,500];
//删除数组中的某一个元素  数组名称.splice(下标 , 1);
//2:下标
//1:删除1个元素
as.splice(2,1);
//结果:[100,200,400,500];

例:删除数组中的多个元素

var as = [100,200,300,400,500];
//输出as数组中的元素
//从下标0开始删除3个元素 0、1、2元素将被删除
as.splice(0,3);
//结果[400,500];