仮眠プログラマーのつぶやき

自分がプログラムやっていて、思いついたことをつぶやいていきます。

自作ゲームやツール、ソースなどを公開しております。
①ポンコツ自動車シュライシュラー
DOWNLOAD
②流体力学ソース付き
汚いほうDOWNLOAD
綺麗なほうDOWNLOAD
③ミニスタヲズ
DOWNLOAD
④地下鉄でGO
DOWNLOAD
⑤ババドン
DOWNLOAD
⑥圧縮拳(ツール)
DOWNLOAD
⑦複写拳
DOWNLOAD
⑧布シミュレーション
DOWNLOAD
⑨minecraft巨大電卓地形データ
DOWNLOAD
⑩フリュードランダー
デジゲー博頒布α版
DOWNLOAD
⑪パズドラルート解析GPGPU版
DOWNLOAD
⑫ゲーム「流体de月面着陸」
DOWNLOAD

2009年05月

技術解説「ババドン」その3 吸引アルゴリズム

日曜大工センターでステンレス板を探してたら、面白いグッズを発見。


キャットアイ(CC-VL110 )という自転車につける速度計


速度だけでなく走行距離やカロリーも測ってくれるみたいです。


毎朝自転車だけで45分かけて登校する人にとっては、なかなか通学を楽しくさせてくれる一品


測ってみたら家から学校まで11キロあるんですね


11キロってどのくらいかと言うと、だいたいうまい棒9万5652本分の長さに相当します!

って多!

そんな長い距離毎朝走っていたのか・・・自分は


往復でちょっと寄り道すればあっと言う間に20万本突破じゃないですか!

どこぞのゲームの販売本数みたいですね



というわけで今日の議題にいきたいと思います

やはりババドンの一番の見せ場はUFOの吸引のシーンでしょう。


UFOに近づくほど吸い込まれやすくなるあのプログラムはどうなっているのか、計算式はどうなのか。


そこを今日は解説します。


まず、「UFOに近づくほど吸い込まれやすくなる」という条件から、ババドンとUFOの距離を求めないと話は始まりません


3平方の定理で距離を求めます。

これはプログラムの一部です「え」とか「け」は変数で数値だと思ってください。


け=-つ.cnt/10+え    ;UFOとババドンのX成分の距離差
こ=-て.cnt/10+お    ;UFOとババドンのY成分の距離差
く=け*け*4+こ*こ*2   ;三平方にちょっと応用


ここで3行目はまだおいといて、1,2行目では3平方の定理で求めるためのX距離差、Y距離差

を算出しています。

最終的には求めた距離に、反比例した変数を作り

そして、その数値がUFOの吸引力となります。


そうすれば「UFOに近づくほど吸い込まれやすくなる」が満たされます


さてそこで、ただ単に距離が近いと吸い込まれやすいのではなくて、UFOから見てババドンが

横にいるよりも下にいるほうが、同じ距離でも、吸引力が上がるようにしたいとします。


その場合、三平方に少し式を加えて


く=け*け+こ*こ      ;本来あるべき3平方の使い方

く=け*け*4+こ*こ*2    ;縦成分のより横成分を多く取った形


下の式のようにします。

すると、この「く」という変数はUFOとババドンとの横成分の距離差に大きく影響をうけることになります。


つまり逆に言えば、横の距離が少しでも離れすぎていると、吸引力が格段に落ちる⇒横より縦のほうが吸引力が高い

ということになります。


こうして、吸い込み力を計算するアルゴリズムの完成です。


あとは、ババドンからUFOの角度を計算し、sin cos を使って吸引力をX、Y成分に分解し、ババドンの座標変数に加算するだけです。



次回:技術解説「ババドン」その4 花火

1億桁×1億桁の開発状況報告①

1億桁×1億桁の開発状況報告


いまさらですが、1億桁×1億桁の計算をしなければならない人ってこの世にいるのでしょうか・・・

