コピペで動かすラムダフレーム

> ホームへ

目次


自分のフレームを設計しよう

とりあえず、サンプルのフレームを動かすことはできたかい?

それじゃあ、自分のフレームを作ってみよう。

フレームは設計できたかい?

フレームを作ったら、もちろん動かしてみたいよね?

でも、プログラミングを深~く理解してから動かすなんていったら、君はフレームを動かす前に、飽きてしまって、

「このクソゲー!1草コイン分の価値もないよ!」と叫んで、すぐさまアンインストールしてしまうかもしれないね。

なので、この記事では、ポケモンGOをしながらでもできるくらいにハードルを下げて、

コピー&ペーストでフレームを動かせるようなチュートリアルを示していくよ。

具体的には、キーボードでフレームの動きを指定できるようになるよ。コピペでね。

必要最小限のプログラム

import qualified Script as S

script :: S.Script ()
script = do
  -- ハイフン2つ(--)より右の文字はコメントだよ。無視されるよ。
  time <- S.getTime     -- 今の時刻を取得
  S.putStr_ (show time) -- 時刻を画面上に表示

自分で作った hsファイル(動画では'Frame.hs')をテキストエディタで開いて、上のコードをコピーして貼り付けよう。

ゲームを始めるとこんな感じに、左下に数字が表示されるよ。

(プレイ中にESCキーを押すとタイトル画面に戻れるよ。)

image

この数字、どんどん大きくなっているのがわかるかな。実はこれは時刻なんだよ。

さっきのプログラムは、この時刻を1回表示するようなものだったんだ。

ということは、このプログラムは、1秒間に何度も実行されているんだね。

つまり、このプログラムは、 その時刻に何をするか? を書いているということになるね。

動かそう!

プログラムには何を書けばいいのか分かったところで動かしてみよう。

でも、今のフレームには動く部分が無いので、ちょっとフレームを改造しよう。

動く部分を取り付けたら、次のプログラムを Frame.hs に貼り付けよう。

import qualified Script        as S

script :: S.Script ()
script = do
  S.command (S.AddRotImpulse "wheel-l" 5)
  S.command (S.AddRotImpulse "wheel-r" 5)

ゲームを開始すると、ホイールが勝手に回転して、左に動いていくと思うよ。

キーボードの状態を知りたい!

ホイールは動かせたかな?

これでもいいけど、ずっと回転しっぱなしじゃあ、自由に移動できないよね。

キーボードの押されている時だけ移動するようにしてみよう。

キーボードが押されているかを知る

import qualified Script        as S
import qualified Input.Keycode as K -- この行を追加したよ!

script :: S.Script ()
script = do
  holdingA <- S.getKeyboardState K.Key'A -- [A]キーが押されているかどうかを得る
  putStr_ (show holdingA)

このコードでゲームを開始すると、

[A]キーを押した時は True と表示されるね。

True当てはまる という意味だよ。

逆に、押していないときは False と表示されるね。

False正しくない とかいう意味だよ。

holdingA <- S.getKeyboardState K.Key'A

こうすると、[A]キーを押した時に、holdingA には True が割り当てられて、

S.putStr_ (show holdingA)

こうすると、 holdingA が画面に表示されるんだ。

さらに、次のコードのように、最後の5行を追加してみよう。

import qualified Script        as S
import qualified Input.Keycode as K

script :: S.Script ()
script = do
  holdingA <- S.getKeyboardState K.Key'A -- [A]キーが押されているかどうかを得る
  S.putStr_ (show holdingA)
  if holdingA
    then do
      S.command (S.AddRotImpulse "wheel-l" 5)
      S.command (S.AddRotImpulse "wheel-r" 5)
    else return ()

これを実行すると、[A]を押している時だけ、ホイールが回るようになったね。

これは、他のプログラミング言語でもおなじみの、if then else で実現しているよ。

if TrueFalseの何か
  then Trueの時に実行されるアクション
  else Falseの時に実行されるアクション

[A]キーを押している時だけ、holdingAがTrueになったから、ホイールが回る部分が実行されたんだね。

else の後には、 return () ってあるけど、これは何もしないっていう意味だよ。

(実は、厳密には違うような気がするけど、今は深く考えないでいいよ。)

他の一般的な言語と違ってちょっと特徴的なのは、elseは省略できないんだよ。

だから、何もしないのに else が必要なんだ。

(これは面倒なので、実は when という関数で置き換えることができるんだけど、今は気にしないでね。)

ちなみに、 K.Key'A の部分は、自分の好きなキーに変えられるよ。

例えば、 K.Key'Space に変えれば、スペースキーを押した時だけホイールが回るようになるんだ。

ここに全てのキーが書かれているよ。

キーボードを(押す | 離す)瞬間を知る

キーが押されているかどうかを知ることができるようになったけど、

このままだと「押された瞬間を判断して弾を撃つ」みたいなことはできないよね。

ということで、さっきのコードに、最後の6行を追加してみてね。

import qualified Script        as S
import qualified Input.Keycode as K

script :: S.Script ()
script = do
  holdingA <- S.getKeyboardState K.Key'A -- [A]キーが押されているかどうかを得る
  S.putStr_ (show holdingA)
  if holdingA
    then do
      S.command (S.AddRotImpulse "wheel-l" 5)
      S.command (S.AddRotImpulse "wheel-r" 5)
    else return ()

  kes <- S.getKeyboardEvents -- キーボードのイベントを得る。
  if S.KeyboardEvent K.Key'J S.Pressed `elem` kes -- [J]キーがちょうど押されたかどうかを得る
    then do
      S.command (S.ShootGun "gun-l") -- gun-l から弾を撃つ
      S.command (S.ShootGun "gun-r") -- gun-r から弾を撃つ
    else return ()

K.Key'J の部分を変えれば、好きなキーで撃つことができるよ。

ここに全てのキーが書かれているよ。

image

逆引きコード辞典

やりたいことからコードを見つけてコピペしよう。

ジョイントを動かす

image

import qualified Script        as S
import qualified Input.Keycode as K

script = do
  S.command (S.SetAngle "Jointの名前" (pi/2))

機銃から弾を撃つ

image

import qualified Script        as S
import qualified Input.Keycode as K

script = do
  S.command (S.ShootGun "Gunの名前") -- 弾を撃つ

ホイールを動かす

image

script = do
  holdingA <- S.getKeyboardState K.Key'A -- [A]キーが押されているか?
  if holdingA
    then S.command (S.AddRotImpulse "Wheelの名前" (-5)) -- ホイールを回転させる
    else return ()

  -- `-5` の部分は調整してね。大きいほど速く回るよ。
  -- 正(プラス)は左回転(反時計回り)
  -- 負(マイナス)は右回転(時計回り)

ジェットで飛ぶ

image

script = do
  holdingS <- S.getKeyboardState K.Key'S -- [S]キーが押されているか?
  if holdingS
    then S.command $ S.command $ S.SetJetOperation "ジェットの名前" $ Just $ JetOpPower 10
    else S.command $ S.SetJetOperation "ジェットの名前" Nothing

  -- `10` の部分を変えて、ジェットの強さを調整してね。

> ホームへ