国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

iOS開發(fā)之粒子效果

2019-11-14 19:53:02
字體:
供稿:網(wǎng)友

本文由糖炒小蝦、Benna翻譯 ,校對:sai、u0u0、iven、子龍山人

 

iOS 5中的UIKit粒子系統(tǒng)教程

 

Ray的話:這是第15篇、也是最后一篇《iOS 5 盛宴》中的iOS 5教程!這篇教程來自我們的新書《iOS 5 教程》中的一篇免費預(yù)覽章節(jié)。這個禮拜三我們將迎來《iOS 5 盛宴》系列的最后一次發(fā)布——來自史詩般的《iOS 5 盛宴》奉送,最后一次#ios5feast的廣播!:]

    這是篇教程由iOS教程小組成員Marin Todorov所撰寫,他是一位擁有超過12年經(jīng)驗的軟件開發(fā)者,一位iOS的獨立開發(fā)者,同時他也是Touch Code Magazine的創(chuàng)立者。

    你可能已經(jīng)看過一些粒子系統(tǒng),它們被應(yīng)用于很多iOS應(yīng)用程序和游戲中,諸如爆炸、火特效、下雨或者下雪等。然而,你所看到的這些特效類型可能大部分出現(xiàn)在游戲之中,因為UIKit不提供內(nèi)置的功能來創(chuàng)建粒子系統(tǒng)----直到iOS 5的出現(xiàn),這種情況將有所改變,本教程將采用UIKit來制作粒子系統(tǒng)!

    現(xiàn)在,利用iOS 5你能直接在UIkit中使用粒子系統(tǒng),給你的應(yīng)用程序帶來很多令人興奮的視覺享受。這里有一些非常適用于使用粒子系統(tǒng)的例子:

  •   UIKit 游戲:是的,你可以通過普通的UIKit制作游戲(有些游戲類型運作得相當(dāng)好,尤其是棋牌類游戲)。現(xiàn)在,你可以用爆炸、煙霧等其他更引人的東西制作更好的游戲!
  •   美化UI效果:當(dāng)你的用戶在界面上移動一個物體時,它能留下一條煙霧痕跡,為什么不做呢?
  •  令人目眩的屏幕轉(zhuǎn)場效果:何不在你的應(yīng)用程序顯現(xiàn)下一個場景時,讓之前的場景消失在一個火球中? 

    希望能用UIKit粒子系統(tǒng)做些什么,也許你已經(jīng)有一些很酷的想法啦。那么,讓我們開始吧!

    在這個教程中,我們將開發(fā)一個叫“Draw with fire”的應(yīng)用程序,讓你(你猜中了)在屏幕上繪制火焰。

    你將和我一起完成粒子系統(tǒng)的創(chuàng)建與設(shè)置來實現(xiàn)屏幕上看到的效果,讓你能將你的想法一步步實現(xiàn)。當(dāng)這個應(yīng)用完成,你就能用它繪制一個用火焰標(biāo)記的漂亮的問號,就像這個:

 

 

新的粒子 API

 

    有兩個類在你創(chuàng)建粒子系統(tǒng)時將會需要使用,它們在QuartzCore框架中,名叫CAEmitterLayer和CAEmitterCell。

    通常的想法是你創(chuàng)建一個CAEmitterLayer,并將一個或多個CAEmitterCell添加到里面。接著每個單元(cell)會按它配置的樣式產(chǎn)生粒子。

    而且CAEmitterLayer繼承自CALayer,你能輕易地在UIKit分層的任何地方加入它!

    我想這個新的UIKit粒子系統(tǒng)最酷的是一個單獨的CAEmitterLayer可以支持多個CAEmitterCell。這支持你完成一些相當(dāng)復(fù)雜而且很酷的效果。例如當(dāng)你創(chuàng)建泉水時,你能擁有一個cell發(fā)射水滴,另一個cell在泉水上發(fā)射水蒸汽!

 

Getting Started

 

    打開Xcode,并從主菜單中選擇File/New/New PRoject,選擇iOS/application/Single View Application模版,點擊Next,鍵入程序名“DrawWithFire”,再鍵入DWF為前綴,選擇iphone for Device Family,確認(rèn)勾選“Use automatic reference counting”(其他選擇框別選)。接著點擊Next,再點擊Create保存項目。

     選擇你的項目,再選擇DrawWithFire的target。接著打開Build Phases選項卡,展開Link Binary  With  Libraies部分,再點擊“+”按鈕,雙擊QuartzCore.framework,將Quartz繪圖功能添加到項目里面。

     我們將創(chuàng)建一個自定義UIView類來開始項目,這個類將有CAEmitterLayer作為它的層。事實上,完成這些非常簡單,通過重寫UIView類的+(Class)layerClass方法并返回一個CAEmitter類。相當(dāng)酷哦!

     創(chuàng)建一個新文件,采用iOS/Cocoa Touch/Objective-C類模板,類名為DWFParticleView,繼承于UIView。

     打開DWFParticleView.m并替換為如下代碼:

復(fù)制代碼
#import "DWFParticleView.h"#import <QuartzCore/QuartzCore.h> @implementation DWFParticleView{    CAEmitterLayer* fireEmitter; //1} -(void)awakeFromNib{    //set ref to the layer    fireEmitter = (CAEmitterLayer*)self.layer; //2} + (Class) layerClass //3{    //configure the UIView to have emitter layer    return [CAEmitterLayer class];} @end
復(fù)制代碼

 

讓我們重溫下初始代碼:

  • 我們創(chuàng)建一個單一的私有實例變量來控制CAEmitterLayer。
  •  在awakeFromNib中,我們設(shè)置fireEmitter為這個視圖的self.layer。我們將它存儲在我們創(chuàng)建的fireEmitter實例變量中,因為之后我們將在這上面設(shè)置許多參數(shù)。
  •  +(Class)layerClass是UIView的類方法,它告訴UIKit使用哪個類作為這個視圖的根CALayer。想要更多關(guān)于CALayer的信息,請查看CALayer教程介紹

 

接下來,讓我們將視圖控制器的根視圖轉(zhuǎn)到DWFParticleView。打開DWFViewController.xib并實現(xiàn)如下步驟:

 

1、  確認(rèn)Utilities工具條是可見的(在這張圖上突出的按鈕都改被按下)。

2、  選擇Interface Builder中的灰色區(qū)域——這是這個視圖控制器的根視圖。

3、  點擊Identity Inspector選項卡。

4、  在Custom Class面板,在文本框中輸入DWFParticleView。

 

現(xiàn)在,我們已經(jīng)將UI全都設(shè)置好——干得好!讓我們在圖中添加一些粒子。

 

A Particle Examined

 

為了發(fā)射火焰、煙霧、瀑布或者其他什么,你將需要一份好的PNG文件來啟動你的粒子。你可以在任何圖像編輯程序中自己制作它。看看我為這個教程制作的圖片(它被放大了并置于黑色背景中,這樣你才能看清楚它的形狀):

 

我的粒子文件大小是32*32像素,這是份透明的PNG文件,我僅使用有點時髦的筆刷,隨意地用白色繪制而成。對粒子來說,最好的就是使用白色,因為粒子發(fā)射器可以用我們想要的顏色對提供的圖像著色。讓粒子圖像呈半透明也是個很好的想法,如此粒子系統(tǒng)就能將粒子通過它們自己混合在一起(你可以通過少量不同的圖像文件理解它如何工作)。

 

這樣,你就能創(chuàng)建自己的粒子或者就使用我制作的這個,但是要確定它添加到你的Xcode項目中并命名為Particles_fire.png。

 

讓我們開始產(chǎn)生粒子吧!

是時候添加代碼讓我們的CAEmitterLayer做一些神奇的事情啦!

打開DWFParticleView.m 將如下代碼添加到awakeFromNib:中

//configure the emitter layerfireEmitter.emitterPosition = CGPointMake(50, 50);fireEmitter.emitterSize = CGSizeMake(10, 10);

 

上面的代碼是用來設(shè)置emitter的坐標(biāo)(view的坐標(biāo)系下) 和生成粒子的大小的。

然后,在awakeFromNib后面添加一個CAEmitterCell到CAEmitterLayer上,讓我們最終能在屏幕上看到粒子效果

復(fù)制代碼
CAEmitterCell* fire = [CAEmitterCell emitterCell];fire.birthRate = 200;fire.lifetime = 3.0;fire.lifetimeRange = 0.5;fire.color = [[UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:0.1]   CGColor];fire.contents = (id)[[UIImage imageNamed:@"Particles_fire.png"] CGImage];[fire setName:@"fire"]; //add the cell to the layer and we're donefireEmitter.emitterCells = [NSArray arrayWithObject:fire];
復(fù)制代碼

 我們生成了一個cell實例,并設(shè)置了一些屬性。然后設(shè)置CAEmitterLayer中emitterCells的屬性---一個包含cells的NSArray數(shù)組。現(xiàn)在emitterCell們已經(jīng)設(shè)置好了,CAEmitterLayer準(zhǔn)備好發(fā)射粒子了!