あまり気にしすぎると体に悪いので、早速解説していきたいと思います



まず1億桁×1億桁の計算に絶対必要なのは多倍長の変数


普通の変数は9桁あたりで限界振り切ってしまいますが多倍長の変数

は何桁までいっても限界を振り切りません


そのためにlongint をプラグインとして使います


まず試しに100万桁×100万桁の掛け算を行います。


#include "longint.hsp"
a=LongInt(1)
repeat 100000;百万桁の数を生成
a*=LongInt("10000000000")
loop
b=LongInt(a);百万桁の数を複製
c=longint(0)
wait 2
mes "掛け算開始"
wait 1
c=a*b
mes "掛け算終了"

・・・・・・・・・・・・コピペして実行してみれば分かりますが


まず百万桁の変数を作るのに1分


百万桁×百万桁に1分10秒


長い・・・・長すぎる・・・

こんなんで1億桁×1億桁の計算をやろうとすると、計算時間が尋常じゃないほど長くなります。


一応どのくらいかかるのかと言うと、桁数100倍より100^2=10000だから

計算時間が1万倍になるので、掛け算部分だけでも700000秒!

日にちにして8.1日かかる!!

これに1億桁の数を生成&複製の計算時間を含めるとさらに長く・・・


これではデバッグだけで1年が過ぎてしまう・・・


結論はつまり、「普通の掛け算」ではダメだということです!!!


何か、計算効率のいい掛け算方法(アルゴリズム)を考えなければいけません!


ちなみにわれわれがよく手動で計算する掛け算の手順

一桁一桁ずつかけて足して・・・という方法はじつはとてつもなく非効率な掛け算方法なのです!

ただ人間にとっては手順が単純明快なので、一番楽な方法として認識されてますが

コンピューターにやらせるのには向いてません


ここで、karatsuba法というけ掛け算アルゴリズムを採用します。


これは多倍長の桁を2分割して掛け算4回分の仕事を掛け算3回分と足し算4回に式変形する方法です。


足し算は掛け算と比べて計算時間が非常に短いのでないものと考えると、1回の分割で計算時間が3/4に減る

ことになります。

すると8回分割で計算時間がなんと10分の1に半減します!


それでもまだ1つの掛け算に40万桁×40万桁の計算が必要なのでさらに5回分割して


1万2千桁×1万2千桁の掛け算になるまで分割すれば、計算時間が(3/4)^13≒0.024


だいたい40分の1くらいに時間が抑えられることになります!


するとなんとたった5時間で、1億桁×1億桁を求められる計算になります!


おおー早い!!

これで、だいたいメドがついてきましたね!


あとはプログラムを打ち込むだけです。


karatsuba法をどうプログラムで再現するか、ここが一番力量が試されるところですが、

何せ計算手順が複雑なのでまだベースプログラムすら出来上がってません・・・

(一応自分が過去にHSPコンテストに出した中で一つkaratsuba法を使った計算プログラムがあるのですが、また新しくプログラムを打ち直すつもりです)

なので詳しいkaratsuba法の計算についてはまたの機会にしたいと思います


次回:技術解説「ババドン」その3 吸引アルゴリズム

技術解説「ババドン」その2 当たり判定②

4つ目


【マスクを使ってドット単位で当たっているか判定する方法】


最後が一番難しいですが、どんな複雑な形にも対応した、一番正確な当たり判定です。


「ババドン」の当たり判定はこの方法を採用しています。


まずマスクとは
ad37ce05.png

bcb084e3.png

 

↑この白黒の画像のことを言います。


上のカラーのUFOのやつはゲーム画面で使い、下の白黒のやつは表の画面に見せないで

裏画に記憶させておきます。


そして、横から来る鉄砲がUFOに当たっているかの判定は、マスク画面上で行います。

例えばババドンを例に挙げてみると、ゲーム画面上でUFOの左上側座標が100,100だったとします。


