Strange comms problem Captain!

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
rarebit
Posts: 39
Joined: Wed Feb 13, 2008 8:09 am
Location: Sheffield, UK

Strange comms problem Captain!

Post by rarebit »

Hi, I have a class for my user and in it I set the key states, but when I come to check 'em, they aren't set. I've tried numerous ways to check but to no avail. I know this will be simple (or the same as the stack problem yesterday). I've condensed the code but it's still quite long and comes in three files. However the problem should be somewhere between the event receiver class and the hero keys...

hero.h

Code: Select all

#ifndef HERO_H_INCLUDED
#define HERO_H_INCLUDED


#include <irrlicht.h>

#include <iostream>


using namespace std;


using namespace irr;

using namespace core;

using namespace scene;

using namespace video;

using namespace io;

using namespace gui;


struct S_HERO_KEYS
{
	int up;
	int down;
	bool right;
	bool left;
	bool run;
};

struct S_HERO_CAM
{
	float height;
	float dist;
};

class RC_HERO
{
public:
	
	struct S_HERO_KEYS hkeys;
	struct S_HERO_CAM cams[3];
	
	
	ISceneNode* hero;
	ICameraSceneNode* cam;
	
	float speed;
	float speed_min;
	float speed_max;
	
	int cam_current;
	float cam_height;
	float cam_dist;
	
	RC_HERO();
	RC_HERO(ISceneNode* user, ICameraSceneNode* camera);
	~RC_HERO();
	void init(ISceneNode* user=NULL, ICameraSceneNode* camera=NULL);
	
	void update();
	void do_run();
	void do_cam();
	
	void set_cam(int num);
	void set_key(int num, int state);
	void init_hero_keys();

private:
};

RC_HERO::~RC_HERO()
{
}

RC_HERO::RC_HERO()
{
	init();
}

RC_HERO::RC_HERO(ISceneNode* user, ICameraSceneNode* camera)
{
	init(user, camera);
}

void RC_HERO::init(ISceneNode* user, ICameraSceneNode* camera)
{
	hero = user;
	cam = camera;
	
	speed = 1.0f;
	speed_min = 1.0f;
	speed_max = 3.0f;
	
	cam_current = 0;
	cam_height = 5.0f;
	cam_dist = 50.0f;
	
	init_hero_keys();
	
	cams[0].height = 5.0f;
	cams[0].dist = 50.0f;
	cams[1].height = 25.0f;
	cams[1].dist = 50.0f;
	cams[2].height = 25.0f;
	cams[2].dist = 10.0f;
}

void RC_HERO::update()
{
	core::vector3df c = hero->getPosition();
	core::vector3df d = hero->getRotation();
	float diry = ((d.Y+90)*3.14)/180;
	
	//cout << ">> user pos: " << c.X << ", " << c.Y  << ", " << c.Z << endl;
	//cout << ">> user dir: " << diry << endl;
	
	do_run();
	do_cam();
	
	if(hkeys.up==1)
	{
cout << "UP " << endl;
		c.X += speed * cos((d.Y) * 3.14 / 180);
		c.Z -= speed * sin((d.Y) * 3.14 / 180);
	}
	if(hkeys.down==1)
	{
		c.X -= speed * cos((d.Y) * 3.14 / 180);
		c.Z += speed * sin((d.Y) * 3.14 / 180);
	}
	if(hkeys.left==1)
	{
		d.Y -= 0.25;
	}
	if(hkeys.right==1)
	{
		d.Y += 0.25;
	}
	
	//cout << "keys: " << hkeys.up << ", " << hkeys.down << ", " << hkeys.right << ", " << hkeys.left << ", " << hkeys.run << endl;
	
	hero->setRotation(d);
	
	float xf = c.X-(sin(diry)*cam_dist);
	float yf = c.Z-(cos(diry)*cam_dist);
	float zf = cam_height;
	
	hero->setPosition(c);
	
	cam->setTarget(c);
	cam->setPosition(vector3df(xf,zf,yf));
	
}

void RC_HERO::do_run()
{
	if(hkeys.run == 1)
	{
		speed += 0.125f;
		if(speed >= speed_max)
		{
			speed = speed_max;
		}
	}
	else
	{
		speed = speed_min;
	}
	return;
}

