2014年11月13日木曜日

[Xcode] No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7s armv7).のエラー

どうも、俺です。

Xcodeでビルドさせたときに、タイトルのようなエラーが出る人へ。


方法は2つ考えられます。

1)Build Settings内にある「Build Active Architecture Only」の値をNoにする。
2)転送先端末(またはシミュレータ)にマッチしたアーキテクチャを「Valid Architectures」に記述する。

これでエラーが出なくなるかもしれません。


1)の「Build Active Architecture Only」ですが、
これは"Yes"にすると現在選択された(転送先)端末に適した
アーキテクチャのみでビルドする、
という設定になるため、そのアーキテクチャが「Valid Architectures」にない場合は上記のエラーとなるようです。

以上でぇぇぇす。

2014年10月24日金曜日

[cocos2d-x] 謎の'string' file not foundエラー

どうも、俺@眠いです。

ある日突然、cocos2d-xでビルドを実行したときに
Lexical or Preprocessor Issue
'string' file not found

というエラーに出くわしました。

環境はMac OSX 10.9.5  +  Xcode v6.0.1 + cocos2d-x v2.1.5です。


ファイルに何も変更を加えておらず、
Clean → Buildを行った際に発生したので何がなんだかです。



エラーが発生しているファイルは、
CCDataVisitor.h
で、
#include <string>

の箇所でエラーが出ました。


ググると同じようなエラーに遭遇した人がたくさんいるようですが、
僕の場合は、

ビルド時にCCDatavisitor.hの#include で'string' file not foundというエラーが突然出るようになってハマったAdd Star


この方と同じ症状で、
Blockクラスを作成していました。

なぜだか理由は分かりませんが、
上記ブログと同じようにBlockクラスを削除して、別のクラス名にするとエラーがなくなりました。



以上でぇぇぇぇぇす。


2014年10月3日金曜日

Androidアプリ Lintエラーの対応

どうも、俺です。
しばらくなかったブログ更新を埋めるかのように連日投稿しています。

今日はAndroidアプリをeclipseでビルドするときに出るLinのエラー対応についてです。

■エラーその1
"xxxxx" is not translated "......"

→解決方法
 無視しましょう。

プロジェクト名>Properties>Android Lint Preferences
を選択、
MissingTranslationを選択してそのSeverityを"Warning"にしましょう。



これは、外部のライブラリ等を組み込んだ時に、
そのライブラリで設定されているローカライズ情報が、
開発中アプリまたはその他ライブラリに影響するために出るエラー、だそうです。。
要約すると、「言語リソースが足りねぇよ」というエラーです。


■エラーその2
"xxxx" is translated here but not found in default locale

→解決方法
google-play-servicesプロジェクト内にある
res>values-en-rIN>auth_strings.xmlをコピーして、
同じくgoogle-play-servicesプロジェクトの
res>valuesフォルダにペースト。



google-play-servicesを導入してから出るようになったエラーなので、
おそらくそれが原因っぽい。。



以上でぇぇぇぇぇぇす。

2014年10月2日木曜日

Xcode6(v6.0.1)でアーキテクチャarmv7sがはずされてしまう。

どうも、俺です。
しばらくぶりのブログです。忙しかったです。


さて、iOS8もリリースされXcodeも新たに6系が出てきました。
が、これまで通りの設定のままXcode6でビルドすると、armv7sでビルドができません。

これは、TARGETS>Build Settings>Architectures>Architecturesのデフォルトの設定にある
Standard Architectures (armv7, arm64)
が原因です。

これでは、いくらValid Architecturesにarmv7sを書いても
そのバイナリは生成されません。


対応するには、
先ほどのArchitecturesを選択し、
Other...
から「armv7s」を追加しましょう。


あとは、Valid Architecturesにarmv7sを記入しておけばOKです。


以上でぇぇぇぇぇぇす。

2014年5月22日木曜日

cocos2d-x CCSprite(テクスチャ)の軽量化

