Page 1 of 1

movement

Posted: Sat Apr 21, 2007 3:04 am
by wiznitch
i cant seem to get it so when you press a key, any movement goes on
all ive done is mixed two of the tutorials together(movement,and hello world) any suggestions on how to fix this, and what might be the shortest solution?

Posted: Sat Apr 21, 2007 5:59 am
by spopo
I'll try to use my telepathic abilities... Maybe you forgot to put receiver into the device creation function :

Code: Select all

device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480),
       16, false, false, false, &receiver);
If it's not true, just post your code here!

Posted: Sat Apr 21, 2007 6:55 am
by monkeycracks
Really you don't need to mix movement and hello world tutorials beacuse Hello World tutorial is just a model being loaded which is done in the movement tutorial as well.

I don't know what could be wrong with your stuff without code, but the guy above me's guess sounds good

Posted: Sat Apr 21, 2007 7:20 am
by Rytz
spopo wrote:I'll try to use my telepathic abilities...
Hmm, yeah ^^^^ what he said :D. Gotta be a little more specific or post some code :).

Posted: Sat Apr 21, 2007 7:23 am
by belfegor
Try this:

Code: Select all

#include <irrlicht.h>
using namespace irr;
#pragma comment(lib, "irrlicht.lib")

IrrlichtDevice* device  = 0;
scene::ISceneNode* node = 0;//node to move

class MER : public IEventReceiver
{
	bool OnEvent(SEvent event)
	{
		if(event.EventType == EET_KEY_INPUT_EVENT)
		{
			switch(event.KeyInput.Key)
			{
			case (KEY_KEY_W):
				{
					node->setPosition(node->getPosition() //get current position
						+ core::vector3df(0.0f, 0.0f, 1.0f));//add to it
					break;
				}
			case (KEY_KEY_S):
				{
					node->setPosition(node->getPosition() //get current position
						+ core::vector3df(0.0f, 0.0f, -1.0f));//add to it
					break;
				}
			case (KEY_KEY_A):
				{
					node->setPosition(node->getPosition() //getcurrent position
						+ core::vector3df(-1.0f, 0.0f, 0.0f));//add to it
					break;
				}
			case (KEY_KEY_D):
				{
					node->setPosition(node->getPosition() //get current position
						+ core::vector3df(1.0f, 0.0f, 0.0f));//add to it
					break;
				}
			}
			return true;
		}
		return false;
	}
};

int main()
{
	MER receiver;
	SIrrlichtCreationParameters param;
	param.DriverType       = video::EDT_OPENGL;
	param.EventReceiver    = &receiver;

	device = createDeviceEx(param);
	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	node = smgr->addCubeSceneNode(30.0f);

	scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
	cam->setPosition(core::vector3df(0.0f, 20.0f, -40.0f));
	cam->setTarget(node->getPosition());

	while(device->run())
	{
		driver->beginScene(true, true, video::SColor(255, 220, 210, 120));
		smgr->drawAll();
		driver->endScene();
	}
	device->drop();

	return 0;
}

Posted: Sat Apr 21, 2007 1:46 pm
by wiznitch

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;


using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;
/*
To be able to use the Irrlicht.DLL file, we need to link with the 
Irrlicht.lib. We could set this option in the project settings, but
to make it easy, we use a pragma comment lib:
*/
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

int x = 0;
int y = 0;
int z = 0;
int count;
int charz = 70;
int chary = -30;
int charx = 0;
/*
This is the main method. We can use int main() on every platform.
On Windows platforms, we could also use the WinMain method
if we would want to get rid of the console window, which pops up when
starting a program with main(), but to keep this example simple,
we use main().
*/
scene::ISceneNode* node = 0;
class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
		/*
		If the key 'W' or 'S' was left up, we get the position of the scene node,
		and modify the Y coordinate a little bit. So if you press 'W', the node
		moves up, and if you press 'S' it moves down.
		*/

		if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
			!event.KeyInput.PressedDown)
		{
			switch(event.KeyInput.Key)
			{
			case KEY_KEY_W:
			case KEY_KEY_S:
				{
					core::vector3df v = node->getPosition();
					v.Y += event.KeyInput.Key == KEY_KEY_W ? 200.0f : -200.0f;
					node->setPosition(v);
				}
				return true;
			}
		}

		return false;
	}
};

