Game Development Community

How do I change this to OnMouseDown?

by Robert Carroll · in Torque Game Builder · 12/03/2009 (10:57 pm) · 10 replies

Heres the code from the examples and Im tring to make it work with onMouseDown.

if (!isObject(ShootsBehaviorAdv))
{
   %template = new BehaviorTemplate(ShootsBehaviorAdv);
   
   %template.friendlyName = "Shoots Advanced";
   %template.behaviorType = "Game";
   %template.description  = "Shoots an object (with more controls)";

   %template.addBehaviorField(projectile, "The projectile to clone and shoot", object, "", t2dSceneObject);
   %template.addBehaviorField(fireKey, "The key to fire the projectile with", keybind, "keyboard space");
   %template.addBehaviorField(fireRate, "The rate to fire when the fire key is held down (seconds)", float, "0.25");
   %template.addBehaviorField(projectileSpeed, "The speed of projectiles (world units per second)", float, "150");
   %template.addBehaviorField(fireAngleOffset, "Direction of motion angle offset relative to the owner's rotation (degrees)", float, "-0");
   %template.addBehaviorField(rotationOffset, "Rotation offset of the projectile itself relative to the owner's rotation (degrees)", float, "-0");
}

function ShootsBehaviorAdv::onBehaviorAdd(%this)
{
   %this.tryingToFire = false;
   
   if (isObject(moveMap))
      moveMap.bindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), "fire", %this);
	alxplay(grenadethrow);
}

function ShootsBehaviorAdv::onBehaviorRemove(%this)
{
   if (isObject(moveMap))
      moveMap.unbindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), %this);
}

function ShootsBehaviorAdv::fire(%this, %val)
{
   //This can be a bit confusing, but it's to ensure that the firing mechanism
   // works as expected, so that the player cannot fire more bullets by tapping the
   // key really fast (the waitSchedule ensures that) - when the wait finishes, it
   // uses the fireCond method to see if the key was pressed again during the wait.
   %this.tryingToFire = %val;
   
   if (%val == 0) 
   {
      cancel(%this.fireSchedule);
      if( !isEventPending(%this.waitSchedule))
         %this.waitSchedule = %this.schedule( %this.fireRate * 1000, "fireCond");
      return;
   }
   
   if (isEventPending(%this.fireSchedule) || isEventPending( %this.waitSchedule))
      return;
   
   if (!isObject(%this.projectile) || !%this.owner.enabled || !%this.owner.getVisible())
      return;
   
   %projectile = %this.projectile.cloneWithBehaviors();
   
   %projectile.setPosition(%this.owner.position);
   %projectile.setRotation(%this.owner.rotation + %this.rotationOffset);
   %projectile.setLinearVelocityPolar(%this.owner.rotation + %this.fireAngleOffset, %this.projectileSpeed);
   alxplay(shoot);
    
   if (!isEventPending(%this.fireSchedule))
      %this.fireSchedule = %this.schedule(%this.fireRate * 1000, "fire", 1);
      alxplay(grenadethrow);
}

function ShootsBehaviorAdv::fireCond(%this)
{
   if( %this.tryingToFire )
      %this.fire( %this.tryingToFire );
      
}

=====
When I tried it wouldn't fire.

#1
12/04/2009 (3:58 pm)
First off, do you want the object to shoot when you click directly on that object or anywhere on the screen?

In a very basic summary, you need to have setUseMouseEvents set to true for whatever object you want to capture the clicks. Then have onMouseDown call the fire function from the object with the shoots behavior. I can help with specifics once I know what sort of click behavior you want to have.
#2
12/05/2009 (12:52 am)
I want it for the object i.e. when object clicked fire the projectile. And what do you mean put the fire thing on mouse down.

Another thing Thank goddness You replied I couldnt contact you brecause I couldn't find any contact info but, I need help on the Astral objects Spwaning. When I do everything the first wave spawns but nothing after that :( how do I fix this?
#3
12/05/2009 (7:53 am)
In the code you posted above, what happens is when you press the space key (or another key you specifically define), it tells TGB to call the fire function that is defined already in that behavior.

