ラベル objective-c の投稿を表示しています。 すべての投稿を表示
ラベル objective-c の投稿を表示しています。 すべての投稿を表示

2014年3月24日月曜日

Objective-Cで文字列の大文字変換、小文字変換

//大文字変換
NSString *upperString = [@"abcdefg" uppercaseString];

//小文字変換
NSString *lowerString = [@"ABCDEFG" lowercaseString];

2014年3月12日水曜日

cocos2dでの並列処理

NSOperationQueueを使う


NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
    [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"bgm2.mp3"];
}];

2014年3月1日土曜日

CCLayerのアンカーポイント変更

CCLayerのアンカーポイント変更


CCLayerはアンカーポイントの無視する設定になっているのでそれを解除する必要がある

//アンカーポイントを無視を無効化
layer.ignoreAnchorPointForPosition = NO;

//アンカーポイントの変更
layer.anchorPoint = ccp(0.5, 0.5);

2014年2月28日金曜日

cocos2dのpopSceneの注意点

pushSceneでシーンをプッシュし、popSceneでシーンを破棄するときに呼び出し元のシーンのonEnterが呼ばれるので注意すること。

2014年2月27日木曜日

cocos2d:CCLineBreakModeがdeprecated

CCLineBreakModeがdeprecatedの場合、頭にkをつける


CCLineBreakModeWordWrap → kCCLineBreakModeWordWrap
CCLineBreakModeCharacterWrap → kCCLineBreakModeCharacterWrap

cocos2d:CCTextAlignmentがdeprecated

CCTextAlignmentの値がdeprecatedの場合、頭にkをつける。


CCTextAlignmentCenter → kCCTextAlignmentCenter
CCTextAlignmentLeft → kCCTextAlignmentLeft
CCTextAlignmentRight → kCCTextAlignmentRight

2014年2月26日水曜日

cocos2dでメニューに画像を使う

CCMenuItemSpriteを使用する


//選択前のボタン
CCSprite *nomalButton = [CCSprite spriteWithFile:@"button.png"];

//選択後のボタン(色を暗くした同じ画像)
CCSprite *selectedButton = [CCSprite spriteWithFile:@"button.png"];
selectedButton.color = ccc3(64, 64, 64);
    
CCMenuItemSprite *item = [CCMenuItemSprite itemWithNormalSprite:nomalButton selectedSprite:selectedButton target:self selector:@selector(tapButton)];
CCMenu* menu = [CCMenu menuWithItems:item, nil];
[self addChild:menu];

2014年2月25日火曜日

objective-cで数値と文字列の変換

objective-cで数値と文字列の変換


文字列から数値


int tempInt = [tempString intValue];


数値から文字列


NSString *tempString = [NSString stringWithFormat:@"%d", tempInt];

NSDictionaryのキーの存在確認

NSDictionaryのキーの存在確認


標準では確認できるメソッドが無いので以下のようにする

if ([[dictionary allKeys] containsObject:key) {
  // 存在する場合の処理
}

2014年2月24日月曜日

cocos2dでAppDelegateの取得

cocos2dでAppDelegateの取得


AppController *appDelegate = (AppController *)[[UIApplication sharedApplication] delegate];

2014年2月21日金曜日

cocos2dでポーズの実装と注意点

cocos2dでポーズの実装と注意点


ポーズと解除


//ポーズ
[[CCDirector sharedDirector] pause];

//ポーズ解除
[[CCDirector sharedDirector] resume];


注意点


1.ホームボタンでのポーズ

AppDelegateの以下のメソッドにもpause,resumeが書かれている。
  • applicationWillResignActive
  • applicationDidBecomeActive
これはホームボタンが押されたときに呼ばれる。
これらのメソッドが呼ばれても問題ないようにフラグ等を追加して制御する必要がある。

2.タッチメソッド

ポーズ中でもタッチ機能は生きているので別途無効化する必要がある。

2014年2月20日木曜日

NSUserDefaults

ちょっとしたデータを保存する場合、NSUserDefaultsが便利


NSUserDefaultsの使い方


//取得時のキー
NSString *key = @"key";
//保存する文字列
NSString *dataString = @"data";

//保存
NSArray *tempArray = [NSArray arrayWithObject:dataString];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:tempArray forKey:key];
[defaults synchronize];


