Problem with changing weapon

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.
Post Reply
alfabeta90
Posts: 52
Joined: Wed Dec 06, 2006 5:18 pm

Problem with changing weapon

Post by alfabeta90 »

Hello
In my eventretriever i have some code who change the weapon when push a '1' or '2' button. The problem is that if i press 1 and/of 2 button i see the same weapon and on center of screen a difrents black something.

Code: Select all

				case KEY_KEY_1:
				{
					//show primary weapon
					IAnimatedMesh* mesh = smgr->getMesh("gun.3ds");
					IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
					ISceneNode* gun_ = smgr->addAnimatedMeshSceneNode(mesh, node, 0);
					camera->addChild(node);
					

					if (gun_)
					{	
						gun_->setMaterialFlag(EMF_LIGHTING, false);	
					    gun_->setPosition(vector3df(8,-4,15));	
						gun_->setRotation(vector3df(0,6,0));						
					}
				}

				case KEY_KEY_2:
				{
					//show seconday weapon
					IAnimatedMesh* mesh2 = smgr->getMesh("pistol.3ds");
					IAnimatedMeshSceneNode* node2 = smgr->addAnimatedMeshSceneNode( mesh2 );
					ISceneNode* gun = smgr->addAnimatedMeshSceneNode(mesh2, node2, 0);
					camera->addChild(node2);

					if (gun)
					{	
						gun->setMaterialFlag(EMF_LIGHTING, false);	
					    gun->setPosition(vector3df(8,-4,15));	
						gun->setRotation(vector3df(0,6,0));
						
					}
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

When you see the first gun, you must set the other to to hidden, like: gun_->setVisible(false); and vice-versa; then when they hit the key corresponding key set it visible again:
gun_->setVisible(true)
it would also be a good idea to load the models before, because now it reloads it everytime you press the key, which could slow it down
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Code: Select all

   IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); 
   ISceneNode* gun_ = smgr->addAnimatedMeshSceneNode(mesh, node, 0); 
   camera->addChild(node);
I don't know why, but you create a gun scene node, then you create another gun scene node that is a child of the first one. Then you set the second one as a child of the camera. You should be able to write

Code: Select all

ISceneNode* gun_ = smgr->addAnimatedMeshSceneNode(mesh, camera, 0); 
Also, you are never removing the old gun. If you press the 1 key 100 times, there will be 100 guns there. As mentioned by the previous poster, you should probably create the gun and pistol scene nodes once and then make one of them visible at a time.

Travis
alfabeta90
Posts: 52
Joined: Wed Dec 06, 2006 5:18 pm

Post by alfabeta90 »

main:

Code: Select all

	gun = smgr->getMesh("uzi.3ds");
	gun_ = smgr->addAnimatedMeshSceneNode(gun, camera, 0);
	camera->addChild(gun_);

	gun_->setMaterialFlag(EMF_LIGHTING, false);	
	gun_->setPosition(vector3df(8,-4,15));	
	gun_->setRotation(vector3df(0,6,0));
	gun_->setVisible(false);


	gun2 = smgr->getMesh("gun.3ds");
	gun_2 = smgr->addAnimatedMeshSceneNode(gun2, camera, 0);
	camera->addChild(gun_2);

	gun_2->setMaterialFlag(EMF_LIGHTING, false);	
	gun_2->setPosition(vector3df(8,-4,15));	
	gun_2->setRotation(vector3df(0,6,0));
	gun_2->setVisible(false);
eventreceiver:

Code: Select all

				case KEY_KEY_1:
				{
					gun_2->setVisible(false);
					gun_->setVisible(true);

				}

				case KEY_KEY_2:
				{
					gun_->setVisible(false);
					gun_2->setVisible(true);
					

				}
When i hit 1 or 2 i see the same weapon
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Is gun_ a pointer to the same node in both places? i.e. is it a global variable, or did you pass the gun_ pointer from main into your event receiver constructor? Or maybe you've created multiple animated mesh nodes again.

If you are just going to throw all of this code into your event receiver, then this will serve you quite well...

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
  MyEventReceiver()
    : ActiveWeapon(0)
  {
  }

  virtual ~MyEventReceiver()
  {
    removeAllWeapons();
  }

  void setActiveWeapon(scene::ISceneNode* node)
  {
    if (ActiveWeapon) {
      ActiveWeapon->setVisible(false);
      ActiveWeapon->drop();
    }

    ActiveWeapon = node;

    if (ActiveWeapon) {
      ActiveWeapon->grab();
      ActiveWeapon->setVisible(true);
    }
  }

  bool addWeapon(scene::ISceneNode* node, EKEY_CODE key)
  {
    SWeapon s;
    s.Key  = key;
    s.Node = node;

    // find a weapon using same key code
    s32 found = Weapons.binary_search(s);
    if (found != -1)
      return false;

    Weapons.push_back(s);
    node->grab();

    setActiveWeapon(node);

    return true;
  }

  bool removeWeapon(scene::ISceneNode* node, EKEY_CODE key)
  {
    SWeapon s;
    s.Key  = key;
    s.Node = node;

    // find a weapon using same key code and node pointer
    s32 found = Weapons.linear_reverse_search(s);
    if (found < 0)
      return false;

    // user removed our active weapon, hopefully they set its visibility
    if (ActiveWeapon == Weapons[found].Node)
      setActiveWeapon(0);

    Weapons.erase(found);
    node->drop();

    return true;
  }

  void removeAllWeapons()
  {
    u32 w;
    for (w = 0; w < Weapons.size(); ++w)
      Weapons[w].Node->drop();

    Weapons.clear();

    setActiveWeapon(0);
  }

  virtual bool OnEvent(SEvent event)
  {
    if (event.EventType == EET_KEY_INPUT_EVENT &&
        event.KeyInput.PressedDown)
    {
      // look for key in our map
      SWeapon s;
      s.Key  = event.KeyInput.Key;
      s.Node = 0;

      s32 found = Weapons.binary_search(s);
      if (found != -1)
      {
        setActiveWeapon(Weapons[found].Node);
        return true;
      }
    }

    return false;
  }

  struct SWeapon
  {
    scene::ISceneNode* Node; // scene node for weapon
    EKEY_CODE Key; // key used to activate weapon

    friend bool operator<(const SWeapon& lhs, const SWeapon& rhs)
    {
      return lhs.Key < rhs.Key;
    }

    friend bool operator==(const SWeapon& lhs, const SWeapon& rhs)
    {
      return (lhs.Key == rhs.Key) && (lhs.Node == rhs.Node);
    }
  };

  core::array<SWeapon> Weapons;
  scene::ISceneNode* ActiveWeapon;
};
You can use it like this...

Code: Select all

   MyEventReceiver receiver;
   device->setEventReceiver(&receiver);

   scene::ISceneNode* node;

   node = smgr->addCubeSceneNode(10, camera);
   node->setPosition(core::vector3df(2, 2, 20));
   camera->addChild(node);

   receiver.addWeapon(node, KEY_KEY_1);

   node = smgr->addSphereSceneNode(5.f, 16, camera);
   node->setPosition(core::vector3df(2, 4, 10));
   receiver.addWeapon(node, KEY_KEY_2);
Travis
Post Reply