剛才設(shè)置了很多CAEmitterCell的屬性,讓我們一一過下

  • Birthrate(出生率):每秒發(fā)射的粒子數(shù)量,一個好的火焰或者瀑布你最少需要幾百個粒子,所以我們設(shè)置為200
  • lifetime(生命時間):一個粒子幾秒后消失,我們設(shè)置為3.0
  • liftetimeRange(生命時間變化范圍):你可以用這個東西使粒子的lifetime產(chǎn)生少許變化。粒子系統(tǒng)會隨機在這個區(qū)間中取一個lifetime出來(lifetime – lifetimeRange, lifetime + lifetimeRange) 在我們的程序中,粒子會存活2.5~3.5秒
  • Color(顏色):粒子內(nèi)容的顏色,我們這里選擇橙色
  • Contents(內(nèi)容):用于cell的內(nèi)容,一般是一個CGImage. 我們把它賦值給粒子圖像。
  • Name(名稱):你可以給你的cell取一個名字,用來在之后的時間里查找和修改它的屬性。

運行程序,來測試一下我們的粒子效果!

 

好吧,它工作了,但是并不像我們想象的那么酷。你甚至可以毫不掩飾的承認(rèn),它看起來像一個橘黃色的斑點。

讓我們做一些小改動使粒子變得更具有動感。把這些代碼添加到setName: on the cell前面

fire.velocity = 10;fire.velocityRange = 20;fire.emissionRange = M_PI_2;   
  •  velocity(速度): 粒子每秒移動的像素數(shù). 這里我們讓cell發(fā)射的粒子向屏幕的右邊沿移動這里我們設(shè)置如下的新屬性在CAEimtterCell中:
  • velocityRange(速度范圍): 速度變化范圍,和lifetimeRange相似
  • emissionRange(發(fā)射角度):這是一個cell發(fā)射的角度范圍(弧度制).M_PI_2(pi/2)是45度(也就是說生成范圍會+-45度)

(編譯并運行來)檢查一下我們的成果

 

這次看起來好點,距離我們的目標(biāo)不遠了!如果你想把這些屬性是如何影響粒子發(fā)生器理解的更透徹,那就去自由發(fā)揮吧,修改屬性值看效果。

再添加兩行,來結(jié)束cell的設(shè)置

fire.scaleSpeed = 0.3;fire.spin = 0.5;     
  • ScaleSpeed(變大速度):每秒修改粒子大小的百分比。我們設(shè)置0.3讓粒子隨著時間則推移變大 這里我們設(shè)置如下的新屬性在CAEimtterCell中
  • Spin(旋轉(zhuǎn)):每個粒子的旋轉(zhuǎn)速率。我們設(shè)置0.5來給粒子一個漂亮的旋轉(zhuǎn)

再次運行:

 

     現(xiàn)在看起來有點像鐵銹色的煙,這是為什么呢?CAEmitterCell有很多屬性來調(diào)整,天空類型在這里受限制。在設(shè)置fireEmitter.emitterSize后面加這么一句話

fireEmitter.renderMode = kCAEmitterLayerAdditive;

    這一行代碼用于讓我們鐵銹色的煙變成沸騰的火球,運行來查看效果

    發(fā)生了什么?遞增渲染模式(additive render mode)基本上是告訴系統(tǒng)不要用普通的方式——一個蓋住一個的繪制粒子,而是換了一種更酷的方法:如果粒子相互重疊的話他們的顏色強度會增加!所以,你會在粒子發(fā)生器的區(qū)域里面看到大量的白色亮斑,但在區(qū)域外是火球,那里因為粒子不斷消亡而數(shù)量減少,色彩漸變到原來的鐵銹色。太棒了!

     你現(xiàn)在可能會覺得火焰非常不真實。的確,你可以通過修改cell的屬性讓火焰的效果更好。但是我們需要這么厚的效果,因為我們要去繪制它。當(dāng)你在設(shè)備屏幕上拖動手指的時候,屏幕上會收到相對少的觸摸點,所以我們用厚重的火球來補償他。

 

玩兒火吧!

 

    現(xiàn)在,你終于可以玩火了(在現(xiàn)實生活中我們被告知永遠不要玩火):]

    下面來實現(xiàn)用手指在屏幕上畫火焰,我們需要通過用戶觸摸點來修改粒子發(fā)生器的位置

    首先在DWFParticleView.h中聲明一個方法:

-(void)setEmitterPositionFromTouch: (UITouch*)t;

然后在DWFParticleView.m中實現(xiàn)它

