您的位置:首页 > Web前端 > Node.js

SpriteKit学习笔记(七)SKEmitterNode(粒子系统)、SKCropNode和SKEffectNode

2013-08-09 22:03 387 查看
最近一段时间都有在看SpriteKit的东西,前几天看了发布会上关于SpriteKit的视频,发现还有很多有趣的东西,之前看官方的API,看得都比较浅显,这几天重新仔细地再看了一下之前没怎么看的东西,今天就把这几天看的东西记录一下

首先SKEmitterNode,也就是粒子系统,emitter是发射器,你需要定义发射器的位置,发射粒子的地方、粒子速度、粒子大小、粒子数目等等

为你的游戏添加粒子系统很简单,XCode中new file时找到resource,可以看到SpriteKit Particle File这一项,XCode自带粒子系统文件而且可以直接用XCode编辑粒子系统,使用起来非常简单方便,只要你了解各个参数代表的意思,就能创造出你想要的任意粒子模型,雨、雪、火和烟等等

下面就来解释一下各个参数



首先第一项BackGround,这是你编辑粒子系统时的背景颜色,这个无关紧要,根据需要,一般都是黑色,但是当你要用一些黑色的粒子时,你可能就需要把它设为白色或者其他可以让黑色呈现的背景色

第二个Particle Texture,粒子的纹理,就是粒子的外形外观,如果是雪花那么你需要一张雪花的png图片,粒子为按照你为它添加的texture展现给你,在这里需要考虑资源消耗和内存问题,太复杂的纹理会消耗太多的资源,所以要注意使用

第三个Particles,它有两个参数,birthrate和maximum,根据字面意思其实就可以猜出大概了,接下来的参数都是这样,birthrate即一开始产生的数目,maximum是可以达到的最大的数目,粒子数目达到此值时就不会再继续发射,maximum为0时可以一直产生粒子,即无限

第四个Lifetime,start即粒子产生之后的生命周期,越大,粒子存在在你的游戏里越久,range即给粒子生命周期一个范围选择,粒子的生命就会有长有短,整个范围一般由range的值与start做加减获得

第五个大项,determing a particle's movement

Position Range, 发射位置范围,在x宽与y长的区域内发射粒子

Angle, 发射角度,start是初始发射角度,range如果为0,所有的粒子都会向start角度发射,设置Range之后,粒子会在start的基础上加减一半range的值作为发射角度,另外,当start的值为0时,粒子向右发射,90度即向上发射

Speed, 发射速度,start即初始速度,range的意思同上,在一个速度范围内选择一个作为粒子的发射角度

Acceleration,给粒子一个加速度,x即水平方向的加速度,正值为向右,y为垂直方向的加速度,正值为向上

接着是Scale,粒子的大小,start为初始大小,这里是按百分比来算的,1为原始大小,2是原始一倍,range用上,设置大小范围,speed可以让粒子在运动过程中改变大小,负值是从大到小,正值即从小到大变化

然后是Rotation,start是初始发射旋转角度,正值为逆时针旋转,range同上,speed可以让你的粒子在运动过程中不停旋转,正值为逆时针旋转

接下来是Color Blend,颜色混合度,factor为1时,粒子保持其原有的混合度,range同上,speed可以让你的粒子在运动过程中不断变化混合度

Color Ramp是粒子的颜色梯度,Color Blend会根据Color Ramp去改变粒子的颜色混合度

最后一个是Blend Mode混合模式,即你的粒子图片与粒子下面的图片的融合方式,一般都设置为alpha混合,如果你想要有其他的效果,可以设置其他的混合方式

到此,所有参数介绍完毕,接着要把它放到你的游戏里面

particle File的文件格式为sks,必须通过resource找到它

SKEmitterNode *snow = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"Snow" ofType:@"sks"]];
snow.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetHeight(self.frame));
[self addChild:snow];


用资源文件初始化发射器,其他的属性设置与普通SKNode没有太大区别

下面是我自己实现的粒子系统截图



太多的粒子会让你的游戏变卡,所有使用的时候要注意

接下来说一说一些其他类型的SKNode,SKCropNode,整个比较有趣,它实现了一个遮罩的效果,它本身不被渲染,使用它必须设置其maskNode属性还有为其添加child,cropNode也不会直接就渲染出child,而是通过maskNode,maskNode作为遮罩面,它的内容也是不会被渲染的,但是他的外边框会渲染出来,cropNode自动在其子node上以maskNode的边框裁剪子node的区域来渲染,是个挺有趣的东西

NSString *videoPath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"m4v"];
NSURL *videoUrl = [[NSURL alloc]initFileURLWithPath:videoPath];

AVPlayer *player = [[AVPlayer alloc]initWithURL:videoUrl];

//SKVideoNode *video = [SKVideoNode videoNodeWithVideoFileNamed:@"test"];
SKVideoNode *video = [SKVideoNode videoNodeWithAVPlayer:player];
video.size = CGSizeMake(300, 300);
//video.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

//[self addChild:video];
[video play];

//SKCropNode不渲染maskNode的content,也不渲染maskNode没有遮盖的地方,crop只渲染maskNode的边框外形,然后maskNode的content会渲染出crop的childrens,按maskNode的边框切割出来的形状渲染,当maskNode移动时,childrens的其他部分也可以被渲染出来,可以这样理解,crop的child是不可见的,而maskNode是可以让child可见的裁剪区域
SKCropNode *crop = [[SKCropNode alloc]init];
crop.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
SKSpriteNode *mask = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
mask.size = CGSizeMake(100, 100);
SKAction *up = [SKAction moveByX:0 y:100 duration:2];
SKAction *down = [SKAction moveByX:0 y:-100 duration:2];
SKAction *right = [SKAction moveByX:100 y:0 duration:2];
SKAction *left = [SKAction moveByX:-100 y:0 duration:2];
[mask runAction:[SKAction repeatActionForever:[SKAction sequence:@[up, down, right, left]]]];
crop.maskNode = mask;
[crop addChild:video];
[self addChild:crop];


maskNode还是与普通SpriteNode一样,可以有动作texture等,crop的child是不动,这时当移动maskNode的时候,可以看到child上不同的区域被渲染出来,我这里是播放一段视频,然后可以看到视频在maskNode的区域里面播放,说到播放视频,我使用videoNode的时候发现只能通过先初始化一个avplayer,然后再去初始化videoNode,这时才成功,不知道是什么问题,这个迟些再解决

还有一个是SKEffectNode,可以为其添加滤波器来改变其child图片,这里不对滤镜做太多的说明,这涉及到CFilter,自己也很少接触到,之前学数字图像处理,没学好,现在那个后悔啊,好多图片处理的好抽象的原理都懵懵懂懂,悲哀

由于这次的内容比较简单,就不贴上Demo了,官方的adventure game感觉做得不是很好,希望自己有机会能用SpriteKit弄个游戏玩玩,哈哈。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: