月別アーカイブ: 2015年1月

cocos2d-x>Node 固有の値

Node は、Node オブジェクトを識別するために以下のメンバ変数を持つ

  int _tag;
  std::string _name;
  void *_userData;
  Ref *_userObject;

_tag は setTag(int), getTag() : int でアクセス可能
_name は setName(const string&), getName() : string でアクセス可能
_userData, _userObject も同様

また、getChildByTag(int), getChildByName(const string&) で子ノードの検索を行うことも出来る

 

箱入り娘データ構造例

enum {
    // ピース種別
    BLANK = 0,
    P2x2,
    P2x1,       // width = 2, height = 1
    P1x2,
    P1x1,
    MASK = 0x0f,
    F = 0x10,            // 代表点意外の場合のフラグ
    P2x2F = P2x2|F,
    P2x1F = P2x1|F,
    P1x2F = P1x2|F,
    WALL = 255,
    // 盤面サイズ
    BD_WIDTH = 4,
    BD_HEIGHT = 5,
    ARY_WIDTH = (BD_WIDTH+1),
    ARY_HEIGHT = (BD_HEIGHT+2),
    ARY_SIZE = (ARY_WIDTH*ARY_HEIGHT),

};
class Board {
    .....
private:
    byte     m_board[ARY_SIZE];};
  • 2次元盤面を番人付き1次元配列で表す
  • 1×1 以外は左上のピース位置を代表ピースとし、それ以外は非代表ピースフラグを立てておく

01/24 までの週間PV数の推移と今後の予測

temp

上図は最近12週間の本サイトのPV数の推移グラフ。
先週は 14,000PV程度を予想してたのだが、実際は 13,148PV だった。水曜・木曜のPV数が何故が少なく、それが足を引っ張った形だ。
今週こそ 14,000PVを越えて欲しいものじゃ。

temp

上図は本サイトのPV数稼ぎ頭ページたちのPV数の推移グラフ。
string, 時間計測, random らが過去最高を更新。vector も過去最高と同じPV数だった。
(プログラミング入門も「はてぶ」された時の一時的効果期間を除けば過去最高)
vector は目標の2,000PVを越えられず 1,915。5%アップで超えるので、今週はなんとかお願いしますよ。
ちなみに、(年末年始を除く)最近8週間の移動回帰分析結果の指数関数係数は 0.0345 なので、予測は +3.5% で、1,982PV だ。

temp

上図は最近追加したページの週間PV数の推移グラフだ。
クラス入門以外はすべて過去最高を記録。list, map は 339PV, 348PV で、最初の目標である 350PV/週 を今週にも達成しそうな勢いだ。
list, map の最近8週間の移動回帰分析結果の指数関数係数は 0.129, 0.198 で、前週比伸び率に換算すると +13.8%, +21.9% と非常に高い値だ。この調子なら3月中旬~下旬には次の目標である 700PV/週 を超えると予測される。

ファイヤーアルパカ>線画の一部を移動・変形してみよう

投げ縄選択と変形機能を使うと、線画の間違いを簡単に修正できるぞ。

temp

例えば、上図のように袖の先の位置が連続せずずれていることにあとで気づいた場合、その部分を消して描き直すよりも、修正したい部分を投げ縄選択し、変形モードにして移動した方が楽ちんだぞ。

temp

 

L コマンドで投げ縄選択モードにし、上図のように選択し、Ctrl + T を押して変形モードにする。
※ L コマンドが使用可能なのは ver 1.1.14 以上からだ。アップデートしていない人は直ぐにアップデートしよう!

temp

変形モードにすると、上図のように、その部分が選択されて、変形ガイドが表示される。
中央部分をドラッグすると移動することが出来る。

temp

上図のように正しい位置に移動したら、Enter を押して、変形モードを終了する。

temp

また、移動だけではなく、四隅のマーカをドラッグすると比率を保って拡大縮小、四辺のマーカをドラッグすると、その方向にのみ拡大縮小、枠の外側でドラッグすると、上図のように回転することもできるぞ。

 

