EventReceiver Problem :s

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Nils:D
Posts: 24
Joined: Sat Sep 09, 2006 12:35 pm

EventReceiver Problem :s

Post by Nils:D »

Hi,

if I press A, S or Escape, the events will be executed else nothing happens. Why ? Another Question: How is it possible to move the Model by one pressing very far ? By this code I must press to much on one of the Keys.

Code: Select all

virtual bool OnEvent(SEvent event)
   {
        if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
            !event.KeyInput.PressedDown)
        {
            r = node->getRotation();
            p = node->getPosition();
            float speed  = 4.0;
            core::vector3df v = node->getPosition();
            switch(event.KeyInput.Key)
            {
                case KEY_ESCAPE:
                    device->closeDevice();
                case KEY_KEY_W:
                {
                    v.X = v.X + ( cos(r.Y * 3.14159265/180)* speed);
                    v.Z = v.Z - ( sin(r.Y * 3.14159265/180)* speed);
                    node->setPosition(v);
                }
                case KEY_KEY_S:
                {
                    v.X = v.X - ( cos(r.Y * 3.14159265/180)* speed);
                    v.Z = v.Z + ( sin(r.Y * 3.14159265/180)* speed);
                    node->setPosition(v);
                } //<--
                case KEY_KEY_A:
                {
                    v.X = v.X + ( cos((r.Y-90) * 3.14159265/180)*speed );
                    v.Z = v.Z - ( sin((r.Y-90) * 3.14159265/180)*speed );
                    node->setPosition(v);
                } //<--
                case KEY_KEY_D:
                {
                    v.X = v.X + ( cos((r.Y+90) * 3.14159265/180)*speed );
                    v.Z = v.Z - ( sin((r.Y+90) * 3.14159265/180)*speed );
                    node->setPosition(v);
                }
                return true;
            }
        }
        return false;
   }
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I don't know what you really mean, but you have a big error in this code !!!
Each case statement has to be closed by "return true;" (normaly with "break;" but "return true" does the same in this case) !!!
I wonder that if you press escape your program doesn't crash !?!?!
Because if you press escape, the code for all defined keys will be executed !!!
This means first close the device and then calculate and set the position of the node for the keys "W", "S", "A" and "D" (because of missing breaks) !!!
Or if you press "A", the key "D" will be executed, too !!!
It should look like this:

Code: Select all

virtual bool OnEvent(SEvent event)
   {
        if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
            !event.KeyInput.PressedDown)
        {
            r = node->getRotation();
            p = node->getPosition();
            float speed  = 4.0;
            core::vector3df v = node->getPosition();
            switch(event.KeyInput.Key)
            {
                case KEY_ESCAPE:
                    device->closeDevice();
                    return true;
                case KEY_KEY_W:
                {
                    v.X = v.X + ( cos(r.Y * 3.14159265/180)* speed);
                    v.Z = v.Z - ( sin(r.Y * 3.14159265/180)* speed);
                    node->setPosition(v);
                    return true;
                }
                case KEY_KEY_S:
                {
                    v.X = v.X - ( cos(r.Y * 3.14159265/180)* speed);
                    v.Z = v.Z + ( sin(r.Y * 3.14159265/180)* speed);
                    node->setPosition(v);
                    return true;
                } //<--
                case KEY_KEY_A:
                {
                    v.X = v.X + ( cos((r.Y-90) * 3.14159265/180)*speed );
                    v.Z = v.Z - ( sin((r.Y-90) * 3.14159265/180)*speed );
                    node->setPosition(v);
                    return true;
                } //<--
                case KEY_KEY_D:
                {
                    v.X = v.X + ( cos((r.Y+90) * 3.14159265/180)*speed );
                    v.Z = v.Z - ( sin((r.Y+90) * 3.14159265/180)*speed );
                    node->setPosition(v);
                    return true;
                }
            }
        }
        return false;
   }
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Nils:D
Posts: 24
Joined: Sat Sep 09, 2006 12:35 pm

Post by Nils:D »

Arghs, thx...that was it :)
[quote=Acki]I don't know what you really mean[/quote]
Ok, i'm not so good in english, sry.

In other words:
If you add a FPS-Camera the camera has automaticly keys (up, down, left, right). This keys can be changed (w, a, s, d). If you press one of those keys for many seconds, the character move for this seconds and if you let the key up, it stops immediately. I want to program this in the 3rd-person camera with the code of the eventreceiver, but i doesn't works, what must i change that the control of the model is like in the fps-camera ?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Basically you need to set a flag that indicates a key is pressed. Then, every render, you need to apply movement based on the keys that are currently pressed down. I wrote an example that does it a few weeks ago. You can find it near the bottom of this post.

