アクターとしてのスプライト


12

私はゲーム開発の質問ではなく、プログラマーとしての経験があります。Scala言語では、非常に安定した、アクターによるスケーラブルなマルチタスクを実行できます。問題なく数十万を同時に実行することもできます。

したがって、2Dスプライトの基本クラスとしてこれらを使用して、すべてのスプライトを通過して移動する必要があるゲームループの問題を解決できると考えました。基本的には、イベント駆動型で自分自身を動かします。

それはゲームにとって意味がありますか?そのようにマルチタスクされていますか?結局のところ、JVM上で実行されますが、最近ではそれほど問題にならないはずです。

編集:

しばらく手をたたいてから、このアイデアには本当の利点が1つしかないことに気付きました。マルチコアサポートです。単純なゲームループは1つのコアでのみ実行され、すべてを順番に処理します。

最近のコンピューターは、自宅でも2つ以上のコアが組み込まれているため、ゲームプログラマーが他のコアを効率的に使用できるようにすることをお勧めします。結局のところ、通常、プレーヤーは自分の8コアマシンでゲームを実行しているだけだと思います。

私が見る他の利点は、Scalaでを持つことができることですRemoteActors。これはまったく同じ方法で処理できますが、別のコンピューターで実行できます。したがって、これによりネットワークゲームも簡素化される可能性があります。

できるだけ早くScala 2Dエンジンに組み込むつもりです。


私はこれがどうなるか知りたいと思っています。Scalaを数回見たことがありますが、これまでに一度も調べたことはありません。
Davy8

多くの人は、明示的なマルチコアのサポートについては、プロセス(およびScalaアクターがプロセスをモデル化する)よりもスレッドを使用したほうがよいと主張します。これは、スレッド間で共有メモリを利用できるためです。もちろん、これはアクターモデルとは異なり、エラーが発生しやすい方法です。
キロタン

Scalaアクターはスレッドプールの上に多重化されるため、スレッドよりも軽量になります。これは、適切に同期されていれば、共有メモリを操作して通信できることを意味します。リモートアクターを使用する場合、それらは異なるプロセス上にある可能性があり、通信する唯一の方法はメッセージの送信です。
axel22

回答:


7

私は試しませんでしたが、私はScalaプログラマーであり、これは最良のアプローチではないと言うでしょう。スプライトは同期してアニメーション化する必要があります。アクターには公正に実行されるという保証はありません。スプライトの中には、他のスプライトよりも高速なものもありますが、これは望みではありません。それらを同期するためにバリアを使用することもできますが、それでは-なぜアクターを使用するのでしょうか。メッセージの受け渡しのみに依存している場合、この種の同期の実装(1000人以上のアクターに対するバリアの実装)はやり過ぎです。

もう1つの問題は、何のためにメッセージの受け渡しを使用しますか?通信するにはスプライトが必要ですか?マスターアクターからメッセージを送信して、各スプライトに次のフレームに移動するように指示することもできますが、パフォーマンスの観点からは、メソッドを直接呼び出して一連のスプライトを反復処理するよりも重要です。

ここで必要なのは、ある種の非常に軽量なマルチタスクであり、メッセージはまったく渡されないように思えます。公平性を保証する独自のアクターのような実装を導入することは、おそらくこれを確実にしたい場合の最善の方法ですが、それはあまりにも多くの利益を得るには多すぎます。もう1つ見なければならないのは、関数型リアクティブプログラミングscala.reactです。

Scalaに2Dアイソメトリックゲームエンジンを実装しました。アニメーション化された目に見えるスプライトを更新するために、1つのグローバルアクターのみを使用しました。

アクターを使用してゲームロジックを実装します。たとえば、ゲームマップのさまざまな部分の計算をさまざまなアクターに配布し、ゲームの状態を並行して更新し、パフォーマンスを向上させます。ゲームオブジェクトごとに単一のアクターを使用するのではなく、リージョンごとにアクターを使用します。細かすぎると、パフォーマンスが低下します。

それでも、もし私があなただったら、何が起こるかを見るためだけに試してみます。


1

したがって、2Dスプライトの基本クラスとしてこれらを使用して、すべてのスプライトを通過して移動する必要があるゲームループの問題を解決できると考えました。基本的には、イベント駆動型で自分自身を動かします。

彼らを動かすイベントは何でしょうか?

フレームごとに1回発行するイベントでしょうか?

もしそうなら、これは実際の方法でシステムをどのように変えましたか?

元々C ++のコンテキストでオブジェクト指向を勉強していたとき、xyz.doThis(x)「doThisメッセージをxyz(xのペイロードで)に送信してすぐに応答するのを待つ」などのステートメントを考えるのが好きな人がいることを知りました。このレベルで見ると、イベントまたはメッセージベースのシステムと通常の手続き型システムの本質的な違いはありません。