どうも、俺@仕事中です。

今日はcocos2d-xで頻繁利用するCCSprite(またはテクスチャ)の軽量化についてめも。
軽量化というのは、ファイルサイズ的な意味ではなくパフォーマンス面での軽量化という意味です。
ファイルサイズ的な意味での軽量化については最後に記します。

CCSpriteで画像生成するとけっこうなメモリを消費します。
けっこうなメモリとはどのくらいかと言うと、一般的なpng画像(24bitフルカラー)の場合、
1pxあたり4byte(赤8bit + 緑8bit + 青8bit + アルファ8bit)になります。
例えば200x200(px)のpng画像の場合、
200 x 200 x 4byte = 160000byte = 156.25KB
必要です。

なのですが、iPhoneや(ほとんどの?)Android端末で画像を処理する場合、
(2014.5.22修正 iPhoneやAndroidで実際にどのようにメモリ確保されるか不明)
利用するハードウェアによって、
画像(テクスチャ)のメモリは、2の累乗のサイズで確保されます。
どういうことかと言うと、
上の200x200サイズ画像の場合、256x256サイズとしてメモリ確保されるため、
消費メモリは
256 x 256 x 4byte = 262144byte = 256KB
になります。
なんと、これだけで約100KB無駄なメモリ領域が発生してしまいます。

500x600サイズ画像の場合は、
512 x 1024 x 4byte = 2097152byte = 2048KB
になります。
約900KB無駄なメモリ領域が。

画像を大量に使用するゲームアプリなどだと、かなり無駄なメモリが消費されてしまうことになります。


そこでこの問題の解決方法(1)として、スプライトシートを使いましょう。


スプライトシートは複数の画像をまとめて一つの画像として扱うため、
上記で述べたような無駄なメモリ領域というのを極力縮めてくれます。

次に解決方法(2)ですが、pngを出力する際に
透過を使わない → png24で出力
画像が荒くても構わない → png8で出力
という方法もあります。
png24は、24bitフルカラーで透過利用不可になります。
png8はGIFと同じ256色になります。

または、cocos2d-x側で、
    // 透過使わない
    CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGB565);
    // 減色させる(赤4bit + 緑4bit + 青4bit + アルファ4bit)
    CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA4444);
を呼び出しておく、という方法もあります。

このpng8で出力、またはkCCTexture2DPixelFormat_RGBA4444の設定は非常に効果的なのですが、画質が目に見えて荒くなるのが分かるのが残念です。
特にグラデーションは目も当てられません。

そこで、TexturePacker(基本有償)というツールを使いましょう。

有償なだけにとても高機能で、
TexturePacker上で画質を上述したRGBA4444に減色出来ます。
またすごいのが、画質が落ちた画像ファイルをディザリングという機能でキレイに加工してくれます。

例えば下の画像はRGBA8888の綺麗なままのpng画像。
※見やすいように拡大表示しています。

これをRGBA4444に画質を落とすと、
のようにグラデーション部分に荒い線が浮き出てしまいます。

これにディザリングをかけると、
のようになります。
荒いポツポツが目立ちますが、
拡大表示していることが原因で、実物サイズにすると
ほらキレイ。
目を細めてみると ほぼ元画像との違いなんて分かりません。

ちなみに、RGBA4444画質の元サイズはこちら。
うーん、、、
画像が小さいからあまり違い分からないですが、
やっぱりグラデーションが汚いです。そう思って下さい。

というわけでTexturePackerを使えば、
スプライトシートを生成できるだけでなく、画質の調整もできちゃうのでオススメです。



冒頭に書いた「ファイルサイズ的」な軽量化についてですが、
MacだとImageOptimがオススメです。

いろんなアルゴリズムを駆使して画像ファイルを圧縮し、ファイルサイズを小さくしてくれます。
ものによっては60%以上ファイルサイズが軽量化することもあります。
配布するアプリサイズが小さくなるので良いですね。
メモリへのロードも早くなるのかな?