function ShootsBehaviorAdv::fire(%this, %val)

So what we want to do is replace or supplement having to press a key with onMouseDown instead. Here is a code snippet with the functions that I changed or added (note this code is from the normal shoots behavior and not the advanced one):

function ShootsBehavior::onBehaviorAdd(%this)
{
   if (isObject(moveMap))
      moveMap.bindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), "fire", %this);
      
   %this.owner.setUseMouseEvents(true);
}

function ShootsBehavior::onBehaviorRemove(%this)
{
   if (isObject(moveMap))
      moveMap.unbindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), %this);
      
   %this.owner.setUseMouseEvents(false);
}

function ShootsBehavior::onMouseDown(%this)
{
   %this.fire(1);
}

function ShootsBehavior::onMouseUp(%this)
{
   %this.fire(0);
}

onMouseDown is passing the variable 1 to the fire function which allows the object to shoot. onMouseUp passes the 0 variable to the fire function in order to stop shooting. This gives you the basics of what you'd like but it does have some quirks that would need to be worked out. For example, if you click down on the object but release the click outside of the object's bounding box, it does not stop shooting because it did not register that you released the mouse button.
#4
12/05/2009 (8:43 am)
For the Astral Objects tutorial, if the spawning is not working then the issue is either due to something in the script of spawnArea.cs, spawnOnRemove.cs or spawnTracker.cs not being correct or you've forgotten to attach a behavior to one of the objects in your scene.

Let's start with the scripts first, can you post what you have for each of the 3 scripts I mentioned in the first paragraph? If you'd like, post it in a separate thread so it is easier for people to find with a search if they have the same issue.
#5
12/05/2009 (3:48 pm)
Ok, so that snippit will make it fire on mouse down? and dont worry about the keep fireing out of object thing. the way I have it set up is I put a scene object and mount it to the gun barrel making it look like the bullets from the gun.

And the new Tread about the spawner is here: www.torquepowered.com/community/forums/viewthread/107037
I hope you can help this is exactly what I need to complete my game. Now I have spawners that just spawn spawners :(
#6
12/05/2009 (3:58 pm)
I can't get teh shoots adv to work :( heres what I did.

function ShootsBehavior::onBehaviorAdd(%this)   
{   
   if (isObject(moveMap))   
      moveMap.bindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), "fire", %this);   
         
   %this.owner.setUseMouseEvents(true);   
}   
  
function ShootsBehavior::onBehaviorRemove(%this)   
{   
   if (isObject(moveMap))   
      moveMap.unbindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), %this);   
         
   %this.owner.setUseMouseEvents(false);   
}   
  
function ShootsBehavior::onMouseDown(%this)   
{   
   %this.fire(1);   
}   
  
function ShootsBehavior::onMouseUp(%this)   
{   
   %this.fire(0);   
}  


function ShootsBehaviorAdv::fire(%this, %val)
{
   //This can be a bit confusing, but it's to ensure that the firing mechanism
   // works as expected, so that the player cannot fire more bullets by tapping the
   // key really fast (the waitSchedule ensures that) - when the wait finishes, it
   // uses the fireCond method to see if the key was pressed again during the wait.
   %this.tryingToFire = %val;
   
   if (%val == 0) 
   {
      cancel(%this.fireSchedule);
      if( !isEventPending(%this.waitSchedule))
         %this.waitSchedule = %this.schedule( %this.fireRate * 1000, "fireCond");
      return;
   }
   
   if (isEventPending(%this.fireSchedule) || isEventPending( %this.waitSchedule))
      return;
   
   if (!isObject(%this.projectile) || !%this.owner.enabled || !%this.owner.getVisible())
      return;
   
   %projectile = %this.projectile.cloneWithBehaviors();
   
   %projectile.setPosition(%this.owner.position);
   %projectile.setRotation(%this.owner.rotation + %this.rotationOffset);
   %projectile.setLinearVelocityPolar(%this.owner.rotation + %this.fireAngleOffset, %this.projectileSpeed);
   alxplay(shoot);
    
   if (!isEventPending(%this.fireSchedule))
      %this.fireSchedule = %this.schedule(%this.fireRate * 1000, "fire", 1);
      alxplay(grenadethrow);
}