鉄砲はとても小さくて1ドットだとして、今鉄砲の座標が110,140だったとします


このとき裏画面で、鉄砲とUFOの重なっている座標で色を抽出し、白だったらハズレ

黒だったらアタリと判定させます。


つまり鉄砲の座標からUFOの座標を引いて10,40になります
これがさっき言った重なっている座標になります。

あとはマスク画面上でpgetをすればginfo_r ginfo_g ginfo_bに色数値が代入され、即判定可能になります。

さっきまで鉄砲が1ドット×1ドットのときの話でしたので

14×8ドットくらいの大きさなら、どうするかというと

鉄砲の先端部分と後ろの末端部分の2箇所でさっきのような当たり判定をするといいです


空中地雷のようにもっと大きい画像の場合は2箇所でなく6、7箇所と数を増やしていけば問題ないはずです

これで一通りの当たり判定の説明は終わりです


どの当たり判定も一長一短がありますので、その場に応じてうまく使い分けてください。(←ちょっと偉そうに・・


しかし、ボクが知らないだけでもっと良いいろんな当たり判定方法があると思います。

が何分、自分の技術不足のためこれ以上の説明は不可能となりそうです。


まだまだこれからもいろんなサイトで勉強させてもらうつもりです




そうそうあたり判定といえば・・・


田舎のばぁちゃんがいきなり大量のお菓子を送りつけてきたのですが、家族総出で消化しようと

口にした途端、全員腹を下しました・・


まさか身内の送ってきたものであたるとは・・


いい加減うちのおばあちゃん、バイオテロの常習犯です


何回もひっかかるウチらもウチらですが。


って、当たり判定関係ないし・・



次回:1億桁×1億桁の開発状況報告

技術解説「ババドン」その1 当たり判定①

技術解説とか大それたこと言ってますが、正直人に教えられるような技術は自分にはないと思ってます・・

(何つったって国語の能力がないわけだし・・


いろんなサイトで調べてきたプログラム技術をそのまま書いてるようなものです。

自分のために書いているものですので、お許しください。



今日と明日の2日間でゲーム「ババドン」の当たり判定の部分のプログラム解説をしたいと思います


最初は当たり判定の基本から説明していきたいと思います。



はじめてプログラミングでゲームを作る人にとって、当たり判定アルゴリズムは最初の難関です!

(アルゴリズムとは問題を解くための効率的手順を定式化した形で表現したものを意味するby wiki 例えばaとbの平均を求める式 c=(a+b)/2 これは平均値を求めるアルゴリズムです、と言う事ができる。)


しかし、アクションゲームでもシューティングでもよけゲーでも当たり判定ができないとゲームの形すら作れませんよね


ゲームを作れるようになるにはこれを理解しないと進めません。


当たり判定アルゴリズムは、考え方として最低4種類あります。(と思ってます




1つ目は


【上下右左の4方向から座標を限定する方法】


例えば敵Aのウィンドウ上の配置座標がa,bだとします

(※ウィンドウには左上を基準とした座標という概念があります)


画面中心(中心の座標は320,240)40ドット四方に敵が入ると死亡としたいなら、敵が

X軸座では300~340内に

Y軸座では220~260内に

いれば死亡と考えるのでプログラムは


if a>300:if a<340:if b>220:if b<260:; 敵死亡


と書けます。


これは自分or敵が四角い場合によく使います。一番簡単な部類の当たり判定です。

逆に自分が不定形のときや丸いときは使いません。


ちなみに(私も含め)よく初級者がひっかかるのは

if 300<a<340


とaの式をひとつにまとめてしまうことがあるのですが、この表記は数学や物理ではよくしますが

プログラムの世界ではバグと認識されてしまうので注意しましょう。




2つ目は


【3平方の定理を使った距離で判定する方法】


自分と敵までの距離を3平方の定理で算出して一定距離以内なら当たっているとする方法です。

例えば自分の座標がx,y 敵がa,b だとすると


kyori2=(x-a)*(x-a)+(y-b)*(y-b); 距離の2乗を算出

kyori=sqrt(kyori2) ;距離を算出

if kyori<50.0: ;距離が50ドット以内なら当たり


となります。三平方の定理を正直に使えば、2乗したもの同士を足して最後に平方根の中に入れて

距離を算出するという、少々面倒な方法になりますが、わざわざ平方根を求めなくても

3行目の50のところを2乗してあげれば計算過程がひとつ減ります。


だから

kyori2=(x-a)*(x-a)+(y-b)*(y-b); 距離の2乗を算出

if kyori2<50.0*50.0: ;距離が50ドット以内なら当たり


これで2行になります
最後に応用で

if (x-a)*(x-a)+(y-b)*(y-b)<2500.0  ;距離が50ドット以内なら当たり


このように変数をも省略し、1行にまとめてしまえばさらにすっきりします。

この方法は自分と敵がだいたい円形である場合に一番威力を発揮する方法です。


逆に極端に横長な場合には使わないほうがいいでしょう



3つ目は


【背景1ドットの色を識別する方法】

pget命令で背景のドット色を読み取り、色のRGBにより、当たっているか判定する方法です。


「ポンコツ自動車シュラーシュラー」はこの方法を使ってます!(図ではババドンのUFOがかかれてますが・・

例えば8fc0cb59.png

図のように背景が黒と白で、黒に当たると死亡としたいなら


この4箇所の点(実際はもっと小さい点)でpgetし、読み取った背景の色がginfo_r ginfo_g ginfo_bに代入されるので、


if ginfo_r=0:if ginfo_g=0:if ginfo_b=0:;色コードが黒なら死亡


と、こう表せます。もちろん背景が2色だけということは稀なので、

条件式if ginfo_r=0のところを >= <=! を使ってうまく式変形して、臨機応変にやってください。


注意すべきはpgetで色を読み取るとき、自機(この場合UFO)の描画命令をした読み取ってしまうと

背景ではなく自機の色をpgetすることになってしまうので、必ず自機の描画命令の前にpgetしましょう。




ふぅ

疲れたので4つ目は明日に回します


次回:技術解説「ババドン」その2 当たり判定②

HSPコンテストに向けて

記事を書いてる途中、うちの母ちゃんに説教を喰らいました・・


「休みだからっていつまでもパソコンいじってないで早く就活しなさい!だいたい秋葉に行くことが世の中の何に役に立ってるというの・・・・」

だそうです。


まるでニートに向かって言う言葉みたいでショックでした(ノω・、)


多分「就職先」じゃなくて「バイト」探せと言いたいのでしょうが・・・

ちなみに世の中の役に立とうと思って秋葉に行ったことは一どもないです・・・



さて、そろそろHSPコンテストにむけて何か作り始めようかと思ってます。


HSPコンテストは確か8月から10月までが応募期間だし、10月ギリギリに出すとしてもあと4ヶ月ちょっと。


もうそろそろ何か始めてもいい時期かと


「走れポンコツ自動車」はできればコンテストに参加させるつもりですが、それだけではちょっとインパクトが足りないような・・・


うーん、もっっっと衝撃的なの作りたいな!


何の役にも立たないものでいいから、「こんな意味のないところに、こんなハイクォリティな技術を使うなんて!」

と思わせるような何かを作りたいですね・・


例えば、1億桁×1億桁の掛け算をどんなフリーソフトよりも高速に計算するソフトとか・・・


待てよ・・・あ、それいいかも!(ぇ


HSPでは前代未聞の桁数だし!


自分お得意の数値計算なら誰にもまける気がしません!!


よーし、なんだかやる気が出てきた!!それなら早速下準備を始めなければ・・・


ちょくちょくこのブログで開発状況を報告するかもしれません!


ではまた

プロフィール

toropippi

記事検索
アクセスカウンター

    QRコード
    QRコード
    • ライブドアブログ