Why I can't init static members - c++

I have a class MotionDirection with static members. The source code of the class is below. But I just can not initialize the static members of the class and I can get the reason. So the problem is in the MotionDirection.cpp, see the comments for the details about the compiler errors.
MotionDirection.h
#ifndef MOTION_DIRECTION
#define MOTION_DIRECTION
namespace game{
class IntPosition;
class MotionDirection {
private:
IntPosition* positionDisplacement;
float angle;
MotionDirection* returnDirection;
public:
MotionDirection( IntPosition* positionDisplacement, float angle );
void setReturnDirection ( MotionDirection* returnDirection );
IntPosition* getPositionDisplacement();
float getAngle();
MotionDirection* getReturnDirection();
static MotionDirection* NONE;
static MotionDirection* LEFT;
static MotionDirection* RIGHT;
static MotionDirection* UP;
static MotionDirection* DOWN;
static void initStatics();
};
}
#endif
MotionDirection.cpp
#include "MotionDirection.h"
#include "IntPosition.h"
namespace game{
MotionDirection::NONE = new MotionDirection ( new IntPosition( 0, 0), 0.0f );
// here I get an error:
// MotionDirection.cpp:10:5: error: 'NONE' in 'class game::MotionDirection' does not name a type
MotionDirection::MotionDirection( IntPosition* positionDisplacement, float angle ) {
this->positionDisplacement = positionDisplacement;
this->angle = angle;
}
void MotionDirection::setReturnDirection ( MotionDirection* returnDirection ) {
this->returnDirection = returnDirection;
}
IntPosition* MotionDirection::getPositionDisplacement() {
return positionDisplacement;
}
float MotionDirection::getAngle() {
return angle;
}
MotionDirection* MotionDirection::getReturnDirection() {
return returnDirection;
}
void MotionDirection::initStatics () {
MotionDirection::NONE = new MotionDirection ( new IntPosition( 0, 0), 0.0f );
MotionDirection::LEFT = new MotionDirection ( new IntPosition(-1, 0), 180.0f );
MotionDirection::RIGHT = new MotionDirection ( new IntPosition( 1, 0), 0.0f );
MotionDirection::UP = new MotionDirection ( new IntPosition( 0,-1), 90.0f );
MotionDirection::DOWN = new MotionDirection ( new IntPosition( 0, 1), 270.0f );
}
MotionDirection::initStatics();
// or here I get an error:
// MotionDirection.cpp:45:35: error: expected constructor, destructor, or type conversion before ';' token
}
P.S. This is Android-NDK project, I run compilation from the cygwin console.

First error
Just replace
MotionDirection::NONE = new MotionDirection ( new IntPosition( 0, 0), 0.0f );
with
MotionDirection* MotionDirection::NONE = new MotionDirection ( new IntPosition( 0, 0), 0.0f );
Note MotionDirection* type before name of the variable: you need to provide compiler with a type.
Second error
You can't put expressions out of function blocks. There are two ways to do this "right":
1.
Make initStatics() return value.
Add private static variable.
Initialize new static variable by assigning value of initStatics() to it.
2.
Add nested class.
Write call to initStatics() in its constructor.
Add private static variable of that nested class.

Related

c++: Proper way to initialize static fields of member struct

I got this:
// mouse.h
class Mouse {
private:
struct Pos {
static GLfloat x;
static GLfloat y;
};
static Pos last;
}
and this:
// mouse.cpp
// 1)
Mouse::Pos Mouse::last = {};
// 2)
Mouse::Pos Mouse::last = { 0.0, 0.0 };
// 3)
Mouse::last.x = 0.0f;
Mouse::last.y = 0.0f;
1), 2) and 3) are the attempts I've made at initializing that thing. I understand that the header should declare that last is static, and that the source should initialize it, but something has been wrong with all my attempts. Could someone please tell me the correct way to do such a thing? Am I missing some very important point? Is this nonsense? It is important that the fields are static. Thanks.
You don't need to declare Pos content as static.
// mouse.h
class Mouse {
private:
struct Pos {
GLfloat x;
GLfloat y;
};
static Pos last;
}
Mouse::Pos Mouse::last = { 0.0, 0.0 };
This should work too
It is important that the fields are static.
Then last will not have any state. It will simply refer to the static x and y values inside Mouse::Pos.
#include "mouse.h"
GLfloat Mouse::Pos::x = 10;
GLfloat Mouse::Pos::y = 10;
Mouse::Pos Mouse::last{};
wandbox example
The following asserts pass:
assert(Mouse::last.x == 10);
assert(Mouse::last.y == 10);