//保存したデータの取得用
NSString *saveString = nil;

//取得
NSArray *array = nil;
array = [[NSUserDefaults standardUserDefaults] arrayForKey:key];
if (array != nil) {
    for (NSString *data in array) {
        saveString =  data ;
    }
}

2014年2月19日水曜日

cocos2dで複数のアクションを同時実行

cocos2dで複数のアクションを同時実行する方法


CCSpawnを使用


id fadeIn = [CCFadeIn actionWithDuration:1.0];
id jump = [CCJumpBy actionWithDuration:1.0 position:ccp(0, 50) height:50 jumps:1];
id spawn = [CCSpawn actions:fadeIn, jump, nil];
[sprite runAction:spawn];

2014年2月18日火曜日

cocos2dでスクロールするレイヤー

Cocos2d「Extensions」を使用してスクロールするレイヤーを実装


ダウンロード



Xcodeに追加

ZIPのExtensions->CCScrollLayerをフォルダごと追加


インポート


#import "CCScrollLayer.h"


初期設定


- (id) init {
 if ((self = [super init])){
  // シーンを複数作成
  NSMutableArray *layerArray = [NSMutableArray array];
  CCLayer* layer1 = [CCLayer node];
  CCLayer* layer2 = [CCLayer node];
  CCLayer* layer3 = [CCLayer node];
  
  [layerArray addObject:layer1];
  [layerArray addObject:layer2];
  [layerArray addObject:layer3];
  
  // CCScrollLayerに追加
  CCScrollLayer *scroller = [[CCScrollLayer alloc] initWithLayers:layerArray widthOffset: 0];

  //ページインジケーターのポジション
  scroller.pagesIndicatorPosition = ccp(self.contentSize.width / 2, 60);
  [self addChild:scroller];
 }
}

2014年2月17日月曜日

レビューを促すライブラリ『Appirater』

レビューを促すAppiraterの導入手順


1.ダウンロード

 githubから、Appiraterをダウンロードする。
https://github.com/arashpayan/appirater

2.プロジェクトに追加

 ダウンロードしたappirater-masterをプロジェクトに追加。

3.不要なファイルの削除

 README.mdは不要なので削除。

4.フレームワークの追加

 プロジェクトにCFNetwork.framework、SystemConfiguration.framework、StoreKit.frameworkを追加する。

5.ローカライズ

 レビューを催促するときに表示される文言を修正する場合は、ローカライズファイルを修正する。
日本語の場合は、AppiraterLocalizable.strings(Japanese)

6.ARC設定

 プロジェクトがARCを利用しない場合、TARGETSの Build Phases ≫ Compile Sources sectionを開き、Appirater.mに -fobjc-arc を設定する。

7.インポート

 AppDelegate.hを修正する。
#import "Appirater.h"


8.設定値の修正

 AppDelegate.mのapplication:didFinishLaunchingWithOptionsメソッドにAppirater起動の設定を記述する。古いプロジェクトの場合はapplicationDidFinishLaunchingでもよい。
[Appirater setAppId:@"000000000"]; // Apple ID(アプリ毎の識別番号:iTunes Connectで参照可)
[Appirater setDaysUntilPrompt: 30]; // 同じバージョンで再びメッセージを表示するまでの日数。(デフォルト:30日)
[Appirater setUsesUntilPrompt: 20]; // 同じバージョンで再びメッセージを表示するまでの起動回数。(デフォルト:20回)
[Appirater setSignificantEventsUntilPrompt: -1]; // ゲームのレベルクリアなど、ユーザーがアプリ内で何か特別な操作したときや、あるレベルに達したときにメッセージを表示するか否かを指定する。(デフォルト:-1)
// 値 : -1=無効, 1=有効
// 表示する場合は、ゲームのレベルクリアしたときなど任意の箇所に [Appirater userDidSignificantEvent:YES] を記述する。
[Appirater setTimeBeforeReminding: 1]; // 「後で見る」を選択したときに再びメッセージを表示するまでの日数。(デフォルト:1日)
[Appirater setDebug: NO]; // デバッグモードの設定。YESにするとアプリを起動するたびに表示される。(デフォルト:NO)
[Appirater appLaunched:YES]; // Appiraterの起動


