<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                正好不知道接下來要怎么寫的時候,發現了一本好書:《Learn IPhone and iPad Cocos2d Game Delevopment》。于是直接翻譯了第4章的例子。如果你看過這部分內容,可以直接跳過不看了。本章講如何響應加速器事件。 ? ## 一、游戲介紹 這個例子是一個叫做DoodleDrop的游戲,是一個重力感應類游戲。玩家操縱角色來躲避從空中墜落的障礙物。游戲界面如下: ![](https://box.kancloud.cn/2016-05-04_572a0b95e0ffe.gif) ? ## 二、設置主場景 1、新建Cocos2dApplication,工程名DoodleDrop。 2、游戲主場景。選File-> new file,選擇User Templates -> Cocos2d.0.99.x -> CCNode.class。SubclassOf選擇CCLayer。文件名選GameScene。 3、在頭文件中聲明靜態方法+(id) scene; 4、.m文件 ~~~ #import"GameScene.h" @implementationGameScene +(id) scene { CCScene *scene = [CCScene node]; CCLayer* layer = [GameScene node]; [scene addChild:layer]; return scene; } -(id) init { if ((self = [super init])) { CCLOG(@"%@: %@",NSStringFromSelector(_cmd), self); returnself; } } -(void)dealloc { // never forget to call [super dealloc] [superdealloc]; CCLOG(@"%@: %@",NSStringFromSelector(_cmd), self); [super dealloc]; } @end ~~~ 5、刪除HelloWorldScene.h和HelloWorldScene.m文件。 6、修改DoodleDropAppDelegate.m,將其中的主場景啟動代碼修改為GameScene: ~~~ [[CCDirectorsharedDirector] runWithScene: [GameScene scene]]; ~~~ ## 三、游戲角色 1、把玩家角色圖片alien.png添加到工程。添加時,選中“Copy items”,同時勾選“add to targets”中的“DoodleDrop”選項。 2、在游戲主場景(GameScene.h)增加變量聲明: CCSprite*player; 3、在游戲主場景(GameScene.m)的init方法中加入下列代碼: ~~~ self.isAccelerometerEnabled= YES; player =[CCSprite spriteWithFile:@"alien.png"]; [selfaddChild:player z:0 tag:1]; CGSizescreenSize = [[CCDirector sharedDirector] winSize]; ?float imageHeight = [playertexture].contentSize.height; player.position= CGPointMake(screenSize.width / 2, imageHeight / 2); ~~~ 這樣,玩家角色就被放到屏幕底部正中的位置上。注意,player變量未retain。因為addChild會自動retain。 [playertexture].contentSize.height返回的是渲染圖的content size。渲染對象(玩家角色圖片alient.png)有兩個尺寸:contentsize和texture size。前者是圖片的實際尺寸,后者是渲染尺寸——iPhone規定渲染尺寸只能是2的n次方。比如圖片實際尺寸100*100,那么渲染尺寸則是128*128,因為最接近100的2的n次方為128。 ## 四、使用加速器 1、為了響應加速器事件,你必須在init方法中加上: ~~~ self.isAccelerometerEnabled= YES; ~~~ 同時實現accelerometer方法: ~~~ -(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration*)acceleration{ CGPoint pos = player.position; ?pos.x += acceleration.x * 10; player.position = pos; } ~~~ 跟java和c不同。你不能對player.position.x進行賦值。這種賦值在 c語言中是可以的,但oc中不行。因為player.position實際上是調用[playerposition],這個方法返回一個臨時的CGPoint變量。當你想對這個臨時的CGPoint的x進行賦值后,這個變量會被被拋棄,所以你的賦值沒有任何作用。所以你需要用一個新的CGPoint變量,修改其x值,然后再把這個CGPoint賦值給player.position(即調用[playersetPosition:])。如果你是來自java和c++的程序員,在oc中需要留心這個“不幸的”問題并盡可能的修改編程習慣。 2、運行測試 模擬器不支持重力感應,請在物理設備上運行代碼。 ## 五、玩家控制 現住發現用加速器控制有些不靈?反應遲鈍,移動也不流暢?為此,我們需要增加一些代碼。 首先需要增加變量聲明: ~~~ CGPointplayerVelocity; ~~~ 為了便于今后的擴展(假設有一天我們會想上下移動角色),這是一個CGPoint類型,而不是一個float。 然后修改加速器方法: ~~~ -(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration*)acceleration { // 減速度系數(值越小=轉向越快) float deceleration = 0.4f; // 加速度系數 (值越大 = 越敏感) float sensitivity = 6.0f; // 最大速度 float maxVelocity = 100; // 根據加速度計算當前速度 ?playerVelocity.x = playerVelocity.x * deceleration + acceleration.x* sensitivity; // 限制最大速度為 ±maxVelocity之間 ?directions if (playerVelocity.x > maxVelocity) { playerVelocity.x= maxVelocity; } else if (playerVelocity.x < - maxVelocity){ playerVelocity.x= - maxVelocity; } } ~~~ 現在,玩家速度由一個一次線性方程決定: V= V? * β + V? * ε 其中, V為終速 V?為初速 β ???為減速系數 V?為加速度 ε為加速系數 其中,β 和 ε兩個系數(即減速度系數和加速度系數:deceleration和sensitivity變量)是兩個經驗值,你可以自己調整它以達到理想效果。 然后,需要通過以下方法來改變游戲角色的位置: ~~~ -(void) update:(ccTime)delta{ // 不斷改變角色x坐標 ?CGPointpos = player.position; pos.x += playerVelocity.x; // 防止角色移到屏幕以外 ?CGSizescreenSize = [[CCDirector sharedDirector] winSize]; float imageWidthHalved = [playertexture].contentSize.width * 0.5f; float leftBorderLimit = imageWidthHalved; float rightBorderLimit = screenSize.width -imageWidthHalved; if (pos.x < leftBorderLimit) { pos.x =leftBorderLimit; playerVelocity= CGPointZero; } else if(pos.x > rightBorderLimit) { pos.x =rightBorderLimit; playerVelocity= CGPointZero; } player.position = pos; ?} ~~~ 然后,在init方法中加入: ~~~ [selfscheduleUpdate]; ~~~ 這樣,每隔一段時間cocos2d會自動調用update方法。 ## 六、添加障礙物 導入spider.png圖片到工程。這是一張蜘蛛的圖片,在游戲中我們需要躲避的東西。 首先,增加如下變量聲明: ~~~ CCArray*spiders; floatspiderMoveDuration; ?int numSpidersMoved; ~~~ 在init方法中,加上一句方法調用語句: ~~~ [selfinitSpiders]; ~~~ 下面是initSpiders方法: ~~~ -(void) { CGSize screenSize = [[CCDirectorsharedDirector] winSize]; // 用一個臨時的CCSprider取得圖片寬度 CCSprite* tempSpider = [CCSpritespriteWithFile:@"spider.png"]; floatimageWidth = [tempSpider texture].contentSize.width; // 計算出要多少蜘蛛圖片可以布滿屏幕的寬度 int numSpiders = screenSize.width / imageWidth; // 初始化數組并指定數組大小 spiders = [[CCArray alloc]initWithCapacity:numSpiders]; for (int i = 0; i < numSpiders; i++) { CCSprite*spider = [CCSprite spriteWithFile:@"spider.png"]; [self addChild:spider z:0 tag:2]; [spidersaddObject:spider]; } [self resetSpiders]; } ~~~ tempSpider是一個臨時變量,我們僅用于取得圖片寬度。我們沒有retain他,也不需要release他——他會自動被release。 與此相反,spiders是由我們init的,我們也沒有retain(實際上init會自動retain),但我們必須自己release(OC規定,init/copy/new出來的對象,必須手動release,OC的內存管理不會自動release)。因此在dealloc方法中有這么一句: ~~~ [spidersrelease],spiders=nil; ~~~ 同時,我們使用了coco2d提供的一個類似NSMutableArray的CCArray類,該類對數組的操作更快。以下是CCArray提供的一些方法: ~~~ + (id) array; + (id)arrayWithCapacity:(NSUInteger)capacity; + (id)arrayWithArray:(CCArray*)otherArray; + (id)arrayWithNSArray:(NSArray*)otherArray; - (id)initWithCapacity:(NSUInteger)capacity; ?- (id)initWithArray:(CCArray*)otherArray; - (id)initWithNSArray:(NSArray*)otherArray; -(NSUInteger) count; -(NSUInteger) capacity; -(NSUInteger) indexOfObject:(id)object; ?- (id) objectAtIndex:(NSUInteger)index; - (id)lastObject; - (BOOL)containsObject:(id)object; #pragma markAdding Objects - (void)addObject:(id)object; - (void)addObjectsFromArray:(CCArray*)otherArray; ?- (void)addObjectsFromNSArray:(NSArray*)otherArray; - (void) insertObject:(id)objectatIndex:(NSUInteger)index; #pragma markRemoving Objects - (void)removeLastObject; - (void)removeObject:(id)object; ?- (void)removeObjectAtIndex:(NSUInteger)index; - (void)removeObjectsInArray:(CCArray*)otherArray; - (void) removeAllObjects; - (void)fastRemoveObject:(id)object; - (void)fastRemoveObjectAtIndex:(NSUInteger)index; - (void)makeObjectsPerformSelector:(SEL)aSelector; - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)object; - (NSArray*)getNSArray; ~~~ resetSpiders 方法如下所示: ~~~ -(void)resetSpiders { CGSize screenSize = [[CCDirectorsharedDirector] winSize]; // 用一個臨時的CCSprider取得圖片寬度 CCSprite* tempSpider = [spiders lastObject]; CGSize size = [tempSpider texture].contentSize; int numSpiders = [spiders count]; for (int i = 0; i < numSpiders; i++) { // 放置每個蜘蛛的位置 CCSprite*spider = [spiders objectAtIndex:i]; spider.position= CGPointMake(size.width * i + size.width * 0.5f, screenSize.height + size.height); [spiderstopAllActions]; } // 為保險起見,在注冊之前先從schedule中反注冊(未注冊則不動作) [self unschedule:@selector(spidersUpdate:)]; // 注冊schedule,每0.7秒執行 [self schedule:@selector(spidersUpdate:)interval:0.7f]; } ? -(void) { ? // 找出空閑的蜘蛛(未在移動的). ? for (int i = 0; i < 10; i++) { ??? // 從數組中隨機抽取一只蜘蛛 ??? int randomSpiderIndex =CCRANDOM_0_1() * [spiders count]; ??? CCSprite* spider = [spidersobjectAtIndex:randomSpiderIndex]; ??? // 若蜘蛛未在移動,讓蜘蛛往下掉 ??? if ([spidernumberOfRunningActions] == 0) { ????? // 控制蜘蛛往下掉 ????? [selfrunSpiderMoveSequence:spider]; ????? // 每次循環僅移動一只蜘蛛 ????? break; ??? } ? } } -(void)runSpiderMoveSequence:(CCSprite*)spider { ? // 隨時間逐漸加快蜘蛛的速度 ? numSpidersMoved++; ? if (numSpidersMoved % 8 == 0 &&spiderMoveDuration > 2.0f) { ??? spiderMoveDuration -= 0.1f; ? } // 移動的終點 CGPoint belowScreenPosition= CGPointMake(spider.position.x, -[spidertexture].contentSize.height); // 動作:移動 ?CCMoveTo* move = [CCMoveToactionWithDuration:spiderMoveDuration position:belowScreenPosition]; // 瞬時動作:方法調用 CCCallFuncN*call = [CCCallFuncN actionWithTarget:self selector:@selector(spiderBelowScreen:)]; // 組合動作:移動+方法調用 CCSequence*sequence = [CCSequence actions:move, call, nil]; // 運行組合動作 [spiderrunAction:sequence]; } spiderBelowScreen方法重置蜘蛛的狀態,讓其回到屏幕上端等待下次墜落。 -(void)spiderBelowScreen:(id)sender { // 斷言:sender是否為CCSprite. ?NSAssert([sender isKindOfClass:[CCSpriteclass]], @"sender is not a CCSprite!"); CCSprite*spider = (CCSprite*)sender; // 把蜘蛛重新放回屏幕上端 CGPoint pos =spider.position; CGSizescreenSize = [[CCDirector sharedDirector] winSize]; pos.y =screenSize.height + [spider texture].contentSize.height; spider.position = pos; } ~~~ 書中作者提到,出于一個“保守”程序員的習慣,作者使用了 NSAssert語句來測試sender是否是一個CCSprite類。雖然理論上,Sender應當是一個CCSprite,實際上它卻有可能根本不是。因為作者曾犯過一個錯誤:把CCCallFuncN寫成了CCCallFunc(二者的區別在于,后者不能傳遞參數而前者帶一個sender參數),導致sender未被作為參數傳遞到調用方法,即sender=nil。這樣的錯誤也被NSAssert捕獲到了,于是作者發現并修改了這個錯誤。 ## 七、碰撞檢測 很簡單。在update方法中添加語句: ~~~ [selfcheckForCollision]; ~~~ checkForCollision中包含了碰撞檢測的所有邏輯: ~~~ -(void )checkForCollision { // 玩家和蜘蛛的尺寸 floatplayerImageSize = [player texture].contentSize.width; floatspiderImageSize = [[spiders lastObject] texture].contentSize.width; //玩家和蜘蛛的碰撞半徑 floatplayerCollisionRadius = playerImageSize * 0.4f; floatspiderCollisionRadius = spiderImageSize * 0.4f; // 發生碰撞的最大距離,如果兩個對象間的距離<=此距離可判定為有效碰撞 floatmaxCollisionDistance=playerCollisionRadius +spiderCollisionRadius; intnumSpiders = [spiders count]; //循環檢測玩家和每一只蜘蛛間的碰撞距離 for (int i =0; i < numSpiders; i++) { ? CCSprite* spider = [spidersobjectAtIndex:i]; ? // 計算每只蜘蛛和玩家間的距離. ccpDistance及其他非常有用的函數都列在CGPointExtension中 ? float actualDistance = ?ccpDistance(player.position,spider.position); ? // 如二者距離小于碰撞最大距離,認為發生碰撞? ? if (actualDistance <maxCollisionDistance) { ??? // 結束游戲. ??? [self showGameOver]; ? } } } -(void)showGameOver { // 屏保開啟 [self setScreenSaverEnabled:YES]; // 凍結所有對象的動作 CCNode* node; CCARRAY_FOREACH([self children], node){ [nodestopAllActions]; } // 使蜘蛛保持扭動 CCSprite* spider; CCARRAY_FOREACH(spiders, spider){ [selfrunSpiderWiggleSequence:spider]; } // 游戲開始前,關閉加速器的輸入 self.isAccelerometerEnabled = NO; // 允許觸摸 self.isTouchEnabled = YES; // 取消所有schedule [self unscheduleAllSelectors]; ? // 顯示GameOver文本標簽 CGSize screenSize = [[CCDirectorsharedDirector] winSize]; CCLabel* gameOver = [CCLabellabelWithString:@"GAME OVER!" fontName:@"Marker Felt"fontSize:60]; gameOver.position =CGPointMake(screenSize.width / 2, screenSize.height / 3); [self addChild:gameOver z:100 tag:100]; // 動作:色彩漸變 CCTintTo* tint1 = [CCTintToactionWithDuration:2 red:255 green:0 blue:0]; CCTintTo* tint2 = [CCTintToactionWithDuration:2 red:255 green:255 blue:0]; CCTintTo* tint3 = [CCTintToactionWithDuration:2 red:0 green:255 blue:0]; CCTintTo* tint4 = [CCTintToactionWithDuration:2 red:0 green:255 blue:255]; CCTintTo* tint5 = [CCTintToactionWithDuration:2 red:0 green:0 blue:255]; CCTintTo* tint6 = [CCTintToactionWithDuration:2 red:255 green:0 blue:255]; CCSequence* tintSequence = [CCSequenceactions:tint1, tint2, tint3, tint4, tint5, tint6, nil]; CCRepeatForever* repeatTint = [CCRepeatForeveractionWithAction:tintSequence]; [gameOver runAction:repeatTint]; // 動作:轉動、顫動 CCRotateTo* rotate1 = [CCRotateToactionWithDuration:2 angle:3]; CCEaseBounceInOut* bounce1 = [CCEaseBounceInOutactionWithAction:rotate1]; CCRotateTo* rotate2 = [CCRotateTo actionWithDuration:2angle:-3]; CCEaseBounceInOut* bounce2 = [CCEaseBounceInOutactionWithAction:rotate2]; CCSequence* rotateSequence = [CCSequenceactions:bounce1, bounce2, nil]; CCRepeatForever* repeatBounce =[CCRepeatForever actionWithAction:rotateSequence]; [gameOver runAction:repeatBounce]; // 動作:跳動 CCJumpBy* jump = [CCJumpBy actionWithDuration:3position:CGPointZero height:screenSize.height / 3 jumps:1]; CCRepeatForever* repeatJump = [CCRepeatForeveractionWithAction:jump]; [gameOver runAction:repeatJump]; // 標簽:點擊游戲開始 CCLabel* touch = [CCLabellabelWithString:@"tap screen to play again"fontName:@"Arial" fontSize:20]; touch.position = CGPointMake(screenSize.width /2, screenSize.height / 4); [self addChild:touch z:100 tag:101]; // 動作:閃爍 CCBlink* blink = [CCBlink actionWithDuration:10blinks:20]; CCRepeatForever* repeatBlink = [CCRepeatForeveractionWithAction:blink]; [touch runAction:repeatBlink]; } ~~~ 當然,為了使游戲一開始就停頓在GameOver畫面,需要在init方法中調用: ~~~ [selfshowGameOver]; ~~~ 只有當用戶觸摸屏幕后,游戲才會開始。這需要實現方法: ~~~ -(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self resetGame]; } resetGame方法負責重置游戲變量并啟動游戲。 -(void)resetGame { // 關閉屏保 [self setScreenSaverEnabled:NO]; // 移除GameOver標簽和啟動游戲標簽 [self removeChildByTag:100 cleanup:YES]; [self removeChildByTag:101 cleanup:YES]; // 啟動加速器輸入,關閉觸摸輸入 self.isAccelerometerEnabled = YES; self.isTouchEnabled = NO; // 重設蜘蛛數組 [self resetSpiders]; // 注冊schedule [self scheduleUpdate]; // 積分 score = 0; totalTime = 0; [scoreLabel setString:@"0"]; } 開啟/關閉屏保的方法: -(void)setScreenSaverEnabled:(bool)enabled { UIApplication *thisApp = [UIApplicationsharedApplication]; thisApp.idleTimerDisabled = !enabled; } 使蜘蛛不停扭動的方法如下(實際上是把圖像不斷的放大縮小): -(void)runSpiderWiggleSequence:(CCSprite*)spider { //動作:放大 CCScaleTo* scaleUp = [CCScaleToactionWithDuration:CCRANDOM_0_1() * 2 + 1 scale:1.05f]; //速度漸變動作:速度由慢至快,再由快至慢 CCEaseBackInOut* easeUp = [CCEaseBackInOutactionWithAction:scaleUp]; //動作:縮小 CCScaleTo* scaleDown = [CCScaleToactionWithDuration:CCRANDOM_0_1() * 2 + 1 scale:0.95f]; //速度漸變動作:速度由慢至快,再由快至慢 CCEaseBackInOut*easeDown = [CCEaseBackInOut actionWithAction:scaleDown]; CCSequence* scaleSequence = [CCSequenceactions:easeUp, easeDown, nil]; CCRepeatForever* repeatScale = [CCRepeatForeveractionWithAction:scaleSequence]; [spider runAction:repeatScale]; } ? ~~~ ## 八、CCLabel、CCBitmapFontAtlas 和 Hiero 我們的計分標準很簡單,以游戲時間作為游戲分數。 在init方法中加入: ~~~ scoreLabel =[CCLabel labelWithString:@"0" fontName:@"Arial"fontSize:48]; scoreLabel.position= CGPointMake(screenSize.width / 2, screenSize.height); // 調整錨點。 scoreLabel.anchorPoint= CGPointMake(0.5f, 1.0f); // 把label添加到scene,z坐標為-1,則位于所有layer的下方 [selfaddChild:scoreLabel z:-1]; ~~~ 為了將計分牌對其到屏幕上端中心位置,這里使用了“錨點”的概念。 錨點即參考點,和position屬性配合使用,用于將物體向其他物體對齊。比如當把一個物體移動到一個位置點時,實際上是把這個物體的“錨點”移動/對齊到另外一個點。錨點由兩個float表示,表示的是錨點相對于物體寬/高的比率。比如錨點(0.5f,1.0f)表示該錨點位于該物體寬1/2,高1/1的地方。 修改update方法,在其中加入: ~~~ // 每秒更新一次計分牌 totalTime +=delta; ?int currentTime = (int)totalTime; if (score< currentTime) { ? score = currentTime; ? [scoreLabel setString:[NSStringstringWithFormat:@"%i", score]]; } ~~~ 這里需要說明的是,[CCLabelsetString]方法的效率很低:它需要釋放老的texture,分配一個新的texture,并用iOS font的rendering方法重新構造texture。你只需要注釋[CCLabel? setString]方法就可以知道,那有多么的糟糕。不使用setString方法時幀率為60幀/秒,而使用該方法的幀率竟然才30幀/秒。 象CCSprite等刷新效率高(只是更費一點內存)的Label類,都是屬于CCBitmapFontAtlas類的特例。我們可以通過簡單地把CCLabel變量聲明從CCLabel更改為CCBitmapFontAtlas,并修改它的構造語句: ~~~ scoreLabel =[CCBitmapFontAtlas bitmapFontAtlasWithString:@"0"fntFile:@"bitmapfont.fnt"]; ~~~ 在游戲中使用bitmapfont是很好的選擇,因為操作更快速,同時會有一個缺點:bitmap字體都是大小固定的。如果同樣的字體,大小不同,你需要對CCBitmapFontAtlas對象進行縮放。或者為不同尺寸的字體創建單獨的bitmap文件,并因此占用更多的內存。 當然需要把bitmapfont.fnt文件和對應的.png文件一起加入到工程的資源目錄下。 如果你需要創建自己的bitmap字體,可以用Hiero這個小工具(javaweb application): [http://slick.cokeandcode.com/demos/hiero.jnlp](http://slick.cokeandcode.com/demos/hiero.jnlp) 也可以使用BMFont (windows應用): ?[www.angelcode.com/products/bmfont/](http://www.angelcode.com/products/bmfont/) Hiero允許你從TrueTypeFont創建一個.fnt文件,該文件可以直接用于cocos2d的CCBitmapFontAtlas類。 安裝Hiero時需要同意一個數字簽名。請放心,迄今為止沒有跡象表明該簽名有任何問題。 ?Hiero的使用很簡單,首先挑選一種TrueType字體,在SampleText 文本框中輸入你要用的字符,然后點擊File->Save BMFont Files…即可保存為.fnt文件。 ? ![](https://box.kancloud.cn/2016-05-04_572a0b960a2f2.gif) ? 其他的選項是可選的。比如你可以加上漸變和陰影效果,使字體顯得更3D。 選擇Glyph cache后,你還可以調整生成的.png文件的大小。當然,如果你象我一樣只用到了極少的幾個字符,只要把頁寬/高設為最小值(比如在這里我們設成了256),然后點擊ResetCache應用。這樣可以創建比較小.png文件同時減少內存占用。對于更復雜的字體,Hiero會創建多個.png文件——記住,每一個.png文件都應當加到工程中。 在這個例子里,我們的字體文件里只放了幾個數字。因為png文件被創建為256*256大小,不管你是輸入1個字還是再加幾個其他的字,都會占用這么多的空間。 注意,如果你使用了在.fnt文件中不存在的字符,那么該字符會被忽略掉,且不會顯示在CCBitmapFontAtlas中。 ## 九、加入音頻 在工程目錄中有一對音頻文件: blues.mp3 和 alien-sfx.caf 。 在cocos2d中播放音頻的最好也是最初的方法是用 SimpleAudioEngine。然而音頻支持并不是cocos2d內置的一部分。它屬于CocosDenshion,就像物理引擎一樣。因此,你需要import額外的頭文件: ~~~ #import "SimpleAudioEngine.h" ? ~~~ 然后可以在init方法中象這樣來播放音樂/音頻: ~~~ [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"blues.mp3"loop:YES]; [[SimpleAudioEngine sharedEngine] preloadEffect:@"alien-sfx.caf"]; ~~~ 對于背景音樂,我們設置loop參數為YES,這樣就會循環播放。 對于音頻聲效,我們并沒有立即播放,而僅僅是加載到內存。然后在條件合適時播放(比如碰撞發生時): ~~~ [[SimpleAudioEngine sharedEngine]playEffect:@"alien-sfx.caf"]; ~~~ 對于音樂,最好使用mp3格式。注意,同一時間內,只能播放1首背景音樂。雖然同時播放多首mp3從技術上是可行的,但物理硬件在同一時間內只能對一首mp3進行解碼。在游戲中拒絕任何額外的CPU開銷,因此對大部分游戲而言,都不會同時播放多首mp3. 至于聲效,我喜歡用CAF格式。如果要進行音頻格式的轉換,可以使用 SoundConverter: http://dekorte.com/projects/shareware/SoundConverter/ 如果文件大小在500k以內,該軟件是免費的,無限制的許可僅僅需要$15。 如果你發現無法播放音頻文件或者出現雜音,不要擔心。有無數音頻軟件和音頻編碼擁有它們特有的文件格式。有些格式無法在iOS設備上播放,然而在其他設備上播放正常。解決辦法是打開它們,然后重新保存。或者使用音頻轉換程序或音頻軟件。 ## 十、遷移至iPad 如果所有的坐標都采用屏幕坐標,在iPad的大屏上運行游戲將會進行簡單縮放而沒有任何問題。相反,如果采用了固定坐標,你不得不重新編寫游戲代碼。 ? 遷移至iPad工程很簡單。在Groups&Files面板中選擇Target,選擇Project->Upgrade CurrentTarget for iPad…,將打開對話框: ![](https://box.kancloud.cn/2016-05-04_572a0b9621b00.gif) ? 對于這個游戲,選“One Universal application”(即iPhone/iPad通用)。 這樣的缺點是兩個設備的特性都會被加到target,增加了程序大小。但程序既可在iPhone上運行,也可在iPad上運行。 另一個選擇是“Two device-specific application”,你會得到兩個獨立于設備的app,你需要提交兩次。如果用戶有兩個設備——iPhone和iPad的,那么需要分別購買。 ? 編譯運行。程序會自動偵測當前所連接的設備類型并運行對應的版本。如圖,選擇iPad Simulator 3.2 ,可以查看在iPad模擬器運行游戲的效果: ![](https://box.kancloud.cn/2016-05-04_572a0b96362ce.gif) ?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看