プチメタ3.0

刺激を受けた物事に対する感想や考察、資産運用や英語学習、自己成長に関することなど。


三平方の定理はゲーム開発で一番役に立っている公式


中学校の数学で習う「三平方の定理(ピタゴラスの定理)」は
ゲーム開発の中でも使われまくっている。
この理屈がなければあちこちが破綻するほどなので
先日紹介した三角関数以上に重要なものだと思っている。

三平方の定理とは


そもそも三平方の定理とは
直角三角形における3つの辺の長さの関係を表したものだ。
直角三角形の底辺の長さと高さをそれぞれ2乗し、
それらを合計した値の平方根は、斜辺の長さに等しい。


斜辺の長さだけに限らず、式を組み替えれば
どの2辺からでも残り1辺の長さを求めることができる。


「長さを知りたいなら直接測ればいいのに」と思うかもしれないが、
縦の長さや横の長さは簡単に測れても
斜め方向はそうはいかないことが多いのだ。

2点間の距離を求める


基本的にプログラムで表示する物体の位置は
横方向を表すX座標と縦方向を表すY座標で管理されている。




つまりゲームに登場するキャラクターが
表示されている位置は簡単にわかる。


ではこの2つのキャラクターが
どれぐらい離れているかという「距離」は
どうすれば求められるだろうか。




それぞれのキャラクターはXY座標を持っているので
X座標同士を引き算すれば横方向の離れ具合が、
Y座標同士を引き算すれば縦方向の離れ具合がわかる。


この2つの数値を直角三角形の底辺と高さに見立てれば
キャラクターを結ぶ直線が斜辺となるのだ。




あとは三平方の定理に当てはめれば
斜辺の長さ、つまりキャラクター間の距離が求まる。


この「2点間の距離を求める」という作業が
三平方の定理のもっとも基本的な利用法である。

当たり判定に利用する


ゲームでは「自機が敵とぶつかったか」
「自機がアイテムを取ったか」「弾が敵に当たったか」といった
2つの物体が衝突したかを判定したいことが非常に多い。
こういった処理は「当たり判定(衝突判定)」と呼ばれる。




当たり判定を実現するには
まず各キャラクターが収まる円を想定する。
キャラクターによって大きさが違うので
それぞれに見合った半径の円を考える。



半径5と半径3のキャラクターは
互いの距離が8のときにギリギリ触れる状態になり、
これ以上近い場合はめり込んでいることになる。



互いの距離が12のときは4離れているというわけだ。
つまり2つのキャラクターの「距離」と「半径の合計」を比べれば
衝突しているかどうかがわかる。
これが距離による当たり判定(円判定)だ。


それぞれのキャラクターに合わせて半径を設定しておけば、
「敵と敵」「アイテムと自機」「弾と自機」など
どういった組み合わせであっても
どのぐらいの距離で衝突することになるかがわかる。



問題としては単なる円として判定しているため、
実際のグラフィックでは衝突していないように見えても
円同士が触れていると当たっていることになってしまうことだ。


これだと理不尽だと受け取られることが多く、
ゲームを遊んでいるプレイヤーから不満が出てしまう。



そこでグラフィックよりも小さめの円に設定することが多い。
今度は逆に、見た目では重なっているのに
内部では衝突していないと判定されてしまうが、
プレイヤーは自分にメリットがある場合は
ほとんど不満を言わないので問題視されない。

目的地に近づく処理に利用する


別の利用法も挙げてみる。
先ほどと同様に2つの座標の距離を求めるが、
片方を「現在地」、もう片方を「目標地点」と考える。


水平方向に60、垂直方向に70離れているので
目標地点までの距離は92.1だとわかる。



さて、この目標地点までの距離で
水平方向の長さ、垂直方向の長さを割ると、
目標方向に1近づくためには
XY座標にいくつ足せばいいのかという値がわかる。


これを使えばあるキャラクターが
指定した座標に少しずつ近づく処理が作れる。
移動量を2倍すれば2ずつ、3倍すれば3ずつ近づいていくので
好きな速度で移動するキャラクターを作ることができるわけだ。

自分で考えるより公式を知っている方が楽

数学の公式を覚えるのを嫌がる人が多いが、
優秀な数学者たちが苦労して編み出した理屈に
自力でたどり着ける可能性はほとんどないわけだから
公式を知らずに必死で考えるよりも覚えた方が楽だ。


ゲームプログラミングには数学が必須と言われるが、
最低限、三平方の定理と三角関数は押さえておきたい。



mclover.hateblo.jp

mclover.hateblo.jp

mclover.hateblo.jp

mclover.hateblo.jp

2Dゲーム開発では画像を表示する順番が大きな意味を持っている

f:id:IKUSHIMA:20210824161444j:plain


どんなゲームにもいろいろな画像が表示されているが、
2Dゲームを作るときには
各画像を表示する順番が重要になってくる。


あとから表示したものの方が上に来るので、
最終的にどの画像が上になるべきなのかを考えて
表示する順番を決める必要がある。