9. 起動時のカウント

AppDelegate.mのapplicationWillEnterForegroundメソッドに、フォアグランド時にカウントするかの設定を記述する。
[Appirater appEnteredForeground:YES];


10.アプリ名

 実行時の画面に表示するアプリ名を変更する場合は、Appirater.hを修正する。
#define APPIRATER_APP_NAME を修正


2013年11月14日木曜日

配列にNULL(nil)を入れる

配列にnilは入れられないので、NSNullを使う

//配列にNullをを入れる
[array addObject:[NSNull null]];

//Null判定
if ([array objectAtIndex:index] == [NSNull null]){
  NSLog(@"This is null!!");
}

2013年11月6日水曜日

SQLite(FMDB)

FMDBを使用



#import "FMDatabase.h"

FMDatabase* _db;
NSString* DB_FILE = @"sample.sqlite3";

//DBオープン
if (![self openDatabase]) {
    //失敗
}

//更新
if (![self executeUpdate]) {
    //失敗
}

//参照
[self executeQuery];

//DBクローズ
[self closeDatabase];

- (BOOL)openDatabase {

    //DBファイルへのパスを取得
    //パスは~/Documents/配下に格納される。
    NSString *dbPath = nil;
    NSArray *documentsPath = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    
    //取得データ数を確認
    if ([documentsPath count] >= 1) {
        //固定で0番目を取得でOK
        dbPath = [documentsPath objectAtIndex:0];
        //パスの最後にファイル名をアペンドし、DBファイルへのフルパスを生成。
        dbPath = [dbPath stringByAppendingPathComponent:DB_FILE];
        NSLog(@"db path : %@", dbPath);
    } else {
        //error
        NSLog(@"search Document path error. database file open error.");
        return false;
    }
    
    //DBファイルがDocument配下に存在するか判定
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:dbPath]) {
        //存在しない
        //デフォルトのDBファイルをコピー(初回のみ)
        //ファイルはアプリケーションディレクトリ配下に格納されている。
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *orgPath = [bundle bundlePath];
        //初期ファイルのパス。(~/XXX.app/sample.db)
        orgPath = [orgPath stringByAppendingPathComponent:DB_FILE];
        
        //デフォルトのDBファイルをDocument配下へコピー
        if (![fileManager copyItemAtPath:orgPath toPath:dbPath error:nil]) {
            //error
            NSLog(@"db file copy error. : %@ to %@.", orgPath, dbPath);
            return false;
        }
    }
    
    //open database with FMDB.
    _db = [FMDatabase databaseWithPath:dbPath];
    return [_db open];
}

- (void)executeQuery {
    
    //クエリ実行
    FMResultSet *rs = [_db executeQuery:@"select * from items where word = ? ",@"abc"];
    
    if ([_db hadError]) {
        NSLog(@"Err %d: %@", [_db lastErrorCode], [_db lastErrorMessage]);
    }
    
    //結果の取得(カラム名指定)
    while ([rs next]) {
        //[rs dateForColumn:@"n"];
        //[rs stringForColumn:@"t"];
        //[rs doubleForColumn:@"r"];
        NSLog(@"id->%d", [rs intForColumn:@"item_id"]);
    }
    
    //close ResultSet.
    [rs close];
    
}

- (BOOL)executeUpdate {
    
    BOOL result = TRUE;
    //トランザクション開始(exclusive)
    [_db beginTransaction];
    
    //ステートメントの再利用フラグ
    //おそらくループ内で同一クエリの更新処理を行う場合バインドクエリの準備を何回
    //も実行してしまうのためこのフラグを設定する。
    //このフラグが設定されているとステートメントが再利用される。
    [_db setShouldCacheStatements:YES];
    
    //update
    [_db executeUpdate:@"update items set correct_count = correct_count + ? ", [NSNumber numberWithInt:1]];
    
    //check
    if ([_db hadError]) {
        result = FALSE;
        NSLog(@"Err %d: %@", [_db lastErrorCode], [_db lastErrorMessage]);
    }
    
    //commit
    [_db commit];
    
    return result;
}


