BLOGワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。リニューアルします!デベロッパーブログとしては最後のエントリーを担当するCTO村田です。2016年7月からはじめた「デベロッパーブログ」ですが、本エントリーをもちまして更新を停止いたします。デベロッパーブログは閉鎖しませんので、今まで掲載した記事はこれからもご覧いただけます。Blog」をご覧ください。引き続き、よろしくお願いいたします。デザインクラッシュフィーバーのUIやエフェクトを担当している伊藤です。クラッシュフィーバーではUIやエフェクトを作る際、CocosBuilderを使用していますが、ウェブでtipsを探すとあまり初心者向けの記事が見当たりません...そこで、CocosBuilderの基本的な機能の備忘を簡単に紹介したいと思います。CocosBuilderのインターフェイス1プロジェクト内のリソースファイル一覧.ccbファイルをダブルクリックで開くと作業ウィンドウで編集できます。2作業ウィンドウUIの組み立てを行う作業ウィンドウです。3パラメータ設定ウィンドウパラメータを変更することができます。▼基本的なCCNode設定画面(フォントやFXなどの設定をする場合は、別途パラメータが設定が表示されます。)表示のチェックボックス:画像の表示非表示ができます。位置:画像の基点を基準指定できます。サイズ:画像オブジェクトやNodeのサイズを指定できます。アンカーポイント:基点の位置を指定します。0.5にすると画像の中心が基点となります。スケール:拡大縮小です。中心の鍵マークをオンにすると比率が固定になります。スキュー:画像を斜めに変形できます。4タイムライン追加したSpriteやNodeが表示されます。下のレイヤーに行くほど、ビューで手前に表示されます。タイムラインでは、追加したSpriteやNodeレイヤーにアニメーションをつけることが出来ます。動かしたい位置まで移動させて以下のキーを押すと、位置やスケールにアニメーションキーが追加されます。表示:V位置:Pスケール:S回転:R透明度:Oカラー:C(もしくは、追加したいタイミングにalt+左クリックで直接キーを追加できます。)5作業ウィンドウのズーム14の作業ウィンドウをズームできます。「=」を押すとリセットされます。6パネルの表示切り替え13、15、18のウィンドウの表示、非表示を切り替えられます。7Nodeの追加CCNodeを追加します。アニメーションを付ける場合、複数あるレイヤーを纏めて動かしたいときなどに使います。平面レイヤーをつくれます。左からCCLayer、CCLayerColor、CCLayerGradient、CCScrollView。画像オブジェクトの追加が出来ます。ボタン左がCCSprite、右がCCScale9Spriteです。◆CCSprite:通常の画像追加。frameで追加したい画像を選択します。opacityで透明度の指定、Colorで色を付けられます。(CocosBuilderでは画像の白い部分に色が付きます。)▼CCSpriteの設定画面Blendでは加算や減算などの合成モードを選択できます。詳しく知りたい方は下記記事を参照下さい。developer.wonderpla.net◆CCScale9Sprite:9Sprite画像の追加。画像を任意のサイズに引き伸ばすことができます。sizeとInsetsの値を設定します。size:オブジェクトの幅、高さを指定します。・insets:オブジェクトの一部分を固定し、伸ばしたくない部分を指定します。全体の横幅が540pxに伸ばす設定しています。10ラベルの追加テキストの追加ができます。ボタン左がCCLabelTTF、右がCCLabelBMFontです。◆CCLabelTTF:システムフォントを追加できます。size:文字サイズを指定opacity:不透明度color:文字の色Dimensions:文字が入る領域を指定しますblemd:合成モード選択LabelText:表示するテキストを入れます◆CCScale9Sprite:ビットマップフォントを追加できます。手書き文字のビットマップフォントの文字サイズはスケールで指定します。ビットマップフォントの作り方は下記事にて紹介されておりますので、ご興味があればご確認下さい。※1112に関しては殆ど使用していないため割愛致します。13FXの追加エフェクトを追加できます。Textureで画像オブジェクトを指定すればエフェクトが簡単に作れます。クラフィではParticleDesignerというツールを使用してParticleエフェクトを作成しているので殆ど使っていない機能ですが、簡単なFXであればかなりお手軽に作れます。別のccbファイルを配置することが事ができます。15プラグインの追加CCAddSprite:スプライトの追加ができます。CCCameraNode:カメラを配置できますCCParticleSystemQuadForCCB:plistの追加ができますUISpriteButton:ボタンを作ることができます。ここはほぼ使用していないため、詳しい説明は省きますが、カメラ位置(視点)の指定や、他のツールを使用して作成したパーティクル(.plist)を追加できます。16表示ウィンドタブ現在開いているccbファイルの一覧です。17タイムラインの再生・停止タイムラインのアニメーションを再生できます。18タイムラインの拡大縮小タイムラインの拡大縮小し、見やすい長さに調整します。下部分をクリックするとタイムラインの長さを変更出来ます。クリックすると長さ指定を行うウィンドウが表示されるので、アニメーションの尺に合わせてタイムラインの長さを変更できます。ーーーーーこの記事が、Cocosを使用する方や、これから使用する方の助けになれば幸いです。I/OでDaydreamについての発表がありました。Previewというデバッグに便利なツールを使ってみたので、今回はそれがどんなものか紹介します。editorで実行すれば、USBで接続したAndroid端末で即実行できるのでデバッグが超便利。ビルドしてアプリに転送しなくても良いのでトライ&エラーがやりやすくなります。UnityをダウンロードしてUnity上でDaydreamが使えるようにしましょう。Previewを利用するには端末側にも専用のアプリをインストールします。USBケーブルでPCに端末を接続し、ターミナルで下記のコマンドでインストールします。SDKのバージョンによって異なるパッケージが用意されています。ここでは最新版のSDKを利用しているので「InstantPreviewForGVRUnitySDKv1.50.0.unitypackage」を使用します。「InstantPreview」フォルダの中に「GvrInstantPreviewMain」というプレハブがインポートされます。これをHierarchyの一番上の階層に配置します。Previewの準備完了です。Previewのアプリをインストールした端末とPCを接続し、Unityの実行ボタンを押しましょう。mode」を選択します。すると、Unity上の画面が端末に反映され、端末の動きに応じて画面がぐるぐる動くようになります。ビルドの時間を待つ必要が無いのでこれでトライ&エラーがやりやすくなりますね。FPSは遅いので、パフォーマンスの確認は実際にアプリにインストールして確認する必要があります。端末の向きに合わせてカメラも動きます。これで端末に画面を表示しながらエディター側で調整作業をすることができます。上の動画ではこのモードで実行しています。名前の通り、コントローラーのみがエディター上で使えるようになります。カメラの向きは動かすことができません。Preview以外にもいくつかのツール類が発表されており、GoogleがVRコンテンツの開発をしやすくなるように力を入れていることがうかがえます。これから開発者向けのツールも、Daydream対応端末も増えてくると思います。Daydreamはまだ日本国内では発売していませんが、いつか発売されることを期待して待っていたいですね。良いソフトウェアとは何か。顧客満足を実現するアプリケーション?不具合がないソフトウェア?難しい質問だと思っておりますが、概して機能の拡張や変更が容易でバグが発生しにくいことに纏められると思います。ソフトウェア開発方法論は開発者がより短い時間で様々な機能を少ないミスで開発できるように発展してきました。今回はオブジェクト指向の五大原則と言われているSOLIDについて話してみましょう。必要なコンセプトだと行っても無理ではないと思います。job.上記の言葉を直訳すると「クラスはただ一つの理由で変更すべきだ。クラスは一つの機能だけを持っているようにすること。SRP原則を適用すれば責任領域が明確になりますので、一つの責任を変更することが次々と他の責任の変更になり続ける連鎖作用を防止できます。責任を適切に分配することにより、コードの可読性の向上,メインテナンスに容易という利点があります。それに加えSRP原則は次回紹介するOCP原則を適用する基盤となっています。活用の例リファクタリング(Refactoring)を要求する問題はこのSRP原則を考えていないことで発生する場合が多いです。一つの変更に複数な変更が行ってしまうことをいいます。stringNum」はギターのタイプによって変更が多い部分だと思います。serialNumber)あるいはクラス全体を修正しなければならないようになってしまいます。SRP原則を考えてリファクタリングしてみましょう。...}上記のように変更が発生した部分を新しいクラスに分けて処理したことが確認できます。まとめクラスは一つのサービスに一つの責任を持たせて、名前はその内容を明確に表すように作成した方は良いと思っております。単純に責任で区別することではなくて各機能の凝集力(cohesion)を考慮し、最初からオブジェクトの間にデカップリング(decoupling)する手間が掛かないようにした方が良いですね。今回は実際にソケットのプログラミングをしてみたいと思っています。目標ですが、TCPプロトコルで簡単なクライアントとサーバを作成し、ソケットのシステムコールの使い方を覚えたいと思います。NAT超えをしてみよう(P2P通信)」にて説明する予定です。今回の流れとして、一旦はシステムコールの呼び出しを一連の流れで実装します。それから、もう少し細かい設定をしていき、最終的にはライブラリ化を行いたいと思います。このライブラリを使い、次回は簡単なチャットのクライアント・サーバを作成する予定です。今回作成するのは、クライアントからサーバへ文字列を送れば、サーバからは少し加工した文字列を返してくれる簡単なものとします。今回はシステムコールを覚えることに目的があるためです。}socketは、システムコールです。引数PF_INETはipv4のIPプロトコルです。第二引数はSOCK_STREAMの場合はTCPになります。PF_INETとSOCK_STREAMを組み合わせることで、このディスクリプターはTCP/IPプロトコル上で動作することになります。inet_addrはxxx.xxx.xxx.xxxの文字列をビッグエンディアン(ネットワークバイトオーダー)の32ビットに変換する。サーバにコネクトを行う。この関数はブロック型である。コネクトのタイムアウトはデバイスドライバーの実装によって違う。このタイムアウト値の設定もくせものでOSによっては設定ができない。ライブラリにまとめる際のコードを参考にして欲しい。sockaddrのキャストだが、sockの第一引数に何を指定しているかで指定される構造体が違うためにキャストすることになる。現代のソフトウェア工学的には気持ち悪い実装かも知れないが、connectがシステムコールである故にやむを得ないところがある。実際にはsendで転送するのがオススメだが、ファイルの扱いと似ているので、理解のためにwriteで転送している。実際にはネットワークデバイスではread/writeのインタフェースを持っている。第二引数はデータのポインターで、第3の引数はデータのサイズである。Terminateの1byteである。}サーバからデータの受信sockに対して何もしなければ、read/recv関数は受信終了までブロックする。サーバからクライアントに1MByteのデータを送信した際に1MByteを全て受信するまでブロックするわけではない。read/recvするタイミングで受信した分までかサイズに指定している分ーーサンプルでは1024ーーまで読み込むことになる。実際に全て受信しきれてない場合は、ループで回りながら受信することになるが、この事に関しては次回もう少し詳しく説明を行う。今のところでは、以下のような形でデータを受信するという感じをつかめて欲しい。close(sock);これらの実装はgitのレポジトリーにまとめていますので、参考にしてください。ver1今度はサーバのサンプルです。流れは、TCP/IP用のディスクリプター生成します。ポート番号とディスクリプターを結びつけます。listenディスクリプターをTCPハンドジェーク用に待ち状態にします。acceptクライアントと確立した接続からクライアントへのディスクリプターを生成します。データのやり取りTCP/IP用のディスクリプターの生成に関してはクライアントと同じです。bind基本的にディスクリプターとポート番号を結びつけます。クライアントも本当はbindすべきですが、クライアントが特定のポートで待ち受けることをしないので、connect関数の中で空いているデフォルトのポート番号を割り当てています。待ち受けるポート番号。ポートが解放されず、バインドされないケースもある。テスト時はプロセスが落ちたりするので、ポートが解放されない場合がある。handshakingを意味します。Wikipedia実際にはTCPのヘッダーのみのやり取りを3回繰り返す事になります。handshakingはデバイスの中で、connectするクライアント側とlisten状態のサーバで行う事になります。クライアントの説明で、connectのタイムアウト処理を行うのはやや複雑になると話したのはそういう意味です。listenの第二引数はbacklogである。筆者がソケットプログラミングを始めた頃では接続がまだ確立されていない状態のクライアントの接続のキューの数だったが、最近は接続確立済みのキューの数になっているようだ。以下の10では、クライアントのコネクション待ち状態は最大10コネクションになり、11番目のコネクションからはコネクトエラーになる。success!!!\n");accept確立したコネクションからディスクリプターを生成します。この生成されたディスクリプターへ書き込むと実際にクライアント側にデータが送信されます。ディスクリプターに対して何もしなければ、acceptはブロック型関数になります。ディスクリプターsockは、クライアントの待ち受け状態になっている。listenがブロックして待っているわけではない。acceptでブロックして待つことになる。connectとbindと引数の指定の仕方が少し違うのに注目。acceptが成功した場合、accept_addrにはクライアントのipアドレスやポート番号などの値が入ってくる。}実行してみよう一旦、これでクライアントとサーバができました。以下のレポジトリーをcloneします。git@github.com:dongho-yoo/network_programming.git/chapter-2/samle1sample1のディレクトリで、makeコマンドを実行します。makeするとclientとserverの実行ファイルが生成されます。&クライアントを実行します。quit別のマシーンで、サーバを立ち上げてテストしてもOKです。サーバ側のファイアウォール設定でサーバに指定したポートが開いていないといけません。ここまでで、流れは単純な通信を行う流れです。read/recv時のタイムアウト処理が入っていません。このような場合、よく使われるのはシステムコールのselectです。selectシステムコールのプロトタイプは以下のとおりです。timeout);第一引数:設定しているディスクリプターの最大値+1が入ります。第四引数:ディスクリプターがエラーになっているかどうかのチェックをするディスクリプターのリストだが、実際に使うシチュエーションがあまりない。第五引数:タイムアウト値の設定。このFD_で始まるマクロに注目。実は、OSによってselectの実装が異なるために、fd_setという構造体の型もバラバラである。そのためにFD_で始まるマクロを利用し、使い方を統一している。以下のマクロはfdzにディスクリプターを設定する。実際には複数のディスクリプターを設定できて、どのディスクリプターからの受信したのかが分かるようになる。この際に設定できるディスクリプターのタイプだが、ソケット以外にもselect対応のデバイスは全て一緒に設定できる。fdzにディスクリプターを設定します。複数ある場合は複数指定できます。場合は、ディスクリプターの不正とみなして良い。こんな感じで、どのディスクリプターに受信されたかをチェックできる。このプログラムでは、sockしかないので無意味ではあるが。}あとは、サーバの処理が多い場合、処理中の別の接続を受け付けることが出来ないので、別のスレッドで分岐するようにします。サーバの分岐acceptしたあと、サンプル1のようにクライアントの受信待ちになると次のacceptができない。selectを使って、listen用のディスクリプターとクライアント用のディスクリプターを両方設定すれば、接続の対応とクライアントの処理を両方行うことはできるが、クライアントの数が多かったり、処理そのものが多かったりすると接続処理に回るまで時間がかかる。accept後はスレッドか子プロセスに分岐するのが一般的である。カーネルからするとスレッドとプロセスはジョブとしては大した差はない。スレッドとプロセスの大きな違いはメモリ空間を共有するかであり、スレッドはメモリ空間を共有しているために、メモリ関係のエラーになった場合プロセスごと強制終了ーーカーネルからプロセスを削除ーーされる。子プロセスは親プロセスを複製しているので、子プロセスがメモリを壊しても親プロセスとは関係ないために子プロセスだけジョブから削除される。故にサーバプログラミングは子プロセスを使うとサーバがダウンすることはかなり少なくなる。*1ただし、forkは親プロセスのメモリ空間を複製するために生成にオーバーヘッドがかかるのとメモリの使用率が非常に高くなるので、サーバの目的によって、どのように分岐させるかを工夫すべきである。サンプルでは、スレッドで分岐している。}ここまでのサンプルは、以下のレポジトリーにあります。実行方法はサンプル1と同じです。git@github.com:dongho-yoo/network_programming.git/chapter-2/samle2説明したものをまとめてライブラリ化します。TCP/IPに特化したライブラリにします。することでネットワークプログラミングがしやすくなります。ライブラリにまとめる際に少し細かい設定などを行なっていますので、ソースを参考にしてください。サンプル2との違いは、connectの非同期処理でタイムアウトができるようにしたり、send時のSIGPIPE対応などが入っています。実はソケットプログラミングはこのような細かな処理を行うのが大変かもしれませんが、ライブラリとしてまとめておけば、そこからは気にすることはありません。一度に読み込むバッファーのサイズ。システムによって最適な値がある。これは実証値を使うべきだが、一旦4KBytesで。