あとは、CCSpriteBatchNodeを利用して、描画も軽量化させると見違えるほどアプリが軽くなります。

以上でぇぇぇぇぇす。

2014年5月13日火曜日

sshで "Received disconnect from xxx.xxx.xxx.xxx: 2: Too many authentication failures for" でログインできひん

どうも、俺@仕事中です。

sshでログインしようとして

$ ssh username@xxx.xxx.xxx.xxx
Received disconnect from xxx.xxx.xxx.xxx: 2: Too many authentication failures for username
が出てログイン出来ないとき。

$ ssh username@xxx.xxx.xxx.xxx -o PreferredAuthentications=password
とやればとりあえずログイン出来る、と思います。
※パスワードログインする場合

このエラーは、サーバ側のsshd_configにある
MaxAuthTries 6
の回数を超えてしまったために出るエラーです。
なので、サーバ側でこの値を増やしてsshd再起動すれば解決しますが、
無闇に増やすのはセキュリティ上多少心配です。

sshの公開鍵認証を設定していると、
数種類のサーバ向けに秘密鍵を用意する事が多いと思いますが、
そういう場合、sshが順番に鍵を使って認証していき(もちろんパスワード認証も)
その結果MaxAuthTriesを超えてしまう、
という事があるようです。
なので不要な秘密鍵を消すために、

$ ssh-add -D
を行ってから接続するのも別の解決策です。

どういう認証手順を踏んでるか確認するには、
$ ssh username@xxx.xxx.xxx.xxx -vvv
と 打てば詳細なログを出力できます。



以上でぇぇぇぇぇす。

2014年5月2日金曜日

Linuxでユーザをグループに追加する

どうも、俺@腹減ったです。

Linuxを作成したユーザを別のグループに追加したいとき。

$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka)
今はkoexukaユーザはgid=500のkoexukaグループに属している状態です。
追加してwheelグループに追加しちゃいましょう。

# gpasswd -a koexuka wheel
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka),10(wheel)
見事wheelグループに追加されました。
では、やっぱwheelグループから削除したいとき、

# gpasswd -d koexuka wheel
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka)
はい、見事にwheelグループから脱却できました。

ちなみにusermodコマンドでもグループ追加できます。
同じようにkoexukaユーザをwheelグループに追加したいときは、
# usermod -G wheel koexuka
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka),10(wheel)
のように出来ます、が!

usermodコマンドでグループに追加すると、
すでに他のグループが設定されていた場合は危険です。
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka),10(wheel)
// ↑↑グループはkoexukaとwheel

# usermod -G hogegroup koexuka
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka),502(hogegroup)

// ↑↑設定されていたwheelが消える!!
上記のようにコマンドを叩くと、すでに設定されたグループが削除されてしまいます。
なので、
# usermod -G hogegroup, wheel koexuka
$ id koexuka
uid=500(koexuka) gid=500(koexuka) groups=500(koexuka),502(hogegroup),10(wheel)
のように、属するグループを,(カンマ)ですべて指定しなければいけません。

面倒なので、つまりgpasswdコマンドを使いましょう!
という結論。


以上でぇぇえぇぇぇす。

2014年4月17日木曜日

[cocos2d-x] CCClippingNodeで画像をくり抜く

どうも、俺@もう帰るで。

今日はcocos2d-xのCCClippingNodeを使うめもめも。
※cocos2d-xはv2.1.5

先日、「スライディングフロッグ」というゲームアプリをリリースしました。
iOSはコチラ
Androidはコチラ


このゲームの結果画面で、メダルが穫れたときにメダルをキラリっと処理しているのですが、
そこでCCClippingNodeを使っています。



では、どう使うのか、サンプルコードを記していきます。

まず前処理として、iOS側ではAppController.mmの
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
メソッドを変更する必要があります。

