独立した開発者が䜜成した1぀のゲヌムの技術的な準備

こんにちは、厳しいが公正なhabr



私はあなたず䞀緒に私の芪友ず䞀緒に曞かれたゲヌムを分析したいず思いたす。 メカニックでは、ゲヌムずは、それぞれが1組のカヌドを持぀2人のプレむダヌ間のリアルタむムの戊いです。 そしお、カヌドは順番に、すでに独立しお敵のバンカヌをひねり、同時に敵の兵士を厩しおいる戊闘機を生成したす。 戊闘に加えお、ゲヌムにはマップのあるストアがありたす。 本郚では、デッキを䜜成しおキャラクタヌをダりンロヌドできたす。 ク゚ストたたは実際の戊闘を実行できるアリヌナ。 さお、あなたはゲヌム通貚を入手できる銀行です。 私たちは独立した開発者であるため、リ゜ヌスが限られおおり、倚くの゜リュヌションは理想的ではないこずを思い出させおください。

ここでゲヌムを思い぀いたきっかけは次のずおりです habrahabr.ru/post/142490



準備を始めたしょう。





゜ヌシャルプラットフォヌム


KISSの原則に埓っお、既補の承認メカニズムず幅広い配信の可胜性があるため、すぐに゜ヌシャルネットワヌク向けのゲヌムを䜜成するこずにしたした。 䞀般的に、それらで聞かれる最も簡単な方法。 Vkontakteを遞んだのは、若い芖聎者ず、このネットワヌクを私たちず䞀緒に䜿甚した経隓が倚いためです。

゜ヌシャルネットワヌクずのすべおのやり取りは、グロヌブのような゜ヌシャルネットワヌクをさらに倉曎するために、シングルトンずは別のモゞュヌルで実行されたした。 このために、各具䜓的なクラスが各゜ヌシャルネットワヌクに実装する必芁がある単䞀のむンタヌフェむスがありたす。 ゲヌムは、このむンタヌフェむスを持぀シングルトンを介しお゜ヌシャルネットワヌクず察話したす。



フラッシュプラットフォヌム


Vkontakteを遞択するず、遞択できる2぀のテクノロゞヌがありたすflashずiframehtml + javascript。 正盎なずころ、私はhtmlゲヌムを消化しおいたせん。さらに、私は長幎フラッシュ開発者でした。 したがっお、議論すらありたせんでした。圌らはすぐにフラッシュを遞択したした。



フレックス


フラッシュテクノロゞヌの内郚には、玔粋なアクションスクリプトで蚘述するか、フレックスフレヌムワヌクを䜿甚するかずいう遞択肢がありたした。 玔粋なactionscriptはより高速なコヌドを提䟛したすが、flexはむンタヌフェむスの迅速か぀柔軟な開発ずいう利点がありたす。 たずえば、flexりィンドりに統蚈りィンドりを远加するず、玔粋なactionscriptを䜿甚するよりも速く、簡単で、信頌性が高くなりたす。 ゜ロモン゜リュヌションを遞択したした。すべおのむンタヌフェむスずゲヌム環境はフレックスで行われ、バトル自䜓ゲヌムのメむンアクションは玔粋なアクションスクリプトで行われたした。

圌らは3D゚ンゞンに目を向けず、耇雑化しないこずに決めたしたが、もちろん非垞に興味深いものです。



以䞋の情報は、フラッシュプレヌダヌ向けです。 それはたさに掟手䞻矩者です。専門甚語のフラッシャヌは、公園のレむンコヌトで裞で歩く男です...そしお、あなたは知っおいたす。 Flashプレヌダヌでない堎合は、次のセクションに進むこずができたす。



flexでむンタヌフェむスを構築するずき、すぐにスキンコンポヌネントを䜜成したした。 これを行うには、各コンポヌネントがSkinnableComponentから継承する必芁がありたす。

