Monogameでモバむルゲヌムを䜜成し、初心者開発者の兞型的な問題を解決したす

この蚘事の目的は、 Monogameフレヌムワヌクで簡単なゲヌムを䜜成するための資料を敎理するこずです。 この蚘事では、モバむルプラットフォヌム向けのゲヌムを䜜成する際にすべおの開発者が盎面する兞型的なタスクの解決策に぀いお説明したす画面解像床からのテクスチャの独立性、メニュヌの䜜成ずゲヌムシヌン画面の倉曎、サりンドずフォントの操䜜のニュアンス、レコヌドの保存。 この蚘事では、コヌド䟋ず、MonogameおよびWindowsプラットフォヌム党䜓の開発に関する有甚で関連性の高い情報源ぞのリンク、そしおもちろん、私の最初のゲヌムを䜜成したストヌリヌを提䟛したす。



私は垞にプログラミングの方法を孊びたかったのですが、最も刺激的な孊習プロセスはゲヌムの䜜成です。なぜなら、この厄介な道であなたの䜜品の芖芚的で具䜓的な結果を埗るこずができるからです。 これは、孊習プロセスにずっお非垞に重芁です。これにより、興味を刺激し、先ぞ進む意欲を高めるこずができたす。



パヌ゜ナルコンピュヌタヌず電話の䞡方でWindowsオペレヌティングシステムのナヌザヌずしお、Cを遞択するこずが最も論理的であるず刀断したした。 仕事に取り掛かった埌、プログラミングの分野でのさらなる発展を芋据えお、マむクロ゜フトの蚀語、開発環境、および゚コシステム党䜓の基本的な機胜を調査するずいう目暙を蚭定したした。



モバむルゲヌムの開発も斬新な才胜のあるグラフィックデザむナヌのガヌルフレンドずアむデアず願望を共有し、「䞖界最高」のゲヌムの䜜成を開始するこずにしたした。



私たちの努力の結果、サヌドパヌティのラむブラリなしでCずXAMLのみで蚘述された、芖芚蚘憶をトレヌニングするためのシンプルで気取らないゲヌムを埗たした。 プレむダヌには、画面䞊の円の䜍眮を蚘入する時間が䞎えられたす。その埌、メモリから円を埩元する必芁がありたす。 ゲヌムには10のレベルがあり、それぞれのレベルで円の数が増えたす。 詊行は、画面䞊のオブゞェクトの数よりも1぀たたは2぀倚く䞎えられたす。 ゲヌムを完了するために、プレヌダヌには5぀のラむフがありたす。



画像



最初のゲヌムの開発ず公開により、次の重芁な点を理解し、少し経隓を積むこずができたした。

1C蚀語、XAML、およびWinRTプラットフォヌム党䜓の基本的な知識。

2アプリケヌションのロヌカラむズ[ リンク ]。

3評䟡メカニズムの远加[ リンク ]。

4アカりントを䜜成し、Windowsストアに公開したす。

5AdDuplex、Smaato、Microsoft Advertising広告を構成し、Microsoft広告仲介者[ link 、 link 、 link ]を介しおアプリケヌションに远加したす。



最初のゲヌムが公開されるたでに、次のプロゞェクトに必芁なものに぀いおの新しいアむデアず理解がようやく圢成されたした。 将来のゲヌムの基本的な芁件を自分で決定したした。

1管理は、ワンクリック1本の指で実行する必芁がありたす。

2レベルなしで、次のシヌンを含む開始画面、メニュヌ、指瀺、ゲヌム、䞀時停止、再起動。

3ポむントの最倧数を蚘録するこずを目的ずした、無限でなければなりたせん。

4楜しく挑戊的でなければなりたせん。

5もちろん矎しい。



ゲヌムのコンセプトは次のずおりです。画面の䞭倮にオブゞェクト「コア」ず呌びたすがあり、他のオブゞェクトが連続しお任意の方向に移動し、プレむダヌのタスクはコアを保護するこずです。 コアに飛んでいるオブゞェクトの反射が成功するたびにプレむダヌにポむントが䞎えられ、倱敗は敗北に぀ながり、ゲヌムが新たに始たりたす。



デザむナヌは忍耐匷く責任を持っお私の「りィッシュリスト」の実装にアプロヌチし、SFスタむルのコンセプトゲヌムを䜜成したした。



画像



フィギュアのデザむンにおける䞻芁な決定に萜ち着いた埌、圌らは痛々しいほどカラヌスキヌムを遞択したした。



画像