int main()
{

MyEventReceiver receiver; 
IrrlichtDevice *device = createDevice(EDT_OPENGL, core::dimension2d<s32>(640, 480), 32, false, false, false, &receiver);	/*
	Set the caption of the window to some nice text. Note that there is 
	a 'L' in front of the string. The Irrlicht Engine uses wide character
	strings when displaying text.
	*/
	device->setWindowCaption(L"Testing program");

	/*
	Get a pointer to the video driver, the SceneManager and the
	graphical user interface environment, so that
	we do not always have to write device->getVideoDriver(),
	device->getSceneManager() and device->getGUIEnvironment().
	*/
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();
    driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);

	/*
	We add a hello world label to the window, using the GUI environment.
	*/

	/*
	To display something interesting, we load a Quake 2 model 
	and display it. We only have to get the Mesh from the Scene 
	Manager (getMesh()) and add a SceneNode to display the mesh.
	(addAnimatedMeshSceneNode()). Instead of writing the filename
	sydney.md2, it would also be possible to load a Maya object file
	(.obj), a complete Quake3 map (.bsp) or a Milshape file (.ms3d).
	By the way, that cool Quake 2 model called sydney was modelled
	by Brian Collins.
	*/
	IAnimatedMesh* mesh = smgr->getMesh("sydney.md2");
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

	/*
	To let the mesh look a little bit nicer, we change its material a
	little bit: We disable lighting because we do not have a dynamic light
	in here, and the mesh would be totally black. Then we set the frame
	loop, so that the animation is looped between the frames 0 and 310.
	And at last, we apply a texture to the mesh. Without it the mesh
	would be drawn using only a color.
	*/




scene::ICameraSceneNode * cam = smgr->addCameraSceneNode(0, vector3df(charx,chary+60,charz-120), vector3df(charx,chary,charz));
//	camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
	//camera->setTarget(core::vector3df(charx,chary,charz));
	cam->setFarValue(12000.0f);

	// disable mouse cursor
	device->getCursorControl()->setVisible(false);

	/*
	Here comes the terrain renderer scene node: We add it just like any 
	other scene node to the scene using ISceneManager::addTerrainSceneNode(). 
	The only parameter we use is a file name to the heightmap we use. A heightmap
	is simply a gray scale texture. The terrain renderer loads it and creates 
	the 3D terrain from it.
	To make the terrain look more big, we change the scale factor of it to (40, 4.4, 40).
	Because we don't have any dynamic lights in the scene, we switch off the lighting,
	and we set the file terrain-texture.jpg as texture for the terrain and 
	detailmap3.jpg as second texture, called detail map. At last, we set
	the scale values for the texture: The first texture will be repeated only one time over 
	the whole terrain, and the second one (detail map) 20 times. 
	*/

	// add terrain scene node
	scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( 
		"media/terrain-heightmap.bmp",
		0,										// parent node
		-1,										// node id
		core::vector3df(0.f, 0.f, 0.f),			// position
		core::vector3df(0.f, 0.f, 0.f),			// rotation
		core::vector3df(40.0f, 3.3f, 40.0f),	// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor,
		5,										// maxLOD
		scene::ETPS_17,							// patchSize
		4										// smoothFactor
		);

	terrain->setMaterialFlag(video::EMF_LIGHTING, false);

	terrain->setMaterialTexture(0, driver->getTexture("media/terrain-texture.jpg"));
	terrain->setMaterialTexture(1, driver->getTexture("media/detailmap3.jpg"));
	terrain->setPosition(vector3df(-1000,-900,600));
	terrain->setMaterialType(video::EMT_DETAIL_MAP);

	terrain->scaleTexture(1.0f, 20.0f);
	//terrain->setDebugDataVisible ( true );

	/*
	To be able to do collision with the terrain, we create a triangle selector.
	If you want to know what triangle selectors do, just take a look into the 
	collision tutorial. The terrain triangle selector works together with the
	terrain. To demonstrate this, we create a collision response animator 
	and attach it to the camera, so that the camera will not be able to fly 
	through the terrain.
	*/
 	if (node)
{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setMD2Animation ( scene::EMAT_STAND );
		node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );
        //node->setPosition(vector3df(2397*2,343*2,2700*2));
        node->setPosition(core::vector3df(0,-30,70));
                	}
	// create triangle selector for the terrain	
	scene::ITriangleSelector* selector
		= smgr->createTerrainTriangleSelector(terrain, 0);
	terrain->setTriangleSelector(selector);
	selector->drop();