ファイヤーアルパカ>投げ縄選択

今朝、ファイヤーアルパカで「投げ縄選択」を行う方法を発見して小躍りしてたのだが、1.1.14 にアップデートしたら、下図のようにツールに「投縄選択」が追加されていたでござるぞ。 ^^;;;

temp

ちなみに、以前のバージョンでは、その上の選択モードに入って、左上のドロップダウンで「投げ縄選択」を選ぶといいぞ。

 

01/17 までの週間PV数の推移と今後の予測

temp

上図は最近12週間の本サイトのPV数の推移グラフ。
先週は月曜日が祭日だったために、PV数は微減している(12,791 → 12,408)。
しかし、平日だけの平均PV数は、2,097.2 → 2,320 と、約10%も上昇している。
よって、今週は先々週の10%増しで、14,000 程度になるのではないかと期待を込めて予測している。

temp

上図は本サイトのPV数稼ぎ頭ページたちのPV数の推移グラフ。
これらも先々週とほとんど同じ程度だが、月曜日が祭日だったことを考慮すれば実質的増加だ。
vector の場合、平日のPV数平均は 342.25 にも達した。土日祭日の平均は142だ。
したがって、今週の vector PV数は 342.25*5 + 142*2 = 1995.25 以上になると予測できる。
初の 2000PV/週 を達成すると期待を込めて予測する。

temp

上図は最近追加したページたちのPV数の推移グラフだ。

 

std::set の比較関数をラムダ式で指定するには?

std::set オブジェクトに格納された要素は operator<() を使って順序付けされるので、オブジェクトのクラスでそれが定義されていないといけない。vector や、自分で作って型のオブジェクトを格納したい場合は、operator<(const T&, const T&) 関数を自分で定義するか、set の第2テンプレートパラメータに比較ファンクタを指定する。

template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

以下の様な構造体がある時、

struct Person {
  std::string m_name;
  double m_height;
};

比較ファンクタは、以下のように定義できる。

struct Compare {
  bool operator()(const Person& lhs, const Person & rhs) {
    return lhs.m_name < rhs.m_name;
  }
};

このファンクタを使えば、set オブジェクトを以下のように宣言することが出来る。

std::set<T, Compre> s;  // 比較ファンクタを指定した set オブジェクトの宣言

で、このファンクタをラムダ式で書いてみたかったのだが、うまくいかず困ってたところ、ツイッターで @9610n 氏にその方法をご教授していただいたので、忘れないよう本稿にメモしておく。

比較関数をラムダ式で書くと以下のようになる。

[](const Person &lhs, Person &rhs) { return lhs.m_name > rhs.m_name; };

で、これを set のテンプレートパラメータに指定してもエラーとなる。

std::set<Person, ラムダ式> s;  //  コンパイルエラーとなる

最初に書いた std::set の定義を見ればわかるように、テンプレートの第2引数はクラスである。しかるにラムダ式はオブジェクトなので、当然エラーとなるわけだ。

そこで、delctype(ラムダ式) を使って、型に変換?するといいのではないかと思えるが、それもエラーとなる。

std::set<Person, decltype(ラムダ式)> s;  //  コンパイルエラーとなる

というわけで、set のテンプレートパラメータに指定するのは std::function にするといいようだ。

std::set<Person, std::function<bool (const Person&, const Person&)>> s;
s.insert(Person{"abc", 170});
s.insert(Person{"xyz", 180});

が、上記コードはビルドは通るものの、実行時にエラーになってしまう。
なぜなら、比較関数の型を指定しただけで、その実体をどこにも指定していないからだ。

そうだったら、最初の方に示したファンクタの場合はなぜうまくいくのかと思われるかもしれないが、デフォルトコンストラクタの宣言をよく見ると、下記のようになっている。