f:id:IKUSHIMA:20210824152327j:plain


たとえば背景とキャラクターの場合、
背景画像を先に表示してからキャラクターを表示する。



f:id:IKUSHIMA:20210824153030j:plain


逆の順番だと、せっかくキャラクターを表示しても
大きな背景画像で覆われてしまうためだ。
つまり「奥にあるものほど先に表示すべき」ということになる。



f:id:IKUSHIMA:20210824105338j:plain


ではキャラクター同士の表示順はどうすべきだろうか。


これは「隠れて見えなくなると困るもの」をより上に表示するのだ。
シューティングゲームだと自機の弾を見失っても支障はないが、
敵の弾が何かで隠れてしまうと、うまくよけることができなくなる。
そういう生死に関わる重要な情報を常に見えるようにする。



f:id:IKUSHIMA:20210824133834j:plain


RPGの画面は世界を斜めから見下ろした表現なので
地面に対して高いものほどあとから表示する。


また、キャラクターは画面の上方向にいるほど
より遠くに立っていることになるため、
縦方向の位置に合わせて表示する順番を決める必要がある。



f:id:IKUSHIMA:20210824140914j:plain


では格闘ゲームの場合はどうなるのだろうか。
この画像だと1P側のキャラクターが上に表示されているが、
常に1Pの方が2Pより上に描かれるわけではない。



f:id:IKUSHIMA:20210824140928j:plain


格闘ゲームでは「攻撃した側」を上に表示するのだ。


たとえばこのローキックをしている方のキャラクターが
喰らっているキャラクターより下に描かれていると
誰もいない空間を蹴っているようなおかしな表現になる。
そこで攻撃した側が喰らっている側の上に被さるように表示する。



f:id:IKUSHIMA:20210824174810j:plain


手足が複雑に絡み合うような表現をするなら
部位ごとに画像を分ける必要が出てくるが、
殴り合いなら「攻撃する側が上に表示される」という程度で
十分それなりの表現に見えるのだろう。



f:id:IKUSHIMA:20210824142258j:plain


ちなみに、例外的に攻撃側でも下に表示されるものもある。
これは右足を時計回りに回転させて足の外側を敵に当てる蹴り技だが、
この場合は喰らう側が上に表示されていないとおかしくなる。
こういった一部の技は例外扱いのようだ。



「あとから描いた画像が上に重なっていく」という理屈は単純だが、
そのルールをもとに、つじつまの合った状態で
ゲーム画面を表現するというのは実は結構難しい。
そのあたりも意識しながら2Dゲームを遊んでみるのも面白い。

パスワードはどのように保存されているのか


いろいろなサイトでパスワードを入力する機会があるが、
サイト側ではどのように保存されているのか。
これには「ハッシュ値」という考え方が使われている。

ハッシュ値とは

lazesoftware.com


ハッシュ値とはある単語をもとに
作り出される一定の長さの英数字のことだ。


 ABC → 55ab19e7
 ABD → 50fb5ef9
 ABCD → 9c653054
 aBC → b53b0cdc


ハッシュ値を作る作業をハッシュ化と呼び、
ハッシュ化する方法(関数)によっても作られる英数字は変わるが、
ポイントは


 ●同じ単語をハッシュ化すれば同じハッシュ値になる
 ●わずか1文字でも違えばまったく異なるハッシュ値になる
 ●ハッシュ値から元の単語を導き出すことは不可能


ということ。
ハッシュ値を元の単語に戻せないことから
ハッシュ化は「暗号化」とは区別される。

パスワードを設定するとき

最初にパスワードを設定するときに
内部で以下のような作業をする。


