首先需要一个简单的Input类来记录鼠标输入。
public class Input
{
public Point MousePosition { get; set; }
}
Input类将在窗体中初始化和更新。想知道鼠标位置的GameStates需要把Input对象放到自己的构造函数中。现在在窗体类中添加一个Input对象。
public partial class Form1 : Form
{
Input _input = new Input();
在窗体中需要创建一个新函数来更新输入类,该函数将在每一帧中调用。
private void UpdateInput()
{
System.Drawing.Point mousePos = Cursor.Position;
mousePos = _openGLControl.PointToClient(mousePos);
// Now use our point definition,
Point adjustedMousePoint = new Point();
adjustedMousePoint.X = (float)mousePos.X - ((float)ClientSize.Width
/ 2);
adjustedMousePoint.Y = ((float)ClientSize.Height / 2)-(float)mouse-
Pos.Y;
_input.MousePosition = adjustedMousePoint;
}
private void GameLoop(double elapsedTime)
{
UpdateInput();
UpdateInput使用PointToClient函数将光标的位置从窗体的坐标系转换到控件的坐标系。然后将基于OpenGL控件的中心,把光标位置转换到OpenGL坐标系中。这是将控件的X坐标和Y坐标减半实现的。现在,最终的坐标正确地将光标的位置从窗体坐标映射到OpenGL坐标。如果把光标放到OpenGL控件的中心,Input类将报告位置(0,0)。
在结束对窗体代码的讨论之前,还需要编写最后一项功能:必须把新的输入对象添加到圆的状态的构造函数中。
_system.AddState("circle_state", new CircleIntersectionState(_input));
还必须修改状态的构造函数。
Input _input;
public CircleIntersectionState(Input input)
{
_input = input;
将输入传递给状态以后,就可以使用光标的位置了。有必要确认代码都在正确工作。最简单的方法是,使用OpenGL在光标所在的位置绘点。
public void Render()
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
_circle.Draw();
// Draw the mouse cursor as a point
Gl.glPointSize(5);
Gl.glBegin(Gl.GL_POINTS);
{
Gl.glVertex2f(_input.MousePosition.X,
_input.MousePosition.Y);
}
Gl.glEnd();
}
运行程序,光标总是会带着一个小方块。注意代码中添加了一个glClear命令。试着删除glClear命令,看看会发生什么事情。
现在鼠标指针已经可以工作,接下来返回到相交性代码。状态的更新循环将执行相交性测试。
public void Update(double elapsedTime)
{
if (_circle.Intersects(_input.MousePosition))
{
_circle.Color = new Color(1, 0, 0, 1);
}
else
{
// If the circle's not intersected turn it back to white.
_circle.Color = new Color(1, 1, 1, 1);
}
}
这是intersect函数的用法,接下来就实际编写该函数。这个测试需要使用大量向量操作,所以把指针对象转换成了一个向量。
public bool Intersects(Point point)
{
// Change point to a vector
Vector vPoint = new Vector(point.X, point.Y, 0);
Vector vFromCircleToPoint = Position - vPoint;
double distance = vFromCircleToPoint.Length();
if (distance > Radius)
{
return false;
}
return true;
}
运行程序,观察光标移入和移出圆时会发生什么情况。