TGB/ScriptTutorials/MouseMovementTutorial
From TDN
Contents |
Introduction
This tutorial is for using mouse movement to control a scene object. In this particular example, we will modify the shooter demo so the ship is mouse-controlled. The ship will not follow the mouse directly (in other words, the ship is not simply a pretty mouse pointer). Instead, we will apply impulses to the ship so it flows smoothly. Note that this requires TGB RC3 or higher to function.
Setup
In order to use the mouse for control, we need to setup the sceneWindow to recognize mouse movement. Open up game.cs inside the shooterDemo project. Add the following inside the startGame function:
Canvas.setContent(mainScreenGui); Canvas.setCursor(DefaultCursor); // Add these two lines Canvas.hideCursor(); sceneWindow2D.setUseWindowMouseEvents(true); moveMap.push();
The Canvas.hideCursor() command hides the mouse pointer, naturally.
The sceneWindow2D.setUseWindowMouseEvents(true) command tells the sceneWindow to pay attention to the mouse.
Moving The Ship
Add the following code to the bottom of game.cs:
function SceneWindow2D::mouseMoveShip(%this, %mod, %worldPosition)
{
%movement = t2dvectorsub(%worldPosition, $lastMousePos);
$pShip.setImpulseForce(%movement);
%this.setMousePosition($pShip.getPosition());
Canvas.hideCursor();
$lastMousePos = $pShip.getPosition();
}
function SceneWindow2D::onMouseMove(%this, %mod, %worldPosition)
{
%this.mouseMoveShip(%mod, %worldPosition);
}
function sceneWindow2D::onMouseDragged(%this, %modifier, %worldPosition, %mouseClicks)
{
%this.mouseMoveShip(%mod, %worldPosition);
}
Let's break apart the mouseMoveShip function. This is simply a helper function that we made up... it is not a TGB default function.
The first line %movement = t2dvectorsub(%worldPosition, $lastMousePos);<b> figures out how much the mouse has moved from its last position, and stores it in the <b>%movement variable.
The second line $pShip.setImpulseForce(%movement); is what actually causes the ship to move. It essentially gives the ship a push in the direction the mouse moved. TGB's physics system handles the rest. Sweet, eh?
The third line %this.setMousePosition($pShip.getPosition()); tells the sceneWindow to position the mouse where the ship is. Without this, the mouse pointer is free to roam away from the ship, and eventually it will leave the window. This really is a hackish way to approach this, but unfortnately mouse binding (which would be better for this case) seems to be broken. For now, this works.
The fourth line Canvas.hideCursor(); hides the mouse pointer, since it seems to reappear all the time, even after we hid it in the startGame function. It turns out that the mouse still flickers a little occasionally. There might be something under the hood to hide the mouse cursor for good, but I don't know what it is.
The fifth line $lastMousePos = $pShip.getPosition(); records the position of the ship, so next time the mouse moves, we will know where the mouse came from. This is actually tied to the player ship. Weird things happen if you just use the mouse position instead of the ship position.
The onMouseMove and onMouseDragged functions are the TGB default functions. They are called whenever either the mouse is moved or dragged. The %mod parameter specifies any modifier keys (like shift, ctrl) that are pressed while the mouse moves. The %worldPosition parameter gives the position of the mouse in world coordinates (not screen or window coordinates).
Now open up player.cs. Scroll down until you find the playerShip spawn function. Add this line in:
updateScores(-$currentScore); // Add this line $lastMousePos = %this.getPosition(); //play ready audio alxPlay( ready1Audio );
This will put something into $lastMousePos before the game starts, so it doesn't do something really weird the first time we move the mouse.
Mouse Shooting
It's at a point now where you can jump in and start controlling the ship with the mouse! There is one thing you might notice, though... you still have to press the space bar to shoot. We can fix that. Go back to game.cs, and add these two functions at the bottom:
function sceneWindow2D::onMouseDown(%this, %mod, %worldPosition, %mouseClicks)
{
$pShip.isFiring();
}
function sceneWindow2D::onMouseUp(%this, %mod, %worldPosition, %mouseClicks)
{
$pShip.notFiring();
}
These are some more mouse event callbacks that are in default TGB. onMouseDown is called whenever the left mouse button is pressed, and onMouseUp is called whenever the left mouse button is released. We don't care about where the event happened, but that information is available if you ever do have a use for it.
Conclusion
Now you know one way of controlling sceneObjects with the mouse. In some ways, using the actionMap bind and bindCmd would be better, but they seem to be broken in RC3. If you ever do find that this has been fixed, say something and I can update this tutorial.
One advantage to the technique in this tutorial over binding is you can still use mouse click events with position attached. So if you have a sceneObject with an onMouseDown callback, you can still click on it to make the callback. This may not be useful for a shooter, but there is some possible creativity to be exploited there.
One disadvantage to this technique is only one mouse is supported. It's rumored that theoretically TGB can support multiple mice, and this method would not allow that. But then again, mouse binding is not working, so multiple mice are not currently supported anyway.
If the ship moves too slow for you, you can adjust the ship's physical properties, like mass, friction, and damping until it moves faster. You may also need to scale the mouse movement or impulse force to push the ship harder.
There are a few little annoyances/glitches with this method as well. I think if you move the mouse very quickly from one place to another, the mouse will leave the window and cause some confusion. This could be fixed by never allowing the mouse to leave the window.
Categories: T2D | TGB | Tutorial



