プレイ日記
おちゃめ ochame_nako
SPANIMをまだ使いこなせない初心者に贈る「十字ボタンやスライドパッドを使ってSPANIMでアニメーションしながら自由な方向に移動できる」というサンプルプログラムです。 初心者の方はぜひ参考にしてみてください。
17そうだね
プレイ済み
返信[1]
親投稿
おちゃめ ochame_nako
先日SPANIMを満足に使うことができない初心者のためにSPANIM2命令を作りました。 https://miiverse.nintendo.net/posts/AYMHAAADAAB2V0fsz6Tuqg この命令を使えば書式が簡単になる上にアニメーションをさせるのも容易になるため初心者にぜひ使って欲しいもののSPANIMも最初のとっつきの悪さを乗り越えればそんなに難しいことはないため今回は自作のSPANIM2命令ではなく標準のSPANIM命令を使っています。 まず最初に十字ボタンを使い「移動しながらアニメーションさせる」というサンプルプログラム」です。
0そうだね
プレイ済み
返信[2]
親投稿
おちゃめ ochame_nako
SPANIMで移動しながらアニメーションさせる場合に重要な部分は次の2つです。 「SPANIMはやSPSTOPやSPCHRなどを使って停止できる」ということとSPANIM最中にSPANIMを実行すると1コマ目からまたアニメが開始する(毎フレームSPANIMを実行していたら1コマ目で静止する)ということです。 したがって、SPANIMはアニメーションさせたい最初のボタン入力の時点で実行してボタン入力の無い場合は静止するということが必要になるわけです。 つまり、「キャラが向いている方向が変わる瞬間」「静止状態から動き出す瞬間」にSPANIMを実行すれば良いわけです。 この十字ボタンによるサンプルプログラムでは変数Cが現在のキャラ(向いている方向)、PCが1フレーム前のCの情報、Bが十字ボタンのボタン情報、PBが1フレーム前のBの情報です。 この4つの変数ですべての状況を判断が可能です。
0そうだね
プレイ済み
返信[3]
親投稿
おちゃめ ochame_nako
静止しているのは十字ボタンを押してない時なのでB==0となります。これは!Bと記述が可能です。 IF !B THEN SPCHR 0,C でその方向のアニメーションを停止が可能になります。 向きが変わるのはC!=PCでこれはC-PCと記述が可能です。(後者の記述はC-PC!=0の「!=0」を省略したもの) あとはボタンを押した瞬間を判定すれば良いです。 これはBUTTON(2)を使っても良いのですが、1フレーム前のBの情報が分かっているため「現在ボタンを押していて前のフレームには押してない」ならば「押した瞬間」と分かります。 したがって、IF C-PC || (!PB && B) THEN SPANIM(以下略)とすれば良いのです。
0そうだね
プレイ済み
返信[4]
親投稿
おちゃめ ochame_nako
これを踏まえてスライドパッドの場合を考えてみましょう。 そのためにはスライドパッドで「指定の向きにキャラが向く」というプログラムを作れる必要があります。 つまり、360度あらゆる方向が取得可能なスライドパッドで4方向に変換する必要があるというわけです。 これにはいろいろな方法がありますが、最も確実な方法は角度で考えるということです。 角度を求めるにはATANを使います。 STICK OUT SX,SY:A=DEG(ATAN(SY,SX))とすればAにスライドパッドの角度が「ラジアン」ではなく「度」で入ります。
0そうだね
プレイ済み
返信[5]
親投稿
おちゃめ ochame_nako
ただし、この角度の基準点は右(時計の3時方向)であり、角度は反時計回りに増加していきます。 これはスライドパッドの回転の方向とは逆であるためSPROT 0,Aとすればスライドパッドの動きとキャラの向きが連動してないことが分かるでしょう。 ここではあくまでSPCHRで向きを変えるためSPROTは使わないのですが、スライドパッドの向きど角度が連動していないというのはいろいろな問題点が出てくる可能性があります。 これは90度補正して角度を正負反転してスライドパッドを入力していない場合の判定を行えば問題解決できるとはいえ実はもっと簡単に解決できる方法があるのです。 それはATANのXとYの値を入れ替えることです。
0そうだね
プレイ済み
返信[6]
親投稿
おちゃめ ochame_nako
スライドパッドで取得できるY座標は正負が画面座標と正負が反転したものになっているためこれによってスライドパッドの向きが時計と同じように12時を基準にした時計回りになります。(言い換えればSPROTと連動が可能になる) つまり、スライドパッドで角度を求める場合のみ「ATANのXとYは通常とは逆」と覚えておけば初心者でも容易に解決が可能ということです。 A=DEG(ATAN(SX,SY))でSPROTと連動が可能と書きましたが実は取得できる値は-180度~179度という範囲です。 これでは分かりにくいから0~359度にしたいというのであればA=(DEG(ATAN(SX,SY))+360)MOD 360で可能です。 これによって12時の方向が0度で3時方向が90度、6時方向が180度、9時方向が270度になります。
0そうだね
プレイ済み
返信[7]
親投稿
おちゃめ ochame_nako
ここで、上下左右90度に分割して考えてみましょう。 上は315度~359度、もしくは0度~44度、右は45度~134度、下は135度~224度、左は225度~31 4度となります。 上方向がちょうど0度の境目にまたがっているため分かりづらいというのであればA=(DEG(ATAN (SX,SY))+405)MOD 360とすれば良いです。 こうすれば上方向の左端を基準にするため0~89、90~179、180~269、270~359でキレイに90の倍数を境にして上、 右、下、左の4分割が可能になります。 キレイに分割ができるということは判定を単純化できる(簡単に判定ができる)というメリットがあります。
0そうだね
プレイ済み
返信[8]
親投稿
おちゃめ ochame_nako
ここまで来たら完成まであと一歩です。 スライドパッドでSPANIMでアニメーションしながら移動する場合もボタンと同じように押してない時は静止、向きが変わった場合や静止している状態から動き出した瞬間はSPANIMを実行で何ら変わりません。 ということでできたのがこのサンプルプログラムです。 このDの値がスライドパッドが押されている時は0、押されてない時は1になり、PDが1フレーム前の情報となります。 それさえ分かればボタンで判定するのと何ら変わらないと思います。
0そうだね
プレイ済み
返信[9]
親投稿
おちゃめ ochame_nako
今回はATANを使って角度を元に求めましたが4方向であれば下記のリストのようにSX、SYの大小比較だけで向きを求めることも可能です。(こっちの方が簡単!) 結果が同じであっても様々なやり方があります。今回の方法だけが正解というわけではなく正解は無数にあるのでぜひ色々試してみてください。 またSPANIMの速度は移動速度に関係なく一定となっていますが、移動が速い時は駆け足で遅い時はゆっくり歩くということも可能なので興味がある人は挑戦してみると良いかもしれません。 キャラを自分で自由に動かせるようになるとゲームを作っていて楽しくなります。 初心者の方はまずは自分の思い通りにキャラを動かせるという快感を味わってみてください。
0そうだね
プレイ済み
返信[10]
親投稿
ひろきち henahenachoco
めちゃめちゃ細かい部分での質問なのですが、 B==0 を !B と書ける、みたいなことってどうやって知るんですか? 別の言語でそういった書き方ができて、同じように書いてみたらできた、 みたいなことでしょうか? それともプログラミング全般のセオリーのようなものでしょうか? そういった、少し進んだプログラムの書き方を知りたいです。
1そうだね
プレイ済み
返信[11]
親投稿
おちゃめ ochame_nako
ひろきちさんへ これを理解する前に知っておくべきことが2つあります。 1つは(プチコンのみではなくほとんどの処理系において)条件判断はtrue(0以外の値)かfalse(0の値)だけで判断がされるということです。(条件式が成立の時はtrue、不成立の時はfalseとなる) !Bの「!」は論理否定(論理反転)と呼ばれる記号でありtrueとfalseを入れ替えるものです。分かりやすく言えば「0を1」に「1を0」に(正確には「0以外の数を0」に)するものです。 IF B==0 THEN ~というのはBの値が0の時にtrueとなるためIF !B THEN ~としても同じになるというわけです。 つまり、IF B==0 THEN ~がIF !B THEN ~と記述可能なのは裏技でも何でもなく上記の2つのことさえ理解できれば自然に分かるものなのです。
2そうだね
プレイ済み
返信[12]
親投稿
まりを tomoyaTT88
先生ェ! 説明全てみてもわからない私はこの先大丈夫でしょうか!?
1そうだね
プレイ済み
返信[13]
親投稿
ひろきち henahenachoco
TRUEとFALSEについてはなんとなく知っていたんですが、 条件式に=を必ずしも使う必要がない、ということを知らなかったです。 ありがとうございます!
1そうだね
プレイ済み
返信[14]
親投稿
ひろきち henahenachoco
「=を必ずしも使う必要がない」って、 これは 〈 だけ、とか使ってるから当たり前のようにやっていたのに… なんだかトンチンカンなこと書いてすみません。 とにかく解説ありがとうございます!
1そうだね
プレイ済み
返信[15]
親投稿
そひ ladixsofiya
似た疑問を覚えて 自分には早すぎたと考えるのをやめたものだけど 結構単純な事だったのねぇ。 自分で書くとなると混乱しそうなので記憶の隅っこに留めておこ。
2そうだね
プレイ済み
返信[16]
親投稿
「==」とか「!=」とか「>」とか「>=」とかは「比較演算子」と言って 左辺と右辺を比較した結果を演算結果として返す記号で、実は「+」とか「*」とかの足し算やかけ算と同じような計算記号なのです。 「3+5」は結果が「8」になるけど、「B==0」としてBhs0だったらこの答えが「TRUE(値は1)」となるのです。 計算結果なので、変数の代入にもできて「X=(B==0)」とすれば変数X に 「B==0」の結果がTRUE(値は1)かFALSE(値は0)で代入されます。 IF文は比較式の部分に書いたものを TRUE(0以外)かFALSE(0)かで判断します。 BUTTON()の結果はボタンが押されてなければ 0 になるので FALSEとして扱うことができて、ボタンが押されていればボタンに対応した数値になるので 0以外として TRUEと扱うことができます。
1そうだね
プレイ済み
返信[17]
親投稿
誤字ミス訂正 × Bhs0 ○ Bが0 プログラムは実行させたいことをコードとして書くことなので 「B==0」は「Bが0のとき」と解釈できるけど 「!B」は「Bに値がないとき(Bに値がある、ではない)」と解釈できます どちらもプログラムとして動く結果は同じだけど、日本語に直すと厳密には意味が違ってきます。 この厳密には意味が違うことを意識してないと、バグの原因として気づかないまま「なんかプログラムの動きがおかしい」ってのが起きることがあるので、条件式に本来の自分が動かしたい条件とちょっとちがう書き方をする場合は注意したほうがいいです。 「1以上(1含む)」の条件を「B>=1」や「B>0」と書くところ「B」と書いてみたけど、実はB が -1 のときに「B>0」はFALSEだけど「B」はTRUEとして扱われるとか、そういうのがあったりします。
2そうだね
プレイ済み
返信[18]
親投稿
おちゃめさんの解説の補足 スライドパッドでATAN使って角度計算しているところは方眼紙に時計や座標を書いたりすると分かりやすくなります。 (今回の以外でもプログラムの説明はあたまのなかで考えるより紙に書いたほうが理解しやすいです) 考え方はスライドパッドの入力向きを、どこかを0度の基準として角度として取得しようとしていて、プログラムで使いやすいように0度の位置を変更しています(数学なら3時の方向が0度で反時計回りに増える) 説明中の「+405」は「+360+45」を表してます MODは 割り算のあまりを求める計算で、角度の範囲がマイナス値にあると思うように動作しないので、360を足して 360の割り算を求めることで、0から359の範囲を求めてます。 円の角度とか第1象限とアークタンジェントとか中学や高校数学のお話もでてくるけど、数学ってこういうところで役に立ってきたりするのです。
1そうだね
プレイ済み
返信[19]
親投稿
おちゃめ ochame_nako
ひろきちさんへ 極端な話をすればこんなIF文も書くことが可能です。 IF 1 THEN ~(必ずTHEN以下を実行する) IF 0 THEN ~(必ずTHEN以下を実行しない) だから、ボタン入力判定でIF B AND #A THEN ~というのもB AND #Aの値が「0」か「0以外か」で実行するかどうかが決まるわけです。 IF B AND #A THEN~を分かりやすく書けば IF (B AND #A)==#A THEN ~となります。 動作的にはIF (B AND #A)!=0 THEN ~と同じですが、このIFの意味合いとしては前者の方が分かりやすいと思います。 この「==#A」とか「!=0」とかは比較演算と言いますが、これを常に省略できるというわけではなく省略できない場合もあるということ知っておいた方が良いかもしれません。
2そうだね
プレイ済み
返信[20]
親投稿
おちゃめ ochame_nako
(続き) 比較演算の省略について詳しくは下記のトピックスを見てください。 https://miiverse.nintendo.net/posts/AYMHAAACAAADVHjrpjduHA まりをさんへ これだけ書いても端折っている部分がかなりあるため分からない部分があれば言ってもらえると助かります。 MODの部分はたんじぇさんが補足してくださっているのでそれを参考にしてみてください。 たんじぇさんへ 補足ありがとうございます。
2そうだね
プレイ済み
返信[21]
親投稿
ふぬー、STICkで8方向とかはこんな風に求めるのか・・・わたしゃROUNDして小数点以下切り捨てしてたよ。 yは上下逆になっちゃうからー1かけてた。
0そうだね
プレイ済み
返信[22]
親投稿
おちゃめ ochame_nako
そひさんへ プログラミングは自由であり今回書いた方法もあくまで一例でしかありません。 自分で分かりやすい方法でやるのがベターだと思います。 うぎゃ~さんへ スライドパッドで上下逆になるのは今回のようにATAN使用時にXとYを入れ替えるのが最も簡単だと私は思いますが、方法はいろいろあるので自分にあった方法で良いでしょう。 あとMODは使用時に強制的に整数型に変換されてしまうため12時の方向を0で時計回りに0~7の8方向の値を取得したいという場合は((DEG(ATAN(SX,SY))+382.5)/45)MOD 8と短く記述が可能です。
0そうだね
プレイ済み
返信[23]
親投稿
nobu divine-creator
う~む…。おちゃめさんが作られたサンプルのうち、XとYの大小による方向転換のほうを参考にして、CAT_WALK_PADはできたのですが、それをタッチに応用しようとしたら、左や上向きに正しく変化できない状態になりました…orz。 たぶん、スライドパッドは左がマイナスになるのに対し、タッチにはマイナスが無いため、そこが上手く変えられなかったせいだと思います。 また、スライドパッドのY軸はプラスとマイナスが逆になっていることも影響しているのだと分かるのですが、それをどう修正すれば良いのか?が分かりません! イメージ的には何となく分かっていても、実際にそれを表す式が作れないのです…OTL。 助けてください!
0そうだね
プレイ済み