[?李華明Himi?](http://www.himigame.com/about-himi)原創,轉載務必在明顯處注明:
轉載自[【黑米GameDev街區】](http://www.himigame.com/)?原文鏈接:?[http://www.himigame.com/iphone-cocos2d/535.html](http://www.himigame.com/iphone-cocos2d/535.html "【iOS開發必備指南合集】申請企業級IDP、真機調試、游戲接入GameCenter")> [](http://blog.csdn.net/xiaominghimi/article/details/6913967)
這里Himi給出對于開發iOS的朋友們整理一個指南集合,其中主要包括申請IDP需要注意的地方、有了開發者證書如何真機調試、在自己的游戲應用中如何接入GameCenter以及如何在游戲接入OpenFeint;
-----------申請企業級IDP,或者個人IDP
通過Himi的申請經驗,直接打蘋果在中國的客服,按照步驟一步一步詳細的讓客服進行指導,可能很多童鞋說我這句跟沒說一樣,呵呵,如果真的你是第一次申請IDP那么如果你不打客服,N多細節都會造成你1~15天耐心等待,Himi申請過程中由于一個名稱和一個勾選錯誤整整耽誤一個月的時間;最后仍是不停的跟客服交涉終于Ok順利申請到;
這里Himi給出蘋果在中國的客服電話:4006701855 (建議撥打客服之前大致的先百度google下申請IDP的流程,網上一大堆,這里Himi不贅述了)
--------------申請到IDP后如何真機調試
1.制作證書的過程Himi這里不多贅述,百度、google下N多文章呢;制作證書連接(前提是申請IDP成功):http://developer.apple.com/membercenter/index.action
2.正確制作證書后,有個這樣的文件:

雙擊此文件,彈出Organizer-Devices界面,連接你的真機iphone、ipad或者touch,然后左側可以看到如下圖:

右側的綠色小燈表示可以正常使用,這個小燈如果是黃色,那就說明你的證書有問題,可能是此手機的UDID沒有在證書內等原因;
3.確保真機正常后,點擊你的項目,右側點擊PROJECT點擊Build Settings頁面,然后Code Signing下設置Code Signing Identity為你的證書,如下圖:

4.點擊你的項目,右側點擊TARGETS,點擊Info頁面下的設置Bundle identifier,這個Bundle identifier在你制作證書的過程中就會了解到,如下圖:

OK,可以編譯運行你的項目到真機中了;
---------------游戲接入GameCenter 指南
1.iTunes Connect 設置
首先,申請一個應用程序,不必提交.目地是為了得到Bundle ID.
然后設置一下工程中Info.plist的Bundle identifier使之與iTunes Connect中的Bundle ID相同,否則當你嘗試登錄GameCenter的時候,會提示一個不支持GameCenter的錯誤.
申請完畢,打開你剛申請的application,點擊Manage Game Center選項.

進入后點擊Enable Game Center使你的Game Center生效.
接下來就可以設置自己的Leaderboard和Achievements.

2.Leaderboard設置
Leaderboard縱觀圖如下所示.

1.sort Order: Leaderboard中的內容是以升序還是降序排列.
2.Score Format Type:分數的類型.
3.*Categories:Leaderboard的一個分數榜,這個可以創建多個,比如游戲可以分為Easy,Normal,Hard三個難度,每個難度一個榜.

*設置完成后保存,完成了一個 Leaderboard的設置.我們可以根據需要添加多個 leaderboard.
4.**Score Format Location: leaderboard支持的語言.

**可以支持多種語言,每支持一種語言,需要完成一個上述操作.
這個時候右下角會出現save change按鈕,點擊完成leaderboard的設置.
你可以根據需要隨時更改你的leaderboard,操作與上述內容類似.
3.Achievements設置
Achievements界面內容比較少,點擊左上角的Add New Achievement,打開如下圖所示的Achievements創建界面.

Hidden:表示該成就為解鎖前玩家是否可見.
Achievement ID:程序通過這個屬性來識別成就.
*Achievement Localization:該成就支持的語言.
*Achievement Localization設置如下圖所示.

*其中,成就的Image必須是512X512,72DPI的.
一切設置完成后,點擊save change按鈕即完成一個成就的設置.
4.總體功能
在使用各個功能前,你需要了解一下塊函數。傳送門:?[https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html](https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html)
4.1 對Game Center支持判斷
~~~
- (BOOL) isGameCenterAvailable
{
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
NSString *reqSysVer = @"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
}
~~~
4.2用戶登錄
~~~
- (void) authenticateLocalPlayer
{
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error){
if (error == nil) {
//成功處理
NSLog(@"成功");
NSLog(@"1--alias--.%@",[GKLocalPlayer localPlayer].alias);
NSLog(@"2--authenticated--.%d",[GKLocalPlayer localPlayer].authenticated);
NSLog(@"3--isFriend--.%d",[GKLocalPlayer localPlayer].isFriend);
NSLog(@"4--playerID--.%@",[GKLocalPlayer localPlayer].playerID);
NSLog(@"5--underage--.%d",[GKLocalPlayer localPlayer].underage);
}else {
//錯誤處理
NSLog(@"失敗 %@",error);
}
}];
}
~~~
對于開發者來說,Game Center必須經過測試才能上線,沒有上線的程序在測試環境中登錄時會出現sandbox提示.如圖.

