Page 1 of 1

Uber noob questions

Posted: Wed Sep 13, 2006 12:16 am
by CeeRo
Let me know if I'm asking about too basic stuff here and should rather go read a couple books...

But I'm trying to just piece together different parts of code to see if I can figure out how stuff works here.

What I've done is:

Started with the terrain-rendering tutorial code, changed around heightmap, textures and scales a bit, tried to use code I found here on the forum to enable jumping with spacebar, tried to use code from the collision tutorial for adding a billboard for HUD, and tried to use code from the demo coming with Irrlicht for shooting.

First, here comes all of my EventReceiver code:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:

	MyEventReceiver(scene::ISceneNode* terrain)
	{
		// store pointer to terrain so we can change its drawing mode
		Terrain = terrain;
	}

	bool OnEvent(SEvent event)
	{
		// check if user presses the key 'B', 'N' or 'M'
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
		{
			switch (event.KeyInput.Key)
			{
			case irr::KEY_KEY_B: // switch wire frame mode
				Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
				Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
				return true;
			case irr::KEY_KEY_N: // switch wire frame mode
				Terrain->setMaterialFlag(video::EMF_POINTCLOUD, !Terrain->getMaterial(0).PointCloud);
				Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
				return true;
			case irr::KEY_KEY_M: // toggle detail map
				Terrain->setMaterialType(
					Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ? 
					video::EMT_DETAIL_MAP : video::EMT_SOLID);
				return true;
			}
      }

      // jumping with spacebar
      if(event.EventType == EET_KEY_INPUT_EVENT && 
         !event.KeyInput.PressedDown && event.KeyInput.Key == KEY_SPACE) 
         { 
          vector3df pos = playernode->getPosition(); 
         playernode->setPosition(vector3df(pos.X,pos.Y+20,pos.Z)); 
         return true; 
         }



            // Shooting with left mouse button
		    else
	        if ((event.EventType == EET_MOUSE_INPUT_EVENT &&
		    event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)) 
            
            /* 
            Disabled the currentScene part below since I have no nextScene stuff and am not sure what it even does :P
            
            &&
		    currentScene == 3) 
            */

      {
		// shoot 
		shoot();
	  }

		return false;
	}

private:
	scene::ISceneNode* Terrain;
	void shoot();
	void createParticleImpacts();
	
};
Code in int main()

Code: Select all

    // For jumping
    vector3df pos = playerNode->getPosition(); 
    posx = pos.X; 
    posy = pos.Y; 
    posz = pos.Z;
This comes up with playerNode and posx, posy and posz undeclared when compiling.

Posted: Wed Sep 13, 2006 12:34 am
by CeeRo
Next, for my copy/pasted parts of code from the Irrlicht demo for shooting and creating particle impacts:

Code: Select all

// testing testing, shoot


