Hi everyone, ive just been having a look at this engine and im very impressed with it compared to the other engines ive used.
However, it is unclear from any of the samples how to check the keyboard? All im trying to do atm is check for the escape key Thankyou
Michael
Howdy - New To IRRLICHT, KBoard question
Howdy - New To IRRLICHT, KBoard question
AMD Athlon XP 1900 (1600mhz), 512MB Ram 55GB HDD, Mandrake Linux 9.1, Windows 2000, NVidia GeForce 2 Ti 64MB.
OpenGL ATW!
OpenGL ATW!
This code is from example #4 Movement
Hope this will help.
Oterwise have a look at the documentation and searchfor IEventReceiver.h (headerfile where the SEvent struct is defined) and "irr Namespace Reference" where you can find the enumertion definitions for the Keys
Maxi
Code: Select all
/*
To get events like mouse and keyboard input, or GUI events like
"the OK button has been clicked", we need an object wich is derived from the
IEventReceiver object. There is only one method to override: OnEvent.
This method will be called by the engine when an event happened.
We will use this input to move the scene node with the keys W and S.
*/
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 ? 2.0f : -2.0f;
node->setPosition(v);
}
return true;
}
}
return false;
}
};
Oterwise have a look at the documentation and searchfor IEventReceiver.h (headerfile where the SEvent struct is defined) and "irr Namespace Reference" where you can find the enumertion definitions for the Keys
Maxi
Ive basically got the hang of how it works, but it doesnt
thats the code for my class. the prog is a console app
Compiles O.K. but when i try to run it crashes
any ideas?
Mike
Code: Select all
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
/*
Checking for esc
*/
if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
!event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_ESCAPE:
{
printf("hey");
}
return true;
}
}
return false;
}
};
Code: Select all
MyEventReceiver receiver;
device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600),
32, false, false, &receiver);
any ideas?
Mike
AMD Athlon XP 1900 (1600mhz), 512MB Ram 55GB HDD, Mandrake Linux 9.1, Windows 2000, NVidia GeForce 2 Ti 64MB.
OpenGL ATW!
OpenGL ATW!
-
- Posts: 360
- Joined: Tue Feb 10, 2004 2:20 am
- Location: Lubbock, TX
I am not sure the way it is done in the demos is a very good way to do input handling. I would suggest doing something like this:
define an array for all keys as such:
Then in the event reciever all you need to do is set the value at the array position of the current event to the value of wether it is pressed down as such:
Then in the main event loop(a a function called there) handle the input. This will also let you handle things like the left or right key being pressed down at the same time(or near the same time):
int main() {
if(keys[KEY_KEY_O]){
node->setRotation( paddle1Node->getRotation()+ core::vector3df(0,0,-0.2f));
}
if(keys[KEY_KEY_Q]){
exit(0);
}
//Put the rest of you main event loop code here
}
Also note this is based on someone elses code originally (it may even be identical. It was so long ago I do not remember if I have changeded it). I just don't want someone geting pissed at me.
define an array for all keys as such:
Code: Select all
//For Key Handling
bool keys[KEY_KEY_CODES_COUNT];
Code: Select all
class MyEventReceiver : public IEventReceiver {
public:
virtual bool OnEvent(SEvent event) {
if(irrDevice != 0 && irrDevice->getSceneManager()->getActiveCamera()) {
keys[event.KeyInput.Key] = event.KeyInput.PressedDown; //Store Key input for control of objects and actions
//Send all other events to camera(Put your camera code here
}
}
};
int main() {
if(keys[KEY_KEY_O]){
node->setRotation( paddle1Node->getRotation()+ core::vector3df(0,0,-0.2f));
}
if(keys[KEY_KEY_Q]){
exit(0);
}
//Put the rest of you main event loop code here
}
Also note this is based on someone elses code originally (it may even be identical. It was so long ago I do not remember if I have changeded it). I just don't want someone geting pissed at me.
the problem im having is that trying to set the event handler in the engines init is what actually seems to cause the prog to crash (heavy crash) to experiment i had a empty event handler that returned 0; and it still went poo poo shaped.
Heres my complete code. its where ive taken the 2d tutorial and tried playing with it.
When i compile and run, i get an access violation error :s
pls note that some code has been commented out
Tx
Mike
Heres my complete code. its where ive taken the 2d tutorial and tried playing with it.
Code: Select all
#include <stdio.h>
#include <wchar.h>
#include <irrlicht.h>
using namespace irr;
static video::IVideoDriver* driver;
static IrrlichtDevice *device = 0;
static scene::ISceneNode* node = 0;
#pragma comment(lib, "Irrlicht.lib")
/*
To get events like mouse and keyboard input, or GUI events like
"the OK button has been clicked", we need an object wich is derived from the
IEventReceiver object. There is only one method to override: OnEvent.
This method will be called by the engine when an event happened.
We will use this input to move the scene node with the keys W and S.
*/
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
/*
Checking for esc
if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
!event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_ESCAPE:
{
printf("hey");
}
return true;
}
}
*/
return 0;
}
};
/*
At first, we start up the engine, set a caption, and get a pointer
to the video driver.
*/
int startengine()
{
MyEventReceiver receiver;
device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600),
32, false, false, &receiver);
device->setWindowCaption(L"The World");
driver = device->getVideoDriver();
return 0;
}
int main()
{
startengine();
gui::IGUIFont* font = device->getGUIEnvironment()->getFont("media/font.bmp");
/*
Everything is prepared, now we can draw everything in the draw loop,
between the begin scene and end scene calls. In this example, we
are just doing 2d graphics, but it would be no problem to mix them
with 3d graphics. Just try it out, and draw some 3d vertices or set
up a scene with the scene manager and draw it.
*/
while(device->run() && driver)
{
if (device->isWindowActive())
{
u32 time = device->getTimer()->getTime();
driver->beginScene(true, true, video::SColor(0,0,0,0));
/*
Drawing text is really simple. The code should be self explanatory.
*/
core::position2d<s32> m = device->getCursorControl()->getPosition(); // get the mouse position
// draw some text
if (font)
font->draw(L"This is a test.",
core::rect<s32>(m.X,m.Y,m.X+270,m.X+50),
video::SColor(255,255,255,255));
// draw transparent rect under cursor
driver->draw2DRectangle(video::SColor(100,255,255,255),
core::rect<s32>(m.X, m.Y, m.X+16, m.Y+16));
driver->endScene();
}
}
/*
That's all, it was not really difficult, I hope.
*/
device->drop();
return 0;
}
pls note that some code has been commented out
Tx
Mike
Wish we'd seen this sooner, might have saved us some leg work. I went through the same thing, made a boolean array in the same way as the code above but had odd crashes. I also wanted to be able to detect an initial keypress as well as key down. The way I found that seems 100% stable and does all this can be found below. Using an array of bytes now instead to store statuses.
In the class itself. Do the resetKeyboard first then can do something like: if (receiver.isKeyDown(KEY_KEY_P)) or if (receiver.isKeyPressed(KEY_KEY_P))
Code: Select all
class MyEventReceiver : public IEventReceiver
{
u8 keys[KEY_KEY_CODES_COUNT];
public:
virtual bool OnEvent(SEvent event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
if (event.KeyInput.PressedDown && keys[event.KeyInput.Key]==0 ) {
keys[event.KeyInput.Key]=1;
}
if (!event.KeyInput.PressedDown && keys[event.KeyInput.Key]!=0) {
keys[event.KeyInput.Key]=0;
}
return true;
}
bool isKeyDown(u8 keycode) {
if (keys[keycode]!=0)
return true;
return false;
}
bool isKeyPressed(u8 keycode) {
if (keys[keycode]==1) {
keys[keycode]=2;
return true;
}
return false;
}
void resetKeyboard(void) {
int i;
// set initial keystates to false
for (i=0; i<KEY_KEY_CODES_COUNT; i++)
keys[i]=0;
}
};
well, i think the problem is, that your eventreceiver only exists in the scopeAnonymous wrote:the problem im having is that trying to set the event handler in the engines init is what actually seems to cause the prog to crash (heavy crash) to experiment i had a empty event handler that returned 0; and it still went poo poo shaped.
Heres my complete code. its where ive taken the 2d tutorial and tried playing with it.
Code: Select all
(...) int startengine() { MyEventReceiver receiver; device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600), 32, false, false, &receiver); device->setWindowCaption(L"The World"); driver = device->getVideoDriver(); return 0; } int main() { startengine(); gui::IGUIFont* font = device->getGUIEnvironment()->getFont("media/font.bmp");
of your startengine()-function. After returning from this function, the instance of MyEventReceiver exists no more, and so you run into problems when trying to receive events with it.
One thing you can do, is to hold a pointer to MyEventReceiver in a global variable, create an instance of MyEventReceiver in your startengine-function with new and assign it to your pointer.
greetings, rincewind
Ah yes, we are creating our MyEventReceiver in the main function as in the tutorials on the Irrlicht site demonstrate so we don't get crashes due to the scope being lost. I am not certain what was the exact cause of the crashing problems we had at first, but it might have been to do with testing event.KeyInput.PressedDown before we were sure the event received was a keyboard event. We used to get crashes if you moved the mouse a lot but the code I posted above has so far proven to be stable for us.