アクターはマルチスレッドソリューションです。通信は同期的ではありません。Scalaアクター(Erlangのコンセプト)を使用すると、簡単にマルチコアプログラムを作成できます。
エリス

そこにはポイントがありますが、ここでの違いは、アクションの実行中にアクターベースのスプライトがゲームループをブロックせず、メソッドアプローチxyz.doThis(x)が完了するまで待機することです。これは、特にマルチコアシステムで、ゲームロジックを高速化するのに役立つ可能性があると思います。
ランボー

エンティティ処理を複数のコアに分散するのが簡単になります。しかし、その代償として、追加のメッセージまたはメッセージで送信された追加のデータなしに、あるアクターから別のアクターに簡単に参照することはできません。そこで、ここでの素朴なアプローチは役に立たないことをすぐに理解します。更新を実行するためのアクターベースの方法を策定できますか?
キロタン

現在、私はある種の分散更新を実験しています。私のアクターはツリー構造のノードのようなもので、ルートを更新すると子がメッセージ配信によって更新されます。また、真の利点はネットワーキングです。Scalaでは、アクターとRemoteActor(別のシステム上のアクター)は、同じメッセージで同じ方法で対処できます。
ランボー

ええ、しかし、問題は更新自体のトリガーではなく、メッセージの受信者が対処するために必要なすべての情報を確実に持っていることです。
キロタン

0

これは、ゲームオブジェクトの更新について考えるためのクールなアプローチです。私はScalaを知りませんが、試してみて、結果がどうなるかを確認し、結果を投稿することをお勧めします!

私の頭に浮かぶ主な質問は次のとおりです。一部のゲームオブジェクトが他のゲームオブジェクトと比較して更新される頻度をどのように管理しますか。レンダリングシステムが1/60秒| 30秒| 24秒ごとにフレームを描画する時間がないように、スプライトアクターが多くのサイクルを使用することを心配する必要がありますか?

考慮すべきもう1つのことは、これが、非常に速いイベントのシーケンスの順序に依存するプレーヤーとAIの相互作用の解決にどのように影響するかです。ゲームの種類によっては、これおそらくそれほど重要ではないかもしれません


Scalaアクターの素晴らしいところは、メッセージ駆動型であることです。それらのすべてに独自のメッセージ/イベントキューがあります。'Draw'がメッセージなのか呼び出し用のメソッドなのかわかりません。後者になると思うので、イベントキューの状態に関係なく、いつでもスプライトを描画できます。また、お互いにメッセージを送信して、特定の順序で処理が行われるようにします。
ランボー

そこで注意してください。各スプライトにDrawメソッドやイベントを持たせることは、可視性を切り替えるためのフラグとして使用する場合を除いて、役に立つとは思いません。ゲームループのレンダリングフェーズでは、スプライトが画面にレンダリングされる順序が結果に大きな影響を与えます。1つのスプライトが他のスプライトの前にある場合(寸法がモニターに向かっている場合)、そのスプライトを2番目に描画します。Scalaのアクターは、ゲームループの更新/ロジック部分に役立ちます。
michael.bartnett

通常、そこにはdrawメソッドしかありません。そのように実装することで、スプライトを処理する通常の方法と大きな違いはないはずです。
ランボー

ああ、私はあなたが説明していたことを誤解しました。私は、スプライトがいつでもどのようにレンダリングされるかを想像していました。これがどうなっているか教えてください!
michael.bartnett

0

まあ、私もそれほどプログラマーではありませんが、あなたの提案には何の問題もありません。私はそのような俳優の育成方法さえ考えていませんでした。

IAは非常に正確である必要があるため、不審な動作を避けるために非常に困難な場合がありますが、それに加えて、かなり良い提案だと思います


0

スプライトによってゲームエンティティを意味する場合は、確認してください。

ゲームエンティティが自分自身を描画することはありません。描画する場所と方法を説明するグラフィックハンドルを更新する必要があります。レンダリングシステム、シーングラフ、または実際の描画を行うもの。グラフィックカードが1つあり、さらに16ミリ秒ごとにグラフィックカードを同期する必要があります。このような設定は、分散非同期処理ではうまく機能しません。

レンダーシステムは1つのアクター(またはトリッキーな場合はカップル)である必要があります。ゲームエンティティがグラフィックスハンドルを更新すると、メッセージがレンダーシステムに送信されます。レンダリングシステムは、バッチレンダリング、オクルージョン、物理ジッタースムージングなど、あらゆる種類の決定や最適化を行うことができます。

私はScalaの開発者ではありませんが、Erlangをかなり使いました。したがって、Scalaの用語の一部に誤りがある場合はご容赦ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.