EAGLViewインスタンスを生成する箇所を、
    EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
                                     pixelFormat: kEAGLColorFormatRGBA8
                                     depthFormat: GL_DEPTH24_STENCIL8_OES
                              preserveBackbuffer: NO
                                      sharegroup: nil
                                   multiSampling: NO
                                 numberOfSamples:0 ];
と変更します。

次に、結果画面を表示するシーン(ResultScene.cppとする)の処理です。
1)メダルSpriteを置く
CCSprite *medalSprite = CCSprite::create("medal.png");
// 適当なpositionに
medalSprite->setPosition(ccp(100, 100));
this->addChild(medalSprite);

2)光らせるSpriteを用意する
CCSprite *content = CCSprite::create("effect.png");
// 左から右へ動かすので、メダルの左側へ
content->setPosition(ccp(medalSprite->getPositionX()-medalSprite->getContentSize().width,
                         medalSprite->getPositionY()));

3)マスクする画像(メダル)を用意する
// 上記のmedalSpriteとは別に用意する
CCSprite *stencil = CCSprite::create("medal.png");
// メダルSpriteと同じpositionに
stencil->setPosition(medalSprite->getPosition());

4)CCClippingNode生成する
CCClippingNode *clippingNode = CCClippingNode::create();
clippingNode->setStencil(stencil);
// 小さい値にする
clippingNode->setAlphaThreshold(0.01f);
// 光らせるSprite
clippingNode->addChild(content);
// アンカーポイントをセットしておく
clippingNode->setAnchorPoint(ccp(0,0));
// 画面の左下へsetPosition()する
clippingNode->setPosition(ccp(0,0));
// 念のため、CCClippingNodeのサイズを画面全体に..不要?
clippingNode->setContentSize(CCSize(CCDirector::sharedDirector()->getWinSize().width,
                                    CCDirector::sharedDirector()->getWinSize().height));
this->addChild(clippingNode);

5)光らせるSpriteを左から右へ動かす
content->runAction(CCMoveBy::create(0.5f,
                                    ccp(medalSprite->getContentSize().width, 0)));

これで出来るはず(!?)です。

ちなみにAndroidの場合は、Cocos2dxActivity.javaを編集します。
    public Cocos2dxGLSurfaceView onCreateView() {
//      return new Cocos2dxGLSurfaceView(this);
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
        glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); 
        return glSurfaceView;
    } 


以上でぇぇぇぇぇす。

2014年4月5日土曜日

cocos2d-x CCLocalizedStringを使ってローカライズ対応する

どうも、俺@休み中です。

 cocos2d-x(v2.1.5)で開発したゲームアプリもローカライズ対応させよう、
ということで、 有志の方がgithubで公開しているCCLocalizedStringを使わせてもらいました。

sue602/CCLocalizedStringDemo

まず、githubからcloneしてから
CCLocalizedString.cpp/CCLocalizedString.hをドラッグ&ドロップでプロジェクトに放り込みます。

git clone https://github.com/sue602/CCLocalizedStringDemo.git

使い方はとてもシンプル。
例えば日本語圏(japan.png)・英語圏(english.png)でそれぞれ違う画像を表示させたい場合は、
表示させたいSceneで、

#include “CCLocalizedString.h”

