自己紹介

低層をがむしゃらに走る自称プログラマ ちょっとWebとかに手を出してる

ブログ アーカイブ

2010年6月17日木曜日

Box2D IsSensor

追記

いや、まて、嘘かも
ごめん俺嘘ついてるかも
もうちょっと調べてからいえばよかったかも
でも今調べ中、調べまくる







やっと効果の意味がわかった(今更)

簡潔に述べるのであれば

Trueならば
<物体同士の接触が発生しなくても、当たり判定の処理をする>

のだ

つまり、物体同士がぶつかっても、ぶつからなくても当たり判定の処理をする
Addだとかの処理を行う

そういうことだった

ああ、なんで今更俺はこんな重大な事に気づくかねまったく……

2010年6月8日火曜日

夏コミ受かった

サークル名:発汗プリン体
土曜日、東地区 ”W"ブロック 24a だそうです
初めての参加なのでどうなることやら…ドキドキ

と は い え

今回は、そう、BOX2Dを利用したSTGゲームを出品予定
それも、目指せ”体験版の体験版”
いわゆるα版を出品予定です。

そんなのでいいんでしょうか、
価格は未定ですが、当然お安くご提供します、
というかお金とっていいんですか?(w

笑えん

まぁ全力でおよそ二ヶ月を突き抜けます

見せられそうなところは所々見せていきたいと思ってますので
よろしくお願いします

2010年6月4日金曜日

BOX2D導入講座 1

設計的には、やや冗長的ではあるが、他の人がいじっても十分対応できる形になったな、と
なんとなく自分の中で納得する。

Box2Dを使う上での知識も、私の中ではそこそこに蓄積されてきたのではないかと思う。
C++でのBOX2Dのソースが、あまりにも不足している中で、
とりあえず入門編的な物を、このブログを通じて提供していければな、と思う

ということで、まず簡単に導入の仕方から。

1.Box2D_v2.0.1.zipを落としましょう


なぜv2.0.1かと言えば、特に理由は無いのだけど
ドキュメントが充実してるかなー、って思ったからだ。
というか更新の仕方が判らなかった、うんこ
多分上書きするだけだけど、うん…


2.VisualStudioの設定をする


わりとここが問題だったりする、というか
初心者の関門的ポジション


起動した後
ⅰ ツール->オプション->プロジェクト及びソリューション->VC++ディレクトリ(までとりあえず行く)
  ここで、インクルードファイルとライブラリファイルを設定します
ⅱ Alt+Sで青くなるポップアップ?欄からインクルードファイルを選択
  そこに、BOX2DのIncludeフォルダを指定
ⅲ 同じくライブラリを選択する
  同じようにLibraryフォルダを指定
ⅳ 今度は、プロジェクト(青い部分)を右クリックしてプロパティを開く
   (もしも出ていない場合は、Ctrl+Alt+L)
ⅴ 構成プロパティ->リンカ->入力->追加の依存ファイル
  と、その前のAlt+Cで”すべての構成”にしておいてください
  その後、追加の依存ファイルに、”Box2D.lib”とか、まぁそんな感じのものを
  入力してください。


それで準備はとりあえずOKです。
あとは使用するソースで

#include "Box2D.h"

をインクルードしてやればOKです。

とりあえず今回はこの辺で…、すんません。

2010年5月26日水曜日

当たり判定ほぼ終了


で、現在進行中なのは
Shape1と2を同じようにUserDataに持たせようと言うことであった
以下次回へすすむはず…


これで終わった前回のブログ
しかしそうはいかなかった、もっと簡単な方法があったのだった

それは

b2ContactPointをUserDataに持たせることであった!



説明しよう!!

まず、ContactListenerを継承した正式な当たり判定処理を行う
この時点で、まずは引数として渡されたb2ContactPointの”中身”を
UserDataに渡すのだ。

小言:
b2ContactPointはstruct。
UserDataにb2ContactPointを持たせたクラスを持たせている(言い方がややこしいが)


そして、UserData内で、当たり判定処理をもう一つ作っておき、

ContactListenerによる正式な当たり判定が終わった後に、
当たり判定後の”アクション処理”を書く

そのアクションの中で、UserData内にあるb2ContactPointを使うことで、
うまいこと動いてくれました

以下必要なところだけ切り出した
荒削りなので微妙かも

----------------------
CallBack.cpp(BOX2Dのb2ContactListener を継承しているクラス)
----------------------

<他の判定処理も同じような事をしてるので省略>
void CCallBack::Add(const b2ContactPoint* point)
{
//UserDataをとってきます
CInfomation* info = static_cast(point->shape1->GetBody()->GetUserData());
   //UserDataに引数を渡す(CInfomation.hで記述)
info->setCP(point);
//当たり判定の種類を渡す
info->setHit( info->e_HIT_ADD );

//当たった物体両方に同じように渡すため、もうひとつのBodyが持つUserDataに同じことをする
info = static_cast(point->shape2->GetBody()->GetUserData());

info->setCP(point);
info->setHit( info->e_HIT_ADD);

}
-----------------
CInfomation.h(UserDataに格納するクラス)
-----------------

class CInfomation
{
private:

       //当たり判定関係 uint8 _uint_hit; //当たり判定状況ビット b2ContactPoint* const _struct_hit; //当たった際必要な情報をまとめている

<偽の当たり判定処理>
<継承先で処理は定義するようになっている>
//相手に「当たった時」呼ばれる
virtual void add(const b2ContactPoint* point) = 0;
//相手に「当たっている時」呼ばれる
virtual void persist(const b2ContactPoint* point) = 0;
//相手に「当たっていた状態から離れた時」呼ばれる
virtual void remove(const b2ContactPoint* point) = 0;


public:

//当たり判定
inline void setHit(uint8 flag) {_uint_hit  = flag;}
inline void setCP(const b2ContactPoint* cp)<これが自分のとこを入れかえてる>
{
_struct_hit->friction = cp->friction;
_struct_hit->id = cp->id;
_struct_hit->normal = cp->normal;
_struct_hit->position = cp->position;
_struct_hit->restitution = cp->restitution;
_struct_hit->separation = cp->separation;
_struct_hit->shape1 = cp->shape1;
_struct_hit->shape2 = cp->shape2;
_struct_hit->velocity = cp->velocity;
}

//オブジェクトを進行させる
void Update();
}

---------------------
CInfomation.cpp
---------------------

<当たり判定以外は省略>
void CInfomation::Update()
{
//当たり判定処理
//CCallBackクラスによって設定されたフラグで、処理が変化
switch(_uint_hit)
{

case(e_HIT_ADD): add(_struct_hit);
_uint_hit = this->e_HIT_NOHIT;
break;
case(e_HIT_PERSIST):persist(_struct_hit);
_uint_hit = this->e_HIT_NOHIT;
break;
case(e_HIT_REMOVE): remove(_struct_hit);
_uint_hit = this->e_HIT_NOHIT;
break;
default:
break;
}
}

第2の問題

当たり判定の問題

結構カオスです当たり判定
あの手この手で、一応前に進んでいる感じはある。


BOX2Dで用意されてる処理は、簡単にまとめるとこんな感じです


当たった処理

当たっている間の処理

離れた時の処理

この三つを行ってる
この判定は、b2ContactListener
によって行われる

見てもらえればわかるだろうが、引数として(b2ContactPoint *point)
が渡されている。

ちなみに、当たり判定の処理中は
B2Body内でのオブジェクトの生成が不可能になる
ようするに、CreateBody等の処理が不可能になるのである

よって

大きい敵に、弾が当たった瞬間、小さい敵を吹き出すなんて処理は、
当たり判定処理とは別のところで行う必要があるわけだ

そこで、まず、三種の内、どの当たり判定が行われたかどうか、というフラグ作り
それぞれのフラグに応じて、独自の当たり判定後処理を行うようにした。

次に、b2ContactPointをUserData内に保持させて、それを当たり判定後処理に使わせようとしたのだ

が

実際やってみたところ、これでは問題があるということが判明した

Shape1と2が消えている^p^
つまりNULLというか、不定値になっているのだ、ぐぇgヵ

死ね

―――――


で、現在進行中なのは
Shape1と2を同じようにUserDataに持たせようと言うことであった
以下次回へすすむはず…

結果

以外と簡単にできたみたい

結局行ったことは、

BOX2Dに送るデータを全て定数分で割って
描画する時全部定数で掛ける

解決!!111

2010年5月22日土曜日

今更だが

Box2Dは、本来は 10m以上の物体を作ってはいけない(正確には、つくるべきではない)
そこで悩むのは、 1cmの物体を作り、 画面上に100pixelで表示する方法だ(当たり判定も100pixel)

描画だけなら、単純に1を100倍するだけで済むので簡単なのだが
当たり判定はどうしようもない

当たり判定の処理は、BOX2Dが行っているからだ


BOX2Dのサンプルの場合は
OpenGLのViewPortを使っているらしい、射影ということなので
実際は1cmと小さくとも、画面解像度まで射影すれば、そりゃでかくもなるという話だ

DirectXにも、同じような機能があるようだ
しかし、現状私はDXライブラリに頼りきりで、3Dに関する知識も乏しい

また少し、頭を悩ませながら、ググリまくる事になりそうだ……