void RC_HERO::do_cam()
{
	float dd;
	if(cam_dist != cams[cam_current].dist)
	{
		dd = cam_dist - cams[cam_current].dist;
		
		if( abs((long)dd) < 1)
		{
			cam_dist = cams[cam_current].dist;
		}
		else
		{
			if(dd > 0)
			{
				cam_dist -= 1.0f;
			}
			else
			{
				cam_dist += 1.0f;
			}
		}
	}
	
	if(cam_height != cams[cam_current].height)
	{
		dd = cam_height - cams[cam_current].height;
		
		if( abs((long)dd) < 1)
		{
			cam_height = cams[cam_current].height;
		}
		else
		{
			if(dd > 0)
			{
				cam_height -= 1.0f;
			}
			else
			{
				cam_height += 1.0f;
			}
		}
	}
	return;
}

void RC_HERO::set_cam(int num)
{
	cout << "setting cam: " << num << endl;
	cam_current = num;
}

void RC_HERO::set_key(int num, int state)
{
	cout << "setting key: " << num << " -> " << state << endl;
	switch(num)
	{
		case 0:
			hkeys.up = state;
			break;
		case 1:
			hkeys.down = state;
			break;
		case 2:
			hkeys.right = state;
			break;
		case 3:
			hkeys.left = state;
			break;
		case 4:
			hkeys.run = state;
			break;
	}
}

void RC_HERO::init_hero_keys()
{
	hkeys.up    = 0;
	hkeys.down  = 0;
	hkeys.right = false;
	hkeys.left  = false;
	hkeys.run  = false;
}

#endif // INCLUDED
collision.h

Code: Select all

#ifndef COLLISION_H_INCLUDED
#define COLLISION_H_INCLUDED


#include <irrlicht.h>

#include <iostream>


#pragma comment(lib, "Irrlicht.lib")

using namespace std;


using namespace irr;

using namespace core;

using namespace scene;

using namespace video;

using namespace io;

using namespace gui;


void ISceneNode_assignTriangleSelector(scene::ISceneNode* node, scene::ISceneManager* smgr, io::IFileSystem* ifs);
void ISceneNode_assignTriangleSelectors(scene::ISceneNode* node, scene::ISceneManager* smgr, io::IFileSystem* ifs);
void ISceneManager_assignTriangleSelectors(scene::ISceneManager* smgr, io::IFileSystem* ifs);

void ISceneNode_gatherTriangleSelectors(scene::ISceneNode* node, scene::IMetaTriangleSelector* meta);
void ISceneManager_gatherTriangleSelectors(scene::ISceneManager* smgr, scene::IMetaTriangleSelector* meta);


void ISceneNode_assignTriangleSelector(scene::ISceneNode* node, scene::ISceneManager* smgr, io::IFileSystem* ifs)
{
  if (!node || !smgr || !ifs)
    return;

  if (node->getType() == scene::ESNT_OCT_TREE)
  {
    io::IAttributes* attribs = ifs->createEmptyAttributes();
    if (attribs)
    {
      node->serializeAttributes(attribs);
      core::stringc name = attribs->getAttributeAsString("Mesh");
      attribs->drop();
      scene::IAnimatedMesh* mesh = smgr->getMesh(name.c_str());
      if (mesh)
      {
        scene::ITriangleSelector* selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
        node->setTriangleSelector(selector);
        selector->drop();
      }
    }
  }
  else if (node->getType() == scene::ESNT_MESH)
  {
    scene::IMeshSceneNode* msn = (scene::IMeshSceneNode*)node;

    if (msn->getMesh())
    {
      scene::ITriangleSelector* selector = smgr->createTriangleSelector(msn->getMesh(), msn);
      msn->setTriangleSelector(selector);
      selector->drop();
    }
  }
  else if (node->getType() == scene::ESNT_ANIMATED_MESH)
  {
    scene::IAnimatedMeshSceneNode* msn = (scene::IAnimatedMeshSceneNode*)node;

    scene::IAnimatedMesh* am = msn->getMesh();
    if (am)
    {
      scene::ITriangleSelector* selector =
        smgr->createTriangleSelector(am->getMesh(0), msn);
      msn->setTriangleSelector(selector);
      selector->drop();
    }
  }
  else if (node->getType() == scene::ESNT_TERRAIN)
  {
    scene::ITerrainSceneNode* tsn = (scene::ITerrainSceneNode*)node;

    scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(tsn, 0);
    tsn->setTriangleSelector(selector);
    selector->drop();
  }
  else if (node->getType() == scene::ESNT_CUBE)
  {
    scene::ITriangleSelector* selector = smgr->createTriangleSelectorFromBoundingBox(node);
    node->setTriangleSelector(selector);
    selector->drop();   
  }
  else
  {
    // not something we want to collide with
  }
}

