[書評] "ゲーム&モダンJavaScript文法で2倍楽しい" グラフィックスプログラミング入門

著者のdoxas様より御恵贈頂きました。内容のご紹介と感想を記したいと思います。
結論を先に書いておきますが、JavaScriptの初心者の方から、これまでゲームの開発をされたことが無い方、ブラウザ上でのCanvasを用いたプログラミングによる画像生成に興味のある方等にとてもお勧めです:+1:

技術評論社: https://gihyo.jp/book/2020/978-4-297-11085-7/
![表紙](https://gihyo.jp/assets/images/cover/2020/thumb/TH160_9784297110857.jpg
 "表紙")

ソースコード: https://github.com/doxas/graphics-programming-book

本書指定推奨開発環境:
- Chrome
- Visual Studio Code

# 著者doxasさんについて

私とdoxasさんとは直で会ったことは2、3度しかないのですが、初めてお会いしたのは2014年6月のことでした。当時、既に私はdoxasさんのWebGL開発支援サイトに1読者としてかなりお世話になっておりました。

https://wgld.org

こちらのサイトはWebGLのコードの書き方を日本語で1から完全に教えるという当時は非常に珍しくありがたいサイトです。そのdoxasさんがHTML5のイベントにて講師として登場されるというので非常に楽しみにしながら1観客として参加しました。現れたdoxasさんはまだ若く、塾講師のようにハキハキと話される方でした。その時にdoxasさんが、自分はサンデープログラマであり、(当時は)通常は全く異なる仕事をされていると伺って非常に驚いた覚えがあります。WebGLをご存知の方ならおわかり頂けるかと思うのですが、WebGLはOpenGL ESを元にしたWeb上でGPUを用いた3Dグラフィックスを実現する基礎技術です。当然、中身はかなり低レイヤーの技術であり、難しいものです。専門の技術者以外の方がこのような詳細なサイトを作られたとは信じられない思いでした。

私は優秀な技術者というのは技術に対する「好き」という感情が桁外れな人達だと常日頃から感じています。私の周りの優秀なプログラマはまるで呼吸をするように常日頃からプログラムを書いたり技術に触れている人達でした。doxasさんもWebGLに対するその愛は上記のサイトでの実に細かな解説に溢れています。doxasさんの初心者を落ちこぼれにさせまいとする事細かな説明は時にある程度わかっている人には冗長にもなりえるのですが、知識がなく、周りに頼る人がいない人にはこれほど頼りになるものはありません。ある方はこの説明の仕方を"「なんとしてでもお前に基礎を叩き込むぞ」みたいなdoxas節"と表現されております :smile:

<blockquote class="twitter-tweet"><a href="https://twitter.com/murasaki_0606/status/1220728010959216643"/></blockquote>


実際、doxasさんは上記の解説サイトだけでは足りずにWebGLを利用したサイトを紹介するWebGL総本山を開設し、さらには御自身でWebGLの塾を開設してしまいました。

WebGL総本山: https://webgl.souhonzan.org
WebGLスクール: https://webgl.souhonzan.org/entry/?v=0003

正直、1つの技術だけに入れ込むというのは中々難しいものです。しかしdoxasさんはWebGLを広めたいという欲求にかられ、実際に何年も有料でのスクールの運営を成功させました。そしていつもTwitterでどうすれば難しい数学に基づく3DCGの世界を理解してもらえるのか、その点について苦心されています。

非常に稀有な方だと感じます。

# 書籍の内容について

そんなdoxasさんが書籍を書かれたというので当然、中身はWebGLだと思いました。ところが中身は2Dだったのです。これには驚きました。しかし本書はいかにもdoxasさんの本でありました。

本書のタイトルはグラフィックスプログラミング入門とされています。通常のグラフィックスの本ですと内容がお絵描きに寄せてあったり、画像処理に寄せてあったりします。本書でも簡単なお絵描きや画像処理は行っています。しかし、本書が大きく力を入れており、さらに本書の大きな特徴となっているのはベクトルをメインとした数学的な空間の捉え方とそれを用いたゲーム開発だったのです。

