本気でプログラマーになるためのプログラミング講座
Akichun★PG (YouTube 2019/7/17~)
傑作(30点) 2023年12月10日 ひっちぃ
JavaScriptで任天堂「スーパーマリオブラザーズ」のようなゲームを作る方法を途中まで解説した動画。
最近仕事でTypeScript(JavaScriptをマイクロソフトが強化したやつ)とReactを使っていて、クラスを使わずに関数でなんでもやってしまう手法に辟易したのだけど、そういえばHTML5ならもうゲームでもなんでもブラウザで動くものが簡単にJavaScriptで作れてしまうというので、いまは解説動画なんて山ほどあるだろうと思って検索してみたら思ったほど引っかからず、その中ですごく分かりやすそうなのを選んだのがこれ。おもしろかった。
著作権がどうなっているのか分からないけれど、いかにもスーパーマリオブラザーズ風のドット絵の素材をもとに、マリオをキーボードで操ってスクロールするフィールドを自在に動き、ブロックを叩いて砕いたりキノコを出したりするのを一つ一つ順にリアルタイムで実装して解説してみせている。
一応元のゲームについて簡単に解説しておくと、京都で花札やトランプなどを作っていた任天堂が世界的な大企業になった始まりが家庭用ゲーム機「ファミリーコンピュータ」で、なかでも「スーパーマリオブラザーズ」は横スクロールアクションゲームの元祖とも言える名作として知られている。ゲームの内容は、配管工のマリオが大魔王クッパにさらわれたピーチ姫を救うため、ブロックでできた世界を縦横無尽に駆け回るというもの。
さすがに露骨にゲーム名やキャラ名を出すのはまずいと思ったのか、「スーパーマリオなんちゃら(伏字になってないw)」「おじさん(マリオのこと)」など言い換えているのが地味におもしろかった。
収録中によく救急車が通り、そのたびにいちいちそれに触れるのがウケた。この人、すっとぼけながらも素朴で人の良さそうな性格をしていて、あえて編集していないので時間を気にしながらやっているし、よく間違いをしてそのたびにささっと原因を調べてすぐ直している。あらかじめやりかたを知っている上で解説しているにせよ、かなり熟練していなければこの動きはできないと思う。
ちなみにどうやって作ったのかというと、ドット絵素材にはアニメーションになったマリオのドット絵がいくつもあるため、キー操作によりマリオを動かすたびにそれを順番に表示することによって歩いたり走ったりしているように見せている。オリジナルは「スプライト」と呼ばれるテレビの走査線に直接キャラクターを描きこむ仕組みを使っており、そのため当時はキャラが横に数体並ぶと描き切れなくなって点滅してしまっていたけれど、いまはJavaScriptといえど爆速で全部描けてしまう。
背景のほうも、当時はハードの性能が低かったため、ピクセル単位ではなく8×8ピクセルのあらかじめ決められた絵のパターンをタイルのように敷き詰めて描いていた。VRAMのどの座標から描くかを変えることによって画面をスクロールしているように見せることもできた。もちろんいまはそんなことをする必要はなくて、毎秒数十コマをベタに描いていてもスムーズに動く。メモリのコピーにDMAを使っていた時代も昔となった。
HTML5についてもうちょっと詳しく説明すると、CANVASオブジェクトという描画のためのオブジェクトが用意されていて、その中の2D用のコンテキストを取得して操作すると自由に絵が描ける。3D用のコンテキストを使うと3Dも描けるらしい。で、描いた絵をアニメーションさせるには、windowオブジェクトのrequestAnimationFrame関数に描画用のコールバック(どっかから呼ばれることが前提の処理)を与えて呼び出すことにより実現できる。そうするとブラウザは、毎秒60回とかでブラウザ自身が表示しなおすタイミングでコールバックを呼び出してくれるので、ゲーム画面を描く関数をコールバックとして作って与えればよい。
キーボードやマウスからの入力は、別途イベントハンドラで読み取った情報を適当な変数に設定しておき、コールバックの中で読み取るようにしていた。
動画を見るとパッと見、本当にスーパーマリオブラザーズそっくりにできていて驚かされる。マリオが急に別の方向を向いたときの振りむいたアニメーションとか、ジャンプ中に腕を上げている動作とか、if文で細かく作りこんでいた。
批判もすると、座標をピクセル単位で扱うと細かい動きが表現できないので小数を使っているのだけど、なにも意識しないと浮動小数点数になって誤差が生じて動作がおかしくなる可能性があるからと、固定小数点数つまりあらかじめ百などを掛けた値で整数として計算し、画面に表示するときに割って使っているのは、ちょっと初心者には難しいと思う。動画では最終的に16を掛けて計算しているのだけど、さらにそれをビット演算で行っていて、たぶん本当の初心者にはついてこれないんじゃないだろうか。じゃあ何が正解だったかと言われると微妙なんだけど、誤差が生じる前提で普通に小数を使うのがよかったんじゃないかと思う。まあ昔はどうやっていたのかというのを知りたい人には参考になったと思うけど。
そういえば昔は、たとえば80を掛けるときは64と16に分けてビット演算して最後に足した方が速い、なんてことを友人が得意げに話していたのを思い出した。いまはどうしているんだろう(遠い目)。
この動画を見つけたあとで、いったんチャンネルのホームに飛んでどの動画から見ればいいのか確認してみたのだけどよくわからなかった。この順番に見て!みたいな案内が欲しかった。どうやらシューティングゲームの動画のほうが先らしい。
ゲームの基本的なしくみだけ作って終わってしまっている。敵も出てこないし、オープニングもないし、ステージクリアもできない。穴に落ちても死なない。最低限遊べるところまで作って欲しかった。なぜかツタを伸ばすのはやっていた。
用意するのはブラウザとメモ帳とあとドット絵だけなので、暇さえあれば誰でもできる…んなわけないかw 動画が結構わかりやすく作られているのに数千再生しかされていないのが意外だった。まあわかりやすいと言っても大学で情報工学を学んだ自分からみての話なので、本当の素人からするともっとつまずくところがあるのだと思う。それにいまさらスーパーマリオって、っていうのもありそう。いまはUnityとかで3Dアクションゲームでも作った方がウケるのかも。
最近知った情報によると、オープンソースソフトウェアを多く抱えた超有名リポジトリ管理コミュニティサイトgithubの中では、なんと現在JavaScriptで書かれたソフトウェアが一番多いらしい。そりゃもうこんだけできれば他の開発環境なんて使う意味が薄れてきた。まあガチでCPUやGPUを使う物理演算やAIなんかを使ったアプリを作るのは無理なんだけど、普通のアプリと区別がつかないような見せ方もできるので、まずはこれで作れないか検討してからのほうがいいと思う。どうしても難しいところだけAPIで外出しにするとかすればいいんだし。
というわけで、ゲーム作り、特にレトロゲームに興味のある人なんかはぜひ見てみるといいと思う。
[参考] https://www.youtube.com/ watch?v=ZKPrG3PlMSg&list=PLa3BDw ShqOrQWEzrFSI8qD5e14KsCwUAR
|