Game Development Community

Solved - Mouse Targeting

by Randy Sewell · in Torque Game Builder · 08/05/2012 (1:37 am) · 6 replies

Hello, I have spent the past 2-3 days trying to create a functioning mouse targeting system for a Platformer prototype I have been working on. I am at the point now where my searches into the forums are providing contradictory and often not quite useful information.

So, my question is, what is the script needed to fire in the direction of the mouse cursor?

player.cs
moveMap.bindCmd(keyboard, "a", "$player.createMissile();", "");
...
function playerClass::createMissile(%this)
{
   %this.playerMissile = new t2dStaticSprite()
   {
      scenegraph = %this.scenegraph;
      class = playerMissile;
   };
   %this.playerMissile.fire();
}

playerMissile.cs
function playerMissile::fire(%this, %worldPosition)    
 {    
   %this.setImageMap(projectile_25ImageMap);    
   %this.setSize(8, 8);
   %this.setLayer(10);
   %this.setCollisionActive( true, true );
   %this.setCollisionPhysics(false, false);
   %this.setCollisionCallback(true);   
   
   //Set the starting position here    
   %playerPositionX = $Player.getPositionX();
   %playerPositionY = $Player.getPositionY();  
   
   %this.setPositionX(%playerpositionX);
   %this.setPositionY(%playerpositionY);  

   %mousePosition = sceneWindow2D.getMousePosition();    
   //Debuging echo command  
   echo("Current position = " @ %mousePosition.x @ " " @ %mousePosition.y);    
      
   %missileSpeed = 300;    
  
  //Compute the angle and speed to launch the missle at  
   %val = %worldPosition.x / mSqrt( mPow(%mousePosition.x,2) + mPow(%playerPositionY - %mousePosition.y,2));  
   %angle = mAcos(%val);  
   %xSpeed = %missileSpeed * mCos(%angle);  
   %ySpeed = %missileSpeed * mSin(%angle);  
  
   %this.setLinearVelocityX(%xSpeed);  
   %this.setLinearVelocityY(%ySpeed);    
    
   // Use the camera view bounds as the basis for the missile's world limits
   %cameraViewBounds = sceneWindow2D.getCurrentCameraArea();
   %this.setWorldLimit( kill, getword(%cameraViewBounds, 0) - (%this.getWidth() / 2),
   getword(%cameraViewBounds, 1) - (%this.getHeight() / 2),
   getword(%cameraViewBounds, 2) + (%this.getWidth() / 2),
   getword(%cameraViewBounds, 3) + (%this.getHeight() / 2) ); 
   
}


Essentially I have gotten to the point where the projectile originates from the ninja, but will only fire down and inaccurately at that.

I have had some success getting him to fire in all directions, but it is always very inaccurate in at least some directions.

Looking through the forums, I see a couple different ways to do it. One of them uses Polar Velocity and AngleBetween, but I can't even tell if that works anymore as all posts are 2005> and there is nothing in the documentation that I can find referring to that.

Anyone have a small snippet of code that could fix my direction & accuracy problems or better yet, a cleaner and more efficient way to mouse target?

#1
08/05/2012 (1:40 am)
Also, does anyone know why ;quot; is placed instead of apostrophes? Is there some plugin I need to install? Happens to me in both Chrome and IE.
#2
08/05/2012 (4:31 am)
So, does mouse position you get match the world position you aiming? Because I would expect t2dSceneWindow::getMousePosition() to return mouse position in the window, and it most likely doesn't match the world position.

Check out t2dSceneObject section of the documentation. The setLinearVelocityPolar() method is actually there, so you can at least try it. And in t2dVectorMath section there are, well, vector math functions you might want to use.
#3
08/05/2012 (6:29 am)
I had tried the setLinearVelocityPolar() but it didn't give very good results. I figured that was because every reference I found with it was from 2005 or earlier. The code I posted was what I got the best results with

setLinearVelocityPolar() does seem like the best option though, assuming I can get it to actually work for me.

Here is what I have now:

function playerMissile::fire(%this)    
 {    
   %this.setImageMap(projectile_25ImageMap);    
   %this.setSize(8, 8);
   %this.setLayer(10);
   %this.setCollisionActive( true, true );
   %this.setCollisionPhysics(false, false);
   %this.setCollisionCallback(true);   
   
   //Set the starting position here    
   %playerPosition = $Player.getPosition();
   %mousePosition = sceneWindow2D.getMousePosition();    
   %shotAngle = t2dAngleBetween(%playerPosition, %mousePosition);      
   
   %this.setPosition(%playerposition);    
   %playerMissile.setLinearVelocityPolar(%shotAngle, 300);
   
  
   // Use the camera view bounds as the basis for the missile's world limits
   %cameraViewBounds = sceneWindow2D.getCurrentCameraArea();
   %this.setWorldLimit( kill, getword(%cameraViewBounds, 0) - (%this.getWidth() / 2),
   getword(%cameraViewBounds, 1) - (%this.getHeight() / 2),
   getword(%cameraViewBounds, 2) + (%this.getWidth() / 2),
   getword(%cameraViewBounds, 3) + (%this.getHeight() / 2) ); 
   
}

The direction it fires is completely off target. Some directions it won't shoot at all, and generally it is shooting 45-180+ degrees off the mouse pointer.

Is there a better way to do the shot angle calculation, or am I missing something else?
#4
08/05/2012 (6:55 am)
You need to use t2dAngleToPoint() instead of t2dAngleBetween() - this last one calculates angle between two vectors, which is not what you feed it.

Basically, try to figure out at which step things break. Try and set fixed %shotAngle to see if it will actually shoot at that angle. Then try fixed %mousePosition and see if it will shoot in the direction of that point...
#5
08/07/2012 (1:06 am)
One of the problems I keep running into with the above code is that it is not applying velocity to the projectile for some reason. It at least fired last night, but today it just sits in space wherever the player was when he fired it.

Any reason why a speed modifier isn't being applied? I have tried multiple methods of applying the speed to the object, but in this format it just won't fire.
#6
08/07/2012 (3:41 am)
Got it! :)

Thank you Rpahut for the angletopoint tip. Definitely evened out the aim.

I used the console heavily to see the exact places where lines of script were having problems and it was extremely useful.

For those of you who don't know, hit ~ in game and it will often give you the lines that are causing you problems so you can focus on those, or at least have a clue where to start.

function playerMissile::fire(%this)      
 {      
   %this.setImageMap(starImageMap);      
   %this.setSize(8, 8);  
   %this.setLayer(10);  
   %this.setCollisionActive( true, true );  
   %this.setCollisionPhysics(false, false);  
   %this.setCollisionCallback(true);     
     
   //Set the starting position here      
   %playerPosition = $Player.getPosition();  
   %mousePosition = sceneWindow2D.getMousePosition();      
   %shotAngle = t2dAngletoPoint(%playerPosition, %mousePosition);        
     
   %this.setPosition(%playerposition);      
   %this.setLinearVelocityPolar(%shotAngle, 300);  
     
    
   // Use the camera view bounds as the basis for the missile's world limits  
   %cameraViewBounds = sceneWindow2D.getCurrentCameraArea();  
   %this.setWorldLimit( kill, getword(%cameraViewBounds, 0) - (%this.getWidth() / 2),  
   getword(%cameraViewBounds, 1) - (%this.getHeight() / 2),  
   getword(%cameraViewBounds, 2) + (%this.getWidth() / 2),  
   getword(%cameraViewBounds, 3) + (%this.getHeight() / 2) );   
     
}