function ShootsBehaviorAdv::fireCond(%this)
{
   if( %this.tryingToFire )
      %this.fire( %this.tryingToFire );
      
}

It wont fire with the key or the mouse :?
#7
12/05/2009 (4:13 pm)
BTW the whole point of this was to make it so the player cant tap the mouse and shoot faster. I already have a shoot behavior.
#8
12/05/2009 (6:04 pm)
When you copied and pasted my code, you forgot to change the behavior names. Instead of ShootsBehavior make sure each after each function it says ShootsBehaviorAdv - that should fix things.
#9
12/05/2009 (6:47 pm)
ohh, OK thnx stupid mistake
#10
12/05/2009 (7:39 pm)
Thank You soooo much :) heres the code for anyone else.

if (!isObject(ShootsBehaviorAdv))
{
   %template = new BehaviorTemplate(ShootsBehaviorAdv);
   
   %template.friendlyName = "Shoots Advanced";
   %template.behaviorType = "Game";
   %template.description  = "Shoots an object (with more controls)";

   %template.addBehaviorField(projectile, "The projectile to clone and shoot", object, "", t2dSceneObject);
   %template.addBehaviorField(fireKey, "The key to fire the projectile with", keybind, "keyboard space");
   %template.addBehaviorField(fireRate, "The rate to fire when the fire key is held down (seconds)", float, "0.25");
   %template.addBehaviorField(projectileSpeed, "The speed of projectiles (world units per second)", float, "150");
   %template.addBehaviorField(fireAngleOffset, "Direction of motion angle offset relative to the owner's rotation (degrees)", float, "-0");
   %template.addBehaviorField(rotationOffset, "Rotation offset of the projectile itself relative to the owner's rotation (degrees)", float, "-0");
}

function ShootsBehaviorAdv::onBehaviorAdd(%this)   
{   
   if (isObject(moveMap))   
      moveMap.bindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), "fire", %this);   
         
   %this.owner.setUseMouseEvents(true);   
}   
  
function ShootsBehaviorAdv::onBehaviorRemove(%this)   
{   
   if (isObject(moveMap))   
      moveMap.unbindObj(getWord(%this.fireKey, 0), getWord(%this.fireKey, 1), %this);   
         
   %this.owner.setUseMouseEvents(false);   
}   
  
function ShootsBehaviorAdv::onMouseDown(%this)   
{   
   %this.fire(1);   
}   
  
function ShootsBehaviorAdv::onMouseUp(%this)   
{   
   %this.fire(0);   
}  


function ShootsBehaviorAdv::fire(%this, %val)
{
   //This can be a bit confusing, but it's to ensure that the firing mechanism
   // works as expected, so that the player cannot fire more bullets by tapping the
   // key really fast (the waitSchedule ensures that) - when the wait finishes, it
   // uses the fireCond method to see if the key was pressed again during the wait.
   %this.tryingToFire = %val;
   
   if (%val == 0) 
   {
      cancel(%this.fireSchedule);
      if( !isEventPending(%this.waitSchedule))
         %this.waitSchedule = %this.schedule( %this.fireRate * 1000, "fireCond");
      return;
   }
   
   if (isEventPending(%this.fireSchedule) || isEventPending( %this.waitSchedule))
      return;
   
   if (!isObject(%this.projectile) || !%this.owner.enabled || !%this.owner.getVisible())
      return;
   
   %projectile = %this.projectile.cloneWithBehaviors();
   
   %projectile.setPosition(%this.owner.position);
   %projectile.setRotation(%this.owner.rotation + %this.rotationOffset);
   %projectile.setLinearVelocityPolar(%this.owner.rotation + %this.fireAngleOffset, %this.projectileSpeed);
   alxplay(shoot);
    
   if (!isEventPending(%this.fireSchedule))
      %this.fireSchedule = %this.schedule(%this.fireRate * 1000, "fire", 1);
      
}

function ShootsBehaviorAdv::fireCond(%this)
{
   if( %this.tryingToFire )
      %this.fire( %this.tryingToFire );
      
}