- (void)closeDatabase {
    if (_db) {
        [_db close];
    }
}

2013年10月23日水曜日

cocos2dでTextField

CCUIViewWrapperを使用

以下のURLよりソースを取得

※そのままではBuild時に警告が出るので以下を修正
[[[[CCDirector sharedDirector] view] window] addSubview: uiItem];
//[[[CCDirector sharedDirector] openGLView] addSubview:uiItem];

/****************************************/

//if(!p.isRelativeAnchorPoint)
if(p.ignoreAnchorPointForPosition)
    transform = CGAffineTransformTranslate(transform, p.anchorPoint.x, p.anchorPoint.y);
    //transform = CGAffineTransformTranslate(transform, p.anchorPointInPixels.x, p.anchorPointInPixels.y);

/****************************************/

transform = CGAffineTransformTranslate(transform, -p.anchorPoint.x, -p.anchorPoint.y);
//transform = CGAffineTransformTranslate(transform, -p.anchorPointInPixels.x, -p.anchorPointInPixels.y);


UITextFieldを実装

ヘッダー

@interface GameLayer : CCLayer <UITextFieldDelegate> {
    CCUIViewWrapper *textFieldWrapper;
    UITextField *textBox;
}
@end

実装

- (void)addTextField {
    textBox = [[[UITextField alloc] init] autorelease];
    textBox.frame = CGRectMake(175, 120, 110, 25);
    textBox.borderStyle = UITextBorderStyleRoundedRect;
    textBox.placeholder = @"hogehoge";
    textBox.returnKeyType = UIReturnKeyDone;
    textBox.clearButtonMode = UITextFieldViewModeWhileEditing;
    textBox.autocapitalizationType = UITextAutocapitalizationTypeNone;
    textBox.enablesReturnKeyAutomatically = YES;
    textBox.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter;
    textBox.textAlignment = NSTextAlignmentCenter;
    textFieldWrapper = [CCUIViewWrapper wrapperForUIView:textBox];
    textBox.delegate = self;
    [self addChild:textFieldWrapper];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    CCLOG(@"text->%@", textBox.text);
}

URL encode/decode

//encoding
NSString *escapedUrlString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
        NULL,
        (CFStringRef)plainString,
        NULL,
        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
        kCFStringEncodingUTF8 );
 
//decoding
NSString *decodedUrlString = (NSString *) CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
        NULL,
        (CFStringRef) escapedUrlString,
        CFSTR(""),
        kCFStringEncodingUTF8);

XMLパーサー

ヘッダー

@interface XMLParserWrapper : NSObject <NSXMLParserDelegate> {
    NSString *searchElementString;
}

- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **) error ;
- (void)parseXMLFileAtData:(NSData *)data parseError:(NSError **) error ;

@end


実装

@implementation XMLParserWrapper

//URLで解析
- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **) error {
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    [self parseXMLFile:parser parseError:error];
}

//Dataで解析
- (void)parseXMLFileAtData:(NSData *)data parseError:(NSError **) error {
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [self parseXMLFile:parser parseError:error];
}

- (void)parseXMLFile:(NSXMLParser *)parser parseError:(NSError **) error {
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
    NSError *parseError = [parser parserError];
    if (parseError && error) {
        *error = parseError;
    }
    [parser release];
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    searchElementString = nil;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"取得したい属性名"]) {
        searchElementString = [NSString stringWithString:elementName];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"取得したい属性名"]) {
        searchElementString = nil;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if ([searchElementString isEqualToString:@"取得したい属性名"]) {
        //stringに取得したい属性の値
    }
}

@end



使い方

NSError *parseError = nil;
XMLParserWrapper *parser = [[XMLParserWrapper alloc] init];
[parser parseXMLFileAtData:receivedData parseError:&parseError];

if (parseError) {
    //parseエラー
    NSLog(@"Parse Error->%@", parseError);
}