4.3用戶變更檢測
由于4.0以后系統支持多任務,玩家的機器有可能被不同的玩家接觸,導致Game Center上的用戶發生變化,當發生變化的時候,程序必須在游戲中通知玩家.
? ?
~~~
- (void) registerForAuthenticationNotification
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(authenticationChanged)
name:GKPlayerAuthenticationDidChangeNotificationName
object:nil];
}
- (void) authenticationChanged
{
if ([GKLocalPlayer localPlayer].isAuthenticated)
{
;// Insert code here to handle a successful authentication.
}
else
{
;// Insert code here to clean up any outstanding Game Center-related classes.
}
}
~~~
5.對Leaderboard進行操作
5.1上傳一個分數
? ?
~~~
- (void) reportScore: (int64_t) score forCategory: (NSString*) category
{
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
// handle the reporting error
NSLog(@"上傳分數出錯.");
//If your application receives a network error, you should not discard the score.
//Instead, store the score object and attempt to report the player’s process at
//a later time.
}else {
NSLog(@"上傳分數成功");
}
}];
}
~~~
當上傳分數出錯的時候,要將上傳的分數存儲起來,比如將SKScore存入一個NSArray中.等可以上傳的時候再次嘗試.
5.2下載一個分數
??
~~~
//GKScore objects provide the data your application needs to create a custom view.
//Your application can use the score object’s playerID to load the player’s alias.
//The value property holds the actual value you reported to Game Center. the formattedValue
//property provides a string with the score value formatted according to the parameters
//you provided in iTunes Connect.
- (void) retrieveTopTenScores
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
{
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.range = NSMakeRange(1,10);
leaderboardRequest.category = @"TS_LB";
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil){
// handle the error.
NSLog(@"下載失敗");
}
if (scores != nil){
// process the score information.
NSLog(@"下載成功....");
NSArray *tempScore = [NSArray arrayWithArray:leaderboardRequest.scores];
for (GKScore *obj in tempScore) {
NSLog(@" playerID : %@",obj.playerID);
NSLog(@" category : %@",obj.category);
NSLog(@" date : %@",obj.date);
NSLog(@" formattedValue : %@",obj.formattedValue);
NSLog(@" value : %d",obj.value);
NSLog(@" rank : %d",obj.rank);
NSLog(@"**************************************");
}
}
}];
}
}
~~~
說明:
1)??? playerScope:表示檢索玩家分數范圍.
2)??? timeScope:表示某一段時間內的分數
3)??? range:表示分數排名的范圍
4)??? category:表示你的Leaderboard的ID.
5.3玩家信息交互
Game Center最重要的一個功能就是玩家交互.所以,必須檢索已經登錄玩家的好友信息.根據自己的需要做出設置,比如,可以與好友比較分數,或者好友排行榜等.
//檢索已登錄用戶好友列表
? ?
~~~
- (void) retrieveFriends
{
GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
if (lp.authenticated)
{
[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) {
if (error == nil)
{
[self loadPlayerData:friends];
}
else
{
;// report an error to the user.
}
}];
}
}
~~~
上面的friends得到的只是一個身份列表,里面存儲的是NSString,想要轉換成好友ID,必須調用- (void) loadPlayerData: (NSArray *) identifiers方法,該方法得到的array里面存儲的才是GKPlayer對象.如下
? ?
~~~
/*
Whether you received player identifiers by loading the identifiers for the local player’s
friends, or from another Game Center class, you must retrieve the details about that player
from Game Center.
*/
- (void) loadPlayerData: (NSArray *) identifiers
{
[GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error) {
if (error != nil)
{
// Handle the error.
}
if (players != nil)
{
NSLog(@"得到好友的alias成功");
GKPlayer *friend1 = [players objectAtIndex:0];
NSLog(@"friedns---alias---%@",friend1.alias);
NSLog(@"friedns---isFriend---%d",friend1.isFriend);
NSLog(@"friedns---playerID---%@",friend1.playerID);
}
}];
}
~~~
至此,leaderboard功能介紹完畢
6.對Achievement進行操作
? 這一部分內容比較多,而且有的地方有點重復的感覺.
6.1匯報一個成就的進度
? 對于一個玩家可見的成就,你需要盡可能的報告給玩家解鎖的進度;對于一個一部完成的成就,則不需要,當玩家的進度達到100%的時候,會自動解鎖該成就.
? ?
~~~
- (void) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
{
GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
if (achievement)
{
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
//The proper way for your application to handle network errors is retain
//the achievement object (possibly adding it to an array). Then, periodically
//attempt to report the progress until it is successfully reported.
//The GKAchievement class supports the NSCoding protocol to allow your
//application to archive an achie
NSLog(@"報告成就進度失敗 ,錯誤信息為: \n %@",error);
}else {
//對用戶提示,已經完成XX%進度
NSLog(@"報告成就進度---->成功!");
NSLog(@" completed:%d",achievement.completed);
NSLog(@" hidden:%d",achievement.hidden);
NSLog(@" lastReportedDate:%@",achievement.lastReportedDate);
NSLog(@" percentComplete:%f",achievement.percentComplete);
NSLog(@" identifier:%@",achievement.identifier);
}
}];
}
}
~~~
其中該函數的參數中identifier是你成就的ID, percent是該成就完成的百分比
6.2讀取一個成就
方法一:得到所有的成就
? ?
~~~
- (void) loadAchievements
{
NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements,NSError *error)
{
if (error == nil) {
NSArray *tempArray = [NSArray arrayWithArray:achievements];
for (GKAchievement *tempAchievement in tempArray) {
[achievementDictionary setObject:tempAchievement forKey:tempAchievement.identifier];
NSLog(@" completed:%d",tempAchievement.completed);
NSLog(@" hidden:%d",tempAchievement.hidden);
NSLog(@" lastReportedDate:%@",tempAchievement.lastReportedDate);
NSLog(@" percentComplete:%f",tempAchievement.percentComplete);
NSLog(@" identifier:%@",tempAchievement.identifier);
}
}
}];
}
~~~
函數中NSArray返回的是你的所有成就ID.
方法二:根據ID獲取成就
? ?
~~~
- (GKAchievement*) getAchievementForIdentifier: (NSString*) identifier
{
NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
GKAchievement *achievement = [achievementDictionary objectForKey:identifier];
if (achievement == nil)
{
achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
[achievementDictionary setObject:achievement forKey:achievement.identifier];
}
return [[achievement retain] autorelease];
}
~~~
6.3獲取成就描述和圖片
在自定義界面中,玩家需要一個成就描述,以及該成就的圖片,Game Center提供了該功能.當然,你也可以自己在程序中完成,畢竟玩家不可能時刻處于在線狀態.
??
~~~
- (NSArray*)retrieveAchievmentMetadata
{
//讀取成就的描述
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
^(NSArray *descriptions, NSError *error) {
if (error != nil)
{
// process the errors
NSLog(@"讀取成就說明出錯");
}
if (descriptions != nil)
{
// use the achievement descriptions.
for (GKAchievementDescription *achDescription in descriptions) {
NSLog(@"1..identifier..%@",achDescription.identifier);
NSLog(@"2..achievedDescription..%@",achDescription.achievedDescription);
NSLog(@"3..title..%@",achDescription.title);
NSLog(@"4..unachievedDescription..%@",achDescription.unachievedDescription);
NSLog(@"5............%@",achDescription.image);
//獲取成就圖片,如果成就未解鎖,返回一個大文號
/*
[achDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
if (error == nil)
{
// use the loaded image. The image property is also populated with the same image.
NSLog(@"成功取得成就的圖片");
UIImage *aImage = image;
UIImageView *aView = [[UIImageView alloc] initWithImage:aImage];
aView.frame = CGRectMake(50, 50, 200, 200);
aView.backgroundColor = [UIColor clearColor];
[[[CCDirector sharedDirector] openGLView] addSubview:aView];
}else {
NSLog(@"獲得成就圖片失敗");
}
}];
*/
}
}
}];
return nil;
}
~~~
如果你不主動使用注釋中的方法,那么你得到的description中不會有圖片,這樣可以減少網絡的使用,盡量少下載東西.當使用注釋中的代碼時,如果成就已經解鎖,則返回該成就的圖標,如果沒有解鎖,則返回一個大問號,至于未解鎖圖標是否可以自定義,我找尋的結果好像是不可以.
**GameCenter ?成就提示更新:**
?GameCenter中成就提示需要開發者自定義,即使官方Demo的例子程序中也沒有給與提示框(橫幅樣式)通知用戶的官方代碼,所以這里Himi介紹如何模仿官方的成就提示:
? ?1. iOS5以及更高SDK中,apple已經提供官方的成就提示:方法很簡單,代碼如下:
~~~
- (void)sendAchievement:(GKAchievement *)achievement {
achievement.percentComplete = 100.0; //Indicates the achievement is done
achievement.showsCompletionBanner = YES; //Indicate that a banner should be shown
[achievement reportAchievementWithCompletionHandler:
^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void)
{
if (error == NULL) {
NSLog(@"Successfully sent archievement!");
} else {
NSLog(@"Achievement failed to send... will try again \
later. Reason: %@", error.localizedDescription);
}
});
}];
}
~~~
將“showsCompletionBanner”屬性設置成YES,提交給蘋果。新iOS屬性“showsCompletionBanner”,其默認設置是NO,但若將其調整成YES,屏幕就呈現包含成就標題和描述的漂亮橫幅;
2.如果低于5.0的SDK設備中是沒有 “showsCompletionBanner”屬性的,所以需要我們自定義提示樣式,當然這里Himi也分享一下如何模仿官方橫幅提示樣式的方法和代碼:
首先,我借鑒[Type One Error所展示的優秀代碼](http://www.typeoneerror.com/articles/post/game-center-achievement-notification),從https://github.com/typeoneerror/GKAchievementNotification中抓取一些代碼植入自己的項目。我們將采用GKAchievementNotification和GKAchievementHandler類,同時進行相應更新和修改。首先,若你在游戲中運用ARC,快速掃描代碼,移除那些發行、保留和自動發行代碼屬性。若你不想進行掃描,試著將文件放入項目及修復不符編譯程序的內容,然后再創建內容。
Type One Error類將展示類似于iOS 5所呈現的通知內容,但代碼需獲悉成就標題和描述是什么。為實現這點,你需要嵌入“showsCompletionBanner”目標。
GKAchievementDescription目標的優點是它們已根據用戶語言設定進行本土化,因此采用此方式不存在任何本土化問題。
其弊端在于你無法只加載一個成就描述,你需要加載所有內容。我認為進行此操作的最佳時間是用戶已在應用上認證Game Center,此時你需要通過異步調用獲得這些消息。值得欣慰的是,蘋果在此設有API調用,我將此放置在用戶認證訪問的CompletionHandler中。
若你采用Ray Wenderlich網站的代碼,那么你就既能夠運用此方法,又擁有新方法。將NSMutableDictionary * self.achievementsDescDictionary添加至所有處理游戲Game Center代碼的類(游戲邦注:它會在隨后的體驗中存儲成就數據)。
? ??
~~~
- (void)authenticateLocalUser {
if (!gameCenterAvailable) return;
NSLog(@”Authenticating local user…”);
if ([GKLocalPlayer localPlayer].authenticated == NO) {
[[GKLocalPlayer localPlayer]
authenticateWithCompletionHandler:^(NSError *error) {
if([GKLocalPlayer localPlayer].isAuthenticated){
[self retrieveAchievmentMetadata]; //Here is the new code
}
}];
}
}
//Here is the new method.
- (void) retrieveAchievmentMetadata
{
self.achievementsDescDictionary = [[NSMutableDictionary alloc] initWithCapacity:2];
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
^(NSArray *descriptions, NSError *error) {
if (error != nil) {
NSLog(@"Error %@", error);
} else {
if (descriptions != nil){
for (GKAchievementDescription* a in descriptions) {
[achievementsDescDictionary setObject: a forKey: a.identifier];
}
}
}
}];
}
“retrieveAchievmentMetadata”方法會初始化所有信息庫,然后調用游戲所有成就描述,進行循環,將它們添加至信息庫。這屬于異步調用,所以不應減緩游戲或項目的啟動。
現在我們握有各成就的標題和描述,因此能夠修改原始代碼創造iOS 4/5的善意通知,其將通過Type One Error代碼連續展示所有成就。
- (void)reportAchievement:(NSString *)identifier
percentComplete:(double)percentComplete {
GKAchievement* achievement = [[GKAchievement alloc]
initWithIdentifier:identifier];
achievement.percentComplete = percentComplete;
if (percentComplete == 100.0) {
//Show banners manually
GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier]; //Update pull achievement description for dictionary
[[GKAchievementHandler defaultHandler] notifyAchievement:desc]; //Display to user
}
[achievementsToReport addObject:achievement]; //Queue up the achievement to be sent
[self save];
if (!gameCenterAvailable || !userAuthenticated) return;
[self sendAchievement:achievement]; //Try to send achievement
}
- (void)sendAchievement:(GKAchievement *)achievement {
[achievement reportAchievementWithCompletionHandler:
^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void)
{
if (error == NULL) {
NSLog(@"Successfully sent archievement!");
[achievementsToReport removeObject:achievement]; //Remove Achievement from queue.
} else {
NSLog(@”Achievement failed to send… will try again \
later. Reason: %@”, error.localizedDescription);
}
});
}];
}
~~~
如果你想讓成就中顯示為你在itunes connect中設置成就的自定義圖片,首先將通知部分代碼修改成如下代碼:
~~~
if (percentComplete == 100.0) {
//Show banners manually
GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier];
[desc loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
if (error == nil)
{
[[GKAchievementHandler defaultHandler] setImage:desc.image]; //If image found, updates the image to the achievement image.
}
[[GKAchievementHandler defaultHandler] notifyAchievement:desc];
}];
}
~~~
使用以上方式默認為橫屏顯示成就通知,如果想換成豎屏提示,那么這里Himi給出參考代碼:
在“GKAchievementHandler”類中找到“notifyAchievement”,更新為:
~~~
- (void)notifyAchievement:(GKAchievementDescription *)achievement
{
GKAchievementNotification *notification = [[GKAchievementNotification alloc] initWithAchievementDescription:achievement];
notification.frame = kGKAchievementFrameStart;
notification.handlerDelegate = self;
//Adjusting rotation.
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) {
notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(-90));
} else {
notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(90));
}
[_queue addObject:notification];
if ([_queue count] == 1)
{
[self displayNotification:notification];
}
}
~~~
---------------游戲接入OpenFeint指南
OpenFeint 是很多iPhone游戲開發者都要用到的社區功能;
一、openfeint中的LeaderBoards 和Achievement的一點體會
1.數據提交的格式
最近想向自己 的游戲中添加點openfeint功能,使用的時候發現,openfeint的功能雖然比較多,也比較強大,但是,有些地方還是不太如人意。我游戲中的分 數有一項是float型的數據,可是當我提交的時候,發現openfeint的在線排名只支持整數形式的數據,改變了官方的api提交之后,服務器那邊仍 自動轉換成了整型的數據。我在論壇上求證了一下,雖然沒有結論,但我認為openfeint高分排行榜僅支持整型的數據。
2.數據提交的方法
[OFHighScoreService setHighScore:你提交的分數?forLeaderboard:@"分數項的ID" onSuccess:OFDelegate() onFailure:OFDelegate()]; //提交高分,如果函數無效,請引入#import "OFHighScoreService.h"
通過上面那個函數,就可以向服務器提 交數據,其中你要提交的分數,無論是什么類型,最后都會轉換成整型的數據,可以參見上一條信息。而分數項ID,則是你在申請LaderBoards的時候 openfeint分配給你的一個數字。后面兩個參數,應該不需要改變,我沒有嘗試過做其他的動作,有興趣和想法的朋友,可以嘗試象@selector那 樣使用它。
[OFAchievementService unlockAchievement: @"成就ID" onSuccess: OFDelegate() onFailure: OFDelegate()];//解鎖成就,如果函數無效,請引入#import "OFAchievementService.h"
這個函數的功能是解鎖成就,當你在游戲過程中達到某一個要求時,就可以解鎖你在openfeint上預設的成就。
例如:
生存游戲中:if (生存時間 > 100s )??{ 調用上面的函數解鎖你自己預設的成就; }
jump游戲中:if ( 高度 > 10000m )??{ 調用上面的函數解鎖你自己預設的成就; }
3.網絡對分數提交的影響
網絡暢通的情況下,調用上述函數提交分數(最高分數被刷新時) 可以成功,并且解鎖成就并不會反復出現解鎖提示。好吧,既然這個可以完成我們的要求,那么這里就不是重點。
網絡不通的情況下,就會出現一點問題:
在闡明問 題之前,我想先說一下我對openfeint的數據存儲的理解或者說感覺。使用penfeint的時候,在documents目錄下會生成兩個文件,一個 FakeKeyChain.plist,據我觀察,這里面存放的就是我們在openfeint里為這個游戲申請的Product Key和Product Secret,而且Secret經過了加密處理。另一個文件則是feint-offline, 這個文件是無法打開的,在windows用記事本打開也是一堆亂碼,也許有其他的辦法,不過我沒有找到。我對于這個文件的用途猜測是,這個文件用來存檔玩 家的一些信息,比如玩家名和分數等,這個文件我暫時叫它為“本地隱 藏信息表”吧。
問題來鳥,在沒有網絡的情況下,取得了一個分數,然后第一次調用分數提交函數,會提示你得 到了一個高分,存儲在本地(我感覺就在本地隱藏信息表中), 問題出現了!當你這時連接網絡,分數并不會自動提交,而你自己手動提交(比如點擊一個按鈕,按鈕的功能是提交最高分數)也沒有任何的效果。
而 在官方文檔中有這樣一Q&A:
????Q:what happens to a high score when a player is offline?
????A:as os openfeint 2.1 high scoreare queued for submission when the player is offline and submitted when next he's online again.
????Q:if a user says no to using openfeint the first time,is there a way that user can change his or her mind to allow openfeint in the future?
????A:when you deny openfeint it will prompt you to approve/deny again when you open the dashboard([OpenFeint launchDashboard]).it will not prompt you on the next?app?bootup,or submitting any requests.only when you open the dashboard.
也就是說,提交失敗,于是我做了個試驗,在有網絡的情況下,提交一個分數100,只顯示 一次,第二次提交100時,沒有提示。然后提交101,有提示,第二次提交101,沒有提示。說明了本地隱藏信息表中還存儲了一個最高分數的提交次數和提交許可,使用一次提交分數的函數,這些內 容就會改變,只有新提交的分數比原來存儲的分數大時,本地隱藏信息 表才會允許你向openfeint正式提交,否則,無效,感覺上和retain與release有點像。也就時說,最高的分數在提交的時 候,沒有網絡,就等于失敗,這里應該算是openfeint的一個小bug吧。也是我遇到問題的所在,沒找到什么解決辦法,大伙有經驗的可以提出來。
用個簡單的圖來形容下吧。
無網絡->得到新高分->存儲在本地->聯網后->不自動上傳最高分。
????
順便說下成就的提交,沒有網絡,不可解鎖成就,也沒有存在本地的提示,聯網后,同樣也不自動解鎖,只有再一次達到條件(方才例子中的if成立)時,才會再次 解鎖。
以上,是我的部分openfeint基礎使用的經驗,也許是我的方法不正確,也許有別的解決辦法,我能提供給大家的幫助, 先這么多了。
二、 openfeint的設置(2.4.8版)
以下步驟是假設你從沒安裝過openfeint,如果有,請將以 前老版本的openfeint從機器中刪除,并從project中刪除所有與openfeint有關的東西,然后,你可以按下面的步驟來做了。
1. 從官網下載一個最新版本的沒有解壓的openfeint SDK。
2.將openfeint文件夾拖入你的project中。
3. 設置info????
???????? a.打開project的info,選中build欄,將configuration設置成All configuration
???????? b.將Other Linker Flags一項的值設置成 -Objc??區分大小寫
???????? c.將Call C++ Default Ctors/Dtors in Objective-c項的選成yes(這一步我沒有設置,不知道是什么意思,英文原文如下:Ensure 'Call C++ Default Ctors/Dtors in Objective-c' is checked under the 'GCC 4.2 - Code Generation' section)
???????? d.設置一個默認的值GCC_OBJC_CALL_CXX_CDTORS 為 YES(這一步我也沒有設置)
4.引入frameworks
需要引入的frameworks 有,Foundation,UIKit,CoreGraphics,QuartCore,Security,SystemConfiguration,libsql3.0 dylie,libz.1.2.3.dylib這些是官方給出需要引入的frameworks,根據幫我搭建工程的前輩說,必須要引入 CoreLocation.framework????CFNetwork.framework?? MapKit.framework??
5.必須在你的?? .pch?? 文件中引入#import “OpenFeintPrefix.pch”
6.將你所有使用openfeint功能的函數改為??.mm??文件
我能想到的就這些了,還有什么問題,大家可以互相討論。
三、openfeint的注冊
openfeint的注冊并不難,能看懂 文檔的水平基本就可以了,也可以配合翻譯軟件來弄。
1.打開官網?[http://www.openfeint.com](http://www.openfeint.com/)?
2.選右上角的 Developers一項,跳轉到的新界面。
3.點擊本頁面的右上角的login會進入登陸界面,選擇右上角的 sign up進行一個簡單注冊,本頁右下角有一個教學的視頻,告訴你如何使用openfeint的基礎功能。
4.簡單注冊界面,填寫完成后跳轉到一個新的界面,點擊Dive in 進入你自己的openfeint里。
5.進入自己的openfeint了,需要進行一個prepare for submission的申請,這個可以讓你的openfeint有效,否則,你只能使用test user 進行測試。在App Home中,可以看到自己的client Id 這個是用來提問用的,以及最重要的Product Key和Product Secret,這兩項是用來識別你的程序獨有的openfeint的。
6.還需要一個你注冊時使用的郵箱認證。進入自己的郵箱就能看到 了。
7.想通過openfeint的審核,還需要完善一個ipurchase的填寫,在basic features/iPurchase里面填寫,項必須要有內容。
8.完成上面這些,你就可以設置自己的LaderBoards和 Achievement了,還有更多的challenge等。
------以上為Himi的經驗總結以及參考資料,希望對大家有幫助;
- 前言
- 【Iphone 游戲開發】游戲引擎剖析
- [Object-C語言隨筆之一]Mac os 下搭建iOS開發環境
- [Object-C語言隨筆之二] 《NSLog》常用的打印調試語句與自動排版
- [Object-C語言隨筆之三] 類的創建和實例化以及函數的添加和調用!
- [Object-C語言隨筆之四]創建視圖并繪制簡單圖形
- 【iOS-Cocos2d游戲開發之一】搭建cocos2d游戲引擎環境HelloWorld!
- 【iOS-Cocos2d游戲開發之二】Cocos2D 游戲開發資源貼(教程以及源碼)
- 【iOS-Cocos2d游戲開發之三】CCScene切換的所有特效(28種)以及設置屏幕橫豎屏!
- 【iOS-Cocos2d游戲開發之四】獨自收集Cocos2d提供的字體!共57種(有對照的字體圖)
- 【iOS-Cocos2d游戲開發之五】多觸點與觸屏事件詳解(單一監聽、事件分發)【11月28日更新】
- 【iOS-Cocos2d游戲開發之六】對觸屏事件追加講解,解決無法觸發ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戲開發之七】在cocos2d中添加/刪除系統組件,并解決View設置透明會影響View中的其他組件的問題!【11月28日更新解決添加組件Cocos2d動畫停止播放的BUG】
- 【iOS-Cocos2d游戲開發之八】開啟高清(960*640)模式問題與解答、圖片適配以及設置iphone橫豎屏
- 【iOS-Cocos2d游戲開發之九】講解CCSpriteBatchNode與TP工具的".pvr.ccz",".plist"共用的終極精靈優化及注意事項!
- 【iOS-Cocos2d游戲開發之十】添加粒子系統特效并解決粒子特效與Layer之間的坐標問題;
- 【iOS-Cocos2d游戲開發之十一】使用Box2d物理系統以及在cocos2d框架添加Box2d物理系統lib包的方法
- 【iOS-Cocos2d游戲開發之十二】淺析使用C++/C/OC進行iOS游戲混編出現“failed with exit”問題與小結;
- 【iOS-Cocos2d游戲開發之十三】CCSprite利用Bezier(貝塞爾)做拋物線動作并讓CCSprite同時播放兩個Action動作!
- 【iOS-Cocos2d游戲開發之十四】音頻/音效/視頻播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d進行視頻播放!)
- 【iOS-Cocos2d游戲開發之十五】詳解CCProgressTimer 進度條并修改cocos2d源碼實現“理想”游戲進度條!
- 【iOS-Cocos2d游戲開發之十六】添加本地通知(UILocalNotification)以及添加系統組件滾動視圖(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戲開發之十七】靈活使用精靈可視區域(TextureRect)與錨點(anchorPoint),并結合可視區域與錨點制作進度條!
- 【iOS開發必備指南合集】申請企業級IDP、真機調試、游戲接入GameCenter 指南(實現仿官方的成就提示)、游戲接入OpenFeint指南;
- 【iOS-Cocos2d游戲開發之十八】解決滾屏背景/拼接地圖有黑邊(縫隙)/動畫播放出現毛邊以及禁止游戲中自動鎖屏問題!【2011年12月18日補充】
- 【iOS開發必收藏】詳解iOS應用程序內使用IAP/StoreKit付費、沙盒(SandBox)測試、創建測試賬號流程!【2012-12-11日更新獲取"產品付費數量等于0的問題"】
- 【iOS-cocos2d-X 游戲開發之一】在Mac下結合Xcode搭建Cocos2d-X開發環境!
- 【iOS-cocos2d-X 游戲開發之二】【必看篇】總結闡述Cocos2d-X與Cocos2d-iphone區別;
- 【iOS-Cocos2d游戲開發之十九】游戲數據存儲的四種常用方式NSKeyedArchiver/NSUserDefaults/Write寫入/SQLite3
- 【iOS-Cocos2d游戲開發之二十】精靈的基礎知識點總匯(位圖操作/貼圖更換/重排z軸等)以及利用CCSprite與CCLayerColor制作簡單遮蓋層!
- 【iOS-Cocos2d游戲開發之二十一 】自定義精靈類并為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!
- 【iOS-Cocos2d游戲開發之二十二 】CCSpeed實現CCAnimate動畫進行時設置慢動作以及設置游戲加減速進行(塔防游戲必備)!
- 【iOS-cocos2d-X 游戲開發之三】Mac下配置Android NDK環境并搭建Cocos2d-x環境并Eclipse正常編譯運行Cocos2dX自帶TestsDemo項目!
- 【iOS-cocos2d-X 游戲開發之四】Cocos2dX創建Android NDK新項目并編譯導入Eclipse中正常運行!
- 【iOS-cocos2d-X 游戲開發之五】游戲存儲之Cocos2dX自帶CCUserDefault類詳解;
- 【iOS-cocos2d-X 游戲開發之六】使用Base64算法對Cocos2dX自帶CCUserDefault游戲存儲數據編碼!
- 【iOS-cocos2d-X 游戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【iOS-iap防護】驗證用戶付費收據!拒絕iap Cracker!拒絕iap Free!讓iphone越獄用戶無從下手!【2012年5月2日更新防護iap Free的方法】
- 【COCOS2DX-LUA 腳本開發之一】在Cocos2dX游戲中使用Lua腳本進行游戲開發(基礎篇)并介紹腳本在游戲中詳細用途!
- 【iOS-cocos2d-X 游戲開發之九】Cocos2dx利用CCSAXParser解析xml數據&CCMutableDictionary使用與注意!
- 【iOS-cocos2d-X 游戲開發之十】自定義CCSprite/Layer/CCNode及靜態類模版&自定義類細節說明&Cocos2dx觸屏事件講解
- 【iOS-cocos2d-X 游戲開發之十一】New CCSprite()帶來的錯誤&使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戲開發之十二】自定義Cocos2dx搖桿(增強Joystick),增加搖桿跟隨用戶觸點作為搖桿坐標,讓搖桿不再死板!
- 【iOS-cocos2d-X 游戲開發之十三】詳細講解在Xcode中利用預編譯并通過Jni調用Android的Java層代碼(cocos2dx里訪問調用Android函數)!
- 【iOS-cocos2d-X 游戲開發之十四】Xcode中c++&Object-C混編,詳細介紹如何在cocos2dx中訪問object函數以及Apple Api
- 【iOS-cocos2d-X 游戲開發之十五】Cocos2dx中響應Android的Back(返回)與Menu(小房子)事件&&Cocos2dx自動釋放粒子內存函數!
- 【iOS-cocos2d-X 游戲開發之十六】配置你的Cocos2dx項目編譯后的Android自動使用(-hd)高清圖&設置Android自適應屏幕、縮放比例方法!
- 【Cocoa(mac) Application 開發系列之四】動作編輯器(Cocos2dx)制作流程詳解及附上響應鼠標滾軸事件、反轉坐標系、導入/創建資源目錄等知識點代碼!
- 【Cocos2d-X(2.x) 游戲開發系列之一】cocos2dx(v2.x)與(v1.x)的一些常用函數區別講解!在2.x版CCFileData類被去除等
- 【Cocos2d-X(2.x) 游戲開發系列之二】cocos2dx最新2.0.1版本跨平臺整合NDK+Xcode,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【Cocos2dX(2.x)_Lua開發之三】★重要必看篇★在Lua中使用自定義精靈(Lua腳本與自創建類之間的訪問)及Lua基礎講解
- 【Cocos2d-X(2.x) 游戲開發系列之三】最新版本cocos2d­2.0­x­2.0.2使用新資源加載策略!不再沿用-hd、-ipad、-ipadhd添加后綴方式
- 【Cocos2d-X(1.x 2.x) 修復篇】iOS6 中 libcurl.a 無法通過armv7s編譯以及iOS6中無法正常游戲橫屏的解決方法
- 【Cocos2d-X(1.x 2.x) 】iOS6與iphone5適相關設置隨筆(解決第三方類庫無法通過armv7s編譯的方法、添加Default-568h@2x.png)