*

GameCenterで友達のハイスコアでゲーム中にアイコン画像と名前を表示するやつ

公開日: : 最終更新日:2014/03/04 iOS

p3

あんまりゲームセンター流行ってないのよね。友達申請とかめったにしないでしょ?
きっと同じことやるならFacebookとかTwitterでやるほうが遊んでもらえると思うんだけど難しそうなんでやってないです。ゲーセンはググってオリャーって簡単にできたのでメモっておきます。

p4

なんか先週水曜にLINEでこういうクエスチョンが来たのと、

コンプガチャ禁止
カテゴリ: ゲーム
現在の価格: 無料

金曜にこういうゲームをリリースしてそこでも同じことやっていたので、まーやりたい人はいるのかな〜と思って。

画像の準備

ゲーセンでアイコン画像設定してない人はエラるので、その人ようのデフォルト画像を用意してResourcesに入れておきます。
・play_friends.png
play_friends
まーこんな感じ(64×64)

それと正常にアイコン画像とれても正方形のが来るので、まん丸にマスクでトリミングするようの画像も用意してResourcesに入れておきます。
・play_friends_mask.png
play_friends_mask
まー
こんなやつ(64×64)

Retinaとか考えてないでしょ。・・・すいません。

 

コーディング〜♪

HighScores.hと.mをNSObjectでプロジェクトに追加しました。各々の友達プレイヤーの「名前(NSString)」と「アイコン画像(UIImage)」と「ハイスコア(int)」と「表示してないか、表示してる最中か、表示終わったか、を示すフラグ(int)」と「表示する座標たち(int)」なんかを管理する独自クラスです。

こっちがヘッダー部

//
// HighScores.h
// PiyoUP ← ※気にしない
//
// Created by marchEnterprise on 2013/10/26. ← ※気にしない
// Copyright (c) 2013年 marchEnterprise. All rights reserved.
//

#import <Foundation/Foundation.h>

#define FLG_DISP_PLAYER_READY 0
#define FLG_DISP_PLAYER_START 1
#define FLG_DISP_PLAYER_END 2

@interface HighScores : NSObject {

NSString *playerName;
UIImage *playerImage;

int playerScore;
int flg_disp_player;
int playerDegree;
int x;
int y;

}
@property (nonatomic, retain) NSString *playerName;
@property (nonatomic, retain) UIImage *playerImage;

@property (nonatomic, assign) int playerScore;
@property (nonatomic, assign) int flg_disp_player;
@property (nonatomic, assign) int playerDegree;
@property (nonatomic, assign) int x;
@property (nonatomic, assign) int y;

@end

こっちが実装部

//
// HighScores.m
// PiyoUP ← ※気にしない
//
// Created by marchEnterprise on 2013/10/26. ← ※他言無用
// Copyright (c) 2013年 marchEnterprise. All rights reserved.
//

#import “HighScores.h”

@implementation HighScores

@synthesize playerName,playerImage;
@synthesize playerScore;
@synthesize flg_disp_player;
@synthesize playerDegree;
@synthesize x;
@synthesize y;

@end

で、実際に表示するゲーム中のクラスにこれ導入するよ。

『コンプガチャ禁止』ではViewController.hと.mに入れてます、というかタイトル画面も結果画面もメインのガチャも全部ViewControllerにぶち込んであるんで、知るか!

こっちはヘッダー部
ViewController.h

#import <GameKit/GameKit.h>

//ゲームセンター識別子
#define GK_HIGHSCORE_STR @”net.marchenterprise.dontcomp.quest”
#define GK_HIGHSCORE_MAX 50 //友達の上位50人まで表示するよ、MAXはいまのとこ100まで
#define TAG_HIGHSCORES 300 //ハイスコア配列で使うタグ : 300〜349

//タイマーインターバル

#define TIMER_INTERVAL (1/30.0f)
//シーン定数
#define SCENE_QUESTINIT 10
#define SCENE_QUEST 11

// マクロ定義

// iPhone デバッグ用マクロ
//プロジェクトの設定を開き、「Debug」構成を選択してから、一番下のユーザ定義カテゴリの
//「GCC_PREPROCESSOR_DEFINITIONS」に「DEBUG」を追加しておきます。
//あとは、NSLog の代わりに LOG を使うようにすれば ok です。
#ifdef DEBUG
# define LOG(…) NSLog(__VA_ARGS__)
# define LOG_CURRENT_METHOD NSLog(@”%@/%@”, NSStringFromClass([self class]), NSStringFromSelector(_cmd))
#else
# define LOG(…) ;
# define LOG_CURRENT_METHOD ;
#endif

//角度からラジアン値
#define degreesToRadians(x) (M_PI * (x) / 180.0)

//整数のランダム値
#define randint(r) ((int) (random()%(r)))