1.パスワードとして「petitmeta」が設定される
2.ハッシュ化する( petitmeta → 41a91806
3.ハッシュ値である「41a91806」だけを保存する


ハッシュ化する前のパスワードそのもの(petitmeta)を
「平文(ひらぶん)」と呼ぶが、
もし平文のまま保存していると
不正アクセスを受けたときにパスワードが流出してしまう。


ハッシュ値から元の単語を導き出すことは不可能なので
ハッシュ値しか保存しないようにしておけば
万が一流出してもトラブルになりにくいのだ。

パスワードを認証するとき

 ****** → d0a28976 NG
 ****** → 41a91806 OK
 ****** → ed2c573f NG


パスワードを認証する際は
入力されたパスワードをハッシュ化し、
保存しているものと同じハッシュ値なら承認する。


同じ単語をハッシュ化すれば同じハッシュ値になるわけだから、
パスワードそのものではなく
ハッシュ値の方を比較しても認証できるというわけだ。


ある単語をもとに特定のハッシュ値が作れるという性質から
ゲームのセーブデータをもとに作ったハッシュ値を保存しておくことで
前回の保存時以降にデータが改ざんされていないかを
チェックするようなことにも使える。



mclover.hateblo.jp

エレベーターを呼ぶボタンから考えるユーザーインターフェースの不思議


ゲーム画面に表示される情報表示、
たとえば主人公の体力や武器の残弾数のようなもの、
また操作の指示などを「ユーザーインターフェース(UI)」と呼ぶ。


いかにわかりやすいUIにするかがポイントだが、
この「直感的に理解しやすい表現」というのは
実は利用者側の感覚によって大きく左右される。




たとえばある建物の3階に行きたいとき
エレベーターの脇にあるボタンの「上」を押すだろう。
これは1階にいる自分が
今より「上」の場所に行きたいからだ。




しかしこのボタンをエレベーターの箱部分(かご)を
操作するコントローラーと考えた場合、
上の方にいるエレベーターを1階まで下ろすには
下のボタンを押す方が正しいことになる。


エレベーター脇のボタンが
「行きたい方向を示すボタン」なのか
「エレベーターの箱を操作するボタン」なのか
どちらにとらえるかによって変わってくるのだ。


しかし、立っているフロアが異なる複数の利用者が
同じエレベーターを操作すると指示が衝突する問題や、
エレベーターの現在位置を確認しないと
上下どちらのボタンを押すべきか判断できない不便があるので、
利用者がいるフロアに対する
目的階の方向を押すという仕様になっている。




もうひとつ別の例を挙げてみる。
縦に長いWebサイトの「下」の方を見るときには
マウスのホイールを「下」に回してスクロールする。





しかし、見ている内容がスライドしていく方向、
または長い用紙を巻き取るイメージで考えると
ホイールを回す方向が逆に思えるだろう。


実際、スマートフォンでは画面の下を見るときに
指を「上」にフリックするはずだ。
こんなにも一貫性がないのに普段は違和感を感じない。


結局は利用者の慣れや、世の中への定着具合なのだ。




最近のスマホゲームでは歯車のアイコンを見ると
ほとんどの人が「設定関係のボタン」だと理解するが、
これも複数のアプリに共通する仕様のおかげで
徐々に浸透して認識できるようになっただけで、
ひと昔前なら意味がわからなかっただろう。




スマホ画面に映ったものを動かすとき
指でドラッグする操作を「直感的」と感じているかもしれないが、
予備知識のない子供に触らせてみると
物体の手前に指を入れて動かそうとした、という実験結果もある。
確かに現実に物を指1本で動かすなら
真上から押さえ込むより手前から突く方が自然だ。


「直感的」というのはいろいろな場面で共通化しているために
その都度の違和感を感じなくなっているだけで、
必ずしも理屈と操作が一致しているわけではない。


カメラを操作するスティックの向きと同様に、
どういう考え方が自然に感じるのか
植え付けられた感覚に左右されているだけなのだ。


UIを考えるときは多くの人が発想する感覚を
作り手が正しく推測しなければならない。
そのためにはたくさんのゲームやアプリに触れ、
今の世の中に浸透した「常識」を身につける必要がある



mclover.hateblo.jp

熱中してしまうゲームにはハイリスク・ハイリターンの法則が活きている


何度もプレイしたくなるような没入感のあるゲームには
たいてい「ハイリスク・ハイリターンの法則」が活きている。
なんらかの危険が増えるものの
その分、利益も大きくなるという選択肢が用意されているのだ。




たとえば上記の場所でコインを取りに行こうとすると
パックンフラワーの攻撃を食らう危険がある。
しかし単に難易度が高いわけではなく
上の足場を進んでやり過ごすこともできるので、
リスクを取るかどうかの選択はプレイヤーに委ねられている。




マリオのステージにはこういったデザインが多く、
腕に自信のあるプレイヤーに挑戦を呼び掛けてくる。
これこそ初心者にも上級者にも楽しめる工夫だ。




上までブロックが積み上がるとゲームオーバーになるテトリスでは
1段ずつブロックを消して安全に過ごすこともできるが、
わざと1列だけ空け、テトリス棒で一気に消すと得点が高くなる。
ゲームオーバーの状態に近いほど
高い成果を出すチャンスが増えるのだ。




どのゲームでも、パワーの強いキャラは動きが鈍く、
スピードの速いキャラは力が弱く設定されている。
欠点のないキャラクターは存在しないので、
何かで利益を得るにはリスクを負う必要がある。




格闘ゲームでは威力の高い技ほど
それを繰り出すのが難しくなっており、
「失敗するリスク」「習得する苦労」を受け入れないと
高いリターンが得られないようになっている。
威力が高い分、扱いが難しい武器などもゲームの定番だろう。




危機的状況を楽に回避できるような強い武器は
少ない数しか持つことができないので、
今使うか温存しておくかで悩むようになっている。


このように、ゲームにはわざとリスクが用意されており、
それをいつどのように回避するかを
プレイヤーが選べるようになっている。
だからこそ成功したときに「自分の考えが正しかった」と実感し、
自分の作戦が狙い通りにいった達成感を味わうことができるのだ。




ただし、将来への積み立てが無縁で
唯一の正解を模索するようなゲーム性の場合は
こういった法則に当てはまらないものもある。



mclover.hateblo.jp

総アクセス数