とりあえずなんか書いとけ

Python3系とかアイワナ(GM8.1 Standard)とか読書とか

アイワナ:sinカーブを傾ける

タイトルではsinカーブとなっていますが,この記事では任意のオブジェクトの移動を傾ける方法について書いていきます.
簡単に言うと,下の図の左のようなsinカーブを右のような傾いたsinカーブにできるみたいな感じです.
sinカーブ以外にも使えますが,今回はsinカーブを傾けるものとして作成していきます.
※めんどくさいので弧度とか度数とかについては適当でいきます.

f:id:toki_0177:20190206130936p:plain
作れるもののイメージ

媒介変数表示について

これを作成する前に,まずsinカーブで移動させる方法を書いておきましょう.
sinカーブのような任意の曲線に従って移動させるには媒介変数表示というものを使います.
あまり簡単に説明できないので必要ならググってもらうとして,x,y座標を媒介変数という別の変数を用いて表す方法です.
たとえば円の媒介変数表示は
\left \{
\begin{array}{}
x=\cos \theta\\
y=\sin \theta
\end{array}
\right.
になりますが,これをGameMakerで実現しようとすると以下のようなコードを,動かしたいオブジェクトのstepイベントに書けばいいことになります.

//step event
x = center_x + 32 * cos(degtorad(theta))
y = center_y + 32 * sin(degtorad(theta))
theta += 1

こうすると(center_x, center_y)を中心とした半径32ドットの円を360ステップで1周するオブジェクトが完成します.


同様にして,sinカーブを考えてみましょう.
sinカーブを媒介変数表示で表すと下のようになります.
\left \{
\begin{array}{}
x=\theta\\
y=\sin \theta
\end{array}
\right.
これをGameMakerで実現する場合は,以下のようになります.細かい数字は適当です.

//step event
x = xstart + 4 * theta
y = ystart + 32 * sin(degtorad(theta) * 6)
theta += 1

こうすると,(xstart, ystart)から右方向にsinカーブを描きながら進んでいくオブジェクトが完成します.4とか6とかは適当です.


他にも媒介変数表示はいろいろあるので,動かしたいものがあれば調べてみましょう.
ここからは傾ける方法について書いていきます.

回転に使う式

まず,一般的な2次元空間についての話をします.
2次元空間上の点(x, y)を原点の周りに角θだけ回転させた点を(x', y')とすると,
\left \{
\begin{array}{}
x'=x\cos\phi -y\sin\phi\\
y'=x\sin\phi +y\cos\phi
\end{array}
\right.
と表されます.これについても「回転移動の1次変換」とかで調べればわかります.
見た目のイメージでいうとこんな感じ.

f:id:toki_0177:20190206140805p:plain:w200
回転移動のイメージ


ここで,図を見ればわかると思いますがGameMakerと座標軸の取り方が異なっているので,実装する場合はそこを考慮して書く必要があります.
GameMakerの座標軸はy軸が下向きが正となっていますが,角度の取り方は反時計回り方向が正となっているので,先ほどの回転に使う式を
\left \{
\begin{array}{}
x'=x\cos (-\phi) -y\sin (-\phi)\\
y'=x\sin (-\phi) +y\cos (-\phi)
\end{array}
\right.
のように変更する必要があります.

sinカーブを傾ける

ここから,GameMakerでの実装について書いていきます.
自機狙いの弾をsinカーブで飛ばすとすると,createイベントとstepイベントに以下のようなコードを書けばいいです.

//create event
phi = point_direction(x, y, player.x, player.y)
//step event
x_tmp = 4 * theta
y_tmp = 32 * sin(degtorad(theta) * 6)

x = xstart + x_tmp * cos(-degtorad(phi)) - y_tmp * sin(-degtorad(phi))
y = ystart + x_tmp * sin(-degtorad(phi)) + y_tmp * cos(-degtorad(phi))

theta += 1

ちなみに,x_tmp,y_tmpに使いたい媒介変数表示を入れることでsinカーブ以外にも対応させることができます.
これで実装は完了です.