@interface ViewController : UIViewController <GKLeaderboardViewControllerDelegate,…> {

//チックタイマー
int tickTimer;
//現在のシーン
int now_scene;

//スクリーンサイズ
float screen_width, screen_height;

 


//リーダーボード取得フラグ
BOOL flg_highscoreload;
//ハイスコア配列
NSMutableArray *highScoreArray;

}

//ゲームセンター処理
#pragma mark –
#pragma mark GAMECENTER

// 1位〜GK_HISHSCORE_MAXまでのプレイヤー取得
-(void) retrieveTopScores;

-(void) dispHighScores;
-(void) removeHighScores;

@end

こっちが実装部
ViewController.m

#import “HighScores.h”

@implementation ViewController

// 初期化
#pragma mark –
#pragma mark Init

-(void) viewDidLoad {
[super viewDidLoad];

//ハイスコア配列初期化
highScoreArray = [[NSMutableArray alloc] init];

//tickタイマー処理化
tickTimer = 0;
//シーン初期化
now_scene = SCENE_QUESTINIT;
//画面サイズを取得
screen_width = [[UIScreen mainScreen] bounds].size.width;
screen_height = [[UIScreen mainScreen] bounds].size.height;
LOG(@” >>screen_width,height=%f,%f”, screen_width,screen_height);

// tickタイマーの開始
[NSTimer scheduledTimerWithTimeInterval: TIMER_INTERVAL
target: self
selector: @selector(tick)
userInfo: nil
repeats: YES];

}

 

// メインタイマー処理
#pragma mark –
#pragma mark MainTimer

-(void) tick {

//シーンによる分岐
switch (now_scene) {

// MARK: SCENE_QUESTINIT
//クエスト画面の初期化 → ※ゲーム開始時の処理ね
case SCENE_QUESTINIT:

if (tickTimer == 1) {

LOG(@” >>scene: SCENE_QUESTINIT : 初期化”);

//ゲーセン
//リーダーボード取得
[self retrieveTopScores];

}

if (tickTimer == (int) (2.5f/TIMER_INTERVAL)) {
//シーンチェンジ
now_scene = SCENE_QUEST;
tickTimer = 0;
}

break;

// MARK: SCENE_QUEST
//クエスト画面 → ※ゲーム中に毎フレーム呼ばれる処理ね
case SCENE_QUEST:
if (tickTimer == 1) {
LOG(@” >>scene: SCENE_QUEST : クエスト開始”);
}

//ハイスコア表示
[self dispHighScores];

break;

}
}

 

//ゲームセンター処理
#pragma mark –
#pragma mark GAMECENTER

// 1位〜GK_HISHSCORE_MAXまでのプレイヤー取得
-(void) retrieveTopScores {

LOG(@”%s”,__func__);

//ハイスコア配列を全消去
[highScoreArray removeAllObjects];

//リーダーボード読み込み
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil) {

leaderboardRequest.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.category = GK_HIGHSCORE_STR;
leaderboardRequest.range = NSMakeRange(1,GK_HIGHSCORE_MAX);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores,
NSError *error) {
if (error != nil) {
// エラーを処理する。
LOG(@” >>leaderboardRequest error!”);
return;
}

NSMutableArray *array = [NSMutableArray array];
//プレイヤーID配列を作成
for (GKScore *score in scores) {
[array addObject:score.playerID];
}

[GKPlayer loadPlayersForIdentifiers:array withCompletionHandler:^(NSArray *players, NSError *error) {
if (error) {
// Report only with player ids
for (GKScore *score in scores)
LOG(@”loadPlayersForIdentifiers error! [%2d] %@: %@ (%@)”, score.rank, score.playerID, score.formattedValue, score.date);
return;
}

for (int i = 0; i < scores.count; i++) { // Report with actual player names

GKPlayer *aPlayer = [players objectAtIndex:i];
GKScore *score = [scores objectAtIndex:i];

LOG(@”[rank:%2d] alias(nickname):%@ score:%@ (date:%@)”, score.rank, aPlayer.alias, score.formattedValue, score.date);
HighScores *highScores = [[HighScores alloc] init]; highScores.flg_disp_player = FLG_DISP_PLAYER_READY;
highScores.playerName = aPlayer.alias;
highScores.playerDegree = 0;
highScores.x = 0;
highScores.y = 0;
NSString *value = [score.formattedValue stringByReplacingOccurrencesOfString:@”,” withString:@””];
highScores.playerScore = value.intValue;
LOG(@” >>playerScore=%d”,highScores.playerScore);

[aPlayer loadPhotoForSize:GKPhotoSizeSmall withCompletionHandler:^(UIImage
*photo, NSError *error) {
if (error != nil || photo == nil)
{
// 必要に応じてエラーを処理する。
highScores.playerImage = [UIImage imageNamed:@”play_friends.png”];
LOG(@” ERROR! : get play_friends.png”);

} else {

//イメージマスク切り抜き&縮小
UIImage *maskImage = [UIImage imageNamed:@”play_friends_mask.png”];
CGSize pImage = CGSizeMake(maskImage.size.width, maskImage.size.height);
CGRect rect = CGRectMake(0, 0, pImage.width, pImage.height);

//マスク画像のCGImageRefを作成します
CGContextRef maskContext = CGBitmapContextCreate(NULL, pImage.width, pImage.height, 8, 0, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
CGContextDrawImage(maskContext, rect, maskImage.CGImage);
CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext);
CGContextRelease(maskContext);

//カラースペースを作成します。
CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef baseImageContext = CGBitmapContextCreate(NULL, pImage.width, pImage.height, 8, 0, genericColorSpace, (CGBitmapInfo) kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(genericColorSpace);

// ベース画像のCGImageRefを作成します。
CGContextDrawImage(baseImageContext, rect, photo.CGImage);
CGImageRef baseImageRef = CGBitmapContextCreateImage(baseImageContext);
CGContextRelease(baseImageContext);
CGImageRef maskedImageRef = CGImageCreateWithMask(baseImageRef, maskImageRef);
UIImage *masked_photo = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(maskedImageRef);
CGImageRelease(maskImageRef);
CGImageRelease(baseImageRef);

//イメージ格納
highScores.playerImage = [UIImage imageWithCGImage:[masked_photo CGImage]];
LOG(@” >>w,h=%f,%f”,highScores.playerImage.size.width,highScores.playerImage.size.height);

}
}];

//ハイスコア配列に記録
[highScoreArray addObject:highScores];

}
}];
}];

}