explicit set (const key_compare& comp = key_compare(),
              const allocator_type& alloc = allocator_type());

デフォルトコンストラクタの第1引数は、比較関数オブジェクトで、省略した場合は、第2テンプレート引数 key_compare の operator() が呼ばれるようになっている。
だから、第2テンプレート引数にファンクタを指定した場合は、コンストラクタの引数を無しにしてもうまく行っていたのだ。

というわけで、以下のように記述するとよい、ということになる。

auto f = [](const Person &lhs, Person &rhs) { return lhs.m_name > rhs.m_name; };
std::set<Person, std::function<bool (const Person&, const Person&)>> s(f);
s.insert(Person{"abc", 170});
s.insert(Person{"xyz", 180});

※ 式が長くなりすぎるので、ラムダ式の部分は分離しておいた。

通常、ラムダ式を使うメリットは記述が簡潔でわかりやすくなる場合が多い、ということだ。だが、この記述をするくらいなら昔からあるファンクタの方が簡潔でわかりやすい気もしている。

みなさんはどう思うであろうか?

 

卵・球の影・ハイライトの付け方

おいらは、センターライト と ハイライトの区別がついていませんでした。

=====

光と影:

temp

 光と影の境界線(ターミネイター)

temp

影:

物体の面が光源方向を向いていないことによる影の部分:

temp

物体が光源からの光を遮ることによる影:

temp

 

光源が物体に近いと、床の影は大きくなる:

temp

 

物体の床を向いた部分は、床からの反射光(Reflected Light)を受け、影が薄くなる

 

temp

 

床からの反射光があるかどうかで、物体の影の濃さが違うことに注目:

temp

 

影の最も濃いい部分(Occlusion Shadow):

temp

ハーフトーン:面の明るさは、面が光源方向を向いているかどうかで決まる

temp

 

光源方向を向いた部分を Center Light と呼ぶ:

temp

光源から出た光が物体で反射し、カメラ or 目に到達する部分を Highlight と呼ぶ:

temp

Center Light と Highlight は異なるので注意!

temp

 

元動画: Shading Light and Form – Basics

cocos2d-x v3>Android admob 広告配信

“プロジェクト/proj.android/AndroidManifest.xml”: 以下の太字部分を追加

<?xml version="1.0" encoding="utf-8"?>
.....
<meta-data android:name="android.app.lib_name" android:value="cocos2dcpp" />
 <meta-data android:name="com.google.android.gms.version"
 android:value="@integer/google_play_services_version"/>
 <activity android:name="org.cocos2dx.cpp.AppActivity"
.....
</activity>
<activity android:name="com.google.android.gms.ads.AdActivity"
 android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
</application>
.....
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>

“プロジェクト/proj.android/src/src/org/cocos2dx/cpp/AppActivity.java”:以下の太字部分を追加

.....
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;

public class AppActivity extends Cocos2dxActivity {
 static AppActivity my;
 private static AdView adView;
 private final int lp = LinearLayout.LayoutParams.WRAP_CONTENT; 
 protected void onCreate(Bundle savedInstanceState){
 super.onCreate(savedInstanceState); 
 
 my = this;
 
 adView = new AdView(this);
 adView.setAdSize(AdSize.BANNER);
 adView.setAdUnitId("ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");
 
 FrameLayout.LayoutParams adParams = new FrameLayout.LayoutParams(lp,lp);
 adParams.gravity = (Gravity.BOTTOM|Gravity.CENTER); 
 addContentView(adView, adParams);
 
 AdRequest adRequest = new AdRequest.Builder().build();
 
 adView.loadAd(adRequest);
 }

eclipse でプロジェクトを開く。
何故かリンクパスが間違っているので、プロジェクトを右クリック>プロパティを開き、ビルドパスの libcocos2d の部分から \2d を削除する

temp

 

次に、プロパティダイアログで Android を選び、右下あたりの【Add】を押す

temp

“google-play^services_lib” を選び、【OK】を押す

temp