void MyEventReceiver::shoot()
{
	scene::ISceneManager* sm = device->getSceneManager();
	scene::ICameraSceneNode* camera = sm->getActiveCamera();

	if (!camera || !mapSelector)
		return;

	SParticleImpact imp; 
	imp.when = 0;

	// get line of camera

	core::vector3df start = camera->getPosition();
	core::vector3df end = (camera->getTarget() - start);
	end.normalize();
	start += end*5.0f;
	end = start + (end * camera->getFarValue());
	

	core::triangle3df triangle;

	core::line3d<f32> line(start, end);

	// get intersection point with map

	if (sm->getSceneCollisionManager()->getCollisionPoint(
		line, mapSelector, end, triangle))
	{
		// collides with wall
		core::vector3df out = triangle.getNormal();
		out.setLength(0.03f);

		imp.when = 1;
		imp.outVector = out;
		imp.pos = end;
	}
	else
	{
		// doesnt collide with wall
		end = (camera->getTarget() - start);
		end.normalize();
		end = start + (end * 1000);
	}

	// create fire ball
	scene::ISceneNode* node = 0;
	node = sm->addBillboardSceneNode(0,
		core::dimension2d<f32>(25,25), start);

	node->setMaterialFlag(video::EMF_LIGHTING, false);
	node->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/fireball.bmp"));
	node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
		
	f32 length = (f32)(end - start).getLength();
	const f32 speed = 0.6f;
	u32 time = (u32)(length / speed);

	scene::ISceneNodeAnimator* anim = 0;

	// set flight line

	anim = sm->createFlyStraightAnimator(start, end, time);
	node->addAnimator(anim);	
	anim->drop();

	anim = sm->createDeleteAnimator(time);
	node->addAnimator(anim);
	anim->drop();

	if (imp.when)
	{
		// create impact note
		imp.when = device->getTimer()->getTime() + (time - 100);
		Impacts.push_back(imp);
	}
I'm not even sure where exactly I should place this, since in the demo things are split up into different files (which I guess I should learn too), but I placed it like that in int main(), which results in "expected primary-expression before void" and "expected ; before void".

Particle effects code works same way, so same errors I guess though Dev C++ doesn't say:

Code: Select all

void MyEventReceiver::createParticleImpacts()
{
	u32 now = device->getTimer()->getTime();
	scene::ISceneManager* sm = device->getSceneManager();

	for (s32 i=0; i<(s32)Impacts.size(); ++i)
		if (now > Impacts[i].when)
		{
			// create smoke particle system
			scene::IParticleSystemSceneNode* pas = 0;

			pas = sm->addParticleSystemSceneNode(false, 0, -1, Impacts[i].pos);

			pas->setParticleSize(core::dimension2d<f32>(10.0f, 10.0f));

			scene::IParticleEmitter* em = pas->createBoxEmitter(
				core::aabbox3d<f32>(-5,-5,-5,5,5,5),
				Impacts[i].outVector, 20,40, video::SColor(0,255,255,255),video::SColor(0,255,255,255),
				1200,1600, 20);

			pas->setEmitter(em);
			em->drop();

			scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector();
			pas->addAffector(paf);
			paf->drop();

			pas->setMaterialFlag(video::EMF_LIGHTING, false);
			pas->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/smoke.bmp"));
			pas->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);

			scene::ISceneNodeAnimator* anim = sm->createDeleteAnimator(2000);
			pas->addAnimator(anim);
			anim->drop();

			// delete entry
			Impacts.erase(i);
			i--;			

		}
}
If this would take a lot of explaining don't worry, but I would appreciate it if someone could tell me what exactly to read up on for this ;)

Posted: Wed Sep 13, 2006 12:38 am
by Acki
As your compiler told you, the vars aren't declared, you'll have to declare them !!!

Code: Select all

float posx, posy, posz; // this vars are not used so you don't need them !!!
IAnimatedMeshSceneNode* playerNode = smgr->addAnimatedMeshSceneNode(...)
the only var you really need is "playerNode" and you'll have to load a mesh into it (look for the examples) !!!

Also I think you should first learn the basics of C/C++ before starting such complex thinks like you did !!!

Posted: Wed Sep 13, 2006 12:49 am
by CeeRo
Alright thanks, that gives me something to work from.

And yeah I know, would be good to learn C++ properly first. I just started a 3 year course in game programming in school, we're working with java right now and aren't gonna start C++ untill next year, so... I got a little set on figuring out just what it really takes to make a game now, and figured I'll learn the basics as I go along. Time will tell if it works I guess ;)

Posted: Wed Sep 13, 2006 9:13 am
by CeeRo
Is it possible to use SKeyMap to set up spacebar for jumping easier?

Posted: Wed Sep 13, 2006 1:17 pm
by Acki
No, not in normal cases !!!
The SKeyMap struct is used for camera movement, but has only 4 states: forward, backward, left and right...
If you want it to jump you'll have to change the Irrlicht source itself and code the jumping into it !!!