flg_highscoreload = YES;
LOG(@” >>flg_highscoreload = YES”);
}

-(void) dispHighScores {

int i=0;
for (HighScores *highScores in highScoreArray) {

if (highScores.flg_disp_player == FLG_DISP_PLAYER_READY) {
//
// ハイスコアの非表示中
//

//ハイスコアの表示圏内に入ったか確認 → ※メインタイマーのtickとスクロール座標が連動しているという手抜き処理
if (tickTimer%50==0) {

if ((int) (tickTimer/50) == (highScores.playerScore)) { → ※メインタイマーのtickと点数が連動しているという手抜き処理

//ハイスコアの表示開始
highScores.flg_disp_player = FLG_DISP_PLAYER_START;

//ハイスコアの表示
highScores.x = screen_width+47+randint(100);
highScores.y = screen_height-50-40-randint(100);
highScores.playerDegree=360;

//名前
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(highScores.x-100, highScores.y+20, 200, 20);
nameLabel.backgroundColor = [UIColor clearColor];
nameLabel.textColor = [UIColor blackColor];
nameLabel.font = [UIFont boldSystemFontOfSize:14];
nameLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
nameLabel.textAlignment = NSTextAlignmentCenter;
nameLabel.text = highScores.playerName;
nameLabel.tag = TAG_HIGHSCORES+(i*2);
[self.view addSubview:nameLabel];
LOG(@” >>nameLabel=%@”, highScores.playerName);

//アイコン画像
UIImageView *highImage = [[UIImageView alloc] initWithImage:highScores.playerImage];
[highImage setFrame:CGRectMake(0,0, 50, 50)];
[highImage setCenter:CGPointMake(highScores.x,highScores.y)];
highImage.tag = TAG_HIGHSCORES+(i*2)+1;
[self.view addSubview:highImage];
LOG(@” >>playerImage=%d,%d”, highScores.x,highScores.y);

}
}

} else if (highScores.flg_disp_player == FLG_DISP_PLAYER_START) {

//
// ハイスコアの表示中
//
highScores.x-=4;
highScores.playerDegree-=randint(10);

//ハイスコアの表示移動
UILabel *nameLabel = (UILabel *) [self.view viewWithTag:TAG_HIGHSCORES+(i*2)];
UIImageView *highImage = (UIImageView *) [self.view viewWithTag:TAG_HIGHSCORES+(i*2)+1];
nameLabel.frame = CGRectMake(highScores.x-100, highScores.y+20, 200, 20);
[self.view bringSubviewToFront:nameLabel];

[highImage setTransform:CGAffineTransformMakeRotation(degreesToRadians(highScores.playerDegree))];
[highImage setCenter:CGPointMake(highScores.x,highScores.y)];
[self.view bringSubviewToFront:highImage];

//ハイスコアの表示終了チェック
if (highScores.x<-100) { LOG(@” >>highScores[%d]=%d END”,i,TAG_HIGHSCORES+(i*2));

//ハイスコアの表示終了
highScores.flg_disp_player = FLG_DISP_PLAYER_END;
[nameLabel removeFromSuperview];
[highImage removeFromSuperview];
}
}
//次へインクリメント
i++;

}

}