void ISceneNode_assignTriangleSelectors(scene::ISceneNode* node, scene::ISceneManager* smgr, io::IFileSystem* ifs)
{
  // assign a selector for this node
  ISceneNode_assignTriangleSelector(node, smgr, ifs);

  // now recurse on children...
  core::list<scene::ISceneNode*>::ConstIterator begin = node->getChildren().begin();
  core::list<scene::ISceneNode*>::ConstIterator end   = node->getChildren().end();

  for (/**/; begin != end; ++begin)
    ISceneNode_assignTriangleSelectors(*begin, smgr, ifs);
}

void ISceneManager_assignTriangleSelectors(scene::ISceneManager* smgr, io::IFileSystem* ifs)
{
  ISceneNode_assignTriangleSelectors(smgr->getRootSceneNode(), smgr, ifs);
} 


void ISceneNode_gatherTriangleSelectors(scene::ISceneNode* node, scene::IMetaTriangleSelector* meta)
{
  scene::ITriangleSelector* selector = node->getTriangleSelector();
  if (selector)
    meta->addTriangleSelector(selector);

  // now recurse on children...
  core::list<scene::ISceneNode*>::ConstIterator begin = node->getChildren().begin();
  core::list<scene::ISceneNode*>::ConstIterator end   = node->getChildren().end();

  for (/**/; begin != end; ++begin)
    ISceneNode_gatherTriangleSelectors(*begin, meta);
}

void ISceneManager_gatherTriangleSelectors(scene::ISceneManager* smgr, scene::IMetaTriangleSelector* meta)
{
  ISceneNode_gatherTriangleSelectors(smgr->getRootSceneNode(), meta);
} 

#endif // INCLUDED
main.cpp

Code: Select all

#include <irrlicht.h>

#include <iostream>


#include "collision.h"

#include "hero.h"


#pragma comment(lib, "Irrlicht.lib")


using namespace std;


using namespace irr;

using namespace core;

using namespace scene;

using namespace video;

using namespace io;

using namespace gui;

void game_pause(int pause=0);

int paused = 0;
IrrlichtDevice *device = 0;
scene::ICameraSceneNode* cam = 0;
RC_HERO rc_hero;

void game_pause(int pause)
{
	if(pause == 0)
	{
		paused = 1;
		device->getTimer()->stop();
	}
	else
	{
		paused = 0;
		device->getTimer()->start();
	}
}

class MyEventReceiver : public IEventReceiver

{

public:

	virtual bool OnEvent(const SEvent& event)

	{
		scene::ISceneManager* smgr = device->getSceneManager();
		IGUIEnvironment* env = device->getGUIEnvironment();
		
		if(event.EventType == EET_KEY_INPUT_EVENT)
		{
			switch(event.KeyInput.Key)
			{
				case KEY_UP:
				case KEY_KEY_W:
					rc_hero.hkeys.up = event.KeyInput.PressedDown;
					//rc_hero.set_key(0, event.KeyInput.PressedDown);
					break;
				case KEY_DOWN:
				case KEY_KEY_S:
					rc_hero.hkeys.down = event.KeyInput.PressedDown;
					//rc_hero.set_key(1, event.KeyInput.PressedDown);
					break;
				case KEY_LEFT:
				case KEY_KEY_A:
					rc_hero.hkeys.left = event.KeyInput.PressedDown;
					break;
				case KEY_RIGHT:
				case KEY_KEY_D:
					rc_hero.hkeys.right = event.KeyInput.PressedDown;
					break;
				case KEY_LSHIFT:
				case KEY_RSHIFT:
					rc_hero.hkeys.run = event.KeyInput.PressedDown;
					break;
				case KEY_KEY_1:
				case KEY_NUMPAD1:
					if(event.KeyInput.PressedDown == 0)
					{
						rc_hero.set_cam(0);
					}
					break;
				case KEY_KEY_2:
				case KEY_NUMPAD2:
					if(event.KeyInput.PressedDown == 0)
					{
						rc_hero.set_cam(1);
					}
					break;
				case KEY_KEY_3:
				case KEY_NUMPAD3:
					if(event.KeyInput.PressedDown == 0)
					{
						rc_hero.set_cam(2);
					}
					break;
				case KEY_ESCAPE:
					device->closeDevice();
					break;
				case KEY_KEY_P:
				{
					if(event.KeyInput.PressedDown == 0)
					{
						if(paused==0)
						{
							game_pause();
						}
						else
						{
							game_pause(1);
						}
					}
					break;
				}
			}
			return false;
		}
		return false;

	}

};