Also, it is usually much easier to read code that doesn't do a bunch of trig. The following can be used to do node movement without writing a bunch of trig code.

Code: Select all

  // this code assumes
  // node is a non-null scene node pointer
  // Time is a f32 that represents the fractional seconds elapsed since last call
  // Velocity is a f32 that represents the movement speed in units per second
  core::vector3df forward(0, 0, 1); 
  core::vector3df upward(0, 1, 0);
  core::vector3df sideward(1, 0, 0);

  core::matrix4 m = node->getRelativeTransformation();

  m.rotateVect(forward); 
  m.rotateVect(upward); 
  m.rotateVect(sideward);

  // get the old position 
  core::vector3df position = node->getPosition(); 

  // get the distance moved this time slice.
  f32 distance = Velocity * Time; 

  if (/*key pressed foreward*/)
    position += (forward * distance); 
  if (/*key pressed backward*/)
    position -= (forward * distance);
  if (/*key pressed right*)
    position += (sideward * distance);
  if (/*key pressed left*)
    position -= (sideward * distance);
  if (/*key pressed up*)
    position += (upward * distance);
  if (/*key pressed down*)
    position -= (upward * distance);

  node->setPosition(position); 
Travis
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Right, the "boolean keys" workaround is what you need for this... ;)

just to understand you correctly, are you trying to create a 3rd person camera, or should the node move independant from the camera ???

If the node shall move with the camera (3rd person) you simply can define the keymap of the camera and set the node as child of the camera...
This way the node moves always together with the camera...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Nils:D
Posts: 24
Joined: Sat Sep 09, 2006 12:35 pm

Post by Nils:D »

N I C E, THX! :) I changed ONLY the needed things (the eventreceiver was and is the main class) and everything is ok, but if I press escape or Alt+F4 then the application will be terminated with an exception. Why ?

Here is the complete code:
(hope it works)
http://upload2.net/page/download/aWsavx ... e.zip.html
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

(könnte jetzt zwar auf Deutsch antworten, aber hier im Forum ist Englisch die "Amtssprache" ;) )

Well, I had to do some changes to the code to get it compiled and run, but since there are no media files included I don't see verry much... ;)
I get only into the menu and can't start the game...

And I can't reproduce the error !!!
If I press Alt+F4, the program shuts down as usual...
And pressing Escape doesn't work at all...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Nils:D
Posts: 24
Joined: Sat Sep 09, 2006 12:35 pm

Post by Nils:D »

(Ich weiss...)

I know, but there is one problem: the game is to big and rapidshare is down. I can't upload it. I hoped that you can see maybe an error in the code.... Is there another FREE uploading-site (not rapidshare ;))?
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Well, your code is not realy easy to read, since there are no comments... ;)
But I think the problem is with the destructor of the game class !!!
In the destructor you delete /drop the selectors:

Code: Select all

game::~game()
{
	if (mapSelector)
		mapSelector->drop();

	if (metaSelector)
		metaSelector->drop();
}
But as far as you drop the device after the main loop, the selectors/device is no longer avilable in the destructor (but the pointers are still referenced) !!!
So you try to drop something that doesn't exist anymore !!!
You should either not drop them or if you want to just drop them before closing the device:

Code: Select all

if (Keys[KEY_ESCAPE]){
  if (mapSelector)
    mapSelector->drop();

  if (metaSelector)
    metaSelector->drop();

  device->closeDevice();
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

So you try to drop something that doesn't exist anymore !!!
That should never happen. If everthing properly used reference counts then the object won't cease to exist until the last drop()
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Right, as far as the device is still avilable...
But first the device is closed and droped, then the program shuts down (either by using Escape or Alt+F4) and then the class calls it's destructor !!!
Then the destructor calls functions from Irrlicht, but the device doesn't exist enymore !!!
I also had this problen a few times... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

It shouldn't matter if the device has been dropped for the last time and doesn't exist anymore. The triangle selectors will still exist and still need to be dropped.

If they are explicitly deleted somewhere then that is a _bug_.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

OK, if you say so ;) (didn't test it)...
But in this case I don't know what the exception could cause (as far as I can't reproduce the error)...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Nils:D
Posts: 24
Joined: Sat Sep 09, 2006 12:35 pm

Post by Nils:D »

I think the error is there because the Map used ever from the game and i can't close the Map. game

Code: Select all

game::~game()
{
	/*if (mapSelector)
		mapSelector->drop();

	if (metaSelector)
		metaSelector->drop();*/
}

...

...
device->closeDevice();
...
It runs.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Hmm, who was the one who said the destructor is the problem !?!?! :lol:
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply