FarmFury! 技術資料
Upcoming SlideShare
Loading in...5
×
 

FarmFury! 技術資料

on

  • 782 views

XBLIGとPSMで配信中の「FarmFury!」の簡単な技術資料です。

XBLIGとPSMで配信中の「FarmFury!」の簡単な技術資料です。

Statistics

Views

Total Views
782
Views on SlideShare
309
Embed Views
473

Actions

Likes
1
Downloads
2
Comments
0

5 Embeds 473

http://ookumaneko.wordpress.com 442
https://ookumaneko.wordpress.com 28
http://s.deeeki.com 1
http://wordpress.com 1
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

FarmFury! 技術資料 FarmFury! 技術資料 Presentation Transcript

  • by MAX NEET GAME
  •  サークルについて  ゲーム紹介  開発環境  技術解説
  •  活動概要  ゲーム作ってます  作ったゲームの資料も公開していく予定  ホームページ  http://maxneet.web.fc2.com/  メンバー  大熊猫 : プログラム、惰眠担当  まる : アート、雑用担当
  •  プラットフォーム  XBOX 360 : 100円で配信中  PlayStation Mobile (PSM) : 100円で配信中  プレイ人数 : 1~2人 (PSM版は1人限定)  ジャンル: 簡易RTS  対戦型タワーディフェンスっぽいらしいです  動画  http://youtu.be/hqBQ9WucfF8  配信先URL:  http://marketplace.xbox.com/ja-JP/Product/FarmFury/66acd000-77fe- 1000-9115-d80258550deb
  •  XBOX 360  XNA 4  PlayStation Mobile  PsmStudio  MonoGame  全体  Tortoise svn,Audacity, Paint.Net, etc  ファイル管理  Dropbox上にsvnのリポジトリ作成し、Dropboxのフォルダを共有  まずはXNAでPC用に作り、そこからXBOX対応。その後に PSM対応しました。
  •  ホームページ - http://monogame.net/  XNAのコードを様々なプラットフォームで動 かせるライブラリ  Windows, XBOX,WP8, ios, OSX, Android, Ouya, PSM  比較的簡単に移植出来る  数十分~1日ぐらい  でも特有の問題も色々ある
  •  導入方法  http://ookumaneko.wordpress.com/2013/10/15/psmメモ-monogamesの導入方法/  コンテンツ(画像、フォント、等)  “Content”というフォルダを作成し、その中にコンテントファイルを入れる  先に.xnbファイルに変換してから使用する必要がある  FarmFury!ではコンバーターソフトを作った(ContentCompiler)  XML読み込みにIntermidiateSerializerを使っている場合、そのまま Content.Load<classType>で読み込みが出来る  Effectクラスでpsmのシェーダーを扱えるかを試してみた所、一部の型が実 装されていないらしい  ちゃんと出来た方は教えてください m_ _m  そのままビルドして使用すると、MetaData内のTouch設定がtrueじゃないと 落ちる。なので、タッチをオフにしたい場合は、MonoGame側でPsmの Touch APIを切る必要があります。
  •  .xnbファイルに変換した いファイルを追加して、 吐き出す  現状はフォルダ単位での 読み込みに対応していな いので、未だ開発中(気が 向いた時のみ)  dllが必要  Microsoft.Build.dll  Microsoft.Build.Framework.dll  XNA系
  •  ビルド用クラス生成時の処理  一時ファイルディレクトリを作る  プロジェクトを作る  プロジェクトにXNAのコンテンツファイルを作る 方法記されているファイルを読み込む  開始ボタンが押された時、ビルドする用の ファイルを追加してからビルド処理を行う  ビルド時の処理  BuildManagerとBuildSubmissionを使用してビルド する
  • using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; using Microsoft.Build.Execution; using Microsoft.Build.Framework; … Project m_buildProject; ProjectRootElement m_projectRootElement; BuildParameters m_buildParameters; List<ProjectItem> m_projectItems = new List<ProjectItem>(); string m_buildDirectory; … // パス設定 string projectPath = Path.Combine(m_buildDirectory, "content.contentproj"); string outputPath = Path.Combine(m_buildDirectory, "bin"); // ビルドプロジェクトを作成 m_projectRootElement = ProjectRootElement.Create(projectPath); //プロジェクトにXNAのコンテンツファイルを作る方法記されているファイルを読み込む、設定 m_projectRootElement.AddImport("$(MSBuildExtensionsPath)¥¥Microsoft¥¥XNA Game Studio¥¥" + "v4.0¥¥Microsoft.Xna.GameStudio.ContentPipeline.targets"); m_buildProject = new Project(m_projectRootElement); m_buildProject.SetProperty("XnaPlatform", "Windows"); m_buildProject.SetProperty("XnaProfile", "Reach"); m_buildProject.SetProperty("XnaFrameworkVersion", "v4.0"); m_buildProject.SetProperty("Configuration", "Release"); m_buildProject.SetProperty("OutputPath", outputPath); m_buildParameters = new BuildParameters(ProjectCollection.GlobalProjectCollection);
  • // 非同期のビルドリクエストを作る BuildManager.DefaultBuildManager.BeginBuild(m_buildParameters); BuildRequestData request = new BuildRequestData(m_buildProject.CreateProjectInstance(), new string[0]); BuildSubmission submission = BuildManager.DefaultBuildManager.PendBuildRequest(request); // ビルド開始 submission.ExecuteAsync(null, null); // ビルドが終わるまで待つ submission.WaitHandle.WaitOne(); // ビルド終了 BuildManager.DefaultBuildManager.EndBuild(); if (submission.BuildResult.OverallResult == BuildResultCode.Failure) { // ...エラー処理 }
  •  このゲームはプログラムを始めてからあ まりたっていない頃に作った物をそのま ま使っている箇所が多いので、基本的に 難しい事、新しい事、面白い事は特にあ りません。  ゲーム作り始めの方なら何か役に立つか もしれないです。
  •  解像度  1280 x 720 or 1920 x 1080 (HD)  コントローラーが抜けたらゲームをポーズする必要がある  コントローラーが抜けた事を判定する方法  どのコントローラーからでもゲームを開始出来る必要がある  タイトル画面と、対戦時の2P開始に「Press Start」表記をし、Startボタンを押したコ ントローラーを記録している  XBOXメニュー画面でもポーズする必要がある  ゲームUIや操作キャラはセーフエリア(テレビサイズ関係無く表示される領 域)に出す必要がある  ゲーム内の外枠はその為にあります  今回は [1280 x 720]の85%をセーフエリア扱いして開発しました。  .Net 2 Compact Framework しか使えない  C#のバージョンが古い為(C# 2)、使用出来ない機能が沢山ある
  •  解像度  960 x544 (Vita), 800 x 480, 1280 x 800  エミュレーターで上記の設定をテスト出来る。  ちゃんと全ての機種の解像度に対応出来ないとリジェクトされます orz  Vita, SONY認定デバイスの両方で同じバイナリを使う  そのせいか、Vitaの背面タッチやアドホックが使えない・・・  コンテントをメインスレッド以外で読み込めない  XBOXでは全て別スレッドで読み込んでいたが、PSMではリストを作り 一つずつ読み込み、一つ終わる度に描画更新した。  サンプルではバイトデータに変換して別スレッドで読み込み、再度元に 戻しているらしい  エラーメッセージが解り難い時がある  SDKのバージョンが古い時に出るメッセージが「ライセンスが切れまし た」
  •  解像度を考慮しないアホ過ぎる作りをした為、表示がかなり 崩れ、作業量がかなり多くなりそう・・・  なので、手抜き実装として画面を解像度に合わせて引き伸ば したり、縮めたりして表示しました。  とった実装手段はレンダーターゲットに画面を描画し、その 画像を画面サイズに合わせて描画する。  この手法の問題はメモリを食うのと、処理が重い事です。 PSMではどれぐらいか解りませんが、Gravity Dazeの人達も RenderTargetの切り替えが遅いから工夫したとCEDECで言っ ていた気がする。  Psm SDKに何時の間にか自動で黒枠を追加する機能があるら しいのを最近知りました・・・orz
  •  デバイスの解像度獲得  width = Sce.PlayStation.Core.Graphics.GraphicsContext.ScreenSizes[0].Width;  height = Sce.PlayStation.Core.Graphics.GraphicsContext.ScreenSizes[0].Height;  行う処理の順番は:  描画先にレンダーターゲットを指定  ゲーム画面を描画  描画先を元に戻す  レンダーターゲットの内容を描画。サイズ指定は上記で獲得した解像度  PSM版MonoGameでのRenderTarget2Dの問題  上記を試してみた所、180度回転した上に左右引っくり返って表示されました  なので、SpriteBatch.Draw()のrotationに180度の指定と、SpriteEffectに SpriteEffects.FlipHorizontallyを設定  ついでに原点(origin)には解像度の半分の大きさを指定しました
  •  基本的な円と円を使った判定を使用 public bool CollisionCheck(Circle obj1, Circle obj2) { float distance =Vector2.DistanceSquared(obj1.Position, obj2.Position); float radius = (obj1.Radius * obj1.Radius) + (obj2.Radius * obj2.Radius); return (distance <= radius); }  DistanceSquaredを使用しているのはsqrt()が結構負荷 が高い計算の為です。実際に処理速度の違いは微々た る物ですが、計算回数が多いゲームの為、取り合えず 削れる所で削っています。
  •  最初はfor文を使ったブルートフォース的 なチェックを行っていた  ただ、負荷が高過ぎた為、簡単な空間分 割を使う事にした(UniformGrid)  当たり判定の管理に含まれるのは動物、 牧場、肉、忍者、手裏剣、火柱
  •  ゲーム画面を一定の大きさの マス目に分裂する。  各オブジェクトはどれかのマ スに配置され、移動した際に は別のマスに配置を移す。  各移動系オブジェクトは、自 分のマスとその周りのマスに 配置されているオブジェクト だけ当たり判定の確認を行う。  オブジェクトのサイズによっ ては確認するマスの範囲は変 わる。
  •  目標は一定範囲内に居る一番近い敵  居ない時は直進  これの距離計算にもVector2.DistanceSquared()を使 用  最初は検索に敵全てを見ていたが重すぎるの で変更。  当たり判定で使用したグリッドを使って同じ ような方法で距離を測り対象を設定
  •  当たり判定、移動先検 索同様グリッドを使用。  保存するのは死骸のみ  掃除機のAIは一番多い マスに向けて移動する  これの難点はAIの方が 人間より集めるのが上 手い確立がかなり高い
  •  結構適当に作ってますw  基本的な動作は:  次に使いたい物選択  金があれば使用、無ければ必要金額を保存し、金を集める  一定金額が集まれば使おうとしていた物を選択  アイコンを選択後に置ける場所を探す  場所へ移動後、置けなくなっていたら再度場所を探す。置 けるまで移動->検索を繰り返す  置いたら最初に戻る  キャラによって選択出来る物が違ったり、比重を置く 物が変わります。
  •  パーティクル  擬似3D  追尾(Trail)  常時(Persistent)  フェードイン・アウト  フェードアウト・フェードインの作り方  振動  どちらかの事務所が破壊された時のエフェクト  雷っぽいもの  タイトルのメニューで選択中の項目に出ているやつ
  •  基本的には小さい画像を沢山飛ばしているだけ  使っているのは右の画像達:  これらの色、大きさ、速度、α値、時間、移動方向、 数、を操作する事でエフェクトを作っています  擬似3DのエフェクトはZ値によって大きさを変える 事でそれっぽくしています。  追尾方エフェクトはオブジェクトの位置を把握し、指 定された時間毎にエフェクトを出しています。細かい 指定は生成時に行われ、くっ付いている先のオブジェ クトが生きている限りは残ります。
  •  使用出来る頂点数が少ない為、PC, XBOXと同 じ用にやろうとすると、直ぐ落ちる  更に、凄く処理落ちする  解決策は特に思いつかなかったので、単純に Vitaに合わせてエフェクトの量やスケールを 変える事で調整。  え?あんどろいど?ナンデスカソレ?・・・
  •  ブログでも紹介しています  振動エフェクトの作り方  ゲーム画面をレンダーターゲットに 描画。保存した画像を複数回描画し、 描画が増える毎に大きく表示する。  描画回数が多いほど濃いエフェクト になる  エフェクト開始時にエフェクトの濃 度設定し、大きさ、α値はこの設定 を使って計算。  濃度は毎フレーム減らし、0になれ ばエフェクト終了  設定や計算はそれっぽく見えるよう に適当にやりましたw
  •  半球の画像と線の画像を用意 する  開始地点と終了地点を指定し、 両方に半球の画像を表示する  開始と終了の間に小刻みに線 の画像を描画する  線の画像は前回の線、または 開始地点から描画を初め、ラ ンダムな角度と長さで描画さ れる  角度の範囲は開始地点と終了 地点の位置から設定する  α値は徐々に下がる
  •  オブジェクトプール  処理負荷計測  FPS (Frames per Second) カウンター  プロファイラー
  •  オブジェクトプールはオブジェクトを一定数最初に生成し、破棄し た時に消さずにプールに戻す事で生成を1回するだけで使いまわす 物  動物、牧場、死骸、パーティクル等の生成と破棄が頻繁に行われる オブジェクトで使用  メモリは最大数分取るが、最初に生成し、破棄がない分インスタン スの生成コストや、ガベージコレクタによる処理負荷が発生しにく くなるので、便利。  作り方は、Pool<T>クラスでT型と使用状態の情報を持ったリストを 作り、コンストラクタで最大数分T型オブジェクトを生成してリス トに追加する。  使用したい時にはリストの中で開いているオブジェクトを引っ張り、 戻す時はそのオブジェクトの使用状態をリセットする
  •  ブロック内の処理にどれくらい時間が掛かっているかを計る  処理としては計測開始時にStopWatchクラスで計測開始し、終了時に経過 時間を獲得する double m_elapsed; Stopwatch m_stopwatch; public void Start() { m_stopwatch = Stopwatch.StartNew(); } public void Stop() { m_elapsed += m_stopwatch.Elapsed.TotalSeconds; }  一定時間(1秒等)を計る時はアウトプットする時に経過時間をリセットする  ゲーム起動時全体の場合は、リセットしない
  •  計測時間をブロック内に限定する為の構造体を用意し、ブロックの先頭で usingでインスタンスを作り、計測する public struct ProfileStarter: IDisposable { Profiler m_profiler; public ProfileStarter(Profiler profiler) { m_profiler = profiler; profiler.Start(); } public void Dispose() { m_profiler.Stop(); } } #if DEBUG Profiler m_profiler; using (new ProfileStarter( m_profiler) ) #endif { // …計測する処理 }
  •  実機用にデバッグ表示付きのReleaseビルドを作成  名前は何か適当につけた  ログ表示  単純にList<T>に文字列を保存し、画面に表示。ファイルにも保存  デバッグコマンド  3倍速 (更新に渡す経過時間を3倍にしただけ)  1ボタンで敵即死  AI vs AI モード  エキシビジョンとしても使えた(自分たちで手を動かす必要が無いので)  処理負荷の計測に便利  入力記録  記録をxmlに保存し、それを再生する処理を作りバグを再現出来るようにした  ただ、乱数を考慮していなかった為、毎回同じ結果にはならない orz  AI は移動や選択する度に入力した体にし、ボタン等を保存  ロケテゲームショウで試合終了時に重かったのはその影響です(言い訳)
  • 他の細かい物は一部ブログに乗っています  メニューの作り方  メニューの作り方  メニューの作り方3:サイズが変わるメニュー  ゲームステート(シーン遷移)の作り方  ゲームの状態変更の実装方法2 (クラス編)  ゲームの状態変更の実装方法3 (クラスの再利用化)  チュートリアルテキスト系  流れるテキストの作り方  自動改行するテキストボックスの作り方  FPSカウンターの作り方  マルチスレッドでコンテントの読み込み  xmlの読み込み & 書き込み(xna 4)  コントローラーの振動機能に時間設定を付ける方法  HPゲージの実装方法
  •  紹介されていない物で知りたい事や、質 問、疑問、ツッコミ、等があればご連絡 ください  Twitter: @ookumaneko_XD  ブログ: http://ookumaneko.wordpress.com/