... 中略 ...
CCSprite *someSprite = CCSprite::create(CCLocalizedString(“FILE_NAME”, “some_comment"));
とします。
第1引数(”FILE_NAME")が変換対象となるキーです。
第2引数はコメント?

次に、ローカライズ用の設定ファイルを言語ごとにResource/フォルダに用意します。
今回は日本語と英語なのでLocalized_jpとLocalized_enになります。
それぞれのファイルに、
・Localized_jp
FILE_NAME = “japan.png”;

・Localized_en
FILE_NAME = “english.png”;

のように “キー” = “値” というフォーマットで記述します。

これで端末の言語設定によって使われるファイルを切り替えられます。

ただ、このままだと日本語・英語圏以外の言語環境でアプリを起動した場合、
ファイルが見つからずにクラッシュしてしまいました。
(やり方間違えてるのかな、、)
なので、CCLocalizedString.cppを少しいじります。

    // Get data of file
    fileContents = CCFileUtils::sharedFileUtils()->getFileData( fullPath.c_str( ) , "rb", &fileSize );

    // ここから
    if (fileContents==NULL) {
        // ファイルがない場合はLocalized_enを読み込む
        fileContents = CCFileUtils::sharedFileUtils()->getFileData( "Localized_en", "rb", &fileSize );
    }
    contents.assign(fileContents,fileContents+fileSize-1);
こうしておけば、対応していない言語環境の場合は
Localized_enを読み込むことが出来ます。


以上でぇぇぇぇぇす。

2014年3月28日金曜日

Macでgitサーバを構築の巻

どうも、俺@仕事中です。
今備忘録を書かないと忘れてしまうので、サボってる訳ではありません。

僕はXcodeで開発するときにgitを使ってソース管理をしています。
標準で使えるので多くの人も使っていると思います。

gitはローカルリポジトリだけでもソース管理ができますが、
今回自分でgitサーバを立てる(共有リポジトリの作成)必要があったのでメモ。


まず、ローカルリポジトリを作成します。
これはXcodeのプロジェクトを作成する際にgitリポジトリ管理とすることで勝手にXcodeがやってくれます。

Xcodeの場合はこの手順でプロジェクト新規作成の時点で、gitのイニシャルコミットまで完了します。
内部的には
git init
git add .
git commit -m "initial commit"
まで済んでる(と思います)。


次にgitサーバを作ります。
適当な場所にサーバの公開ディレクトリとなる基底フォルダ(名前も任意)を作成します。
mkdir ~/Documents/gitserver

そしてのフォルダ内に先ほど作成したXcodeプロジェクト用のディレクトリを作成し、共有リポジトリとするためののコマンドを叩きます。
ここでは仮にプロジェクト名を「TestProject」とします。
mkdir ~/Documents/gitserver/TestProject.git
cd ~/Documents/gitserver/TestProject.git
git init --bare --shared

これで共有リポジトリが出来ました。

さて、次は外部からgitプロトコルで接続するための設定です。
まず設定ファイル(git-daemon.plist)を作成します。
cd ~/Library/LaunchAgents
vim git-daemon.plist

パスは適宜変えて下さい。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
<dict>
 <key>KeepAlive</key>
 <false>
 <key>Label</key>
 <string>git-daemon</string>
 <key>ProgramArguments
<array>
  <string>git</string>
  <string>daemon</string>
  <string>--export-all</string>
  <string>--enable=receive-pack</string>
  <string>--base-path=/Users/koexuka/Documetns/gitserver</string>
 </array>
 <key>RunAtLoad</key>
 <true>
 <key>ServiceDescription</key>
 <string>git-daemon</string>
</true></false></dict>
</plist>

kikaigyo/plist - GitHub から拝借させて頂きました。


次に、gitをデーモンとして起動させるようにします。

launchctl load -w git-daemon.plist

最後にローカルリポジトリから作成した共有リポジトリを登録します。
git remote add origin git://MY_iMac/TestProject.git

My_iMacの部分は自分のMacのIPアドレスやホスト名、またはlocalhostでOKです。


これで設定は完了しましたので、あとは別のPCから

git clone git://MY_iMac/TestProject.git
が成功すれば完了です!!!


以上でぇぇぇぇぇぇす。



2014年1月15日水曜日

Xcode cannot run using the selected device

どうも、俺です。

Xcodeでビルドしようとした際に
「Xcode cannot run using the selected device」というエラーが出てビルド出来ないあなたへ。

"Xcode cannot run using the selected device"に苦しんだ数日間 - マキシぐんだんの中の人のブログ
に同様の問題の対応方法がありますが、僕の場合は少し違いました。

Info.plistの"Target Membership"にチェックが入ってしまっていたことが原因。
チェックを外して解決しました。


以上でぇぇぇぇぇぇす。