movement
I'll try to use my telepathic abilities... Maybe you forgot to put receiver into the device creation function :
If it's not true, just post your code here!
Code: Select all
device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480),
16, false, false, false, &receiver);
-
- Posts: 1029
- Joined: Thu Apr 06, 2006 12:45 am
- Location: Tennesee, USA
- Contact:
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;
}
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;
}
you've got two objects called node. The first is
and the second
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
is always false.
To solve it, replace the first by :
and the second become :
Code: Select all
scene::ISceneNode* node = 0;
Code: Select all
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
Code: Select all
if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
!event.KeyInput.PressedDown)
To solve it, replace the first by :
Code: Select all
scene::IAnimatedMeshSceneNode* node = 0;
Code: Select all
node = smgr->addAnimatedMeshSceneNode( mesh );
one more thing
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
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;"
}