-(void)setEmitterPositionFromTouch: (UITouch*)t{    //change the emitter's position    fireEmitter.emitterPosition = [t locationInView:self];}

 

     這個方法獲得一個觸摸點并作為實參, 將觸摸點信息轉(zhuǎn)移到ParticleView的坐標(biāo)系中,并修改粒子發(fā)生器的坐標(biāo)

我們需要在view controller中控制它,所以我們下一步是在viewController中定義接口

復(fù)制代碼
#import <UIKit/UIKit.h>#import "DWFParticleView.h" @interface DWFViewController : UIViewController{    IBOutlet DWFParticleView* fireView;}@end
復(fù)制代碼

之后打開DWFViewController.xib 然后按住control從File’s Owner向root view拖動,在彈出的選項卡中選擇fireView正如你所見,我們import了我們的自定義view類,并且在DWFParticleView中定義了實例變量。

 

現(xiàn)在我們能通過view controller 訪問emitter 層。打開DWFViewController.m 刪掉所有自動生成的代碼,添加如下代碼

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {    [fireView setEmitterPositionFromTouch: [touches anyObject]];}

試著用更快或者更慢的速度拖動它,來看對粒子產(chǎn)生所造成的影響運行,觸摸并向四周拖動,你會看到粒子發(fā)生器跟著移動并留下一串很酷的火焰

 

動態(tài)修改Cell

今天最后的話題是在emitter 層動態(tài)的改動cell們。現(xiàn)在,粒子發(fā)生器一直在產(chǎn)生粒子。沒能給用戶一種是他們畫上去的感覺,讓我們來將粒子發(fā)生的條件改為僅當(dāng)手指觸摸到屏幕的時候產(chǎn)生粒子.那么一開始就不要產(chǎn)生了,于是將DWFParticleView.m的awakeFromNib method方法中 粒子的birthrate設(shè)為0

fire.birthRate = 0;

如果你現(xiàn)在運行的話,會發(fā)現(xiàn)屏幕空空如也,很好!下面添加一個方法來作為粒子發(fā)生(發(fā)射)器的開關(guān)。首先在DWFParticeView的頭文件中定義如下方法

-(void)setIsEmitting:(BOOL)isEmitting;

 

然后在DWFParticleView.m實現(xiàn)它

-(void)setIsEmitting:(BOOL)isEmitting{    //turn on/off the emitting of particles    [fireEmitter setValue:[NSNumber numberWithInt:isEmitting?200:0]       forKeyPath:@"emitterCells.fire.birthRate"];}

 這里使用setValue:forKeyPath:方法來改動一個cell, 是因為我們早先將cell的名字添加到了emitter中。我們使用”emitterCells.fire.birthRate”做keypath是因為birthRate是emitterCells數(shù)組中一個叫做叫fire的cells的屬性。

最后我們需要在觸摸開始的時候打開粒子發(fā)生器的開關(guān),在抬起手指的時候關(guān)掉它。在DWFViewController

中添加如下代碼

復(fù)制代碼
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {    [fireView setEmitterPositionFromTouch: [touches anyObject]];    [fireView setIsEmitting:YES];} - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {    [fireView setIsEmitting:NO];} - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {    [fireView setIsEmitting:NO];}
復(fù)制代碼

完成并運行~觀察效果咯~記住,你在玩兒火:-)

 

Where To Go From Here?

這里是樣例工程的全部代碼。

如果你喜歡這個教程,這里有更多你可以研究的東西。你可以

  • 實驗不同的粒子圖片
  • 去CAEmitterCell的官方文檔中看看它全部的屬性們
  • 添加一個函數(shù),將屏幕上的圖片渲染保存到圖片中
  • 將繪制過程保存到視頻文件中
  • 在你的所有應(yīng)用的文本框的后面添加燃燒的火焰作為背景。

以上內(nèi)容是轉(zhuǎn)載別人的,這里是我自己實現(xiàn)的粒子效果Demo,下載下來就可以跑啦。下載地址:TestFire.zip


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 玉树县| 沙坪坝区| 盘锦市| 宿迁市| 湟源县| 卫辉市| 大足县| 理塘县| 专栏| 甘南县| 连平县| 万宁市| 乌拉特中旗| 黄大仙区| 临猗县| 庆安县| 东乡族自治县| 清徐县| 酒泉市| 黎川县| 新平| 连平县| 尼勒克县| 铅山县| 高唐县| 林西县| 襄城县| 通辽市| 甘泉县| 南丹县| 周口市| 凌海市| 汶川县| 东城区| 九台市| 永丰县| 西峡县| 开原市| 若羌县| 子长县| 泌阳县|