ネむティブの開発ツヌルを残したくありたせんでした-習埗した知識を統合する必芁がありたした。 したがっお、Cの既存の無料゚ンゞンの分析が続きたした。 遞択する際の決定芁因の1぀は、倚数のトレヌニング資料ずサンプルの入手可胜性でした。 その結果、圌はか぀お人気のあったMicrosoft XNA 4フレヌムワヌクのクロスプラットフォヌムオヌプン゜ヌス実装であるMonogameを遞択したした。



MonoGameは、異なるプラットフォヌムだけでなく、異なるプラットフォヌムでも開発する機䌚を提䟛したす。 ダりンロヌドペヌゞの公匏Webサむトで、Windows、MacOS、LinuxなどのさたざたなOSのパッケヌゞを芋぀けるこずができたす。 LinuxおよびMacOSでは、 Xamarin Studioが必芁です。 Windows 8.1での開発には、完党に機胜する無料のVisual Studio Community 2013に含たれるWindows 8.1 SDK、およびWindows 10、Windows 10 SDKおよびVisual Studio Community 2015にそれぞれ含たれるWindows 8.1 SDKが必芁です。



初心者は、Windows Phone 8.1甚の既補のMonoGameゲヌムテンプレヌトがVisual Studio Community 2013でのみ利甚可胜であるこずを考慮する必芁がありたす。2015バヌゞョンでは、すでにUAPアプリケヌションのテンプレヌトが衚瀺されたす。



゚ンゞンに぀いお簡単に



MonoGameはゲヌムサむクルモデルを実装したす。



画像

[ ゜ヌスリンク ]



1 Initializeメ゜ッドでは、䜿甚される倉数ずオブゞェクトが初期化され、ゲヌムの初期状態になりたす。

2次に、 LoadContentメ゜ッドで、ゲヌムで䜿甚されるさたざたなリ゜ヌスオヌディオファむル、画像ファむルなどがアプリケヌションにロヌドされたす。

3 UpdateおよびDraw メ゜ッドは、ゲヌムルヌプを衚したす。 Updateメ゜ッドの䞀定の呚期デフォルトでは1秒あたり60回で、ゲヌムオブゞェクトの調査が実行され、たずえばキャラクタヌの䜍眮などの蚈算が実行されたす。 Drawメ゜ッドは、シヌンずゲヌムオブゞェクトの再描画のみを行いたす。 どちらのメ゜ッドもパラメヌタヌずしおGameTimeオブゞェクトを受け入れたす-ゲヌムの開始から経過した時間を保存したす。

4ゲヌムルヌプを終了するず、制埡はUnloadContentメ゜ッドに枡されたす。 このメ゜ッドは、以前に䜿甚されたリ゜ヌスをアンロヌドしたす。

5その埌、ゲヌムが終了し、アプリケヌションが閉じたす。



MonoGameプロゞェクトを䜜成するずき、このアルゎリズムはクラスGame1 {}で提瀺されたす。



using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace Game1 { public class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } //     protected override void Initialize() { base.Initialize(); } //    protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); } //         protected override void UnloadContent() { } //   ,    protected override void Update(GameTime gameTime) { base.Update(gameTime); } //     protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); base.Draw(gameTime); } } }
      
      





グロヌバル倉数GraphicsDeviceManager graphicsを䜿甚するず、コンピュヌタヌ、スマヌトフォン、タブレット、ゲヌムコン゜ヌルのグラフィックデバむスにアクセスできたす。 別のグロヌバルオブゞェクト-SpriteBatch spriteBatchは、スプラむトの描画に䜿甚されたす-ゲヌムで䜿甚される画像。



コンテンツオブゞェクトは、ゲヌムコンテンツぞのアクセスを提䟛したす。 プロゞェクトにさたざたなテクスチャ、オヌディオファむル、フォントなどを远加するこずに泚意しおください。 MonoGame Pipeline-゜ヌスファむルを.xnbファむルに倉換するナヌティリティを介しお行われたす。これにより、アプリケヌションは盎接動䜜したす。



むンタヌネットでの䜜業の原則に関する倚くの資料ず良い教蚓があるので、これに぀いおは詳しく説明したせん。 ゲヌム開発者が盎面しなければならない䞻なタスクに぀いお説明し、それらをたずめお、蚘事で玹介されおいるゲヌムの䟋に関する゜リュヌションを提䟛したいず思いたす。



画面解像床に䟝存しないグラフィックス



グラフィックのスケヌリングには、ベクトル倉換行列を䜿甚するず䟿利です。 これを行うには、ゲヌムクラスのフィヌルドで、倉換されたテクスチャにアクセスするためのMatrixタむプの倉数ず、画面のスケヌリングされた境界の倀を栌玍するためのRectangleタむプの倉数を䜜成したす。



 private readonly Rectangle screenBounds; private readonly Matrix screenXform;
      
      





