Tutorial details

Tutorial 19 | App Code for Sale | Preview

Tutorial 19 - Integrating Game Center (Part 3) | iOS Tutorial

Integrating Game Center

Overview PAGE TOP

Screen_Shot_2012-10-20_at_2.24.25_PM.png

21.1 On the Shoulders of Giants... PAGE TOP

Juan Belón (@juaxix over on the Codea Forums) has already done a lot of the hard work required to get Game Center up and running on your Codea App. If all you need is to submit scores to a single leaderboard then just follow Juan's instructions at this post. Juan has also provided the ability to play and stop mp3's from a Codea App.

We want to be able to submit scores to multiple leaderboards (Easy, Medium and Hard) and incorporate achievements so we need to add to the code that Juan has generously contributed. To this end we will fork his Game Center class on GitHub.

We will start by updating the Codea Runtime Objective C code.

21.2 Modifications to LuaState PAGE TOP

In Xcode, make sure that you are showing the Project Navigator (top left button on the tool bar). Open up the Frameworks group, then Codea -> Backend. In Backend, click on the LuaState.m file. Within this file you will see a method called - (void)create{ }. To this method add the following:

//  Game Center Functions:
    LuaRegFunc(aGameCenter_start);
    LuaRegFunc(aGameCenter_isGameCenterAvailable);
    LuaRegFunc(aGameCenter_showEasyLeaderboard);
    LuaRegFunc(aGameCenter_showMediumLeaderboard);
    LuaRegFunc(aGameCenter_showHardLeaderboard);
    LuaRegFunc(aGameCenter_reportEasyScore);
    LuaRegFunc(aGameCenter_reportMediumScore);
    LuaRegFunc(aGameCenter_reportHardScore);
    LuaRegFunc(aGameCenter_reportAchievementIdentifier);
    LuaRegFunc(aGameCenter_showAchievements);
    LuaRegFunc(aGameCenter_resetAchievements);

//  Play Music
    LuaRegFunc(playMusic);
    LuaRegFunc(stopMusic);

Screen_Shot_2012-10-20_at_11.23.13_AM.png

21.3 Modifications to OSCommands PAGE TOP

In the same directory as LuaState you will see OSCommands.h and OSCommands.m, click on the header file OSCommands.h and after int alert(struct lua_State *L) add the following:

//  Game Center:
    int aGameCenter_start(struct lua_State *state);
    int aGameCenter_isGameCenterAvailable(struct lua_State *state);
    int aGameCenter_showEasyLeaderboard(struct lua_State *state);
    int aGameCenter_showMediumLeaderboard(struct lua_State *state);
    int aGameCenter_showHardLeaderboard(struct lua_State *state);
    int aGameCenter_reportEasyScore(struct lua_State *state);
    int aGameCenter_reportMediumScore(struct lua_State *state);
    int aGameCenter_reportHardScore(struct lua_State *state);
    int aGameCenter_reportAchievementIdentifier(struct lua_State *state);
    int aGameCenter_showAchievements(struct lua_State *state);
    int aGameCenter_resetAchievements(struct lua_State *state);
  //  Play Music
    int playMusic(struct lua_State *L);
    int stopMusic(struct lua_State *L);

Then in the implementation file, OSCommands.m add the following:

static aGameCenter_Codea *CodeaGameCenter;

int aGameCenter_start(struct lua_State *state){
    NSLog(@"Starting Game Center");
    if (CodeaGameCenter==nil){
        CodeaGameCenter = [[[aGameCenter_Codea alloc] init] autorelease];
    }

    [CodeaGameCenter start];
    return 0;
}

int aGameCenter_isGameCenterAvailable(struct lua_State *state){
    return [CodeaGameCenter isGameCenterAvailable];
}

int aGameCenter_showLeaderboard(struct lua_State *state) {
    [CodeaGameCenter showLeaderboard];
    return 0;
}

int aGameCenter_reportEasyScore(struct lua_State *state) {
    [CodeaGameCenter reportEasyScore:lua_tonumber(state,1)];
    return 0;
}

int aGameCenter_reportMediumScore(struct lua_State *state) {
    [CodeaGameCenter reportMediumScore:lua_tonumber(state,1)];
    return 0;
}