int main()

{

	video::E_DRIVER_TYPE driverType;
	driverType = video::EDT_OPENGL;
	

	device = createDevice(driverType, core::dimension2d<s32>(800, 600), 32);
	

	if (device == 0)

		return 1;
	

	device->setWindowCaption(L"GEng");

	

	video::IVideoDriver* driver = device->getVideoDriver();

	scene::ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* env = device->getGUIEnvironment();
	

	MyEventReceiver receiver;

	device->setEventReceiver(&receiver);
	
	//	AMBIENT LIGHT
	smgr->setAmbientLight(video::SColorf(0.0f, 0.5f, 0.5f, 0.5f));
	
	//	CAMERA
	cam = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
	
	//	GROUND
	IAnimatedMesh * movingplane;
	movingplane = smgr->addHillPlaneMesh("floor", irr::core::dimension2d<float>(35.0f, 35.0f), irr::core::dimension2d<unsigned int>(40, 40), 0, 0.0f, irr::core::dimension2d<float>(4, 4), irr::core::dimension2d<float>(1, 1));
	
	IAnimatedMeshSceneNode *floor = smgr->addAnimatedMeshSceneNode(movingplane);
	floor->setPosition(vector3df(0,0,0));
	floor->setMaterialTexture(0, device->getVideoDriver()->getTexture("media/wall.bmp"));
	floor->setMaterialFlag(video::EMF_LIGHTING, true);
	
	//	USER
	ISceneNode* hero = smgr->addCubeSceneNode(10);
	if (hero)
	{
		hero->setPosition(vector3df(0,3,0));
		hero->setMaterialFlag(EMF_LIGHTING, true);
	}
	
	RC_HERO rc_hero(hero, cam);
	
	device->getCursorControl()->setVisible(false);
	
	//	COLLISION DETECTION OF LOADED SCENE see collision.h
	ISceneManager_assignTriangleSelectors(smgr, device->getFileSystem());
	scene::IMetaTriangleSelector* meta = smgr->createMetaTriangleSelector();
	ISceneManager_gatherTriangleSelectors(smgr, meta);
	//	ADD USER
	scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(meta, hero, core::vector3df(0.7f,0.7f,0.7f), core::vector3df(0,-1,0), core::vector3df(0,0,0), 0.005f); //ISceneNodeAnimator CreateCollisionResponseAnimator(ITriangleSelector world, ISceneNode sceneNode, Vector3D ellipsoidRadius, Vector3D gravityPerSecond, Vector3D ellipsoidTranslation, float slidingValue
	hero->addAnimator(anim);
	anim->drop();
	
	meta->drop(); 
	//	end collision detector stuff...
	
	int lastFPS = -1;
	while(device->run())
	{

		if (device->isWindowActive())

		{
			rc_hero.update();
			
			driver->beginScene(true, true, video::SColor(0,200,200,200));
			
			smgr->drawAll();
			env->drawAll();
			

			driver->endScene();

		}

	}



	device->drop();

	

	return 0;

}


For fun i've left in the collision detection and for those that know the 3rd person camera is a rehash from another example somewhere here. Apart from one texture, you should be able to run this as is (opengl).

Cheers!

C'mon you Blades!
rarebit
Posts: 39
Joined: Wed Feb 13, 2008 8:09 am
Location: Sheffield, UK

Post by rarebit »

Yep, it's been a while since using classes, and when I think about it it should have been obvious!

At top of main.cpp I changed to:

Code: Select all

RC_HERO *rc_hero;
In the main statement changed to:

Code: Select all

rc_hero = new RC_HERO(hero, cam);
And other references in main.cpp were amended to use '->'...
Post Reply