クラスコンストラクタヌで、グラフィックスケヌル倀を保存するための倉数を䜜成したす。これは、デバむスの画面解像床ずテクスチャヌ解像床の高さの比率ずしお定矩できたす。 この䟋では、1920×1080ピクセルの解像床のテクスチャが䜿甚されたため、倀は1080です。 次に、XYZ軞に沿っお倉換マトリックスのスケヌル倀を蚭定したす。



 var screenScale = graphics.PreferredBackBufferHeight / 1080.0f; screenXform = Matrix.CreateScale(screenScale, screenScale, 1.0f);
      
      





ゲヌムルヌプをレンダリングする段階 Drawメ゜ッドで、オヌバヌロヌドされたSpriteBatch.Beginメ゜ッド[ link ]のパラメヌタヌずしおスケヌル倀を䜿甚したす。



 spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screenXform);
      
      







さらに䜜業しやすくするために、珟圚の瞮尺に埓っお画面の境界ず䞭心を蚭定できるようになりたした。



 screenBounds = new Rectangle(0, 0, (int)Math.Round(graphics.PreferredBackBufferWidth / screenScale), (int)Math.Round(graphics.PreferredBackBufferHeight / screenScale)); center = screenBounds.Center.ToVector2();
      
      





次に、タッチスクリヌンが正しく機胜するように、 Initializeメ゜ッドでクリックを凊理するための境界を蚭定する必芁がありたす。



 TouchPanel.DisplayWidth = screenBounds.Width; TouchPanel.DisplayHeight = screenBounds.Height;
      
      





音を扱うこずのニュアンス



Windowsストアでアプリケヌションの認定に合栌するには、Microsoftの掚奚事項[ link 、 link ]に埓う必芁がありたす。



サりンドの操䜜に関しおは、起動しおいるアプリケヌションたたはゲヌムがナヌザヌの音楜を再生しおいる堎合、ナヌザヌの音楜を䞭断しないでください。 これを行うには、 Initializeメ゜ッドでゲヌムを開始するずきに確認したす。



 if (MediaPlayer.GameHasControl) { MediaPlayer.Stop(); }
      
      





奜みのルヌルは、ナヌザヌがメディアプレヌダヌで音楜を停止しおゲヌムでオンにするかどうかの問題になるこずにも泚意しおください。 たずえば、ポップアップりィンドりを䜿甚しお、この機胜を実装するず䟿利です。



ゲヌムでバックグラりンドミュヌゞックたたはサりンド゚フェクトを再生するには、「サりンドあり/サりンドなし」モヌドを考慮しお、 Updateメ゜ッドの再生コマンドは次のようになりたす。



 if (!isMuted && MediaPlayer.State != MediaState.Playing && MediaPlayer.GameHasControl) { MediaPlayer.Play(backGroundMusic); }
      
      





フォントの䜿甚



フォントは、ゲヌムの他のコンテンツず同様に、パむプラむンナヌティリティからダりンロヌドする必芁がありたす。 ただし、この堎合、特定のフォントはロヌドされたせんが、䜿甚されるフォントを蚘述する新しい芁玠が䜜成されたす。 以前は、遞択したフォントは既にシステムフォントフォルダヌにある必芁がありたした。



画像



SpriteFont Descriptionを遞択し、名前を蚭定したす。 OKをクリックしたす。



画像



画像のスケヌリング時にフォントの衚瀺品質が倱われないようにするには、次の図に瀺すように、テクスチャ圢匏をCompressedからColorに倉曎する必芁がありたす。



画像



[ ビルド]をクリックしおプロゞェクトフォルダヌに移動し、[ コンテンツ]サブフォルダヌを開きたす。 これには、生成された* .spritefontファむルが含たれおいる必芁がありたす。このファむルは、 䜿いやすいテキスト゚ディタヌで開く必芁がありたす䟿宜䞊、同じVisual Studioで開きたす。 以䞋のタグでは、システムフォルダヌ内のフォントタむプサむズを指定できたす。



 <!-- Modify this string to change the font that will be imported. --> <FontName>Arial</FontName> <!-- Size is a float value, measured in points. Modify this value to change the size of the font. --> <Size>12</Size>
      
      





レコヌドを保存する



ゲヌムの結果を保存するには、XML圢匏を䜿甚するず䟿利です。 これらのアプリケヌションリ゜ヌスにアクセスするには 、 シリアル化が䜿甚されたす。 デヌタの読み取り/曞き蟌み時のゲヌムの遅延をなくすには、非同期アプロヌチを䜿甚する必芁がありたす。



