あめにっき - (2006/01/29 (日) 02:33:34) の1つ前との変更点
追加された行は緑色になります。
削除された行は赤色になります。
なるたけ多めに更新するようがんがります。そーすつきで。
スクリーンショット入れたいんだがなぁ。
これのためにソースの整理をする決意ができたので、それだけで満足だ
ライセンスは良く判りませんが、煮るなり焼くなり(ry
とりあえず、思いついたことをドカドカ書いていくので、興味あるところはリクエストしてくださったら、もちっとマシな解説を考えます。
----
*OOなんて嫌いだ?
ヘルのチャットで8086さんと話をしていた結果、なんかワタシOOの機能を殆ど使ってないことが判ったよ。(実際は故あってOOの機能を使うのを止めた)
クラス作る意味ないのかなぁ・・・
今日、メモリリークを幾つか潰しました。つか、以前も同じトコで悩んでたことがあったので、備忘録で残しておきます。
そんなわけで、タダでさえ誰も読まない系のページなのに、OOの話とかしてひとりよがりしてみるのです。
とりあえず継承関係のクラスを作ったわけです。
>class oya{ oya(); ~oya();};
>
>class kodomo : public oya{ kodomo(); ~kodomo();};
kodomoクラスでは、コンストラクタでnew、デストラクタでdeleteしてたりなわけです。
で、ある日こんなことを
>oya* = pOya;
>
>pOya = new kodomo;
当然、生成時にコンストラクタkodomo()が呼び出されます。
で、使い終わったのでポインタをdeleteしました。
>delete pOya;
なので、kodomoは消え去ったつもりだったのですが、
実はoyaポインタに対してデリートしたので、実体がkodomoでも
呼び出されるデストラクタは~oya()だったのでした。
で、kodomoで使ったデータがdeleteされることは無く、
メモリリークとなったのでありましたとさ。めでたし、めでたし。
うぇーい。
この項おわり
----
*担詠嘆 担詠嘆 担詠~(060125)
今日ソースを見てたらバグだらけ~。急いで作ったからな。つうことで、バグを見つける間違い探しなんだよ!
修正する時間が無いので、とりあえずアークタンジェント関数。サインとコレがあれば大抵のことは出来るでショ。多分。
タンジェントは-90度から+90度の間で単調増加(って云うんだっけ?)なんで、入力のタンジェント値とテーブルのタンジェント値を比較した大小で走査すれば求める角度が得られる。
因みに、タンジェントの値はsin()/cos()で求まります。理由は…sinとcosの定義を調べてみてね。
&ref (tan.png)
ので、2分探索って云うよく知られるアルゴリズムで求めてます。これなら、4096だったら12手で必ず解が求まります。理由は4096=2の12乗だから。
>(sin.h)
>二分探索でアークタンジェントを求める
>alpha = 1023;
>beta = -1023;
>
>for(i=0;i<12;i++)
>{
> ctr = (alpha + beta) / 2;
>
> if( (Sin4096(ctr)<<15)/Cos4096(ctr) >= ((y<<15)/x) )
> {
> alpha = ctr;
> }
> else
> {
> beta = ctr;
> }
>}
>return alpha + delta;
ところで、純粋なタンジェントの値からだけだと、2つの角度が求まってしまいます(0~360度の範囲では)。なので、xとyの符号を見て場合わけします。なので、自作アークタンジェントの入力はxとyの2つです。
>if( x > 0 )
>{
> delta = 0;
>}
>else if( x < 0 )
>{
> delta = 2048;
>}
>else // ( x==0 )
>{
> if( y > 0 )
> return 1024;
> else
> return 3072;
>}
因みに、90度と270度の時はタンジェントは無限大になってしまうので、そこも場合わけしてあげやう(ホントの理由は違うんだけど
やっぱサンプルは以前のやつで。
この項おわり
----
*自機に弾を向ける(060124)
自機に向いた角度を取得するには?
そんなときはアークタンジェント。なんかつよそうですね。
アークタンジェントは、タンジェントの値、y/xを与えると、その角度を返す関数です。
なんで、弾の発射元のx座標と自機のx座標の差、元のy座標と自機のy座標の差をアークタンジェントに食べさせればOK。
&ref (atan.png)
サンプルboss.cの18行目
>AddTama( 320<<16, 100<<16, Atan4096( (GetPlayerX()>>16)-320, (GetPlayerY()>>16)-100 ) );
これでOK。自作のアークタンジェント関数の精度がイマイチで、
入力は65536未満?じゃないと駄目かも。
>AddTama( int x, int y, int Angle );
これは(x,y)に角度Angleの弾を発生させる関数ですよ。
>GetPlayerX();
>GetPlayerY();
これはプレイヤのx座標、y座標を返す関数。
サンプルはやっぱり昨日のやつ。
この項おわり
----
*とりあえず弾(060124)
とりあえず弾を飛ばす。
速さR、角度θで弾が飛ぶときはx軸y軸それぞれの成分は
&ref (vector.png)
>Vx = Rcosθ
>Vy = Rsinθ
であるから、
サンプルのTama.cの45,46行目
>Tama_x[i]=Tama_x[i]+TAMA_SPEED*Cos4096( Tama_Angle[i] );
>Tama_y[i]=Tama_y[i]+TAMA_SPEED*Sin4096( Tama_Angle[i] );
tama_x[i]ってのは、沢山ある弾のうち、i番目の弾のx座標。
つまり、ある特定の弾に対して考えると
>x = x + SPEED * COS( Angle );
>y = y + SPEED * sin( Angle );
これで速さSPEED、角度Angleで弾が飛ぶよ。
ワタシの作ったサインとかだと、
画面右が+x、画面下が+yの座標になってるので、
右が0度で時計回りに角度が増えてゆくことに注意。
サンプルは前回(060123)のやつをみてね。
この項おわり
----
*自機狙い弾とか(060123)
取り敢えずサンプルをつくった。
解説事項が多すぎるので、解説はまた今度。
斜めブーストも修正しないとなw
&ref (sam.JPG)
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/new.lzh
この項おわり
----
*サインちゃん(060122)
友人にこのページを読んでもらったら、訳判らん意味不明とか云われました。
おーのー。
確かに意味不明文章だけど、頑張ってソースにコメント打ったりしてんねんけどなぁ。。。
で、サインウェーブです。
ゲームやってたらどこもかしこもサインちゃん。
サインに非ずんばゲームに非ず、と。
よくわからんけど、サインはマクローリン展開だがテイラー展開だか出来るんですって。
>sin(x) = x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + …
>cos(x) = 1 - (x^2)/(2!) + (x^4)/(4!) - (x^6)/(6!) + …
ここでxはラジアンだから注意だよ。ラジアンってのは1周を2Π(円周率)で表す角度の単位だよ。
なので、素直に代入してみましょう。
>Θ:求める角度(4096で1周)
>x = (1608*Θ) / 4096; //角度>ラジアンに変換 (2*PI*i/4096)*256 (256は65536固定小数にするため)
>
>COS = 65536 //1項目
> - (x*x/2) //2項目
> + (x*x/2/256*x/3/256*x/4) //3項目
> - (x*x/2/256*x/3/256*x/4/256*x/5/256*x/6) //4項目
> ;//終わり
無限に足すのは出来ないので、飽きたところで終了。
4項くらい足しておけば十分っぽいです。
↓Cの<math.h>のsin()との誤差をプロットしてみた
http://www7a.biglobe.ne.jp/~root-ame/src/sin.JPG
なんで4096を1周にしてるかと云うと、昔偉いひとにそれがいいって云われたからだよ。
よくわかんないけど、いい数字なんですって。
で、求めたサインを4096要素の配列に代入しましょう。
>for(i=0;i<1024;i++)
>{
>x = (1608*i) / 4096; //角度>ラジアンに変換 (2*PI*i/4096)*256 (256は65536固定小数にするため)
>
>tmp= 65536 //1項目
> - (x*x/2) //2項目
> + (x*x/2/256*x/3/256*x/4) //3項目
> - (x*x/2/256*x/3/256*x/4/256*x/5/256*x/6) //4項目
> ;
>
>SIN4096[1024-i] = tmp; // 0~ 90度
>SIN4096[i+1024] = tmp; // 90~180度
>SIN4096[3072-i] = -tmp; //180~270度
>SIN4096[i+3072] = -tmp; //270~360度
>}
展開式はxが大きくなるほど誤差が大きくなるので、
4分周だけ求めてあとは使いまわすんですって。
生活の知恵ですよね。
>int SIN4096(int s )
>{
>return SIN4096[(s+4096)%4096];
>}
>
>int COS4096(int s )
>{
>return SIN4096[(s+4096+1024)%4096];
>}
使うときはこんな感じでどうぞ。
COSは90度足すだけでいいからお徳ですよね。
やっほーい。
どうでしたか、わけわからんですか。わけわからんですね。
うぇーい。
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/sin.lzh
-参考文献
S.Programs NET/小さなねた/10bit 精度の sin テーブル
http://sprocket.babyblue.jp/html/hsp_koneta.htm
大変参考にさせていただきました。実はワタクシもよく判ってない。もしかしたらもっと精度を上げられるのかもしれんが、力尽きました。
暁のコード部屋(第10回)sin/cosに苦しむ
http://www.aya.or.jp/~sanami/peace/memorial/code1-10.html#CODE10
最近になってようやくじわじわ理解できるようになってきましたわー。シュゴー
この項おわり
----
*次回予告(060118)
ネタはあれども、ソース書く暇が無いと云う。うぇーい。今はキャラ管理クラスとか書いてますよ。
次は三角関数にしようと思うのですよ。例によってさ~さんの受け売りで4096分周のテーブルでな。
ネッツで調べたらアークタンジェントの出し方もあったよ。
ほうほう結局はテーブルから探索ですか。なるへそ。
そんな感じで。
今日のおまけ
僕愛用のサインテーブル
http://www7a.biglobe.ne.jp/~root-ame/src/sin4096.h
この項おわり
----
*固定小数のススメ(060116)
今日は寝不足で電車の中で爆睡してたので、ソース書いてません。いきなりネタがありません(笑)ので、以前書いた文章をペタリ。
ゲーム中の数式計算なんて大体正しければいいのですが、流石に整数だけでは辛いので、小数を使いましょう。
小数っつうとCで云うfloat型とかの浮動小数を使えばいいですが、通ぶって固定小数でいきましょう。
-かんがえかた
「固定小数点型なんてCじゃサポートしてないよう」だなんて泣くことはなくて、10000を基準に考えて
十分の一の1000を0.1だと思い込んで使えば無問題。
-つかいかた
値を代入するときにはリアル数字(人間様が認識してる数)に10000とか決められた数を掛けてやるだけ。
で、実際に使用する際(例えば画面上の座標にするとき)に10000で割るだけ。
>int x,y; /* 座標 */
>
>x = 5 * 10000; /* 固定小数への変換 */
>y = 10 * 10000; /* 固定小数への変換 */
>
>
>/* 値をアレコレ */
>x = x + 15000; /* xに1.5(リアル数字)を足す */
>x = x + 27000; /* xに2.7を足す */
>
>/* 実際に値を使う */
>DRAW( x/10000, y/10000 ); /* DRAW:架空の関数 */
先ずはxを50000で初期化。そのあとxに15000を足してみて65000に。もいっちょオマケで92000に。
で、実際に画面表示とかに使われるときは10000で割って9。5 + 1.5 + 2.7 = 9.2。
ドット以下は表示できないので、切捨てでおっけ。そんな感じ。
通は乗除する数を65536にすると素敵。ゲームとかだと2のべき乗で掛けたり割ったりすることが多い(→65536だと誤差が生じない)ので便利だし、ビットシフトで計算すれば高速(だと思う)だし。
>int x,y;
>
>x = 5 * 65536; /* 固定小数への変換 */
>y = (10<<16); /* これでも同じ */
>
>DRAW( (x>>16), (y>>16) );
注意としては、Cだとビットシフトの優先順位はびっくりするぐらい弱いので、嫌っていうほど括弧をつけるクセをつける必要があることか。
-注意
乗除算を行う時はちょと注意が必要。(hoge*10000) * (foo*10000) = (hoge*foo)*100000000になってしまうのでー。
>int hoge, foo, bar;
>
>/* 変換~ */
>hoge = (3*10000);
>foo = (5*10000);
>
>bar = hoge * foo; /* NGggggggggggggg */
>bar = (hoge/100) * (foo/100); /* OKkkkkkkkkkk */
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/kotei.zip
カーソル右で加速。カーソル左で減速。なめらかな加減速を体感しやう。
例によってyaneuraoさんのYGS2Kの実行ファイルが置いてあったり。
-参考文献
暁のコード部屋(第22回)固定小数点における正しい乗算
http://www.aya.or.jp/%7Esanami/peace/memorial/code21-30.html#CODE22
つか、受け売りを実行してるだけなので、さっさとこちらのページにいっときましょう。
この項おわり
----
*最近の開発
丼さんがエロSTGつくれと仰るので開発に着手。
縦STGから横STGに仕様変更。
理由は聞かないでください。
その後
波紋効果を入れてみた。
何らかの形で自機の位置を知らせるフィーチャーは必要だと
思ってみたから。
ステージスタート時の演出とカスリ時に
波紋を出したらいいんじゃね?
適当なサイトから適当なソースをぶっこ抜いてくる。
zキーでオーバードライヴ
結果:いい感じ
ダガシカシ
ワタクシの絵づらから鑑みるに
パステル調とかの方がよい気がしてきた。
半透明とか加減算のエフェクトは合わない気がしる。
ワタクシの1ヶ月は徒労に終わる。
この項おわり
----
やっぱり米欄つくってみた
- この項おわりでうけた。&br()すまんす。ぜんぜん役に立たぬコメントで。 -- D.K (2006-01-16 22:55:13)
#comment(vsize=2,nsize=20,size=40)
----
*ソースファイル
http://www7a.biglobe.ne.jp/~root-ame/bin/ero_src_fluu0116.lzh
(1MBくらい)
VC6とDirectXSDK8以降があればコンパイルできると思いたい。
実行ファイルも入ってるので多い日も安心。
yaneuraoさんのYaneuraoGameSdk2ndを改悪したモノが混入されてますが、
ダウソ即コンパイルできるやうに敢えて置いておきました。
そんな感じで。
なるたけ多めに更新するようがんがります。そーすつきで。
スクリーンショット入れたいんだがなぁ。
これのためにソースの整理をする決意ができたので、それだけで満足だ
ライセンスは良く判りませんが、煮るなり焼くなり(ry
とりあえず、思いついたことをドカドカ書いていくので、興味あるところはリクエストしてくださったら、もちっとマシな解説を考えます。
----
*OOなんて嫌いだ?
ヘルのチャットで8086さんと話をしていた結果、なんかワタシOOの機能を殆ど使ってないことが判ったよ。(実際は故あってOOの機能を使うのを止めた)
クラス作る意味ないのかなぁ・・・
今日、メモリリークを幾つか潰しました。つか、以前も同じトコで悩んでたことがあったので、備忘録で残しておきます。
そんなわけで、タダでさえ誰も読まない系のページなのに、C++の話とかしてひとりよがりしてみるのです。
とりあえず継承関係のクラスを作ったわけです。
>class oya{ oya(); ~oya();};
>
>class kodomo : public oya{ kodomo(); ~kodomo();};
kodomoクラスでは、コンストラクタでnew、デストラクタでdeleteしてたりなわけです。
で、ある日こんなことを
>oya* = pOya;
>
>pOya = new kodomo;
当然、生成時にコンストラクタkodomo()が呼び出されます。
で、使い終わったのでポインタをdeleteしました。
>delete pOya;
なので、kodomoは消え去ったつもりだったのですが、
実はoyaポインタに対してデリートしたので、実体がkodomoでも
呼び出されるデストラクタは~oya()だったのでした。
で、kodomoで使ったデータがdeleteされることは無く、
メモリリークとなったのでありましたとさ。めでたし、めでたし。
うぇーい。
この項おわり
----
*担詠嘆 担詠嘆 担詠~(060125)
今日ソースを見てたらバグだらけ~。急いで作ったからな。つうことで、バグを見つける間違い探しなんだよ!
修正する時間が無いので、とりあえずアークタンジェント関数。サインとコレがあれば大抵のことは出来るでショ。多分。
タンジェントは-90度から+90度の間で単調増加(って云うんだっけ?)なんで、入力のタンジェント値とテーブルのタンジェント値を比較した大小で走査すれば求める角度が得られる。
因みに、タンジェントの値はsin()/cos()で求まります。理由は…sinとcosの定義を調べてみてね。
&ref (tan.png)
ので、2分探索って云うよく知られるアルゴリズムで求めてます。これなら、4096だったら12手で必ず解が求まります。理由は4096=2の12乗だから。
>(sin.h)
>二分探索でアークタンジェントを求める
>alpha = 1023;
>beta = -1023;
>
>for(i=0;i<12;i++)
>{
> ctr = (alpha + beta) / 2;
>
> if( (Sin4096(ctr)<<15)/Cos4096(ctr) >= ((y<<15)/x) )
> {
> alpha = ctr;
> }
> else
> {
> beta = ctr;
> }
>}
>return alpha + delta;
ところで、純粋なタンジェントの値からだけだと、2つの角度が求まってしまいます(0~360度の範囲では)。なので、xとyの符号を見て場合わけします。なので、自作アークタンジェントの入力はxとyの2つです。
>if( x > 0 )
>{
> delta = 0;
>}
>else if( x < 0 )
>{
> delta = 2048;
>}
>else // ( x==0 )
>{
> if( y > 0 )
> return 1024;
> else
> return 3072;
>}
因みに、90度と270度の時はタンジェントは無限大になってしまうので、そこも場合わけしてあげやう(ホントの理由は違うんだけど
やっぱサンプルは以前のやつで。
この項おわり
----
*自機に弾を向ける(060124)
自機に向いた角度を取得するには?
そんなときはアークタンジェント。なんかつよそうですね。
アークタンジェントは、タンジェントの値、y/xを与えると、その角度を返す関数です。
なんで、弾の発射元のx座標と自機のx座標の差、元のy座標と自機のy座標の差をアークタンジェントに食べさせればOK。
&ref (atan.png)
サンプルboss.cの18行目
>AddTama( 320<<16, 100<<16, Atan4096( (GetPlayerX()>>16)-320, (GetPlayerY()>>16)-100 ) );
これでOK。自作のアークタンジェント関数の精度がイマイチで、
入力は65536未満?じゃないと駄目かも。
>AddTama( int x, int y, int Angle );
これは(x,y)に角度Angleの弾を発生させる関数ですよ。
>GetPlayerX();
>GetPlayerY();
これはプレイヤのx座標、y座標を返す関数。
サンプルはやっぱり昨日のやつ。
この項おわり
----
*とりあえず弾(060124)
とりあえず弾を飛ばす。
速さR、角度θで弾が飛ぶときはx軸y軸それぞれの成分は
&ref (vector.png)
>Vx = Rcosθ
>Vy = Rsinθ
であるから、
サンプルのTama.cの45,46行目
>Tama_x[i]=Tama_x[i]+TAMA_SPEED*Cos4096( Tama_Angle[i] );
>Tama_y[i]=Tama_y[i]+TAMA_SPEED*Sin4096( Tama_Angle[i] );
tama_x[i]ってのは、沢山ある弾のうち、i番目の弾のx座標。
つまり、ある特定の弾に対して考えると
>x = x + SPEED * COS( Angle );
>y = y + SPEED * sin( Angle );
これで速さSPEED、角度Angleで弾が飛ぶよ。
ワタシの作ったサインとかだと、
画面右が+x、画面下が+yの座標になってるので、
右が0度で時計回りに角度が増えてゆくことに注意。
サンプルは前回(060123)のやつをみてね。
この項おわり
----
*自機狙い弾とか(060123)
取り敢えずサンプルをつくった。
解説事項が多すぎるので、解説はまた今度。
斜めブーストも修正しないとなw
&ref (sam.JPG)
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/new.lzh
この項おわり
----
*サインちゃん(060122)
友人にこのページを読んでもらったら、訳判らん意味不明とか云われました。
おーのー。
確かに意味不明文章だけど、頑張ってソースにコメント打ったりしてんねんけどなぁ。。。
で、サインウェーブです。
ゲームやってたらどこもかしこもサインちゃん。
サインに非ずんばゲームに非ず、と。
よくわからんけど、サインはマクローリン展開だがテイラー展開だか出来るんですって。
>sin(x) = x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + …
>cos(x) = 1 - (x^2)/(2!) + (x^4)/(4!) - (x^6)/(6!) + …
ここでxはラジアンだから注意だよ。ラジアンってのは1周を2Π(円周率)で表す角度の単位だよ。
なので、素直に代入してみましょう。
>Θ:求める角度(4096で1周)
>x = (1608*Θ) / 4096; //角度>ラジアンに変換 (2*PI*i/4096)*256 (256は65536固定小数にするため)
>
>COS = 65536 //1項目
> - (x*x/2) //2項目
> + (x*x/2/256*x/3/256*x/4) //3項目
> - (x*x/2/256*x/3/256*x/4/256*x/5/256*x/6) //4項目
> ;//終わり
無限に足すのは出来ないので、飽きたところで終了。
4項くらい足しておけば十分っぽいです。
↓Cの<math.h>のsin()との誤差をプロットしてみた
http://www7a.biglobe.ne.jp/~root-ame/src/sin.JPG
なんで4096を1周にしてるかと云うと、昔偉いひとにそれがいいって云われたからだよ。
よくわかんないけど、いい数字なんですって。
で、求めたサインを4096要素の配列に代入しましょう。
>for(i=0;i<1024;i++)
>{
>x = (1608*i) / 4096; //角度>ラジアンに変換 (2*PI*i/4096)*256 (256は65536固定小数にするため)
>
>tmp= 65536 //1項目
> - (x*x/2) //2項目
> + (x*x/2/256*x/3/256*x/4) //3項目
> - (x*x/2/256*x/3/256*x/4/256*x/5/256*x/6) //4項目
> ;
>
>SIN4096[1024-i] = tmp; // 0~ 90度
>SIN4096[i+1024] = tmp; // 90~180度
>SIN4096[3072-i] = -tmp; //180~270度
>SIN4096[i+3072] = -tmp; //270~360度
>}
展開式はxが大きくなるほど誤差が大きくなるので、
4分周だけ求めてあとは使いまわすんですって。
生活の知恵ですよね。
>int SIN4096(int s )
>{
>return SIN4096[(s+4096)%4096];
>}
>
>int COS4096(int s )
>{
>return SIN4096[(s+4096+1024)%4096];
>}
使うときはこんな感じでどうぞ。
COSは90度足すだけでいいからお徳ですよね。
やっほーい。
どうでしたか、わけわからんですか。わけわからんですね。
うぇーい。
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/sin.lzh
-参考文献
S.Programs NET/小さなねた/10bit 精度の sin テーブル
http://sprocket.babyblue.jp/html/hsp_koneta.htm
大変参考にさせていただきました。実はワタクシもよく判ってない。もしかしたらもっと精度を上げられるのかもしれんが、力尽きました。
暁のコード部屋(第10回)sin/cosに苦しむ
http://www.aya.or.jp/~sanami/peace/memorial/code1-10.html#CODE10
最近になってようやくじわじわ理解できるようになってきましたわー。シュゴー
この項おわり
----
*次回予告(060118)
ネタはあれども、ソース書く暇が無いと云う。うぇーい。今はキャラ管理クラスとか書いてますよ。
次は三角関数にしようと思うのですよ。例によってさ~さんの受け売りで4096分周のテーブルでな。
ネッツで調べたらアークタンジェントの出し方もあったよ。
ほうほう結局はテーブルから探索ですか。なるへそ。
そんな感じで。
今日のおまけ
僕愛用のサインテーブル
http://www7a.biglobe.ne.jp/~root-ame/src/sin4096.h
この項おわり
----
*固定小数のススメ(060116)
今日は寝不足で電車の中で爆睡してたので、ソース書いてません。いきなりネタがありません(笑)ので、以前書いた文章をペタリ。
ゲーム中の数式計算なんて大体正しければいいのですが、流石に整数だけでは辛いので、小数を使いましょう。
小数っつうとCで云うfloat型とかの浮動小数を使えばいいですが、通ぶって固定小数でいきましょう。
-かんがえかた
「固定小数点型なんてCじゃサポートしてないよう」だなんて泣くことはなくて、10000を基準に考えて
十分の一の1000を0.1だと思い込んで使えば無問題。
-つかいかた
値を代入するときにはリアル数字(人間様が認識してる数)に10000とか決められた数を掛けてやるだけ。
で、実際に使用する際(例えば画面上の座標にするとき)に10000で割るだけ。
>int x,y; /* 座標 */
>
>x = 5 * 10000; /* 固定小数への変換 */
>y = 10 * 10000; /* 固定小数への変換 */
>
>
>/* 値をアレコレ */
>x = x + 15000; /* xに1.5(リアル数字)を足す */
>x = x + 27000; /* xに2.7を足す */
>
>/* 実際に値を使う */
>DRAW( x/10000, y/10000 ); /* DRAW:架空の関数 */
先ずはxを50000で初期化。そのあとxに15000を足してみて65000に。もいっちょオマケで92000に。
で、実際に画面表示とかに使われるときは10000で割って9。5 + 1.5 + 2.7 = 9.2。
ドット以下は表示できないので、切捨てでおっけ。そんな感じ。
通は乗除する数を65536にすると素敵。ゲームとかだと2のべき乗で掛けたり割ったりすることが多い(→65536だと誤差が生じない)ので便利だし、ビットシフトで計算すれば高速(だと思う)だし。
>int x,y;
>
>x = 5 * 65536; /* 固定小数への変換 */
>y = (10<<16); /* これでも同じ */
>
>DRAW( (x>>16), (y>>16) );
注意としては、Cだとビットシフトの優先順位はびっくりするぐらい弱いので、嫌っていうほど括弧をつけるクセをつける必要があることか。
-注意
乗除算を行う時はちょと注意が必要。(hoge*10000) * (foo*10000) = (hoge*foo)*100000000になってしまうのでー。
>int hoge, foo, bar;
>
>/* 変換~ */
>hoge = (3*10000);
>foo = (5*10000);
>
>bar = hoge * foo; /* NGggggggggggggg */
>bar = (hoge/100) * (foo/100); /* OKkkkkkkkkkk */
-サンプル
http://www7a.biglobe.ne.jp/~root-ame/bin/kotei.zip
カーソル右で加速。カーソル左で減速。なめらかな加減速を体感しやう。
例によってyaneuraoさんのYGS2Kの実行ファイルが置いてあったり。
-参考文献
暁のコード部屋(第22回)固定小数点における正しい乗算
http://www.aya.or.jp/%7Esanami/peace/memorial/code21-30.html#CODE22
つか、受け売りを実行してるだけなので、さっさとこちらのページにいっときましょう。
この項おわり
----
*最近の開発
丼さんがエロSTGつくれと仰るので開発に着手。
縦STGから横STGに仕様変更。
理由は聞かないでください。
その後
波紋効果を入れてみた。
何らかの形で自機の位置を知らせるフィーチャーは必要だと
思ってみたから。
ステージスタート時の演出とカスリ時に
波紋を出したらいいんじゃね?
適当なサイトから適当なソースをぶっこ抜いてくる。
zキーでオーバードライヴ
結果:いい感じ
ダガシカシ
ワタクシの絵づらから鑑みるに
パステル調とかの方がよい気がしてきた。
半透明とか加減算のエフェクトは合わない気がしる。
ワタクシの1ヶ月は徒労に終わる。
この項おわり
----
やっぱり米欄つくってみた
- この項おわりでうけた。&br()すまんす。ぜんぜん役に立たぬコメントで。 -- D.K (2006-01-16 22:55:13)
#comment(vsize=2,nsize=20,size=40)
----
*ソースファイル
http://www7a.biglobe.ne.jp/~root-ame/bin/ero_src_fluu0116.lzh
(1MBくらい)
VC6とDirectXSDK8以降があればコンパイルできると思いたい。
実行ファイルも入ってるので多い日も安心。
yaneuraoさんのYaneuraoGameSdk2ndを改悪したモノが混入されてますが、
ダウソ即コンパイルできるやうに敢えて置いておきました。
そんな感じで。
表示オプション
横に並べて表示:
変化行の前後のみ表示: