Lesson 10
Lasing Around
In which we gain control of our laser!
We will be controlling our laser via the mouse, and so we want to know where the mouse-pointer is. For this we turn to Panda3D’s set of “watchers”, objects that keep track of certain inputs, the mouse included. And once again, it provides easy access to the mouse-watcher via a variable stored in the ShowBase object, called “mouseWatcherNode”.
So, we get the mouse-position like this:
Next, we want to find out what 3D point our 2D mouse-coordinate corresponds with. Now, a 2D point on an image corresponds not to a single 3D point, but to a line travelling “into” the image. What we want, then, is the point on that line that happens to be at floor-height.
So, first we’ll figure out what that line is by getting a corresponding point on the near-plane of the “camera”, and one on the far-plane of it, by having the camera’s lens calculate them for us.
Then, since we’re playing on a flat, horizontal level, we can make use of a neat convenience function that Panda provides: its “Plane” class can determine where a line, defined by two points, intersects it. That will give us our 3D point.
(Panda3D distinguishes “points” from “vectors”–a matter on which I disagree with whoever made that distinction in the engine. For the most part the “Point” class can be used or ignored as you prefer. However, note that there are a few cases in which Panda will insist on having a “point”, not a “vector” (or vice versa), such as in the code above.)
Finally, now that we have the point that we want, we can use it to direct our ray and orient our character.
To do so, we construct a vector from the player’s position to the point, and take just the horizontal part of it, since we’re not interested in any difference in z-position. From this, we find the angle that it makes with the positive y-axis–this is the angle at which to face our player-character. (This is much like what we did with the “WalkingEnemy”, except that instead of using the vector between the player and the enemy, we’re using the vector between the 3D mouse-point and the player.) Then we set the ray’s origin to the player’s position, and its direction to our vector.
And finally, we store our mouse-pos in “lastMousePos”.
Of course, it’s not fair that the walking enemy can be hit by both us and the traps, but can’t do anything itself. So let’s give it the ability to attack, too…