本書は8章で構成されています。

1章は「基礎の基礎」と名付けられCGの世界がどのような世界かを紹介します。

2章は「ES2015入門」としてJavaScriptを学びます。
バージョン管理の説明を避けるためソースの配布はGitHubながらもzipで落とせることを説明。
環境をChromeに限定することで説明を最小限にしていますが、その分デバッグコンソールの使い方を説明することで実用性が高くなっています。本書特有な説明としてはコメントにJSDocを徹底しているところが面白いと思いました。この章のみでなく、全体的ですが仕事にも使えるような美しいコードを重視される説明が多いかと思います。5章の中に説明が分かれていますが、JSに関してはprototype basedであることを重点的に説明されているのが印象的でした。ES2015なのでclass構文を使うのですが、一般的なクラスによるオブジェクト指向言語ではないということをしっかりと説明されているのが良かったと思います。

3章は一転してグラフィックプログラミングに必要な数学の基礎、三角関数と行列を学びます。
いつだったか、どこかの政治家が三角関数は実生活には何の役にも立たないと発言して炎上しました。もちろん、実際には三角関数は現代社会ではなくてはならないものです。そのことを読者は5章からのゲーム開発で嫌というほど知ることになります:laughing: ここで数学が出てくると引く人がでるかもしれません。しかし、実際には三角関数はただの比でしかありません。関数自体はコンピュータが計算してくれます。大事なことは内積や外積などの関係とその利用方法を知ることです。本書は主にベクトル、三角関数、行列を扱いますが、これは小学生でも算数の成績が良い子なら問題無く理解できるでしょう。ベクトルは数の組み合わせでしかなく、行列演算は足し算とかけ算の延長でしかありません。できれば親御さんやお兄さん、お姉さんがちょっと手助けしてあげると良いかと思います。
82ページのコラムで説明される内積、外積の説明は至高の一文だと思います。5章以降でわからなくなったらこのページに戻ると良いでしょう。

4章ではWeb上でグラフィックを書くための基本としてCanvas2Dを学びます。これは難しいことは何もありません。命令通りにブラウザが絵を描いてくれますので楽しんで下さい。

## ゲーム開発 (5章～7章)

5章から7章までは楽しい、楽しい、ゲームの開発です。題材はシューティングゲームです。

ここからの章ではプログラムを漸進的に徐々に拡張していくことで開発します。
バージョン管理の説明を省くためにプログラムはディレクトリ別にバージョンが分けられております。
何と3章にわたり、1つのゲームで23もの別バージョンでの解説になります。

doxasさんの「なんとしてでもお前に基礎を叩き込むぞ」の解説はわざと失敗を体験させることも含みます。例えば最初は自機の移動がカクカクになりますが、その後、理由と改善策が提示されます。また自機の弾も最初は一気に弾が出てしまい、弾切れになりますが、それをどう調整するかが提示され、さらには3-wayへと改善され、画像の回転表示等へと説明が続きます。

コードは日本語でほぼ1行毎のようにwhyを示すコメントが付けられています。これは本当に大変だったのではと思います。

本書のゲーム実装では私は結構な衝撃を受けることになりました。ちょっと脱線するのですが読者はゲームを開発されたことがありますでしょうか？

昔はゲームもかなり単純でした。画面は文字列だけだったり、グラフィックが使えても色が8色だけだったり、狭い空間であったりしました。この時代ゲームは整数を使うのが普通でした。計算機というのは整数のほうが実数よりも計算が速いものです。昔のPCは今のものに比べると信じられない程遅かったので整数を使い座標を指定し、画面の値を直接読んで衝突判定をしたりしたものでした。ゲームの開発と言えば最適化との戦いでした。

