神は言われた.「光Array」.
すると,
まばゆく輝く配列「index out of range」
…とか何とか言う啓示を受けた気がしないでもないので,プログラミングの話をしよう.そうしよう.
例によって,まともにゲームプログラミングをしたことのない者の妄言というかそんな.
---
RPG でも SLG でも何でもいいけど,「AがBを攻撃する」という処理があるとしよう.
この処理だけを考えれば,
何か攻撃手段に応じたダメージ計算をして,必要なら追加でBが状態異常になるとかいう処理をしたり,BのHPが0になったらどうのこうの…
っていうのをやることになるのだろうけど,この処理って,単に処理(計算)するだけなら一瞬で終わるよね.
で,ふつーの(仕事とかの?)処理ってのは,まぁ一瞬で終わるならそれに越したことは無いわけで,「OK,できた」ってなるんだけども,これがゲームだと話が違ってくる:
何か攻撃のエフェクトを表示して,次にダメージの表示があって,Bが消える演出が…
とか何とかいうことになって,これは「一瞬」で済ませるわけにはいかない.面倒な限りだ.
つまり,処理内容的には一瞬で済むような話なんだけども,その様子を時間をかけて,言わば「スロー再生」して見せなければならなくて,且つ「それが終わるまでは処理を次に進めない」っていう制御が必要になるわけだ.
こういうのって,どうやってるんだろう?(何かしらのかっこいい実装方法的な意味で) っていう話.
表示ってどうやって作ってんの?
表示ってどうやって作ってんの?
最後に編集したユーザー usao on 2022年8月29日(月) 18:29 [ 編集 1 回目 ]
Re: 表示ってどうやって作ってんの?
とりあえずこんな形に組み替えれば,表示物単体と表示物のシーケンスとの区別が無くなったから,好きな単位で待つ形に使えば良い,と.
ところで,処理(計算)側が「表示器」の Finished() にダイレクトにアクセスできるのだとしたら,「Observer がどうの」いう通知機構の部分は別に要らないんだよなぁ.
両者がそれなりに離れたところにあって互いに直接触れられない,っていうような分離した形で実装することにならないと恩恵は 薄いor無い っていうことになりそうだな.
ところで,処理(計算)側が「表示器」の Finished() にダイレクトにアクセスできるのだとしたら,「Observer がどうの」いう通知機構の部分は別に要らないんだよなぁ.
両者がそれなりに離れたところにあって互いに直接触れられない,っていうような分離した形で実装することにならないと恩恵は 薄いor無い っていうことになりそうだな.
Re: 表示ってどうやって作ってんの?
どうでもいいけど,シーケンスの AddDispItem() のコメントには "would" を使ってみましたぞ!
(よくわかってないのにw)
(よくわかってないのにw)
Re: 表示ってどうやって作ってんの?
そんなこんなで,「表示器」側と「ゲーム自体の進行処理(計算)」側のそれぞれに Update() というメソッドがある状態だから,例えば通常時には両者を平等に呼ぶ:
みたいなことになっている個所があるのだとして,ここのところがある条件下においては不平等になる:
とかすれば「2倍速表示モード」みたいな話になる感だな.
みたいなことになっている個所があるのだとして,ここのところがある条件下においては不平等になる:
とかすれば「2倍速表示モード」みたいな話になる感だな.
Re: 表示ってどうやって作ってんの?
いやこれ,「シーケンス」の動作がシーケンシャルになってねぇやんっていう,しょーもないバグに一同驚愕!
パラレルすぎてワラタw
パラレルすぎてワラタw
Re: 表示ってどうやって作ってんの?
というわけで,つまらないバグ修正.
パラレルなやつもそれはそれで必要なので適当な名前にして残し,シーケンスの側はqueueの先頭だけを扱うやつとして追加.
「 IDispItem::Finish() が初回コールでいきなり true を返してくる可能性!」とか思って Update() の最初に備えを入れてみたけど,Paint() 側はそこらへんどうなん?っていう.
(そういう項目が先頭にある状態で Update() 呼ばずに Paint() 呼ばれた場合…うーん,シラネw)
パラレルなやつもそれはそれで必要なので適当な名前にして残し,シーケンスの側はqueueの先頭だけを扱うやつとして追加.
//Sequence of IDispItem.
class DispItemSeq : public IDispItem
{
public:
DispItemSeq(){}
DispItemSeq( const DispItemSeq & ) = delete;
DispItemSeq &operator=( const DispItemSeq & ) = delete;
virtual ~DispItemSeq(){}
public:
//Add to the tail of sequence.
//When the added item's Finished() returns true, the item would be automatically popped from this sequence.
void PushDispItem( std::shared_ptr<IDispItem> spItem ){ m_Items.push( spItem ); }
public: //IDispItem implementation
virtual bool Finished() const override { return m_Items.empty(); }
virtual bool Update() override
{
//Handling the fact that item's Finish() may return true at the first call.
while( !m_Items.empty() && m_Items.front()->Finished() ){ m_Items.pop(); }
bool NeedToRedraw = false;
if( !m_Items.empty() )
{
NeedToRedraw = m_Items.front()->Update();
if( m_Items.front()->Finished() ){ m_Items.pop(); }
}
return NeedToRedraw;
}
virtual void Paint( HDC hdc, int W, int H ) const override
{
if( !m_Items.empty() ){ m_Items.front()->Paint( hdc,W,H ); }
}
protected:
std::queue< std::shared_ptr<IDispItem> > m_Items;
};
(そういう項目が先頭にある状態で Update() 呼ばずに Paint() 呼ばれた場合…うーん,シラネw)
Re: 表示ってどうやって作ってんの?
表示物側の Update() っていうメソッド名がどうにも好きじゃない.
(処理側のメソッドと名称が被ってる点も嫌)
…なんだけど,他の良い単語があるのか?っていうのがわからん.
(処理側のメソッドと名称が被ってる点も嫌)
…なんだけど,他の良い単語があるのか?っていうのがわからん.