Posted: Wed Sep 13, 2006 1:28 pm
by CeeRo
K... I'm having some trouble setting up and pointing to the playerNode...

Code: Select all

// jumping with spacebar 
      if(event.EventType == EET_KEY_INPUT_EVENT && 
         !event.KeyInput.PressedDown && event.KeyInput.Key == KEY_SPACE) 
         { 
          vector3df pos = playerNode->getPosition(); 
         playerNode->setPosition(vector3df(pos.X,pos.Y+20,pos.Z)); 
         return true; 
         } 
This is the jump code in MyEventReceiver, which comes before int main(), and I'm trying to set up the playerNode in int main(), but then it still comes up with playerNode undeclared from the code in EventReceiver. So I'm trying to get a feel for where and in which order things should come, but I'm kind of in the blue here, as the only code examples I have to look at that are advanced enough are split up in different files, making it very hard to see the order and structure properly :/

Posted: Thu Sep 14, 2006 2:09 am
by CeeRo
Alright, I think I'm on to something, but still having some trouble. At least something's happening when pressing space now, but the terrain just flashes and then comes back lacking a lot of surface, and the command window says "Could not draw triangles, too many primitives(115200), maximum is 65535".

Here's my code:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:

	MyEventReceiver(scene::ISceneNode* playerNode)
	{

		playernode = playerNode;

	}

	bool OnEvent(SEvent event)
	{
/*
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
		{
			switch (event.KeyInput.Key)
			{
            case irr::KEY_SPACE: // Jumping
                 vector3df pos = playernode->getPosition();
                 playernode->setPosition(vector3df(pos.X,pos.Y+10,pos.Z));
                 return true;

			}
      }
*/
       if(event.EventType == EET_KEY_INPUT_EVENT && 
         !event.KeyInput.PressedDown && event.KeyInput.Key == KEY_SPACE) 
         { 
          vector3df pos = playernode->getPosition(); 
         playernode->setPosition(vector3df(pos.X,pos.Y+20,pos.Z)); 
         return true; 
         } 


		return false;
	}

private:
	scene::ISceneNode* playernode;

};
Both ways of doing it end up with the same result..
And

Code: Select all

 ISceneNode* playerNode = smgr->addAnimatedMeshSceneNode(smgr->getMesh("c:/Spillprogrammering/irrlicht-1.1/media/sydney.md2"));
Any thoughts anyone?

Posted: Thu Sep 14, 2006 2:34 am
by rooly
i've an idea. you might find it easier to declare a global variable to use in your event reciever, and just initialize it in main before you declare your event reciever. this takes out the need for a whole new constructor.

another useful method is to not use a constructor in your event reciever's playerNode acceptance, but a simple addPlayerNode(ISceneNode*) function. this is better in the idea that you don't rule out possibly neccessary intialization commands in the built in constructor.

watch:

Code: Select all

//globally
IAnimatedMeshSceneNode* PlayerNode;

//main
PlayerNode=scnmgr->addAnimatedMeshSceneNode(bla);

MyEventReciever evr;

IrrDevice->setEventReciever(&evr);
or

Code: Select all

//event reciever
private:
     IAnimatedMeshSceneNode* PlayerNode;
public:
     void setPlayerNode(IAnimatedMeshSceneNode* tNode)
     {
          PlayerNode=tNode;
     }
...

//main
IAnimatedMeshSceneNode* myNode=scnmgr->addAnimatedMeshSceneNode(bla);

MyEventReceiver evr;
evr.setPlayerNode(myNode);

device->addEventReceiver(&evr);
not really hard, just a little typing

Posted: Thu Sep 14, 2006 2:59 am
by CeeRo
Thanks for the tip, that second example looks interesting, if I did it like that I could also use the terrainNode code that you see in my first post in the event receiver right? Been wondering about how to do that.

I'll have to look into it tomorrow though, 5am here now and I should be getting to bed :/