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

自分がプログラムやっていて、思いついたことをつぶやいていきます。 2025年からzennに移行

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

技術解説「ババドン」

技術解説「ババドン」その5 花火②

実は花火の元となる画像はこんなに汚いです
b5f06338.png
 

これを何枚も加算合成して、光ってる感じを出させてます。


さて、次は花火の「軌道」を確認します。


最初花火の玉が爆発して、放射状に↑の画像(以後パーティクルと呼ぶ)がとびちります。

そのあと、重力の影響を受けながら薄く消えていきます。

好きな人は、空気抵抗とかもお好みでつけたりします。


このプログラムに特殊な命令は必要ありません。全部四則演算で事足ります。


まず用意しなければいけないのは、配列変数です。


しかし、ただの配列ではなくて2次の配列です


今回はx成分、y成分、薄さの値など要素が多いので、1次だと少し不便です(できなくはないが)


dim par,100,5


と、100×5の2次の配列をつくります。


parは花火のパーティクル100個の座標などさまざまなパラメーターを代入する変数です。


X座標、Y座標、Xの速度、Yの速度、寿命。

この5つのパラメーターを2次の配列に記憶させます。


たとえば

par.12.1

と言ったら、花火の12番目のパーティクルのY座標の値のことを意味します


寿命の項目には、花火生成のときあと何フレームで消えるかの数値を入れておいて、まいフレームごとに

値を1ずつ減らしていきます。0になったら、パーティクル消滅とさせます。

(当然変数字体は消滅しないので、描画命令を読ませないプログラムにしろ、ということです)


花火生成プログラムですが、火薬玉爆発の瞬間は花火のパーティクルの位置は同じなので、同じ値を代入しておきます。


そして放射状に吹き飛ぶようにしたいので、速度のパラメーターのところに、それぞればらばらな値を入れておけばいいんです。


repeat 100

rad=3.1415*rnd(100)*0.02

par.cnt.2=10.0*cos(rad)

par.cnt.3=10.0*sin(rad)

loop


これでパーティクルの初期設定は完了。


あとは毎フレームごとにX座標、Y座標にXの速度、Yの速度を加算していけばいいだけです。


par.cnt.0=par.cnt.0+par.cnt.2

par.cnt.1=par.cnt.1+par.cnt.3


という操作です。


しかしこれでは飛び散ってしまう一方なので

ここで、重力の概念をプログラム化します。


重力は下に働くのでYの速度を毎フレームごとに1とか2プラスしてあげれば

パーティクルの動きが放物線になります。


par.cnt.3+=2


最後に寿命ですが

加算合成の合成%をgmodeで指定するとき、寿命の数値が小さくなればなるほど合成%も小さくなるように

指定します。


そうすれば、花火の先が徐々に薄くなっていくプログラムも完成です。



次回:  不明・・・

技術解説「ババドン」その4 花火①

ネタバレ注意!

ババドンのエンディングの詳細について書いてあります。エンディングを楽しみにしている人は読まないほうがいいです!




いきなりですがエンディングの話です。


多分もう皆さんババドンは1週クリアしてるという前提で話していきます!


エンディングの最後のほうに、UFOがババドン星に着陸した後、花火が上がるシーンありますよね?


今回はその花火について解説します。


その前に・・・

プログラミング初心者の方はよく聞いてほしいのですが、画像を描画する画像処理命令(gcopy)には大まかに分けて6種類のモードがあります。


①透明色なしの単純なコピー

②透明色ありのコピー

③半透明コピー

④加算合成コピー

⑤減算合成コピー

⑥アルファーブレンドコピー


すべて説明すると大変ですが、最低でも①②③④はマスターしましょう。


そして花火には④の加算合成コピーが使われてます。


加算合成コピーとは、色のコードRGBの値を足してコピーするので加算合成と言いますが、

使いどころが分からない人もいるのでは?


加算合成はよく、「光るもの」を再現するときに使います。


花火なんかも光ってる感じが出せればきれいに見えますよね?


まぁ、ババドンのエンディングにある花火は綺麗なのか微妙ですけど。・・・


「光るもの」と言えば、宇宙から見たキラキラ星なんかもCGなどでよくみるシーンですよね。

あれは加算合成でないと説明がつきません。


ほかにも、爆発モーションとかも加算合成にしたほうがきれいになる場合があります。


花火の話に戻しますが、・・・一応これも2日にわけて説明してみたいと思います。


続きは次回です


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

技術解説「ババドン」その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 花火

技術解説「ババドン」その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 当たり判定②

プロフィール

toropippi

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

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