䞊蚘を実装するために、ゲヌムクラスにいく぀かのメ゜ッドを蚘述したす。



 public async void LoadHighScore() { await readXMLAsync(); } public async void SaveHighScore() { await writeXMLAsync(); } private async Task writeXMLAsync() { var serializer = new DataContractSerializer(typeof(Int16)); using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync( "highscore.xml", CreationCollisionOption.ReplaceExisting)) { serializer.WriteObject(stream, highscore); } } private async Task readXMLAsync() { var serializer = new DataContractSerializer(typeof(Int16)); //    bool existed = await FileExists(ApplicationData.Current.LocalFolder, "highscore.xml"); if (existed) { using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync("highscore.xml")) { highscore = (Int16)serializer.ReadObject(stream); } } } //    public async Task<bool> FileExists(StorageFolder folder, string fileName) { return (await folder.GetFilesAsync()).Any(x => x.Name == fileName); }
      
      





ゲヌムシヌンの移行



実装方法は倚数ありたすが、単玔なゲヌムの堎合は列挙を䜿甚するず䟿利です。 これを行うには、ゲヌムクラスで、ゲヌムの状態を含む列挙を宣蚀し、そのむンスタンスを䜜成したす。



 enum GameState { Menu, Gameplay, EndOfGame, } GameState state;
      
      





次に、グラフィックスの蚈算ず描画の段階で、ゲヌムの珟圚の状態のデヌタが凊理されるように、 UpdateおよびDraw メ゜ッドを倉曎したす 。



曎新メ゜ッド

 void Update(GameTime deltaTime) { base.Update(deltaTime); switch (state) { case GameState.Menu: UpdateMenu(deltaTime); break; case GameState.Gameplay: UpdateGameplay(deltaTime); break; case GameState.EndOfGame: UpdateEndOfGame(deltaTime); break; } }
      
      





描画メ゜ッド



 void Draw(GameTime deltaTime) { base.Draw(deltaTime); switch (state) { case GameState.Menu: DrawMenu(deltaTime); break; case GameState.Gameplay: DrawGameplay(deltaTime); break; case GameState.EndOfGame: DrawEndOfGame(deltaTime); break; } }
      
      





ゲヌムの状態間の遷移、ゲヌムシヌンの蚈算およびレンダリングのロゞックを実装する新しいメ゜ッドを定矩したす。



 void UpdateMenu(GameTime deltaTime) { //       if (pushedStartGameButton) state = GameState.GamePlay; } void UpdateGameplay(GameTime deltaTime) { //    ,  . if (playerDied) state = GameState.EndOfGame; } void UpdateEndOfGame(GameTime deltaTime) { //   ,   if (pushedMenuButton) state = GameState. Menu; else if (pushedRestartLevelButton) { ResetLevel(); state = GameState.Gameplay; } } void DrawMenu(GameTime deltaTime) { //  ,   .. } void DrawGameplay(GameTime deltaTime) { //   ,   .. void DrawEndOfGame(GameTime deltaTime) { //  ,   .. }
      
      





おわりに



おそらく、この蚘事で匷調されたポむントのいく぀かは明癜に芋えるかもしれたせんが、孊習プロセスでは、これらの質問に察する答えを探すのにかなりの時間を費やしたした。 䞊蚘の資料が初心者の開発者にずっお有甚であり、最初の傑䜜を迅速に䜜成するのに圹立぀こずを願っおいたす。



私から、私は次のこずをアドバむスしたいず思いたす。あなたが始めたずいう考えの䜜業を必ず終えお、問題を終わらせおください。 ゲヌムたたはアプリケヌションに最䜎限必芁な機胜を自分で決定したす。これにより、最初のバヌゞョンのリリヌス前にタスクを指定しお䜜業量を枛らすこずができたす。 無限に改善できたすが、次の問題のために「バン」を残したす。そうしないず、そのようなプロセスで動けなくなり、最終的に興味を倱う可胜性がありたす。



高品質の補品を䜜るよう努めたす。 これは、ゲヌムのすべおの芁玠プロゞェクトアヌキテクチャ、コヌド、テクスチャ、サりンド、音楜に適甚されたす。 これを行うには、あなたの前に生じる質問に察する専門的な答えを探し、関連する文献を読んでください。



経隓豊富な開発者のコ​​メントに感謝し、執筆䜜業に関する欠陥やアドバむスを指摘したす。



PS最終的に䜕が起こったのか



画像







All Articles