3

作業中のプログラムの基本構造に問題があります。私は、複数の状態を使用するプログラムの基本を自分自身に教えようとしている、非常に経験の浅いプログラマーです。

現在、イベント、ロジック、レンダリングをStateManagerクラスにリダイレクトするゲームループを備えた非常にシンプルなゲーム風のプログラムがあります。このクラスは、状態をにプッシュおよびポップします。次に、StateManagerクラスは、イベント、ロジック、およびレンダリングを、ベクターのback()にある状態にリダイレクトします。アイデアは、プログラムのフェーズごとにさまざまな状態を用意することです(この場合、スプラッシュスクリーン、メニュー、ゲームプレイ、デススクリーンなどを備えたシンプルなゲーム)...

しかし、私は非常に初心者のコーダーであり(最善を尽くして学習しようとしています)、最初の州のクラスからプログラムで根本的な問題に遭遇しました...

私が作成した最初のクラスはSplashScreenStateです。そして、基本的な考え方は、基本的に一連の「スプラッシュ画面画像」(例として3つ)を表示するだけの状態にすることでした。ユーザーがキーを押すたびに、次の画像に切り替わり、最後に(スプラッシュ画面の画像が表示されていない場合)、次の状態(menustate)に切り替わります。

私の問題は、これをどのように構成するかを理解するのに苦労していることです。もともと、私はそれぞれの異なるスプラッシュ画面画像をSplashScreenStateのインスタンスとして扱うという間違いを犯しました。ただし、3つのスプラッシュ画面はすべて技術的に同じ「状態」の一部であるため、これは正しくないと考えました。

だから今私は2つの主要な問題があります:

  • 最初の問題は、すべてのスプラッシュスクリーン画像をどのように/どこに保存するかがわからないことです。プログラムの起動時に3つの異なる画面イメージを循環させたい場合、それらをすべてSplashScreenStateクラスのメンバーにする必要がありますか?または、「currentImage」に1つのクラスメンバーを設定し、ユーザーがキーを押すたびにload()関数を実行して、次の画像をcurrentImageポインターにロードする方が賢明ですか?画像の配列またはベクトルを作成し、それらを循環させる方が良いですか?よくわかりません...

  • 2番目の問題は、SplashScreenStateのeventhandling()に関するものです。画面上の画像を次のように変更したいことはわかっています。* image1-> image 2-> image 3-> changeState(menuState)..ユーザーがキーボードのキーを押すたびに、最後のスプラッシュ画面まで次のスプラッシュ画面に切り替わり、そこで変更されます。メインメニューに状態します。これを行うための最良の方法もわかりません。各スプラッシュ画面に列挙型を作成し、それらをインクリメントする必要がありますか(状態が変化する最後の画面まで)?また、さまざまな画面をすべて配列に格納すると、簡単にインクリメントできると思いますが、すべての画面を常にメモリに格納する必要があるため、最適化されていないのでしょうか。

とにかく、私はこの質問が非常に基本的で無愛想であるかもしれないことを知っています、しかしそれは残念ながら私が今いるところです!私はプログラミングの正式な教育を受けておらず、自分自身を教えてきたので、このサイトにあるすべての助けと専門知識に本当に感謝しています!^^

ありがとう!

4

2 に答える 2

1

状態遷移を処理するためのオブジェクト指向と手続き型のパラダイムの間で引き裂かれているようです。列挙された状態の変化を処理するためのswitchステートメントを提案するもう1つの答えは、それを実行するための優れた手続き型の方法です。その欠点は、すべての可能な状態のイベント/ロジック/レンダリングを処理するためのすべてのコードとすべての不要な状態固有のデータを含むモノリシックゲームクラスになってしまう可能性があることです。これを処理するオブジェクト指向の方法ははるかにクリーンであり、これらを独自の個別の状態オブジェクトにカプセル化し、共有インターフェースを介して多態的に使用できます。次に、ゲームクラスのすべての状態を処理するためのすべての詳細を保持する代わりに、ゲームクラスは状態ポインターを格納するだけでよく、具象状態オブジェクトの実装の詳細について心配する必要はありません。これにより、状態遷移を処理する責任がゲームクラスから、それが属する状態クラスに移動します。デザインパターンブックから状態/戦略パターンを読む必要があります。状態の変更の処理は、状態オブジェクト自体の責任である必要があります。ここにいくつかの読書があります:

http://www.codeproject.com/Articles/14325/Understanding-State-Pattern-in-C

http://sourcemaking.com/design_patterns/state

http://sourcemaking.com/design_patterns/state/cpp/1

http://codewrangler.home.comcast.net/~codewrangler/tech_info/patterns_code.html#State

http://en.wikipedia.org/wiki/State_pattern

http://www.codeproject.com/Articles/38962/State-Design-Pattern

デザインパターンとパターン指向のソフトウェアアーキテクチャの本からの引用:パターンベースのアプローチでは、データ構造の代わりにコードを使用して状態遷移を指定しますが、状態遷移アクションに対応するのに適しています。状態パターンは、状態遷移を定義する必要がある場所を指定しません。これは、コンテキストオブジェクトで実行することも、個々の派生状態クラスで実行することもできます。一般に、状態サブクラスに継承状態と遷移を行うタイミングを指定させる方が、より柔軟で適切です。

事前に状態オブジェクトを作成し、それらを破棄しないというオプションがあります。これは、状態の変化が急速に発生し、すぐに再び必要になる可能性のある状態を破棄しないようにする場合に適しています。一方、コンテキストは入力される可能性のあるすべての状態への参照を保持する必要があるため、不便になる可能性があります。

入力される状態が実行時に不明であり、コンテキストが状態を頻繁に変更しない場合は、必要に応じて状態オブジェクトを作成し、その後それらを破棄することをお勧めします。どちらを使用するかを決定する際には、コストと遷移頻度を考慮する必要があります。

于 2012-08-12T09:40:34.243 に答える
1

まず第一に、あなたの問題の優れた説明。

スプラッシュ画面を管理するゲームの部分は、2つの方法で機能します。あなたは問題を調べました、そしてそれは本当にとても簡単です:

入力を受け取ります。次の状態を設定します。

だから、例:

 STATE_SPLASH1
 STATE_SPLASH2
 STATE_SPLASH3
 STATE_TITLE
 STATE_GAME_INIT
 STATE_GAME
 STATE_EXIT

擬似コード:

state = STATE_SPLASH1

while (state != STATE_EXIT) 
  ... receive input ...
  ... process events to responders ...
  ... update ...
  ... yadda yadda ...
  switch (state) {
    case STATE_SPLASH1:
      show_splash1()
    case STATE_SPLASH2:
      show_splash2()
    case ..:

    case STATE_TITLE:
      show_title()
    case STATE_GAME_INIT:
      show_loading()
      setup_level()
      setup_characters()
    case STATE_GAME:
      game_update()
    case STATE_EXIT:
      cleanup_and_quit()

もう1つの方法は、スプラッシュを「ゲーム状態」として管理し、次にスプラッシュの状態を内部状態として管理することです。スプラッシュに実行するロジックがなくなったら、ゲームの状態を次の状態に設定します。私が学んでいたとき、私はDOOMソースが貴重なリソースであり、人間であることに気づきました。それは何百ものステートマシンに他なりません。:)

于 2012-08-12T09:50:35.363 に答える