scene::IAnimatedMeshSceneNode* anms = smgr->addAnimatedMeshSceneNode(smgr->getMesh("sydney.md2"));

	if (anms)
	{
		scene::ISceneNodeAnimator* anim =
			smgr->createFlyStraightAnimator(core::vector3df(0,80,0), 
			core::vector3df(0,80,1000), 2500, true);
		anms->addAnimator(anim);
		anim->drop();

		/*
		To make to model look right we set the frames between which the animation
		should loop, rotate the model around 180 degrees, and adjust the animation speed
		and the texture.
		To set the right animation (frames and speed), we would also be able to just
		call "anms->setMD2Animation(scene::EMAT_RUN)" for the 'run' animation 
		instead of "setFrameLoop" and "setAnimationSpeed",
		but this only works with MD2 animations, and so you know how to start other animations.
		but it a good advice to use not hardcoded frame-numbers...
		*/
		anms->setMaterialFlag(video::EMF_LIGHTING, false);

		anms->setFrameLoop(160, 183);
		anms->setAnimationSpeed(40);
		anms->setMD2Animation(scene::EMAT_RUN);

		anms->setRotation(core::vector3df(0,x,0));
		anms->setMaterialTexture(0, driver->getTexture("media/sydney.bmp"));

	}

	/*
	To make the user be able to switch between normal and wireframe mode, we create
	an instance of the event reciever from above and let Irrlicht know about it. In 
	addition, we add the skybox which we already used in lots of Irrlicht examples.
	*/

	// create event receiver

	
 	// create skybox
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	smgr->addSkyBoxSceneNode(
		driver->getTexture("media/irrlicht2_up.jpg"),
		driver->getTexture("media/irrlicht2_dn.jpg"),
		driver->getTexture("media/irrlicht2_lf.jpg"),
		driver->getTexture("media/irrlicht2_rt.jpg"),
		driver->getTexture("media/irrlicht2_ft.jpg"),
		driver->getTexture("media/irrlicht2_bk.jpg"));

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);


	int lastFPS = -1;

	while(device->run())
	{
	if (device->isWindowActive())
	{
anms->setRotation(core::vector3df(0,x,0));
		driver->beginScene(true, true, 0 );
 x++;
 if (x>360)
 x=0;
	smgr->drawAll();
		guienv->drawAll();

		driver->endScene();
}
		// display frames per second in window title

}
	device->drop();

	return 0;
}
its pretty much just a mix of a lot of tutorials, i got a rotating animation randomly to see how the rotation and stuff works, but i couldnt get the myevent part working :(

Posted: Sat Apr 21, 2007 2:01 pm
by Perceval
you've got two objects called node. The first is

Code: Select all

scene::ISceneNode* node = 0;
and the second

Code: Select all

IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); 
Your problem is that you want to move the second, but the test in your event receiver is done on the first (i think), which is never initialized, so this condition

Code: Select all

if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
         !event.KeyInput.PressedDown) 
is always false.
To solve it, replace the first by :

Code: Select all

scene::IAnimatedMeshSceneNode* node = 0;
and the second become :

Code: Select all

node = smgr->addAnimatedMeshSceneNode( mesh ); 

Posted: Sat Apr 21, 2007 2:08 pm
by wiznitch
wow thanks that really helped :)

one more thing

Posted: Sat Apr 21, 2007 2:25 pm
by wiznitch
i figured out how to make it so when the key is down it runs, but the animation restarts every loop, any way to fix that? and also how can i turn it back to the stand animation

Posted: Sat Apr 21, 2007 2:28 pm
by spopo
To disable looping : node->setFrameLoop(false);

To set stand animation : node->setMD2AnimationType(irr::scene::EMAT_STAND);

Posted: Sat Apr 21, 2007 2:36 pm
by wiznitch
no but i mean, i want it to loop, but it only does the first frame of the animation when you hold the key down how can i prevent that?
and also when i let go of the key it returns to the stand position?

Posted: Sat Apr 21, 2007 2:41 pm
by Perceval
You need to memorise the current action in a variable, and for example, if you want your node to walk, do something like this (in pseudo code) :

Code: Select all

if(keyPressed && currentAnimation!= "walk"){
            node->setAnimation("walk");
            currentAnimation="walk;"
}

Posted: Sat Apr 21, 2007 2:45 pm
by wiznitch
nevermind, i kind of get what you are saying, that should work too :D

Posted: Tue Apr 24, 2007 12:40 am
by wiznitch
and it does :lol: