0

前に、いくつかのデータをシングルトン オブジェクトの GamePropertiesManager に移動しました。このクラスで _gameSpeed という変数を定義し、クラス コンストラクターで初期化リストを使用してデフォルトとして 1 に設定します。

別のクラスには、(私の制御の範囲外で)常にできるだけ頻繁に更新する更新ループがあります。私は意図して、「速度」変数を使用して更新を遅くすることに成功しました。これは、たとえば、2 に設定すると、ゲームは onUpdate への 1 回おきの呼び出しのみを更新することで機能しました。以下の PlayState::onUpdate() の内容を見れば、理解できるかもしれません (コメント者):

#include "PlayState.hpp"
#include "PlayerController.hpp"
#include "AIController.hpp"

#include <stdlib.h>
#include <time.h>

//testin
#include <iostream>

/// Implement PlayState

PlayState::PlayState()
{}
PlayState::~PlayState()
{}

bool PlayState::onCreate()
{
   _gameProperties = GamePropertiesManager::GetInstance();

   _frameCounter = 0;
   application.addKeyListener( *this );
   _collisionFlag = false;

   //snakes created, intialising a pointer to fruit managaer, controller and opposing snake
   _player1 = new Snake();
   _player2 = new Snake();
   _player1->Initialise(&_fruitManager, new PlayerController(_player1), _player2);
   _player2->Initialise(&_fruitManager, new AIController(_player2), _player1);

   return true;
}
bool PlayState::onDestroy()
{
   return true;
}

void PlayState::onEntry()
{
   //seed to randomise food positions later
    srand ( time(0) );
}

void PlayState::onExit()
{

}

void PlayState::onUpdate()
{
   //TODO: rename _snake speed and maybe make it global gamespeed
   ++_frameCounter; //FrameCounter can be used to slow the snake down
   if(_frameCounter >= _gameProperties->GetGameSpeed())
   {

       //updating
       _fruitManager.UpdateFruits();
      _player1->Update(&_collisionFlag);
      _player2->Update(&_collisionFlag);

      if (_collisionFlag)
         application.setState("gameover");

      _frameCounter = 0;
   }

}

void PlayState::onRender( Canvas& c )
{
   _player1->Draw(c);
   _player2->Draw(c);

    _fruitManager.DrawFruits(c);
}

bool PlayState::onKey (const KeyEvent& key)
{
if( key.key_state == KeyEvent::KB_DOWN ){

    switch (key.key){
         case KeyEvent::KB_ESC_KEY:
            application.exit();
            break;
        case 'p':
            application.setState("pause");
            break;
      }
}
   return true;
}

_gameProperties は、クラス PlayState が最初に作成されたときに、PlayState::onCreate() で割り当てる GamePropertiesManager へのポインターです。

実際の G​​amePropertiesManager クラスは次のようになります。

#include "GamePropertiesManager.hpp"

GamePropertiesManager* GamePropertiesManager::_instance = NULL;

GamePropertiesManager* GamePropertiesManager::GetInstance()
{
   if (!_instance) //instance not yet created
      _instance = new GamePropertiesManager();

   return _instance;
}

void GamePropertiesManager::Destroy()
{
   delete _instance;
   _instance = 0;
}

GamePropertiesManager::GamePropertiesManager() :
   _gameMode(PLAYERVSCOM), _player1Name("Player 1"), _player2Name("Player 2"),
      _player1Score(0), _player2Score(0), _matchSurvivor("NONE"), _gameSpeed(1)
{

}

unsigned int GamePropertiesManager::GetGameSpeed()
{
   return _gameSpeed;
}

私の問題は、初期化リストの _gameSpeed の値を (1) 以外の値に変更すると、実行時にプログラムがクラッシュすることです。以前に _frameCounter を 1 以外のハードコードされた値と 1 以外の値に設定された速度変数の両方と比較し、プログラムが期待どおりに正常に実行されたため、これは特に奇妙です。問題についてのアイデアはありますか?

私は自分自身を十分に説明したいと思っています、あなたの助けに感謝します!

4

2 に答える 2

1

その理由はほぼ間違いなく、1以外の値の場合PlayState::onUpdateifチェックの最初の呼び出しが実行されず、初期化されていないものが残っている可能性が高いためです。

于 2012-04-19T20:08:42.133 に答える
1

プロセスがマルチスレッドであり、複数のスレッドがになっている場合はonUpdate、に適切なロックを追加しGetInstanceて、2つの競合するスレッドが最初の(同時)呼び出し時に独立したインスタンスを作成できないようにする必要があります。さらに重要なのは、1つのスレッドを公開することです。別のスレッドによって開始された、不完全に初期化されたインスタンス。

于 2012-04-19T20:09:55.350 に答える