(C++) Simple to use Event Receiver class for Irrlicht 1.3
It looks really nice and efficient and I think ill start using it.
Although is has the basic features well-coded I believe it would be much more better with more new and advanced features. I think you should develop it to something bigger which can handle more complicated situations. If I'll have any ideas trust me I'll put them up here, but still, this class is a Well done work.
Although is has the basic features well-coded I believe it would be much more better with more new and advanced features. I think you should develop it to something bigger which can handle more complicated situations. If I'll have any ideas trust me I'll put them up here, but still, this class is a Well done work.
-
- Posts: 14
- Joined: Tue Jun 05, 2007 8:04 am
- Location: INDIA,MAHARASHTRA
can u please correct out the problem in it she dont move when i press this button w continously this code compiles with out any error and executes too but when i press w that time she dont move i think so this is the right post to check this code with mastevent receiver aurthor plzz help out
thanks a lot for any help that u guys had given i triedieventreceiver but i then started using mastevent receiver as effeicient class but can u plzz correct out this probles for me Mastiff or any one who know to use masteventreceiver class plzzzzz
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace io;
using namespace gui;
using namespace scene;
using namespace video;
#include "MastEventReceiver.cpp"
#pragma comment(lib, "Irrlicht.lib")
int main()
{
MastEventReceiver receiver;
IrrlichtDevice *device =
createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(1024, 768),16,false,false,false,&receiver);
if(device==0)
{
return 1;
}
IGUIEnvironment *guienv = device->getGUIEnvironment();
ISceneManager *smgr = device->getSceneManager();
IVideoDriver *driver = device->getVideoDriver();
//load map
device->getFileSystem()->addZipFileArchive("./../media/map-20kdm2.pk3");
scene:: IAnimatedMesh *mesh = smgr->getMesh("20kdm2.bsp");
ISceneNode *node =0;
if (mesh)
node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
if (node)
node->setPosition(core::vector3df(-1300,-144,-1249));
//load object
scene::IAnimatedMeshSceneNode* node1 = 0;
scene::IAnimatedMesh* mesh1 = 0;
mesh1 = smgr->getMesh("sydney.md2");
node1 = smgr->addAnimatedMeshSceneNode( mesh1 );
node1->setPosition(core::vector3df(0,0,30));
node1->setMaterialFlag(video::EMF_LIGHTING, false);
if(mesh)
{
smgr->addOctTreeSceneNode(mesh->getMesh(0));
}
if(node)
{
node->setPosition(core::vector3df(-1300,-144,-1249));
}
smgr->addCameraSceneNodeFPS();
while(device->run())
{
receiver.endEventProcess();
driver->beginScene(true,true,SColor(0,100,100,133));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
if(receiver.keyPressed(KEY_KEY_W))
{
core::vector3df v = node1->getPosition();
v.X = v.X+2;
node1->setPosition(v);
node1->setMD2Animation(scene::EMAT_RUN);
}
if(receiver.keyReleased(KEY_KEY_W))
{
node1->setMD2Animation(EMAT_STAND);
}
receiver.startEventProcess();
}
device->drop();
return 0;
}
it doesn't work :'(
or to be more explicit, it works wonderfully but only for some time, after which the key input handler become mad >.>
i did this test :
and as long as i don't keep "m" down for too long it works as intended, but if i keep it down i will get some messages saying it is pressed, randomly O.o
For the record, it screws up for the first time for i around 300 (it can be 230 as well as 440...), and after it failed the first time it fails regularly (between every 15 and 30 i steps)
I'm using linux + OpenGL and am desperate to find an answer (the mouse seems to not have this problem)
The worst is that the test seems to be good... but then how could this problem be solved ????
or to be more explicit, it works wonderfully but only for some time, after which the key input handler become mad >.>
i did this test :
Code: Select all
int i = 0;
if (eventReceiver.keyPressed('M'))
{
cout << i << " ... pressed" << endl;
}
if (eventReceiver.keyDown('M'))
{
i++;
cout << i << endl;
}
if (eventReceiver.keyReleased('M'))
{
cout << i << " ... released" << endl;
}
For the record, it screws up for the first time for i around 300 (it can be 230 as well as 440...), and after it failed the first time it fails regularly (between every 15 and 30 i steps)
I'm using linux + OpenGL and am desperate to find an answer (the mouse seems to not have this problem)
The worst is that the test seems to be good... but then how could this problem be solved ????
up !
it is a double post, but for the good hopefully as it works now !!!
I am posting the code (there is not much really) so others can use it if they experience problems (@Mastiff : don't hesitate to use it too if you want thanks for the original code btw )
(it is from the beginning of the onEvent function)
if other people could confirm it still works for them (especially windows users) it would be nice (it would suck if what helped making it work for me screwed it up for others :p)
it is a double post, but for the good hopefully as it works now !!!
I am posting the code (there is not much really) so others can use it if they experience problems (@Mastiff : don't hesitate to use it too if you want thanks for the original code btw )
Code: Select all
if (keyState[event.KeyInput.Key] == !DOWN)
instead of :
if (keyState[event.KeyInput.Key] == UP || keyState[event.KeyInput.Key] == RELEASED)
if other people could confirm it still works for them (especially windows users) it would be nice (it would suck if what helped making it work for me screwed it up for others :p)
To MasterGod:
Thanks much, and I might possibly expand it for more advanced features, possibly GUI events/user events.
Any idea's are welcome.
To prajay.shetty:
You should probably be calling:
eventReceiver.init();
just after you create the instance of the class.
And the problem is probably this:
if(receiver.keyPressed(KEY_KEY_W))
should be:
if(receiver.keyDown(KEY_KEY_W))
The key "Pressed" event only ever happens once, so your character will only move 2 units, which could hardly be visible.
The key "Down" event is always active if the key is held down, meaning it would constantly update it's position.
To eneru:
Are you placing:
receiver.endEventProcess();
at the start of your whileloop and
receiver.startEventProcess();
at the end of the loop?
I used your test code and it works perfectly for me(I used an object to hold the key down for quite a while even), I couldn't get it to go wrong on my Windows XP install. (currently dont have a working linux install to test on atm)
I even used the modified code you supplied and again nothing was wrong.
Since it works either way on my XP install I modified the code to work as the way you changed it since it obviously works for you and doesn't break the code.
It could have something to do with how Linux handles key events, either way it shouldn't happen anymore.
Thanks much, and I might possibly expand it for more advanced features, possibly GUI events/user events.
Any idea's are welcome.
To prajay.shetty:
You should probably be calling:
eventReceiver.init();
just after you create the instance of the class.
And the problem is probably this:
if(receiver.keyPressed(KEY_KEY_W))
should be:
if(receiver.keyDown(KEY_KEY_W))
The key "Pressed" event only ever happens once, so your character will only move 2 units, which could hardly be visible.
The key "Down" event is always active if the key is held down, meaning it would constantly update it's position.
To eneru:
Are you placing:
receiver.endEventProcess();
at the start of your whileloop and
receiver.startEventProcess();
at the end of the loop?
I used your test code and it works perfectly for me(I used an object to hold the key down for quite a while even), I couldn't get it to go wrong on my Windows XP install. (currently dont have a working linux install to test on atm)
I even used the modified code you supplied and again nothing was wrong.
Since it works either way on my XP install I modified the code to work as the way you changed it since it obviously works for you and doesn't break the code.
It could have something to do with how Linux handles key events, either way it shouldn't happen anymore.
#include <"signature.h">
OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
ok, i don't have windows to test it but from what i understood the events are not dealt exactly the same way on windows or linux, thus the (weird) problem
If my hack still works on windows then the problem is completely solved ^^
and yes i placed the 2 methods well
There is also another problem i had (though it should be the same on windows) : my GUI never got the events as your OnEvent method always return true if there was a mouse or keyboard event, and so irrlicht doesn't send the event to the GUI in case if it should be handled there !
I made this method to always return false as of now, and it works for the GUI now (and of course still works great for the keyboard and mouse)
and that's it, thanks again for your class
If my hack still works on windows then the problem is completely solved ^^
and yes i placed the 2 methods well
There is also another problem i had (though it should be the same on windows) : my GUI never got the events as your OnEvent method always return true if there was a mouse or keyboard event, and so irrlicht doesn't send the event to the GUI in case if it should be handled there !
I made this method to always return false as of now, and it works for the GUI now (and of course still works great for the keyboard and mouse)
and that's it, thanks again for your class
Very nice code, but ...
Hi guys,
I was really clueless for implementing an event receiver in such a way that I could make use of it it a nice way! This looks very nice, and I will happily use it in my code. But I have a weird artifact!
My code was up adn running, I used the RTS camera, that uses its own event receiver internally which worked fine. But after adding this event receiver, my camera moves forward and I cannot interact with my program at all.
Here are some snippets of my code:
I did not change anything to the MastEventReceiver, besides the irrlicht.h include. It all compiles fine without any mayor bugs. I do get 4 times this warning:
Severity and Description Path Resource Location Creation Time Id
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 369 1185348358734 9095
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 381 1185348358734 9096
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 393 1185348358734 9097
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 405 1185348358734 9098
but i guess those are harmless! they annoy me ofcourse, but I do not understand them either!
Hopefully somebody understands or can give me a pointer to what is going wrong.
Thanks in advance!
I was really clueless for implementing an event receiver in such a way that I could make use of it it a nice way! This looks very nice, and I will happily use it in my code. But I have a weird artifact!
My code was up adn running, I used the RTS camera, that uses its own event receiver internally which worked fine. But after adding this event receiver, my camera moves forward and I cannot interact with my program at all.
Here are some snippets of my code:
Code: Select all
int main() {
MastEventReceiver eventReceiver;
eventReceiver.init();
IrrlichtDevice* device;
device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(640,480),32,false,false,false,&eventReceiver);
..
..
RTSCamera* camera = new RTSCamera(device,smgr->getRootSceneNode(),smgr,-1,1000.0f,10.0f,10.0f);
camera->setPosition(core::vector3df(-500,3000,2500));
camera->setTarget(core::vector3df(0.f,2500.f,2500.f));
..
..
int lastFPS = -1;
int xbox = 0 ;
int zbox = 0 ;
f32 xposbox = 0;
f32 zposbox = 0;
vector3df newpos;
while(device->run())
if (device->isWindowActive())
{
eventReceiver.endEventProcess();
driver->beginScene(true, true, 0 );
smgr->drawAll();
env->drawAll();
gui::ICursorControl* cursor = device->getCursorControl();
core::vector3df intersection;
core::triangle3df tri;
mouseOverPlayerNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getPosition(),(0x01));
if (mouseOverPlayerNode && eventReceiver.leftMouseDown()){
if (smgr->getSceneCollisionManager()->getCollisionPoint(
smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(cursor->getPosition()), selector, intersection, tri))
{
xbox = int(intersection.X / 340);
zbox = int(intersection.Z / 340);
//cout << xbox << " " << zbox <<endl;
xposbox = xbox * 340.f + 170.f;
zposbox = zbox * 340.f + 170.f;
//cout << xposbox << " " << zposbox <<endl;
newpos.set(xposbox,152.f,zposbox);
mouseOverPlayerNode->setPosition(newpos);
}
}
driver->endScene();
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Terrain Renderer - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
eventReceiver.startEventProcess();
}
device->drop();
return 0;
}
Severity and Description Path Resource Location Creation Time Id
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 369 1185348358734 9095
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 381 1185348358734 9096
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 393 1185348358734 9097
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 405 1185348358734 9098
but i guess those are harmless! they annoy me ofcourse, but I do not understand them either!
Hopefully somebody understands or can give me a pointer to what is going wrong.
Thanks in advance!
Just fooling around abit!
-
- Posts: 224
- Joined: Tue Oct 25, 2005 4:32 pm
- Location: Louisiana, USA, backwater country
- Contact:
hey, i found a bug in this code. in your mouse state array, you set it to have 2 places, yet you check for 3 in all your loops. you should change
to
Code: Select all
keyStatesENUM mouseButtonState[2];
Code: Select all
keyStatesENUM mouseButtonState[3];
When banks compete, you win.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
Tss, rooly - you could have mentioned the other bug as well...
As keyState has size KEY_KEY_CODES_COUNT the init() function should use
instead of
As keyState has size KEY_KEY_CODES_COUNT the init() function should use
Code: Select all
for (int i = 0; i < KEY_KEY_CODES_COUNT; i++)
Code: Select all
for (int i = 0; i <= KEY_KEY_CODES_COUNT; i++)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
XkbSetDetectableAutoRepeat
Spent a while tracking this bug down so I thought I'd share:
Under X11 it is apparently default behavior, when a user presses a key, to send a continuous stream of Released/Pressed messages. This will obviously confuse any system where you're trying to tell if a key has been "Pressed" for the first time.
There's a fix for this now, but it's not in CIrrDeviceLinux (yet?):
http://lists.freedesktop.org/archives/x ... 15819.html
So for the time being, I've added
Which fixed everything and allows you to use this class as it was intended under linux. AFAIK you can't do this "outside" of the CIrrDeviceLinux class because there's no way to access the display variable "after the fact": http://kerneltrap.org/node/5960.
Under X11 it is apparently default behavior, when a user presses a key, to send a continuous stream of Released/Pressed messages. This will obviously confuse any system where you're trying to tell if a key has been "Pressed" for the first time.
There's a fix for this now, but it's not in CIrrDeviceLinux (yet?):
http://lists.freedesktop.org/archives/x ... 15819.html
So for the time being, I've added
Code: Select all
CIrrDeviceLinux:22
#include <X11/XKBlib.h>
...
CIrrDeviceLinux:528
// disable auto-repeat
{
Bool detectable_autorepeat_supported;
XkbSetDetectableAutoRepeat(display,
True,
&detectable_autorepeat_supported);
}
the ICameraSceneNodeFPS does not respond(as in with the key codes it uses for moving). I guess I'll have to make a custom one,but thats even better,because irrlichts one doesn't allow jumping. But you may wanna take a look at that(I think I know why it wouldn't work though,because your event receiver over rides irrlichts? maybe? probably not actually).
I got some problems when trying to compile my app after included this
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyPressed(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:369: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyDown(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:381: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:381: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyUp(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:393: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:393: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyReleased(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:405: warning: array subscript has type ‘char’
:: === Build finished: 0 errors, 6 warnings ===
My company: http://www.kloena.com
My blog: http://www.zhieng.com
My co-working space: http://www.deskspace.info
My blog: http://www.zhieng.com
My co-working space: http://www.deskspace.info
There is a change that need to be made to work with SVN revision 1004+:
From:
To:
From:
Code: Select all
virtual bool OnEvent(SEvent event)
Code: Select all
virtual bool OnEvent(const SEvent& event)