Access violation for object

I have an Entity.h like this:
using namespace physx;
class Entity
{
public:
Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id);
virtual ~Entity(void);
virtual void update(Ogre::Real dt);
virtual void init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity=PxVec3(0, 0, 0));
protected:
Ogre::Entity* mOgreEntity = NULL;
Ogre::SceneNode* mOgreNode = NULL;
Ogre::Vector3 mPosition;
Ogre::Vector3 mDimensions;
std::string mMesh;
std::string mId;
PxRigidDynamic* mActor;
PxMaterial* mMaterial;
};
And here is my Entity source:
#include "Entity.h"
Entity::Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id)
{
mDimensions = dims;
mPosition = pos;
mMesh = mesh;
mId = id;
mActor = NULL;
mMaterial = NULL;
}
Entity::~Entity(void)
{
}
void Entity::update(Ogre::Real dt)
{
PxVec3 pos = mActor->getGlobalPose().p;
Ogre::Real r = 0;
mOgreNode->setPosition(Ogre::Vector3(pos.x + r, pos.y + r, pos.z + r));
}
void Entity::init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity)
{
// Create an Entity
mOgreEntity = sceneMgr->createEntity(mId, mMesh);
mOgreEntity->setCastShadows(true);
// Create a SceneNode and attach the Entity to it
mOgreNode = sceneMgr->getRootSceneNode()->createChildSceneNode(mId + "Node");
Ogre::AxisAlignedBox box = mOgreEntity->getBoundingBox();
Ogre::Vector3 realSizes = box.getSize();
mOgreNode->setPosition(mPosition);
mOgreNode->attachObject(mOgreEntity);
Ogre::Vector3 scaler = Ogre::Vector3(mDimensions.x / realSizes.x, mDimensions.y / realSizes.y, mDimensions.z / realSizes.z);
mOgreNode->scale(scaler);
mMaterial = physics->createMaterial(1.5f, 1.5f, 1.0f);
PxGeometry* geometry = NULL;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = &g;
} else {
// geometry = NULL;
}
PxTransform transform = PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z));
mActor = PxCreateDynamic(*physics, transform, *geometry, *mMaterial, PxReal(.1));
// if(!mActor) {
// MessageBox( NULL, "no actor", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
// return;
// }
mActor->setLinearVelocity(velocity);
// And add the actor to a scene:
scene->addActor(*mActor);
}
Now, if I create a single entity and initialize it works. Even wirh a second entity var it works as well. Now with an array:
Entity *mEntities[20];
for(int i = 0 ; i < 20 ; i++ ){
ostringstream nameStream;
nameStream << "Sphere_" << i;
string name = nameStream.str();
Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), Ogre::Vector3(i*5, i*4.5, i*6), "sphere.mesh", name);
sphere->init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0));
mEntities[i] = sphere;
}
I got Access violation. W/ the just-in-time debugger, it turned out that mActorwas null as well as mMaterial
EDIT:
This code does not work either:
mEntity = Entity(Ogre::Vector3(50.0f, 50.0f, 50.0f), Ogre::Vector3(50.0f, 40.5f, 60.0f), "sphere.mesh", "sphere");
mEntity.init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0));
1)
Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6),
Ogre::Vector3(i*5, i*4.5, i*6),
"sphere.mesh",
"Sphere_"+i);
Look at the "Sphere_"+i
If the i is larger then length of ”Sphere_” you are passing pointer to some random memory. I assume that you wanted to create a string with i at the end.
Use sprintf or std::string for that.
2)
If you change the loop range from 20 to let's say 3 it will probably work. The problem is that your names will be:
Sphere_, phere_, here_
Because by doing "Sphere_"+i you are not adding integer to the string.
This is "equal" to:
char *string = "String";
string += 3;
3)
This code will generate string that you need:
std::ostringstream newStringStream;
newStringStream << "Sphere_" << i;
std::string newString = newStringStream.str();
Here is another issue:
PxGeometry* geometry = NULL;
if(mMesh == "sphere.mesh")
{
geometry = &PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
The problem with this is that you are assigning to geometry the address of a temporary value. Once that line of code is completed, that temporary is gone.
The probable fix for this is to do this:
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
geometry = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
//...
mActor = PxCreateDynamic(*physics, transform, geometry, *mMaterial, PxReal(.1));
Now geometry is no longer a pointer, and you're assigning geometry to the value returned, (not address-of the value returned).
I am reading the documentation here:
http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/classPxSphereGeometry.html
So PxSphereGeometry(x) is a constructor call. So you need to assign the return value to a PxShpereGeometry, not a PxSphereGeometry*.
Edit: Your latest changes also do not have the desired effect:
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = &g;
}
The g is local to the if() block. You assign the address of this g to geometry. Then when that block exits, g is gone, and now you have geometry pointing to something that no longer exists.
The difference between your edited code and the answer I gave is that my answer assigns the return value to an existing object. So I created a duplicate of the return value. What your doing in the edited code is not creating a duplicate, but pointing to a local object, which as explained, won't exist after it leaves scope.
So if you were to write code that follows the pattern of your edited code, and have it be valid, the change would look like this:
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = g;
}
However, this does extraneous work. The original answer is sufficient.
I tried the alternate way to create a rigid body and it worked!!!!
mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)));
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x / 2), *mMaterial);
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);

