0

之前我将一些数据移动到一个单例对象 GamePropertiesManager。在这个类中,我定义了一个名为 _gameSpeed 的变量,在类构造函数中,我使用初始化列表将其设置为默认值 1。

在另一堂课中,我有一个更新循环(在我的控制之外),它总是会尽可能频繁地更新。我打算并成功地使用了“速度”变量来减慢更新速度。例如,将其设置为 2 游戏只会更新对 onUpdate 的所有其他调用。如果您查看下面 PlayState::onUpdate() 的内容,我可能会说得通(我在建议下发布了整个 cpp评论者):

#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::onCreate() 中分配的 GamePropertiesManager 的指针,当我的类 PlayState 首次创建时..

实际的 GamePropertiesManager 类如下所示:

#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::onUpdate检查if时都不会运行,很可能会留下一些未初始化的东西。

于 2012-04-19T20:08:42.133 回答
1

如果您的进程是多线程的,并且有多个线程使其成为onUpdate,那么您需要添加足够的锁定GetInstance,以确保两个竞争线程无法在第一次(并发)调用时创建独立实例,更重要的是,让一个线程发布由另一个线程启动的未完全初始化的实例。

于 2012-04-19T20:09:55.350 回答