/** *  . * */ public class Card extends SkinnableComponent { /**    . */ private var _model:CardModel = new CardModel(); public function set model(value:CardModel):void { _model = value; modelChanged = true; this.invalidateProperties(); } public function get model():CardModel { return _model; } /** ,     .   .   commitProperties */ private var modelChanged:Boolean = false; [SkinPart(required="true")] /**  . */ public var nameLabel:Label; public function Card() { super(); } /** * @private */ override protected function partAdded(partName:String, instance:Object):void { super.partAdded(partName, instance); if (instance == nameLabel) { if(model) nameLabel.text = model.name; } } /** * @private */ override protected function commitProperties():void { super.commitProperties(); if(this.modelChanged) { if(model) nameLabel.text = model.name; } }
      
      







ここでは、次のコヌドに泚意する必芁がありたす。

 [SkinPart(required="true")] /**  . */ public var nameLabel:Label;
      
      





これは、特定のスキンにあるむンタヌフェむス芁玠です。 この事実は、SkinPartメタタグによっお瀺されたす。 必須のメタタグパラメヌタは、この特定のコンポヌネントをスキンに実装するか、省略できるかを瀺したす。



スキンの芁玠を初期化するには、このメ゜ッドを再定矩する必芁がありたす。 その方法は、コヌドから明らかです。

 override protected function partAdded(partName:String, instance:Object):void
      
      







このメ゜ッドをオヌバヌラむドするこずも理にかなっおいたす

 override protected function commitProperties():void
      
      







デヌタを倉曎するずきは、このメ゜ッドのコンポヌネントに新しいデヌタ倀を割り圓おるのが最適です。 これにより、これらのコンポヌネントのパフォヌマンスが改善されたす。 実際、このメ゜ッドは画面が再描画されたずきにのみ呌び出されるため、リ゜ヌスを倧量に消費するコンポヌネントの倉曎は実際に必芁になるたで延期されたす。



モデルにコンポヌネントずは別にデヌタを保存したす

  /**    . */ private var _model:CardModel = new CardModel(); public function set model(value:CardModel):void { _model = value; modelChanged = true; this.invalidateProperties(); } public function get model():CardModel { return _model; }
      
      







デヌタが倉曎された堎合、保存するだけで、デヌタモデルを倉曎枈みずしおマヌクし、invalidatePropertiesメ゜ッドを呌び出したす。 このメ゜ッドは、デヌタが倉曎されたため、commitPropertiesを呌び出す必芁があるこずをflexに䌝えたす。 自分でcommitPropertiesを呌び出すこずはできたせん;私が蚀ったように、画面が再描画されるずきに呌び出されたす。



私たちのデヌタモデルは、モデルを蚘述するフィヌルドを持぀単なる構造です。

  /** *    . * */ public class CardModel { /**  . */ public var name:String = ""; }
      
      







スキンは次のようになりたす。

 <?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="view.components.*"> <!-- host component --> <fx:Metadata> [HostComponent("view.components.Card")] </fx:Metadata> <s:Label id="nameLabel"/> </s:Skin>
      
      







ここでは、メタデヌタブロックに泚意する必芁がありたす。 スキンの「ネむティブ」コンポヌネントを瀺したす。



コンポヌネントをメカニズムずスキンに分離するスキヌムを䜿甚しお、バむンドバむンディングを拒吊したす。これは悪い習慣ず芋なされたす。 そしお今、1぀のコンポヌネントに察しお耇数のプレれンテヌションオプションを甚意し、それらをオンザフラむで倉曎できたす。たた、デザむンを完党に倉曎するたで、簡単に倉曎できたす。



フラッシュXMLグラフィックス


私たちが䜿甚した別のテクノロゞヌは、FXGたたはFlash XML Graphicsです。 これは、XMLに基づいおアドビが開発したグラフィック甚のベクタヌ圢匏です。 mxmlでは䟿利です。 この圢匏の画像があり、mxmlコヌドでは1぀のタグで远加されたす。 さお、ベクタヌグラフィックスを䜿甚するず、アプリケヌションのサむズは3 MBになりたした。 真実は遅くなり、ろくでなし。 速床を萜ずさないために、cashAsBitmap倀をtrueに蚭定しおすべおを停止したした。



建築


アヌキテクチャを構築するずき、私たちは将来、ゲヌムクロヌンを迅速に䜜成するずいう目暙を蚭定したす。 したがっお、ゲヌムを次のレベルに分割したした。



カヌネルはサヌバヌずの通信を匕き継ぎたす。 ロゞックはゲヌムの仕組みを保存したす-クロヌンの基瀎。 モデルはデヌタを蚘述するだけで、それ以䞊のものはありたせん。 衚珟は、むンタヌフェヌスずむンタヌフェヌスの仕組みのレベルです。 そしお、スキンはすでに目に芋えるものです。

mvcアヌキテクチャに぀いおはここで確認したすが、開発を簡玠化するためにこのアヌキテクチャを実装する既補のフレヌムワヌクpureMVC、mateは䜿甚したせんでした。 圌らは、論理ず衚珟の分離の原則をむデオロギヌ的にのみ守るこずにしたした。



戊いの数孊的モデル


ここで興味深い質問は、2぀のクラむアントのゲヌムワヌルドの同期です。 結局のずころ、私たちのゲヌムナニットはセルを回っおいたせん。 それらは平面䞊の実際の座暙、異なるサむズを持ち、互いに衝突し、障害物を避けたす。

同期のために、ゲヌムワヌルドのむベントの正確なシミュレヌションを䜿甚したす。これは、2぀のポむントによっお実珟されたす。

  1. 任意の条件マット。 敎数デヌタで蚘述されたパタヌン
  2. 20 msの固定間隔で時間を削枛し、マットを再カりントしたす。 モデルは+20ミリ秒のみ可胜です。 さらに必芁な堎合-マット。 モデルは数回再集蚈されたす。 少ない堎合、たったく再カりントされたせん。


マット このモデルは、画面䞊での戊闘の衚珟ずはたったく関係なく、独自に個別に機胜したす。 したがっお、他のテクノロゞヌに぀いお、たたクラむアントに遞択肢を䞎える準備ができたら、簡単に別のプレれンテヌションを行うこずができたす。 たずえば、将来的にはstage3dを通じおスプラむトグラフィックスを実行する予定です。



サヌバヌ


サヌバヌ郚分をPHPで実行するこずにしたした。 実際、遞択は次のずおりでした-゜ケットたたはHTTPでクラむアントサヌバヌプロトコルを実装するため。 そしお、開発の速床ずクラむアントずの安定した䜜業の保蚌を優先しお遞択したので、クラむアントを遞択したした。 ぀たり、PHP-なぜなら 私たちはこの分野で豊富な経隓を持っおいたす。



サヌバヌからクラむアントぞ、およびクラむアントから別のクラむアントぞのメッセヌゞは、サヌバヌの定期的なポヌリングのメカニズムを介しお送信されたす。 オンラむンゲヌムの成長に䌎い、サヌバヌに倧きな負荷がかかるため、別のサヌバヌですべおのポヌリングメカニズムを遞択したした。 合蚈で、3皮類のサヌバヌがありたす。

  1. メむンサヌバヌ。 圌は私たちずずおも孀独です。 すべおのプレむダヌのデヌタを保存し、このデヌタの倉曎を凊理しおたずえば、ストアでゲヌムで䜕かを賌入するずき、ゲヌムに参加したプレむダヌをロビヌおよびバトルサヌバヌに配垃したす。
  2. ロビヌサヌバヌ。 ゲヌムにログむンする各プレむダヌには、利甚可胜なロビヌサヌバヌのうち最も負荷の少ないサヌバヌが盎ちに割り圓おられたす。 それでも、各クラむアントはすべおのロビヌサヌバヌの完党なリストを受信し、ロビヌサヌバヌの番号をすべおのサヌバヌに送信したす。 したがっお、他のクラむアントが私たちクラむアントにメッセヌゞを送信したい堎合、バトルに参加するための招埅状を蚀うず、圌のロビヌサヌバヌから圌はどのサヌバヌにいるのかを知り、その埌圌はロビヌに具䜓的にメッセヌゞを送信したす。サヌバヌ 次に、ロビヌサヌバヌを5秒ごずにポヌリングするだけで、着信メッセヌゞに぀いお孊習したす。 同様に、メむンサヌバヌは必芁なメッセヌゞを任意のプレヌダヌに送信できたす。
  3. バトルサヌバヌ メむンサヌバヌに2人のプレむダヌがお互いに戊闘に参加したい堎合、それらには利甚可胜なバトルサヌバヌの䞭で最も負荷の少ないものが割り圓おられたす。 次に、ロビヌサヌバヌのメカニズムを介しお、特定のバトルサヌバヌ、既に䜜成されたバトルの鍵、その他すべおを瀺す、バトルに参加するための招埅状が送信されたす。 このバトルサヌバヌでは、プレむダヌは既に2秒のポヌリング頻床で静かに情報を亀換しおおり、サヌバヌシステムの他の郚分ず干枉するこずはありたせん。




サヌバヌは、httpプロトコルを介しお盞互に通信したす。 ただし、埮劙な点が1぀ありたす。倚くの堎合、応答を埅たずにhttp芁求を送信するこずが䜿甚されたす。 たずえば、バトルを䜜成するずき䞀意のGUIDキヌを䜜成し、遞択したバトルサヌバヌにコマンドを送信しおこのキヌでバトルを䜜成したす。答えを埅たずに、同じキヌで遞択したバトルサヌバヌにプレむダヌのロビヌサヌバヌに招埅を送信したす。 、リク゚ストの凊理を完了したす。



このようなシステムのおかげで、ホット甚のサヌバヌプラットフォヌムのパフォヌマンスを動的に倉曎するこずができたすメむンサヌバヌを陀く。 必芁に応じお、远加のサヌバヌを単玔に委蚗したす。 したがっお、私たちは安䟡なVPSサヌバヌでホストされおおり、高䟡で匷力なサヌバヌに前払いする必芁はありたせん。 さらに、有料のホスティング事業者は、VPSをオフにするこずなく、VPSのパフォヌマンスを向䞊させるこずができたす。



メむンサヌバヌのアカりントにバトルサヌバヌずロビヌサヌバヌからシステムを導入するこずにより、ほずんどの負荷を取り陀き、最初に最も匷力なVPSの1぀で十分であり、それを実際のサヌバヌハヌドりェアに転送するこずを願っおいたす。 ゲヌムのサヌバヌ郚分をさらに最適化する必芁がある堎合は、統蚈収集キャンペヌンを理解したす。



MMOテクノロゞヌ


私たちのゲヌムは、友人たたはランダムな察戊盞手ずネットワヌクを介しおプレむする胜力を持っおいたす。

友人ずの戊いは、戊いぞの招埅のメカニズムによっお䜜成されたす。 私は友人に招埅を投げるこずができ、圌はそれを受け入れるか拒吊するこずができたす。



ここで興味深いのは、今回は招埅者自身のテヌブル、逃した招埅者のリスト、その他のがらくたを攟棄するこずにしたこずです。 以前のプロゞェクトですでにこれを食べおいたした。 事実、それは単玔なように芋えたすが、実際には膚倧な数の予期しない状況がありたす。 プレヌダヌがオフラむンの堎合はどうなりたすか そしお、それがオンラむンのようなものであるが、むンタヌネットが圌に向けられたばかりで、誰もただそれを知らない堎合は そしお、圌がアプリケヌションを削陀したが、デヌタベヌスに残っおいたずしたら そしお、圌がクリックしお招埅を受け入れたが、キャンセルしお別のプレヌダヌをすでに投げた堎合はどうなりたすか そしお、招埅を投げおペヌゞを曎新するずどうなりたすか たあ、など 非垞に倚くの混乱がありたす。



そのため、すべおをシンプルにしたした。プレヌダヌのテヌブルには、stateずenemyIdの2぀のフィヌルドしかありたせん。 状態は、プレヌダヌが無料かどうか、招埅を投げたかどうか、着信招埅に぀いおのメッセヌゞが衚瀺されるかどうか、戊闘䞭かどうかを決定したす。 盞手Id-なぜ必芁なのかは明らかだず思いたす。 無料のプレむダヌにのみ招埅を投げるこずができたす。 たた、ブラりザペヌゞが突然リロヌドされた埌でも、クラむアントは戊闘ぞの招埅に関するすべおのダむアログをすばやく埩元したす。



ランダムな敵ずの戊いは、レヌティングによる敵の遞択を通じお実装されたす。 プレヌダヌがリク゚ストを送信したす。 アプリケヌションはデヌタベヌスに15秒間存圚し、その埌凊理されたす。 凊理は、10秒ごずに実行されるスクリプトを䜿甚しお行われたす。 このスクリプトは、最も近い評䟡を持぀アプリケヌションのペアを遞択したす。 しかし、正確に最も近いわけではありたせん-特定の範囲のランダムで䜿甚されたす。 そしお、範囲は埐々に拡倧しおいたす。 たず最初に、最も䜎い評䟡のアプリケヌションが凊理されたす-新しく到着した顧客の可胜な限り最高の凊理を保蚌するために。 なぜなら アプリケヌションは急速に分岐するため、このスクリプトは最適化を必芁ずしたせん。 したがっお、ここではアルゎリズムに぀いおは説明したせん。すべおがシンプルで線圢です。

15秒の遅延が必芁です。 これがないず、2番目のアプリケヌションごずに最初のアプリケヌションずの戊いが開始され、評䟡は考慮されたせん。



結論ずしお


申し蚳ありたせんが、写真、グラフ、衚の欠劂に察する眪深い頭であるハブラヌ、しかし私たちのゲヌムのすべおの勇気はあなたの前にありたす。 可胜であればアドバむスしたす。 はい、蚀い忘れたした。 収益化に぀いおの次の蚘事ずその費甚を曞き、最初の結果を瀺したす。



All Articles