-(void) removeHighScores {

int i=0;
for (HighScores *highScores in highScoreArray) {

if (highScores.flg_disp_player == FLG_DISP_PLAYER_START) {
UILabel *nameLabel = (UILabel *) [self.view viewWithTag:TAG_HIGHSCORES+(i*2)];
UIImageView *highImage = (UIImageView *) [self.view viewWithTag:TAG_HIGHSCORES+(i*2)+1];
highScores.flg_disp_player = FLG_DISP_PLAYER_END;
[nameLabel removeFromSuperview];
[highImage removeFromSuperview];
}

i++;
}

}

以上!かな。

で難しいゲームを作ると、ゲームスタートした瞬間に・・・

p2

わらわらわら・・・ってでてくるんです、知るか!

あ、そうそう友達のアイコン画像50人分とか取ってくんのに通信して時間かかるんじゃねー?っていうのが疑問だったんだけどゲーセンがキャッシュしてるのかー知らぬ間にローカルに取ってきてんのか激はやでちょっとびっくりしたよ。
あ、たしかARCのプロジェクトだったはず。iOS7,Deployment6.0, XCode5.0.2。


Author Profile

ま〜ち
ま〜ち
フリーランスのiPhone/iPadアプリ開発者、2児を保育園の送り迎えしながら日々ノマド創作生活をしています。
代表作 : 「コンプガチャ」(AppStore無料総合5位/無料ゲーム総合1位)、「美少女ブラ外しPutti!」(AppStore有料総合6位/エンターテインメント有料1位)、「星空時景」(AppStore有料総合3位/ライフスタイル有料1位)、「パワースポット写真集」(AppStore有料総合3位/ライフスタイル有料1位)、「ゆるゆりシェイクユー」、「ガリガリアイス」「ケントくんのiマニュアル」「パチスロアプリ全紹介」など。

関連記事

pr800x475_width_text

『i立ち食いそば』がAppStore/GooglePlayにて登場いたしました

兵士達を率いて駅そばへ駆け込め! 命を賭して通勤ラッシュに挑むFPS(※First Perso

記事を読む

build

Subview touchesEnded 送る to ParentView

iOS5から変わったとか。わっけっわっかっらっん。。。 旧) -(void) touches

記事を読む

ogp1200x630

Unity習作の第2弾『あみみとパズルとゾンビとドラゴンズ』がめでたくリリースとなりました

3月末に「アニメマンガゲームエンタメ親睦会」というのがFacebookイベントでありまして、その会が

記事を読む

Icon1024x1024

MIKA・RIKA・TOUCH

つくりました、よろしくお願いします!! MIKA・RIKA・TOUCHカテゴリ: ゲーム現在の

記事を読む

build

PHPをバージョンアップしたらMySQLに登録されるUTF-8文字列がエスケープされちゃって困った。

ニッチな話Easy APNSとEasyAPNSPanelってゆーのを使ってiOSアプリのPush通知

記事を読む

build

Easy APNSとEasyAPNSPanel

Core Pushってゆーサービスを導入してみるけどバッヂの指定もできないしいろいろ融通が効かなすぎ

記事を読む

Fullscreen-1

LHSprite registerTouchBeganObserver

-(id) init { if( (self=)) { ... LHSprite

記事を読む

Fullscreen-1

SpriteHelperだけのスプライト表示

LevelHelperで配置してないやつはBatchNodeでCCSpriteしなきゃいけないみたい

記事を読む

bg

UIView Animation suddenly become very fastで困った。

たった一行で3日もハマッた。もうだめぽな ま〜ちさんです。 iOS App‘s UIView

記事を読む

no image

UnityのAppleTV対応つまづいたメモ

音が鳴らない Unity tvos AudioClipとかでググっても情報なし。 散々いろいろや

記事を読む

Ads

Ads

no image
UnityのAppleTV対応つまづいたメモ

音が鳴らない Unity tvos AudioClipとかでググって

ogp1200x630
Unity習作の第2弾『あみみとパズルとゾンビとドラゴンズ』がめでたくリリースとなりました

3月末に「アニメマンガゲームエンタメ親睦会」というのがFacebook

pr_1024x500
なんかどうもうまくいかないUnity5メモ

前回までのメモ i立ち食いそばカテゴリ: ゲーム現在の価格: 無

pr800x475_width_text
『i立ち食いそば』がAppStore/GooglePlayにて登場いたしました

兵士達を率いて駅そばへ駆け込め! 命を賭して通勤ラッシュに挑むF

Icon1024x1024
MIKA・RIKA・TOUCH

つくりました、よろしくお願いします!! MIKA・RIKA・TO

→もっと見る

PAGE TOP ↑