ゲーム開発に関する世界観です。テレビゲームも参照のこと。
僕はいくらかの本を読んだだけで、ゲーム開発の経験はありませんが、ゲーム作りには「判定」が多いです。
判定とは、0と1でそれが「成功」となるか「失敗」となるか、ということです。
ゲームには、判定が多く登場します。たとえば、キャラクターの動作がどうなるか、選んだ攻撃が当たるかどうか、敵や味方のHPがいくら下がるか、生死の判定などが、対戦画面での判定です。
敵に勝利した時は、どれくらいの経験値でレベルアップするか、レベルアップしたとしたらどれだけ強くなるか、なども判定です。
マップ画面では、キャラクターがどの方向にどれだけ動けるか、マップをどの方向にスクロールするか、どんな場面ではどういう敵が出現するか、どれだけのエンカウント率で敵が出現するか、なども判定と言えます。
このように、ゲームの開発は「判定」が主になります。
判定ルーチンは、基本的なものであればイベントループとフラグ管理・比較だけでできてしまうため、一見簡単に見えますが、複雑なゲームになると、物理シミュレーションやAIなど、専門性が高くなっていきます。そのため、市販ゲームの開発者などは、一部の専門性のあるスーパープログラマにしかできません。一見ゲームやプログラミングとは関係ないように見える数学上の理論なども勉強する必要があることがあると聞いています。
最近の3Dのゲームでは、高度なCGで3Dのバーチャル世界を探検することができます。また、敵に出現した時は、バトル画面へと画面が移り変わります。
このような画面のデザインは、ひとつ作って使いまわせばいい、ということが言えます。
ポケモンを作るのであれば、マップ画面と対戦画面とステータス表示画面だけを作って、データとなる変数(味方と敵のステータス、マップと登場人物の位置)をそこにあてはめて、どんな場合でも成り立つように、上手く画面を表示させて動かせばいいのです。
昔は2D画面のドット絵でしたが、これでも、最初にこうした画面を読み込むのに時間がかかりました。プレステ2などになってくると、初回プログラムとデータの読み込みには1分以上かかることもありました。
そのほか、ゲームのポイントには、自分の今の状態を外部データに保存することがあげられます。シリアライズあるいはファイルやデータベースなどに保存することになるでしょう。
また、アイテムや装備品の売買や装備などにより、自分の強さを増やす、ということもあります。このためには強さや力だけではなく装備やお金も管理しなければなりません。魔法や回復アイテムを使う機能、装備する機能、攻撃する技を選択する機能なども必要です。
また、楽しいゲームにするためには、エフェクトも重要になります。必殺技はかっこいいほうが面白いでしょう。
また、ゲームのプログラミング以外にも、キャラクターデザインやシナリオなども重要です。かわいいキャラクターで、面白いシナリオでなければ、面白くないからです。
また、単にゲームが開発できるということと、「面白いゲームを作る」ということは別の問題です。単なるRPGの焼き直しを作ったところで、RPGとしては面白いかもしれませんが、それだけがゲームではなく、たとえばファイアーエムブレムやチョコボの不思議なダンジョンのような、「ゲーム性のある面白いゲーム」を作ることは、プログラミングができるかどうかとは別の問題です。
そして、ゲームには、ほかにもさまざまに考えるべきポイントが多いです。グラフィックスをどう描画するか、マルチスレッドをどうするか、巨大になるメモリの管理をどのようにすれば途中でフリーズしないか、など、さまざまな問題があります。低レベルな水準になってくると、ハードウェアデバイスの問題も深くのしかかってきます。Windowsでも汎用ゲーム機でも同じ技術を使えることが保証されているわけでもありません。
また、通常のプログラムと違うのは、ゲームはテレビ画面とコントローラを使うということです。文字を入力に使うことは少なく、信号とボタンの操作でプログラムを制御し、画面を再描画しなければなりません。これには、イベント駆動などの考え方を使うことになります。
後日注記:僕はゲーム作りで一番難しいのは、マルチスレッドの問題だと思います。キャラクターがそれぞれ、同時に動かなければいけません。もし、最初からキャラクターの動作とエフェクトが決まっていたとしても、それぞれをマルチスレッドで動かしながら対戦する、これはけっこうな難易度のプログラムになると思います。僕が作るとしたら、まずシングルスレッドで決められた通りに外部に反応して動作するキャラクターのルーチンを作り、このルーチンをキャラクターの数の分だけスレッドを使って並列で動かすようにするルーチンが必要です。これをC++で書くのはかなり難しいと思います。
僕は、ゲーム開発の考え方として、「自動でゲームを作成するゲーム」というのがあると思います。
たとえば、不思議のダンジョン系のゲーム(ローグライクゲーム)では、ダンジョンを自動で作成します。僕は、登場するモンスターやマップについても自動で作成できると思いますし、多くのゲームが、そうしたものを自動で作成しています。
ゲームを作るということは、すべてが人間によってデザインされたゲームを遊ぶだけではなく、自動的にゲームを作成するゲームを作る、ということではないかと思います。
詳しくは以下の書籍が参考になります。
C++でゲーム開発を行う上で、プロの技法を身につけるために、以下のやねうらお氏の書籍が参考になります。
ただし、この本は初心者にはおすすめしません。ゲーム開発というよりはC++プログラミング技法の本であり、この本だけでゲーム開発はできません。
さまざまなゲームの開発手法については、以下の書籍が参考になります。主に2Dグラフィックスのゲームで使われる画像処理の手法を中心に、さまざまなゲームに必要な技法がDelphiのコードとともに説明されています。ゲーム開発を今から始めたいと思っている少年少女にはよい本だと思います。
また、以下の書籍はゲーム開発に必要なVisual Basic 6.0のグラフィックス処理が説明されており、VBの開発の練習にもなります(ただしVB 6.0は既に古すぎる言語です)。
後日注記:やねうらお氏の書籍は、ゲームを作るための入門者のための本ではなく、「プロのエンジニアならこれくらいのテクニックは知っておかないとゲームは作れないよ」という本です。なので、ゲームを作る初心者向けの本ではなく、どちらかというとゲーム開発を通じてC++の基本となるプログラミングテクニックを学びたい、C++入門者向けの本であると言えます(もちろんゲームの内容は多いです)。
2023.05.09編集
2023.05.12編集
2024.11.13編集
Unityを参照のこと。
Blenderは3DCGのモデリングソフトウェア。操作は難しいが、出来ることは多い。オープンソースでクロスプラットフォーム。
Blenderを参照のこと。
ゲームを開発するエンジニアになりたいのであれば、Unityだけにとどまらず、OpenGLやDirectXなどの3Dグラフィックスができるようになっておこう。
最近のゲームは、全部3DCG。特にAndroid用のゲームを使うのであれば、Javaのような技術も必要。最近はRubyなどでもゲームが作れるようにはなってきている。正統派はC++とOpenGLを使うが、これは3Dレンダリングの処理速度を高めるため。XboxなどのMicrosoft製品ではC#を使うこともある。一部のネットゲームではPerl/CGIなどでブラウザゲームが作られたりはしているが、3Dを行うのであればネットゲームではDirectXは必須である。
OpenGLやDirectXやAndroidやPerl/CGIなどを参照のこと。
ゲーム開発初心者は、以下のリンク先で分かりやすい解説動画を視聴できます。とは言いつつ、実際は僕もまだ第三回までしか見ていません(今から見ます)。Mac上のAndroid StudioでXMLとJavaと画像ファイルを用いてゲームを作成する動画です。Android向けなのでC#ではなくJavaとXML(Androidアプリの画面レイアウトに使う)を使うことに注意しましょう。
Androidも参照のこと。
昔のBASICを使ったゲーム開発についてはホビーパソコンやBASICを参照のこと。
テレビゲームを作るために必要なのは、統合シチュエーション、統合シーンを作ることです。
一つの戦闘シーンと一つの冒険シーンを作ってしまえば、あとはキャラクターとデータを作るだけで、その戦闘シーンを使いまわすことが出来ます。
必要なのは、全てのシチュエーションに抽象的・包括的に対応する、統合シチュエーションを作ることだと思います。
ただ、ゲームプログラミングのことを何も知らずに書いているので、きっと本当は違うと思います。それは注意してください。
後日注記:このようなゲームの「画面」のことを、ゲーム用語では「シーン」と呼びます。ゲームの開発とはシーンを作ることです。詳しくはやねうらお氏の「Windowsプロフェッショナルゲームプログラミング」の「第7章 ゲームプログラミングフレームワーク」(339ページより)が参考になります。
2024.11.13編集
ゲームを作るのは思ったより簡単です。
なぜなら、リアルタイムで変化するキャラクター(敵・味方)ごとのパラメータがあって、それを常に参照しながら表示処理を変えればいいだけだからです。
3Dの戦闘画面では、キャラクターが移動したり攻撃したりするのは複雑に見えますが、実際は単に円形状のグラウンドにキャラクターが立っているという「点情報」があるだけにすぎません。
点情報は、時間とともに刻々と変化します。キャラクターのヒットポイントなどのパラメータも刻々と変化します。基本的に、この常に変化するパラメータを、リアルタイムに画面に反映させるように、「画面プログラム」を作ればいいのです。
点情報に自分から変化を加えるのは、コントローラで操作した際のイベントをハンドリングして、キャラクターが移動したり、攻撃をした時に、再描画と判定を繰り返す時ぐらいでしょう。これらは、イベントループで行うことができます。常にイベントを待機するための関数を作り、イベント関数がreturnした時にその返り値を取り出すようにすればいいのです。
攻撃を行った時は、攻撃処理のイベントを通知して、そのイベントに応じて攻撃のエフェクトを表示したり、キャラクターがどこに居るかに基づいて「当たった」とか「外れた」といった判断をして、パラメータに変化を加えます。自分が敵に対して行う攻撃だけではなく、敵が自分に対して行う攻撃も、マルチスレッドで処理しなければなりません。
マップの移動も同じで、単にキャラクターが移動した時に画面を再描画しながら、常に敵が出現するかどうかを判断するエンカウント判定を行えばいいのです。
キャラクターのレベルアップや能力値、装備品などの変化は、単にパラメータを変えるだけでできます。
画面の再描画は難しく見えるかもしれませんが、実際は単に表示する画像を変えればいいだけです。あらかじめ用意しておいた3DCGのキャラクター画像をグラウンド画面の中に埋め込み、常に表示し直し続ければよいのです。
むしろ、AI的な要素に難しさがあると思います。敵キャラクターは、プレイヤーが操作するのではなく、コンピュータが自分で操作しなければなりません。むしろ、ゲームにおいて真に難しいのは「AI」ではないかと僕は思います。
総合して考えると、まず、円形状のグラウンドで点情報としてキャラクターが移動するようなパラメータがまず必要です。これはキャラクターの数だけ、味方だけではなく敵の値も作ります。これらはマルチスレッドで刻々と変化します。また、移動するだけではなく、攻撃をした場合に、それが当たるか外れるかの判定と、それをヒットポイントに反映するような関数も必要です。これらは、パラメータの変化とは別に、非同期でいつ起きるのか分からない「イベント」として作ります。そして、このイベントはイベント発生関数から生み出されます。それはイベントループによってコントローラなどのデバイスの情報を監視することで作ることができます。敵についてはAIによってコンピュータが自動で動かします。その上で、これらの情報を3DCGの画面に描画する機能を作ります。これはOpenGLなどの3DCG描画ソフトを使って、グラウンドの画像にキャラクターやエフェクトの画像を常に表示し直す形で作ります。
これらのルーチンを、全部上から下に流れるように書けば、確かに複雑なプログラムになりますが、実際は関数やクラスを上手く使うことで、思ったよりも簡単に開発できると思います。
キャラクターがたくさん居るようなネットゲームであっても、基本は同じです。単に、キャラクターが居た時にそのキャラクターのデータをデータベースから取得すればいいだけです。データベースサーバと接続する方式のプログラムにすれば、同じように開発できるでしょう。
そう、ゲームを作るのは、思ったより簡単です。
ゲーム開発の基本は、グラフィックス処理です。
ユーザーのさまざまなイベントに応答しながら、グラフィックス処理を行うのがゲームの基本です。
つまり、ゲームはパソコンが絵を描いているだけです。
2Dであっても3Dであっても、ゲームの開発はパソコンが絵を描いているだけです。パソコンがグラフィックス処理を行いながら、ユーザーの作り出したイベントに反応し、「判定」を行うのがゲームの基本です。
ゲームは、普通のプログラミングとは異なり、難しい点が多々ありますが、「パソコンが絵を描く」という基本が分かればなんとかなる部分が多いと思います。
2023.06.30
ゲームやWindowsに限らず、グラフィックスの基本は再描画です。
すなわち、画面を描き直すことです。
基本的に、画面を描き直す方法さえ分かってしまえば、どんな環境でもゲームは作れます。
たとえば、コンソールの黒画面しかないBASICやMS-DOSのような端末であっても、画面を描き直す方法さえ分かればゲームは作れます。
あとは、技術として、OpenGLでの画像合成と座標変換を分かっておくとためになります。簡単に画面を変更できるようになります。
本当は、これは昔の端末だけには限らず、今の高度なWindowsのGUI開発でも同じです。PhotoshopやIllustratorなどは、すべて「画面を再描画する方法」で作られているのです。
もし、本当にその方法を知りたいなら、それはフレームバッファについて学ぶべきです。
フレームバッファとは、今から画面に表示されるグラフィックスを格納しているメモリのことで、ハードウェアに近い低水準で使われます。
基本的に、フレームバッファに描くことで、BASICやMS-DOSなどでのグラフィックス処理は行われます。
それくらいで、頑張ればゲームは作れるはずです。
2023.07.06
やねうらお氏の「Windowsプロフェッショナルゲームプログラミング」を読めば分かりますが、ゲームの基本は「サーフェース」と呼ばれるグラフィックス画面のメモリ領域に絵を描くことが中心です。
やねうらお氏が言うように、サーフェースには表(プライマリ)と裏(セカンダリ)があり、いったんセカンダリに画像を格納した上で、それをプライマリに転送します。このようにする理由は、画面の操作をしている途中のちらつきを見せなくするためです。
ゲームを作る際に、グラフィックスを画面に表示したくても、その元の画面を表の見える画面でいきなり表示して、それを操作していく途上をすべて表示するのではなく、いったん裏の画面で画面のすべてを構築した上で、それを表の画面に転送して見せるようにします。
それ以上の詳しくて高度なことは、すべてやねうらお氏の本の「第6章 描画クラスの設計」(297ページより)に書かれています。たくさんの高度な用語が登場しますが、概念や仕組みやコード(アセンブラ・C/C++)が丁寧に書かれているので、きちんと読めば分かると思います。ただしグラフィックスの低レベルな話や、デバイスの話が多いので、興味がない方にとってはつまらない本だと思います(失礼)。
2024.11.13
カードゲームを作るためには、どのようにすればいいでしょうか。
クリーチャー系のカードを作るのは、そう難しくはありません。攻撃する相手のクリーチャーを選び、自分の攻撃力が相手の防御力を上回っていれば、それで相手のクリーチャーを破棄できるようにすれば作れます。
手札からカードを場に出すのも難しくはありません。手札にあるカードを出すために必要なマナがあればそれを場に出せるようにすればいいだけです。
難しいのは、場に存在するだけで場を支配し、能力を発揮するような、エンチャント系のカードの能力です。
この種のカードは、ターンの開始時と終了時に効力を発揮します。
なので、ターンの開始時と終了時に行う処理をフック(外部から書き換え)できるようにし、場に対してさまざまな効果を与えられるような機構を作ります。
具体的には、ターンの開始と終了の際の通常の処理の後に特定の処理を追加できるような、メソッドチェーン的な機構を作り、エンチャント系のカードがこのメソッドチェーンに処理を追加できるようにします。
あるいは、ターンの開始時と終了時に、場にエンチャント系の能力を持つカードがないかを確認し、あれば順次その能力を実行するようにしてもいいでしょう。ですが、その場合にも、なんらかのフック機構は必要となるでしょう。
後日注記:フックやメソッドチェーンのような機構を実現するには、関数ポインタやfunctorのような面倒くさい方法を使わなくても、単にオブジェクトの参照を渡して場のインスタンスに格納し、ターンの開始時と終了時にすべての参照の特定のメソッドを順次実行するようにすればいい。カードごとにクラスが違う場合は、共通の親クラスを継承するか、Javaのように多重継承ができない場合は共通のインターフェースを実装する。あるいは、「ターン開始・終了マネージャ」のような専門のクラスを作り、このクラスにエンチャント系カードのオブジェクトを管理させてもいい。
Java(継承)も参照のこと。
2023.05.14-15
カードゲームを作るために難しいのは、機能を適用する順番だと思います。
クリーチャー(モンスターのこと)が複数場に存在した時、エンチャント(魔法のこと)が複数場に存在した時に、どのような順番でその機能と効果を適用していくか、ということがまず問題です。
カードゲーム会社がそのようなルールは定めているとは思いますが、僕は詳しくないので、単純に左から右に順番に適用すればいいと思います。
そして、あとを作るのは難しくありません。単にそれぞれのカードの効果をひとつひとつ実行すればいいからです。
カードを作る際には、「カードAPI」という内部APIを作るといいと思います。カードから場のさまざまなパラメータを操作するために、このカードAPIを使ってパラメータを操作します。カードごとの複雑な機能や効果についても、カードAPIを使って実現します。
あとのカードゲームに必要なのは、自分と敵のヒットポイントとか、クリーチャーが戦った時にどちらが勝つかとか、カードを出すためにマナ(魔力のこと)をどう消費するかとか、あるいはデッキからカードを引いて手札に加えた後でそのカードを場に出す、とかいったことです。それはひとつのルーチンにすれば作れると思います。
2024.11.10
自動操作のキャラクターの制御を担当するAIとして、「天の声」というAIが考えられます。
「天の声」は、僕が今作った造語で、僕の考えたAIです。
天の声AIは、キャラクターの戦闘状況を把握しており、自動操作のキャラクターに対して命令を行います。
戦闘状況とは、「キャラクターの残りヒットポイント」「キャラクターの能力値と使うことのできる攻撃の種類」「キャラクターが戦闘場面で今居る三次元空間上の位置」などです。
天の声AIは、キャラクターの戦闘状況を考えながら、自動操作のキャラクターそれぞれ(敵・味方含む)に対して、複数の種類から選ばれる常にひとつの「命令」を与えます。
たとえば、「追跡」命令を天の声AIが指示すると、そのキャラクターは相手のキャラクターを追いかけまわします。「退避」命令を指示すると、逆に相手のキャラクターから逃げ回ります。
また、「攻撃」命令を指示すると、相手に攻撃を行います。攻撃には「隙を見て攻撃」のような攻撃のやり方や、「物理攻撃」や「魔法攻撃」のような攻撃の種類があります。
また、キャラクターが瀕死の状態になってくると、「回復魔法」命令を天の声AIが指示し、回復を行います。あるいはキャラクターの能力値や装備品によっては「回復アイテムの使用」命令を指示してもいいでしょう。
ほかにも、「必殺技」命令を天の声AIが指示すると、そのキャラクターは自分の持っている特技や究極魔法のような必殺技を使います。
キャラクターが今、どのような戦闘状況にあって、どこに居るのか、どれくらいのヒットポイントが残っているのか、相性のいい相手は誰か、どの敵が一番近くてどの敵から倒すべきなのかということなど、さまざまなことを天の声AIは判断し、そこから常にどのような命令を与えるかということを判断して、自動操作のキャラクターを動かすのです。
2023.04.17
ゲームを作る上で、もっとも難易度が高いのは「AIを作る方法」でしょう。
プレイヤーがゲームを楽しむためには、それなりに強いAIを作らなければいけません。
ですが、僕が個人的に考えた内容を言うと、「最適な戦い方」を考えればAIは作れます。
最適な戦い方とは、もしそのゲームのすべてのパラメータを知っていて、その中で使うことのできる能力が今揃っていたとしたら、その中でどのような戦いをすることが戦い方として最適か、ということを考えるサブルーチンです。
その最適な戦い方では、どのようにプレイヤーが戦ったとしても、そのプレイヤーを上回る「ベストな戦いの仕方」を出すようにします。
ですが、実際のゲームでは、それではプレイヤーは勝つことができないため、いくらかそれを弱くします。特に、イージーモードではできるだけ簡単にプレイヤーが勝てるように「ノイズ」の比率を増します。エキスパートモードではより強くなるように「ノイズ」の比率を減らします。
そうすれば、おそらく、どのようなゲームであってもAIを作ることができます。
難しいのは、キャラクターを弱くすることです。たとえばスターオーシャンセカンドストーリーというゲームでは、「裏ガブリエル」という最強モードのガブリエルが出てきますが、あんなに強いと子供は誰も勝てません。弱いキャラはとことん弱くして、たとえばスーパーマリオブラザーズに出てくるクリボー並みに弱くすべきです。ですが、本当にクリボー並みに弱くするのが案外難しいのです。
2024.11.10
人工知能・AIも参照のこと。