例えば2004年に出版された「シューティングゲーム アルゴリズム マニアックス (著・松浦健一郎)」ではDDA(デジタル微分解析器)を用いた整数のみで自機狙い弾を実装するアルゴリズム等が紹介されています。

本書のプログラムはとても富豪的です。全てのキャラクターは自機、
敵機の弾を問わずCharacterクラスを継承し、位置ベクトルと速度ベクトルを持ちます。移動は位置ベクトルに速度ベクトルを足すだけです。自機の速度ベクトルを回転させれば自機の3-way弾は斜めに飛んで行きます。敵機の自機狙い弾は自機と敵機の間のベクトルを取るだけです。圧巻は最後のホーミング弾でしょう。ホーミング弾自身のベクトルと自機との間のベクトルと、内積で回転量を、外積で回転の向きを決定するだけとなります。衝突判定はオブジェクト間の距離の問題のみになります。

これには3章で習った数学がバンバンと利用されます。

これは頭が古い人間には考えられない世界です。PCが遅くて仕方が無い時代の人間はこのようなやり方では組み合わせの爆発が起こってとても遅くなるのではと余計なことを考えてしまいます。しかし、今のPCは、JavaScriptは流石です。これだけ複雑で、莫大な量の演算をきちんと60FPSを実現する16msの間にやってくれます。

本書はゲーム開発が本題ではありません。あくまでもグラフィックスプログラミングが主題です。そのような本書では最適化の話等は枝葉でしょう。そういう意味で、本書の解説はゲームを通して複雑な関係性を持つグラフィックをどのように構築するか、初心者に向けての説明に実にうまく成功していると感じました。

また言語がJavaScriptなのも利点です。過去多くのゲームの教科書はC++で、アドレス参照等の難解な文法を理解することが必要でした。しかし、本書ではJSでほぼarrayを用いて本質的な問題だけに集中することができます。これは本当に良い時代になったと感じます。

## 8章 画像処理

8章は一転して画像処理を行います。ImageDataにより画像のpixelデータを得て、演算によりノイズ除去、エッジ検出、ネガ、モザイクを作成します。

この章はちょっとだけ、物足りないとは感じました。本書がグラフィックプログラミングの本であるために、これらのテーマも避けては通れなかったのかもしれません。画像処理の基礎中の基礎を学ぶという意味では成功しておりますが、欲を言えばこの内容を本書のこの場所で扱うのであればもう一工夫が欲しかったと感じます。

ピクセルの処理はあまり3章の数学を活かせてはいません。できればデモで良くある画像に対するアニメーションの波の加工等、より高度な内容も付属できれば良かったのではないかと思います。そうすれば3章の数学と5章からのゲーム開発とanimationの内容が活かせたのではと考えます。

# 重箱の隅

本書は大変に満足できる内容だったのですが、重箱の隅に過ぎないのですが気になる点もありました。その内の1つがmap関数の扱いです。

JSのmapは他言語でも良くあるものですがarrayの要素全てに関数を適用し、arrayを返す関数です。関数型では基礎中の基礎で、BigDataの分野では多大な量のデータを並列的に処理するためのMapReduceの仕組みにも採用されたものでした。

本書ではmap関数をreduceやforEachのほうが適切な場合にも、あえてmap関数を利用しています。これはJSの説明を省くためにあえてそうした可能性があります。

しかし、例えば本書で各画像のload終了を確認する場合にbool値に対し全てandを取る場合等はreduceのほうが適切です。また全てのobjectに対し個別に衝突判定を行う部分ではforEachのほうが適切だったと言えるでしょう。

# まとめ

本書はグラフィックスプログラミング入門と題して、ブラウザ上でのCanvasを用いた画像描画に関して非常に良くできた教材になったと感じます。
著者の得意である、基礎と数学を重視した詳細な説明が十分に発揮されていました。

願わくはdoxasさんが好きなWebGLの書籍もぜひ、続編で読めればと思います。