Cocos2d-x Polymorphism

I am currently working on subdividing my cocos2dx-cpp game into a more modular system. I want to have one layer to receive all Touches and direct those touches to the affected CCSprite-derived objects.
The derived objects are stored in a CCArray in an EntityManager (which helps me create and manage the entities).
The problem I am facing is that I can't seem to access the correct virtual method for my derived CCSprites.
Here is the code from my Touch layer (called TouchManager):
void TouchManager::ccTouchesBegan( cocos2d::CCSet* pTouches , cocos2d::CCEvent* pEvents )
{
cocos2d::CCSetIterator i;
cocos2d::CCTouch* touch;
cocos2d::CCPoint tap;
auto entities = EntityManager::sharedManager()->getVisibleEntities();
for ( i = pTouches->begin() ; i != pTouches->end() ; ++i )
{
touch = ( cocos2d::CCTouch* ) ( *i );
if ( touch )
{
tap = touch->getLocation();
for ( unsigned int entityIndex = 0 ; entityIndex < entities->size() ; ++entityIndex )
{
auto entity = entities->at( entityIndex );
// OLD: auto entity = ( TouchableSprite* )entities->objectAtIndex( entityIndex );
if ( entity->boundingBox().containsPoint( tap ) )
{
entity->setTouch( touch );
entity->onTouch( tap );
}
}
}
}
}
I want to have the TouchManager detect the entity that has been touched, and send the Touch to it. But there is my problem: it detects the touch but doesn't send it further. Either I have a crash or nothing at all.
I have created a Touchable interface class:
#include "cocos2d.h"
class Touchable : public cocos2d::CCSprite
{
cocos2d::CCTouch* m_pTouch;
public:
virtual cocos2d::CCTouch* getTouch();
virtual void setTouch( cocos2d::CCTouch* touch );
virtual void onTouch( cocos2d::CCPoint location ) = 0 ;
virtual void onMoved( cocos2d::CCPoint location ) = 0 ;
virtual void onEnded( cocos2d::CCPoint location ) = 0 ;
};
as well as a TouchableSprite base class:
#include "cocos2d.h"
#include "Touchable.h"
class TouchableSprite : public Touchable
{
//cocos2d::CCTouch* m_pTouch;
public:
//virtual cocos2d::CCTouch* getTouch();
//virtual void setTouch( cocos2d::CCTouch* touch );
static TouchableSprite* createSpriteWithFile( const char* fileName );
void resetPosition( float positionX = 0.0f , float positionY = 0.0f );
virtual void onTouch( cocos2d::CCPoint location ) ;
virtual void onMoved( cocos2d::CCPoint location ) ;
virtual void onEnded( cocos2d::CCPoint location ) ;
TouchableSprite(void);
~TouchableSprite(void);
};
with simple implementation (TouchableSprite.cpp):
#include "TouchableSprite.h"
TouchableSprite::TouchableSprite(void)
{
}
TouchableSprite::~TouchableSprite(void)
{
}
TouchableSprite* TouchableSprite::createSpriteWithFile( const char* fileName )
{
auto sprite = new TouchableSprite();
if ( sprite && sprite->initWithFile( fileName ) )
{
sprite->autorelease();
return ( TouchableSprite* )sprite;
}
CC_SAFE_DELETE( sprite );
// should not reach this point
return NULL;
}
void TouchableSprite::resetPosition( float positionX , float positionY )
{
this->setPosition( ccp( positionX , positionY ) );
}
void TouchableSprite::onTouch( cocos2d::CCPoint location )
{
}
void TouchableSprite::onMoved( cocos2d::CCPoint location )
{
}
void TouchableSprite::onEnded( cocos2d::CCPoint location )
{
}
And finally, here's my derived class (in this case, ControlStickSprite):
#include "cocos2d.h"
#include "RenderSystem.h"
#include "EntityManager.h"
#include "TouchableSprite.h"
class ControlStickSprite : public TouchableSprite
{
ControlStickSprite* m_sprite;
public:
cocos2d::CCNode* create( cocos2d::CCNode* parent );
void onTouch( cocos2d::CCPoint location ) ;
void onMoved( cocos2d::CCPoint location ) ;
void onEnded( cocos2d::CCPoint location ) ;
ControlStickSprite(void);
~ControlStickSprite(void);
};
with simple implementation for testing (skipping the Create part because it works):
void ControlStickSprite::onTouch( cocos2d::CCPoint location )
{
this->setScale( 0.5f );
}
void ControlStickSprite::onMoved( cocos2d::CCPoint location )
{
this->setPosition( location );
}
void ControlStickSprite::onEnded( cocos2d::CCPoint location )
{
}
Please help me get this working! I'm not too familiar with the usage of virtual methods so maybe I missed something there. I'm also relatively new to C++ and cocos2dx programming.
Thanks in advance!
EDIT: Thanks to #musikov for fixing the first part! I updated the above code to reflect the changes. I replaced the CCArray with std::vector< TouchableSprite* > to eliminate the need for casting the from CCObject*.
Now, I am facing the problem that when touched, ControlStickSprite::onTouch() is never chosen; it's always TouchableSprite::onTouch().
Added ControlStickSprite::create and EntityManager::createEntity methods:
My ControlStickSprite::create() method is like this:
ControlStickSprite* ControlStickSprite::create( cocos2d::CCNode* parent )
{
// auto parent = this->getParent();
auto entityType = "control-stick";
auto scale = 6.0f;
auto rotation = 0.0f;
auto positionX = RenderSystem::sharedRenderSystem()->getScreenWidth() * 0.9f ;
auto positionY = RenderSystem::sharedRenderSystem()->getScreenHeight() * 0.25f ;
auto sprite = EntityManager::sharedManager()->createEntity(
parent ,
entityType ,
scale ,
rotation ,
positionX ,
positionY
);
m_sprite = ( ControlStickSprite* )sprite;
return m_sprite;
}
which makes use of my EntityManager:
cocos2d::CCNode* EntityManager::createEntity( cocos2d::CCNode* parent , const char* entityType , float scale , float rotation , float positionX , float positionY )
{
std::string extension = ".png";
std::string fileName = entityType + extension;
auto entity = TouchableSprite::createSpriteWithFile( fileName.c_str() );
entity->setRotation( rotation );
entity->setScale( scale );
entity->resetPosition( positionX , positionY );
parent->addChild( entity );
// add to VisibleEntities vector
this->addEntity( entity , true );
return entity;
}
The only thing I can think of is that the createEntity() method creates a TouchableSprite* but returns a CCNode*, which I then cast to a ControlStickSprite*. Am I doing this wrong again? :)
Thanks for all your help!
You have wrong create method implementation in TouchableSprite and maybe in ControlStickSprite too.
Your create method creates Sprite instance and casts it to TouchableSprite class. It's completely wrong :)
That's why your program crashed on setTouch method call - because your calling this method in Sprite instance.
You need to change your create method:
TouchableSprite* TouchableSprite::createSpriteWithFile( const char* fileName )
{
auto sprite = new TouchableSprite();
if ( sprite && sprite->initWithFile( fileName ) )
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE( sprite );
// should not reach this point
return NULL;
}
Added controlstick implementation
ControlStickSprite.h
#include "cocos2d.h"
#include "RenderSystem.h"
#include "EntityManager.h"
#include "TouchableSprite.h"
class ControlStickSprite : public TouchableSprite
{
public:
static ControlStickSprite* create();
bool init();
void onTouch( cocos2d::CCPoint location ) ;
void onMoved( cocos2d::CCPoint location ) ;
void onEnded( cocos2d::CCPoint location ) ;
ControlStickSprite(void);
~ControlStickSprite(void);
};
ControlStickSprite.cpp
bool ControlStickSprite::init()
{
auto entityType = "control-stick";
std::string extension = ".png";
std::string fileName = entityType + extension;
if (initWithFile( fileName.c_str() )) {
// auto parent = this->getParent();
auto scale = 6.0f;
auto rotation = 0.0f;
auto positionX = RenderSystem::sharedRenderSystem()->getScreenWidth() * 0.9f ;
auto positionY = RenderSystem::sharedRenderSystem()->getScreenHeight() * 0.25f ;
sprite->setRotation( rotation );
sprite->setScale( scale );
sprite->resetPosition( positionX , positionY );
return true;
}
return false;
}
ControlStickSprite* ControlStickSprite::create()
{
auto sprite = new ControlStickSprite();
if ( sprite && sprite->init() )
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE( sprite );
// should not reach this point
return NULL;
}
EntityManager:
void EntityManager::addEntity( cocos2d::CCNode* parent , TouchableSprite* entity )
{
parent->addChild( entity );
// add to VisibleEntities vector
this->addEntity( entity , true );
}
Remember to call EntityManager::addEntity(parent, entity) after ControlStickSprite::create(), if you decide to use this solution

error C2146: syntax error : missing ';' before identifier 'ContextRecord'

i have a header file which contained all of the class' functions including code so the class didn't have a cpp file. everything worked. I added the cpp file and moved the function code over to that and now i get this error when compiling. the header that im getting the error in ((x86)\microsoft sdks\windows\v7.0a\include\winnt.h(6361)) isnt even included by the file that im changing. does anyone know what the reason for this might be? i can provide code i just don't know what would be helpful.
the cpp file:
#include "Fisherman.h"
void Fisherman::Initialise(){
memset((void*)&mListener, 0, sizeof(X3DAUDIO_LISTENER));
memset((void*)&mEmitter, 0, sizeof(X3DAUDIO_EMITTER));
memset((void*)&mDSPSettings, 0, sizeof(X3DAUDIO_DSP_SETTINGS));
XAUDIO2_VOICE_DETAILS details;
mCastSplash->GetSourceVoice()->GetVoiceDetails(&details);
mEmitter.ChannelCount = details.InputChannels;
mEmitter.CurveDistanceScaler = 1.0f;
X3DAUDIO_VECTOR emitterPos = { 0.0f, 0.0f, 0.0f};
mEmitter.Position = emitterPos;
X3DAUDIO_VECTOR emitterVel = { 0.0f, 0.0f, 0.0f };
mEmitter.Velocity = emitterVel;
mDSPSettings.SrcChannelCount = mEmitter.ChannelCount;
mDSPSettings.DstChannelCount = mXACore->GetChannelCount();
FLOAT32 * matrix = new FLOAT32[mDSPSettings.SrcChannelCount * mDSPSettings.DstChannelCount];
mDSPSettings.pMatrixCoefficients = matrix;
X3DAUDIO_VECTOR front = { 0.0f, 0.0f, 1.0f };
X3DAUDIO_VECTOR top = { 0.0f, 1.0f, 0.0f };
mListener.OrientFront = front;
mListener.OrientTop = top;
X3DAUDIO_VECTOR listenerVel = {0.0f, 0.0f, 0.0f};
mListener.Velocity = listenerVel;
X3DAUDIO_VECTOR listenerPos = { 0.0f, 0.0f, 0.0f };
mListener.Position = listenerPos;
}
void Fisherman::Rotate (int MouseDeltaX){
X3DAUDIO_VECTOR input = mListener.OrientFront;
X3DAUDIO_VECTOR result;
float theta = -(X3DAUDIO_PI/1000)*MouseDeltaX;
float cs = cos(theta);
float sn = sin(theta);
if(cs < 0.00001) cs = 0.0f;
result.x = input.x * cs - input.z * sn;
result.z = input.x * sn + input.z * cs;
result.y = 0.0f;
mListener.OrientFront = result;
}
bool Fisherman::Cast(Fish* aFish){
mCast->Play(0);
mCastOut = true;
mFish = aFish;
X3DAUDIO_VECTOR seg_v = Multiply(mListener.OrientFront, 30);
X3DAUDIO_VECTOR pt_v = {mFish->GetX(), 0.0f, mFish->GetZ()};
float proj_v_length = Dot(pt_v, mListener.OrientFront);
X3DAUDIO_VECTOR proj_v = Multiply(mListener.OrientFront, proj_v_length);
X3DAUDIO_VECTOR dist_v = Subtract(pt_v, proj_v);
if(VectorLength(dist_v) < mFish->GetRadius()){
mEmitter.Position = mFish->GetEmitter().Position;
return true;
}else{
mEmitter.Position = Multiply(mListener.OrientFront, 15);
return false;
}
}
void Fisherman::ReelIn(Fish* aFish){
mFish = aFish;
mFish->MoveCloser(mReelSpeed);
mReelingIn = true;
}
void Fisherman::ReelOut(Fish* aFish){
mFish = aFish;
mFish->MoveFurther();
mReelingIn = false;
}
void Fisherman::SetReelSpeed(float deltaTime){
float reelSpeed = 1.0f - deltaTime;
if(reelSpeed < 0.0f){
reelSpeed = 0.0f;
}
if(reelSpeed > 10){
mReelSpeedList.push_back(reelSpeed);
if(mReelSpeedList.size() > 3){
mReelSpeedList.pop_front();
}
reelSpeed = 0.0f;
std::list<float>::const_iterator iterator;
for (iterator = mReelSpeedList.begin(); iterator != mReelSpeedList.end(); ++iterator){
reelSpeed += *iterator;
}
mReelSpeed = reelSpeed/mReelSpeedList.size();
}else
mReelSpeed = reelSpeed;
mReelClickTimer = 0.1 / mReelSpeed;
}
void Fisherman::PlayReelClick(){
if(!mReelClick[0]->IsPlaying()){
mReelClick[0]->Play(0);
}else if(!mReelClick[1]->IsPlaying()){
mReelClick[1]->Play(0);
}else if(!mReelClick[2]->IsPlaying()){
mReelClick[2]->Play(0);
}else if(!mReelClick[3]->IsPlaying()){
mReelClick[3]->Play(0);
}else if(!mReelClick[4]->IsPlaying()){
mReelClick[4]->Play(0);
}else {
return;
}
}
bool Fisherman::NothingPlaying(){ // check to see if any sounds are playing
if(mCast->IsPlaying())return false;
if(mCastSplash->IsPlaying())return false;
for(int i =0; i < REEL_CLICK_OBJECTS; i++){
if(mReelClick[i]->IsPlaying()){
return false;
}
}
return true;
}
void Fisherman::SetReelingIn(bool isReelingIn){
mReelingIn = isReelingIn;
}
void Fisherman::SetCastOut(bool hasCastOut){
mCastOut = hasCastOut;
}
float Fisherman::GetReelClickTime(){
return mReelClickTimer/CLICK_TIMER_MULTIPLIER;
}
bool Fisherman::IsReelingIn(){
return mReelingIn;
}
float Fisherman::GetReelSpeed(){
return mReelSpeed;
}
X3DAUDIO_LISTENER Fisherman::GetListener(){
return mListener;
}
X3DAUDIO_EMITTER Fisherman::GetEmitter(){
return mEmitter;
}
X3DAUDIO_DSP_SETTINGS Fisherman::GetSettings(){
return mDSPSettings;
}
XASound* Fisherman::GetCastSound(){
return mCast;
}
XASound* Fisherman::GetCastSplashSound(){
return mCastSplash;
}
bool Fisherman::HasCastSplashed(){
return mCastSplashBool;
}
void Fisherman::SetCastSplashed(bool splashed){
mCastSplashBool = splashed;
}
bool Fisherman::IsCastOut(){
return mCastOut;
}
the header:
#ifndef _FISHERMAN_H_
#define _FISHERMAN_H_
#include <X3DAudio.h>
#include <math.h>
#include <list>
#include "VectorCalculations.h"
#include "Fish.h"
#include "XASound.hpp"
using AllanMilne::Audio::XASound;
const float CLICK_TIMER_MULTIPLIER = 2.5f;
const int REEL_CLICK_OBJECTS = 5;
class Fisherman{
public:
Fisherman(XACore* aXACore, XASound *cast, XASound *castSplash, std::list<XASound*> reelClickList)
: // a Fish Object pointer for the fisherman to interact with.
mFish (NULL), mXACore (aXACore),
//XASound objects with sounds for the fisherman
mCast (cast), mCastSplash (castSplash)
{
mReelSpeedList.clear();
for(int i = 0; i < REEL_CLICK_OBJECTS; i++){
mReelClick[i] = reelClickList.front();
mReelClick[i]->SetVolume(2.0f);
reelClickList.pop_front();
mReelClickList.push_back(mReelClick[i]);
}
mCastSplash->SetVolume(7.0f);
mXACore = aXACore;
mCastSplashBool = false;
mCastOut = false;
mReelingIn = false;
mCastDistance = 0.0f;
Initialise();
}
~Fisherman(){}
void Initialise();
void Rotate(int MouseDeltaX);
bool Cast(Fish* aFish);
void ReelIn(Fish* aFish);
void ReelOut(Fish* aFish);
void SetReelSpeed(float deltaTime);
void PlayReelClick();
bool NothingPlaying(); // check to see if any sounds are playing
void SetFront(X3DAUDIO_VECTOR front);
void SetReelingIn(bool isReelingIn);
void SetCastOut(bool hasCastOut);
float GetReelClickTime();
bool IsReelingIn();
float GetReelSpeed();
X3DAUDIO_LISTENER GetListener();
X3DAUDIO_EMITTER GetEmitter();
X3DAUDIO_DSP_SETTINGS GetSettings();
XASound* GetCastSound();
XASound* GetCastSplashSound();
bool HasCastSplashed();
void SetCastSplashed(bool splashed);
bool IsCastOut();
private:
XACore *mXACore;
XASound *mCast;
XASound *mCastSplash;
XASound *mReelClick[REEL_CLICK_OBJECTS];
float mCastDistance;
float mReelClickTimer;
float mReelSpeed;
std::list<float> mReelSpeedList;
std::list<XASound*> mReelClickList;
X3DAUDIO_LISTENER mListener;
X3DAUDIO_EMITTER mEmitter;
X3DAUDIO_DSP_SETTINGS mDSPSettings;
Fish *mFish;
bool mCastOut;
bool mCastSplashBool;
bool mReelingIn;
};
#endif
including windows.h at the top of the header file solved this issue.
Does the error also say PCONTEXT undefined?
Try adding #include <Windows.h> before #include <X3DAudio.h>.
In reply to comment about unresolved external symbol:
That's because you didn't define Fisherman::SetFront in the cpp file.
Whole code would be helpfull. Did you remember obvious to give namespace to names of functions etc?
class A { void foo() { } };
=>
class A { void foo(); }
void A::foo() { ... }
etc?
Fastest way would be reverting back to state when it worked, and not moving whole at once, but only one function at a time. Then when problem would occure you could give us that specific code or try to fix it yourself.
It is very possible that there is just a missed ';', somewhere before this line.
Double-check your code, remember that everything you define in a cpp file has to already be declared in your class definition.
I'd prefer to post a comment, but apparently I'm not allowed.
Anyway, as a simpler way to give us a feel of what you're trying to do, definatley post your code - it does not have to be exactly as you use, but should be a concise piece of generic code, highlighting how you are doing something. (SSCCE) If it really is a bug in how you typed it, it would be good to have your exact code, but put it on pastebin and provide a link so that this page doesn't end up with reams of code.
EDIT:
winnt.h apparently causes all sorts of problems: Weird compile error dealing with Winnt.h
it is used to provide definitions for winAPI specific headers, as far as I know. One of the solutions proposed on that thread is to get the definitions from a different windows header before including whichever header requires those definitions.

non static or const array syntax

what's wrong with this syntax? sorry for the newbie question.
source:
Level::Level()
{
NintyDegreeDirections[4] =
{
1.0f, 1.4f, 2.4f, 0.1f
}
...rest of class
header:
//all necessary includes
class Level
{
private:
float NintyDegreeDirections[4];
...rest of header
how do I have an array as a instance member? I'm converting from C#
In the current version of C++ (C++11), you can initialize the member array like this:
Level::Level()
: NintyDegreeDirections( { 1.0f, 1.4f, 2.4f, 0.1f } )
{
}
C++11 isn't universally supported and if you don't have support for this in your compiler you will have to assign to each member in turn.
E.g.:
NintyDegreeDirections[0] = 1.0f;
NintyDegreeDirections[1] = 1.4f;
//...
Did you try:
NintyDegreeDirections[0] = 1.0f;
NintyDegreeDirections[1] = 1.4f;
/* ... */