int aGameCenter_reportHardScore(struct lua_State *state) {
    [CodeaGameCenter reportHardScore:lua_tonumber(state,1)];
    return 0;
}

int aGameCenter_reportAchievementIdentifier(struct lua_State *state) {
    [CodeaGameCenter reportAchievementIdentifier:lua_tonumber(state,1)];
    return 0;
}

int aGameCenter_showAchievements(struct lua_State *state) {
    [CodeaGameCenter showAchievements];
    return 0;
}

int aGameCenter_resetAchievements(struct lua_State *state) {
    [CodeaGameCenter resetAchievements];
    return 0;
}

int playMusic(struct lua_State *L){
    [CodeaGameCenter playMusic:lua_tonumber(L,1)];
    return 0;
}

int stopMusic(struct lua_State *L){
    [CodeaGameCenter stopMusic];
    return 0;
}

Screen_Shot_2012-10-20_at_11.22.57_AM.png

21.4 Modifications to the aGameCenter_Codea Class PAGE TOP

The final change in Xcode is to add the updated version of the aGameCenter_Codea class. You can download the forked version of Juan's code here. Add these two files to the Supporting Files group in the runtime.

1   //
2   //  aGameCenter_Codea.h
3   //
4   //  Created by Juan Belón on 28/05/12
5   //  Games -> http://www.xixgames.com
6   //  LGPL - @juaxix - Codea connection!
7   //
8   //  Modified by Reefwing Software on 14/10/12
9   //  http://www.reefwing.com.au
10  //  @reefwing on the Codea Forums
11  //
12  //  Version: 1.5
13  //      - Multiple Leaderboard (Easy, Medium & Hard) access added
14  //      - Achievements added.
15  //           1.6
16  //      - Modified for universal apps (http://codeatuts.blogspot.com.au/2012/10/tutorial-22-building-universal-app-in.html)
17  //      - New showLeaderBoard: (int)ident method
18  //
19  //  Licensed under the Apache License, Version 2.0 (the "License");
20  //  you may not use this file except in compliance with the License.
21  //  You may obtain a copy of the License at
22  //
23  //  http://www.apache.org/licenses/LICENSE-2.0
24  //
25  //  Unless required by applicable law or agreed to in writing, software
26  //  distributed under the License is distributed on an "AS IS" BASIS,
27  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28  //  See the License for the specific language governing permissions and
29  //  limitations under the License.
30  //
31  
32  #import <Foundation/Foundation.h>
33  #import <GameKit/GameKit.h>
34  #import <AVFoundation/AVAudioPlayer.h>
35  
36  @interface aGameCenter_Codea : NSObject <GKLeaderboardViewControllerDelegate, AVAudioPlayerDelegate, GKAchievementViewControllerDelegate>
37  {
38      bool hasGameCenter;
39      bool playing;
40      AVAudioPlayer *player;
41  }
42  
43  - (void) start;
44  - (void) authenticateLocalPlayer;
45  - (void) registerForAuthenticationNotification;
46  - (void) authenticationChanged;
47  - (BOOL) isGameCenterAvailable;
48  - (void) leaderboardViewControllerDidFinish: (GKLeaderboardViewController *)viewController;
49  - (void) showAchievements;
50  - (void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController;
51  - (void) resetAchievements;
52  - (void) reportAchievementIdentifier: (int) ident;
53  
54  - (void) showLeaderboard: (int)ident;
55  - (void) showEasyLeaderboard;
56  - (void) showMediumLeaderboard;
57  - (void) showHardLeaderboard;
58  - (void) reportEasyScore:(int) score;
59  - (void) reportMediumScore:(int) score;
60  - (void) reportHardScore:(int) score;
61  - (void) playMusic:(int) songNumber;
62  - (void) stopMusic;
63  @end

aGameCenter_Codea.h hosted with ❤ by GitHub

1   //
2   //  aGameCenter_Codea.m
3   //
4   //  Created by Juan Belón on 28/05/12
5   //  Games -> http://www.xixgames.com
6   //  LGPL - @juaxix - Codea connection!
7   //
8   //  Modified by Reefwing Software on 14/10/12
9   //  http://www.reefwing.com.au
10  //  @reefwing on the Codea Forums
11  //
12  //  Version: 1.5
13  //      - Multiple Leaderboard (Easy, Medium & Hard) access added
14  //      - Achievements added.
15  //
16  //  Licensed under the Apache License, Version 2.0 (the "License");
17  //  you may not use this file except in compliance with the License.
18  //  You may obtain a copy of the License at
19  //
20  //  http://www.apache.org/licenses/LICENSE-2.0
21  //
22  //  Unless required by applicable law or agreed to in writing, software
23  //  distributed under the License is distributed on an "AS IS" BASIS,
24  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  //  See the License for the specific language governing permissions and
26  //  limitations under the License.
27  //
28  
29  #import "aGameCenter_Codea.h"
30  #import "SharedRenderer.h"
31  
32  @implementation aGameCenter_Codea
33  
34  - (id)init
35  {
36      self = [super init];
37      player = [[AVAudioPlayer alloc] init];
38      playing = false;
39      return self;
40  }
41  
42  - (void)dealloc
43  {
44      [player release];
45      [super dealloc];
46  }
47  
48  - (void) start
49  {
50      //Game Center
51      
52      hasGameCenter = false;
53      
54      [self authenticateLocalPlayer];
55  }
56  
57  - (BOOL) isGameCenterAvailable
58  {
59      // Check for presence of GKLocalPlayer API.   
60      Class gcClass = (NSClassFromString(@"GKLocalPlayer"));   
61      
62      // The device must be running running iOS 4.1 or later.   
63      NSString *reqSysVer = @"4.1";   
64      NSString *currSysVer = [[UIDevice currentDevice] systemVersion];   
65      BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
66      
67      if (gcClass && osVersionSupported)
68          NSLog(@"Game Center is Available");
69      else
70          NSLog(@"Game Center is not Available");
71          
72      return (gcClass && osVersionSupported);
73  }
74  
75  - (void)authenticateLocalPlayer
76  {
77      
78      if(![self isGameCenterAvailable])
79      {
80          hasGameCenter = false;
81          return;
82      }
83      [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error)
84      {
85          if (error == nil)
86          {
87              [self registerForAuthenticationNotification];
88              hasGameCenter = true;
89              NSLog(@"Game Center - local player authenticated.");
90          }else
91          {
92              hasGameCenter = false;
93          }
94      }];
95  }
96  
97  - (void)registerForAuthenticationNotification
98  {
99      NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
100     [nc addObserver: self selector:@selector(authenticationChanged) name:GKPlayerAuthenticationDidChangeNotificationName object:nil];
101 }
102 
103 - (void)authenticationChanged
104 {
105     if([self isGameCenterAvailable ])
106     {
107         return;
108     }
109     
110     if ([GKLocalPlayer localPlayer].isAuthenticated)
111     {
112         hasGameCenter = true;
113     }else
114     {
115         hasGameCenter = false;
116     }
117 }
118 
119 // Achievement Methods
120 
121 - (void) reportAchievementIdentifier: (int) ident
122 {
123     NSString *identifier;
124     
125     // INSERT YOUR ACHIEVEMENT IDENTIFIERS BELOW
126     
127     switch (ident)
128     {
129         case 1:
130             identifier = @"Easy Winner";
131             break;
132         case 2:
133             identifier = @"Medium Winner";
134             break;
135         case 3:
136             identifier = @"Hard Winner";
137             break;
138         case 4:
139             identifier = @"Boom";
140             break;
141         case 5:
142             identifier = @"Bad Luck";
143             break;
144         case 6:
145             identifier = @"Decathlon";
146             break;
147         case 7:
148             identifier = @"Centurion";
149             break;
150         default:
151             NSLog(@"Warning Unknown Achievement");
152             break;
153     }
154     NSLog(@"Achievement complete: %@", identifier);
155     
156     GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier: identifier];
157     if (achievement)
158     {
159         achievement.showsCompletionBanner = YES;
160         achievement.percentComplete = 100.0;
161         [achievement reportAchievementWithCompletionHandler:^(NSError *error)
162          {
163              if (error != nil)
164              {
165                  NSLog(@"Error in reporting achievements: %@", error);
166              }
167          }];
168     }
169 }
170 
171 - (void)showAchievements
172 {
173     GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
174     if (achievements != nil)
175     {
176         achievements.achievementDelegate = self;
177         [[SharedRenderer renderer] presentViewController: achievements animated: YES completion:nil];
178     }
179     [achievements release];
180 }
181 
182 - (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
183 {
184     [[SharedRenderer renderer] dismissViewControllerAnimated:YES completion:nil];
185     [[SharedRenderer renderer] startAnimation];
186 }
187 
188 - (void) resetAchievements
189 {
190     // You may want to allow the player to reset their progress on achievements in your game.
191     // First, this method clears any locally cached achievement objects created by you.
192     // Then, it calls Game Kit to reset the player’s progress stored on Game Center.
193     //
194     // Clear all locally saved achievement objects - Enter your code to clear locally saved achievements below.
195     
196     // YOUR CODE GOES HERE
197     
198     // Clear all progress saved on Game Center.
199     
200     [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error)
201      {
202          if (error != nil)
203              // handle the error.
204              NSLog(@"Game Center: Error Resetting Achievements - %@", [error localizedDescription]);
205          else
206              NSLog(@"Game Center - Achievements Reset.");
207              }];
208 }
209 
210 //  Leaderboard Methods
211 
212 - (void)showLeaderboard: (int)ident
213 {
214     NSString *identifier;
215     
216     // INSERT YOUR ACHIEVEMENT IDENTIFIERS BELOW
217     
218     switch (ident)
219     {
220         case 1:
221             identifier = @"Easy Difficulty";
222             break;
223         case 2:
224             identifier = @"Medium Difficulty";
225             break;
226         case 3:
227             identifier = @"Hard Difficulty";
228             break;
229         default:
230             NSLog(@"Warning Unknown Leader Board");
231             break;
232     }
233     
234     GKLeaderboardViewController *leaderBoardCont = [[GKLeaderboardViewController alloc] init];
235     if (leaderBoardCont)
236     {
237         // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
238         leaderBoardCont.category=identifier;
239         leaderBoardCont.timeScope=GKLeaderboardTimeScopeToday;
240         leaderBoardCont.leaderboardDelegate=self;
241         
242         [[SharedRenderer renderer] presentModalViewController:leaderBoardCont animated:YES];
243     }
244 }
245 
246 - (void)showEasyLeaderboard
247 {
248     GKLeaderboardViewController *leaderBoardCont = [[GKLeaderboardViewController alloc] init];
249     if (leaderBoardCont)
250     {
251         // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
252         leaderBoardCont.category=@"Easy Difficulty";
253         leaderBoardCont.timeScope=GKLeaderboardTimeScopeToday;
254         leaderBoardCont.leaderboardDelegate=self;
255         
256         [[SharedRenderer renderer] presentModalViewController:leaderBoardCont animated:YES];
257     }
258 }
259 
260 - (void)showMediumLeaderboard
261 {
262     GKLeaderboardViewController *leaderBoardCont = [[GKLeaderboardViewController alloc] init];
263     if (leaderBoardCont)
264     {
265         // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
266         leaderBoardCont.category=@"Medium Difficulty";
267         leaderBoardCont.timeScope=GKLeaderboardTimeScopeToday;
268         leaderBoardCont.leaderboardDelegate=self;
269         
270         [[SharedRenderer renderer] presentModalViewController:leaderBoardCont animated:YES];
271     }
272 }
273 
274 - (void)showHardLeaderboard
275 {
276     GKLeaderboardViewController *leaderBoardCont = [[GKLeaderboardViewController alloc] init];
277     if (leaderBoardCont)
278     {
279         // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
280         leaderBoardCont.category=@"Hard Difficulty";
281         leaderBoardCont.timeScope=GKLeaderboardTimeScopeToday;
282         leaderBoardCont.leaderboardDelegate=self;
283         
284         [[SharedRenderer renderer] presentModalViewController:leaderBoardCont animated:YES];
285     }
286 }
287 
288 - (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
289 {
290     [[SharedRenderer renderer] dismissModalViewControllerAnimated:YES];
291     [[SharedRenderer renderer] startAnimation];
292 }
293 
294 - (void) reportEasyScore:(int) score
295 {
296     // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
297     GKScore *scoreReporter = [[[GKScore alloc] initWithCategory: @"Easy Difficulty"] autorelease];
298     if(scoreReporter)
299     {
300         scoreReporter.value = score;
301         
302         [scoreReporter reportScoreWithCompletionHandler:^(NSError *error)
303         {
304             if (error != nil)
305             {
306                 // handle the reporting error
307                 NSLog(@"Game Center: Error Reporting Easy Score - %@", [error localizedDescription]);
308             }
309         }];   
310     }
311 }
312 
313 - (void)reportMediumScore:(int) score
314 {
315     // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
316     GKScore *scoreReporter = [[[GKScore alloc] initWithCategory: @"Medium Difficulty"] autorelease];
317     if(scoreReporter)
318     {
319         scoreReporter.value = score;
320         
321         [scoreReporter reportScoreWithCompletionHandler:^(NSError *error)
322          {
323              if (error != nil)
324              {
325                  // handle the reporting error
326                  NSLog(@"Game Center: Error Reporting Medium Score - %@", [error localizedDescription]);
327              }
328          }];   
329     }
330 }
331 
332 - (void)reportHardScore:(int) score
333 {
334     // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
335     GKScore *scoreReporter = [[[GKScore alloc] initWithCategory: @"Hard Difficulty"] autorelease];
336     if(scoreReporter)
337     {
338         scoreReporter.value = score;
339         
340         [scoreReporter reportScoreWithCompletionHandler:^(NSError *error)
341          {
342              if (error != nil)
343              {
344                  // handle the reporting error
345                  NSLog(@"Game Center: Error Reporting Hard Score - %@", [error localizedDescription]);
346              }
347          }];   
348     }
349 }
350 
351 // Music Play and Stop Methods
352 
353 - (void)playMusic:(int) songNumber
354 {
355     NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
356     NSString* song = [[NSString alloc] initWithString:@""];
357     NSError* err;
358     
359     switch (songNumber)
360     {
361         case 1: //menu song
362             song = @"/menu.MP3";
363             break;
364         case 2:
365             song = @"/game.MP3";
366             break;
367         case 3:
368             song = @"/winner.MP3";
369         default:
370             break;
371     }
372 
373     if ([song isEqualToString:@""])
374     {
375         return ;
376     }
377     //NSLog(@"Playing song %d: %@",songNumber,song);
378     resourcePath = [resourcePath stringByAppendingString:song];
379     //NSLog(@"Path to play: %@", resourcePath);
380     //Initialize our player pointing to the path to our resource
381     if (playing && player)
382     {
383         [player stop];
384         playing = false;
385     }
386     player = [[AVAudioPlayer alloc] initWithContentsOfURL:
387               [NSURL fileURLWithPath:resourcePath] error:&err];
388     
389 
390     if( err )
391     {
392         //bail!
393         NSLog(@"Failed with reason: %@", [err localizedDescription]);
394     }
395     else
396     {
397         //set our delegate and begin playback
398         player.delegate = self;
399         [player prepareToPlay];
400         player.numberOfLoops = -1; //One Infinite Loop (music!) ;)
401         [player play];
402         playing = true;
403     }
404 
405 }
406 
407 - (void)stopMusic
408 {
409     if (playing)
410     {
411         [player stop];
412         playing = false;
413     }
414 }
415 @end

aGameCenter_Codea.m hosted with ❤ by GitHub

21.5 Modifications to your Codea App PAGE TOP

Once you start adding the Game Center functionality you wont be able to compile and run your App in Codea anymore (since these functions are only defined in the runtime). Consequently, debug all of your code apart from the Game Center specific parts before you make the following modifications.

After you are in Xcode and using the runtime, you can still update your Lua code but you need to force the runtime to reload the Lua files into the documents directory. You can do this by changing the version number in the Lua info.plist which can be found in Project.codea.

This number just needs to be different (not necessarily larger) to what it was the last time you compiled, to force an upload. Alternatively, if you get sick of doing this each run-test cycle (like we did), you can go into the CodifyAppDelegate.m file, find the - (BOOL) migrateProjectAtPath:(NSString)path toPath:(NSString)destPath method and comment out the following code as shown below.

// NSString* oldVersion = [self versionForProjectAtPath:destPath];
// NSString* newVersion = [self versionForProjectAtPath:path];

// if ([oldVersion isEqualToString:newVersion]) 

//    {
//        return YES;
//    }

Should you need to add sprites, you can save these directly into the dropbox folders in the runtime but you may need to do a clean build (select Product from the menu bar and then Clean) before Xcode will see them.

As part of the Game Center update of MineSweeper (v1.5) we took the opportunity to tweak the code based on feedback from the Codea Forum. In particular:

  1. There is a new MineSweeper logo on the Menu screen courtesy of @derhannes (you can see their web site at: http://www.boba-soft.com).
  2. The falling mines on the Menu Screen now start dropping from above the screen which makes the animation look smoother. Thanks to @Fred for this suggestion.
  3. The textBox used to enter the players name, if a new high score is achieved, now handles a changing orientation (e.g. Portrait to Landscape). Thanks to @West for finding this bug.

Once you have added all the code above, the actual Game Center implementation in Lua is very simple. In the Setup() function in Main add the following code:

-- Initialise Game Center if it is available (requires a device running iOS 4.1
-- or later and the App needs to be running within the Codea run time).

    aGameCenter_start()
    if aGameCenter_isGameCenterAvailable() then
        print("Game Center Started.")
    else
        print("Game Center not available")
    end

Then you just need to report your scores and achievements as they happen. For example in MineSweeper when the game is won we do the following achievement checks:

-- Check if any Achievements were completed once game
-- has been won.

        if gameDifficulty == stateEasy then
            if readLocalData("easyWinner") == nil then
                saveLocalData("easyWinner", "YES")
                aGameCenter_reportAchievementIdentifier(1)
                print("Easy Winner Achievement.")
            end
        end

        if gameDifficulty == stateMedium then
            if readLocalData("mediumWinner") == nil then
                saveLocalData("mediumWinner", "YES")
                aGameCenter_reportAchievementIdentifier(2)
                print("Medium Winner Achievement.")
            end
        end

        if gameDifficulty == stateHard then
            if readLocalData("hardWinner") == nil then
                saveLocalData("hardWinner", "YES")
                aGameCenter_reportAchievementIdentifier(3)
                print("Hard Winner Achievement.")
            end
        end

        if readLocalData("gamesPlayed") == nil then
            gamesPlayed = 0
        else
            gamesPlayed = readLocalData("gamesPlayed")
        end

        gamesPlayed = gamesPlayed + 1
        saveLocalData("gamesPlayed", gamesPlayed)
        if gamesPlayed == 10 then
            if readLocalData("decathlon") == nil then
                saveLocalData("decathlon", "YES")
                aGameCenter_reportAchievementIdentifier(6)
                print("Decathlon Achievement.")
            end
        end

        if gamesPlayed == 100 then
            if readLocalData("centurion") == nil then
                saveLocalData("centurion", "YES")
                aGameCenter_reportAchievementIdentifier(7)
                print("Centurion Achievement.")
            end
        end

To save high scores onto the relevant leader board we updated the saveHighScore function as shown below.

function saveHighScore(d)

    -- Build the high score data into a string which is saved
    -- using saveLocalData(key, value). Also save gameTime as
    -- the score on Game Center for the appropriate leader board
    -- (easy, medium or hard).
    --
    -- n = playerName
    -- t = gameTime
    -- d = os.date() [current date] not used in this version

    playerName = textBox.text
    print("New High Score by: "..playerName)

    local hsDataString = string.format("return {\"%s\", %d}", playerName, gameTime)

    if gameDifficulty == stateEasy then
        saveLocalData("easyHighScore", hsDataString)
        aGameCenter_reportEasyScore(gameTime)
    elseif gameDifficulty == stateMedium then
        saveLocalData("mediumHighScore", hsDataString)
        aGameCenter_reportMediumScore(gameTime)
    elseif gameDifficulty == stateHard then
        saveLocalData("hardHighScore", hsDataString)
        aGameCenter_reportHardScore(gameTime)
    end

    hideKeyboard()
    highScoreSaved = true

end

Reference PAGE TOP

http://codeatuts.blogspot.in/2012/10/tutorial-21-integrating-game-center.html

0 Comments Leave a comment

Please login in order to leave a comment.

Newest first
!

Sign-in to your Chupamobile Account.

The Easiest way to Launch your next App or Game.

Join Chupamobile and get instant access to thousands of ready made App and Game Templates.

Creating an account means you’re okay with Chupamobile’s Terms of Service and Privacy Policy.