MathematicaでGUIのゲームを作ることはできるか?
おそらくあまり知られていないですが、mathematicaはアニメーションやボタンイベント、クリックイベントなど、GUIを作るときにJavaなどでは良く使うような関数が揃っています。
そればかりか、PopupMenuやゲームパッドコントローラの入力を読み込んだりとぶっ飛んだものまであります。
これだけあればいろいろ作れるのではないか?と思い立ったので、やってみました。
随時更新型のゲームを作る場合、使う枠組はこのようになると思います。
Dynamic[Refresh[ (* 各種計算 *) Graphics[ { (* 描画 *) } ], UpdateInterval -> 3 ] ]
Dynamicは値を随時変更して出力し、Refreshのオプション、UpdateIntervalで更新頻度を決定します。
UpdateIntervalは0に設定することで「できるだけ速く」という設定になりますが、速度が安定しないので1よりは大きい値を設定するのが良いのではないでしょうか。
この辺はマシンパワーとの兼ね合いもあります。
で、作ってみたのがこちらです。
バーを動かして玉を跳ね返すだけの、ゲームというのもおこがましいものですけども・・・
バーで跳ね返すとSuccessを+1、跳ね返せずに下の枠にあたってしまうとFailedを+1します。
バーの操作方法はMousePositionを呼び、マウスの現在位置を反映するようにしています。
ブロック崩しかテーブルテニスぐらいまでなら発展させられるかも。
以下、誰得ソースです。
X = 0; Y = 0; XFLAG = True; YFLAG = True; GSizeX = 100; GSizeY = 200; Speed = 1; BarLength = 40; BarPosition = -20; SuccessCount = 0; FailedCount = 0; Suc Dynamic[Refresh[ If[XFLAG == True, X += Speed, X -= Speed ]; If[YFLAG == True, Y += Speed, Y -= Speed]; If[X > GSizeX, XFLAG = False]; If[X < -GSizeX, XFLAG = True]; If[Y > GSizeY, YFLAG = False]; If[Y < -GSizeY, YFLAG = True; FailedCount++]; BarPosition = MousePosition["Graphics", {0, 0}][[1]]; BarXL = BarPosition - BarLength 0.5; BarXR = BarPosition + BarLength 0.5; If[Y == -180 && X >= BarXL && X <= BarXR && YFLAG == False, YFLAG = True; SuccessCount++]; MyText1 = "Success - " <> ToString[SuccessCount]; MyText2 = "Failed - " <> ToString[FailedCount]; Graphics[ { Red, Disk[{X, Y}, 3], Blue, Thick, Line[{ {BarXL, -180}, {BarXR, -180} }], Purple, Text[Style[MyText1, FontSize -> 20], {-GSizeX + 50, GSizeY - 10}], Text[Style[MyText2, FontSize -> 20], {-GSizeX + 50, GSizeY - 30}] }, PlotRange -> {{-GSizeX, GSizeX}, {-GSizeY, GSizeY}}, Frame -> True, FrameTicks -> None ], UpdateInterval -> 3] ]
さて、作りながら痛感しましたが、Mathematicaで随時更新のプログラムを書いてはいけないと思います。
他の言語より圧倒的に遅いです。なにより速度が安定せず、すぐに音を上げます。今はまだオブジェクトが少ないので動いていますが、数が多くなるとカタカタになってしまうと思われます。
Graphics部分を毎回律儀に再描画していたり、変数の精度が無駄に高いだろうことが原因だと思いますが・・・それからコンパイルがないことも大きいかな。
今回は手続き的に書きましたが、そもそもMathematicaは手続き的な書き方だと圧倒的に計算速度が遅くなるので、書き方を変えることで改善できるかもしれません。
もっといろいろ勉強しなくてはと感じました。