首先需要一個(gè)簡(jiǎn)單的Input類(lèi)來(lái)記錄鼠標(biāo)輸入。
public class Input
{
public Point MousePosition { get; set; }
}
Input類(lèi)將在窗體中初始化和更新。想知道鼠標(biāo)位置的GameStates需要把Input對(duì)象放到自己的構(gòu)造函數(shù)中。現(xiàn)在在窗體類(lèi)中添加一個(gè)Input對(duì)象。
public partial class Form1 : Form
{
Input _input = new Input();
在窗體中需要?jiǎng)?chuàng)建一個(gè)新函數(shù)來(lái)更新輸入類(lèi),該函數(shù)將在每一幀中調(diào)用。
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函數(shù)將光標(biāo)的位置從窗體的坐標(biāo)系轉(zhuǎn)換到控件的坐標(biāo)系。然后將基于OpenGL控件的中心,把光標(biāo)位置轉(zhuǎn)換到OpenGL坐標(biāo)系中。這是將控件的X坐標(biāo)和Y坐標(biāo)減半實(shí)現(xiàn)的?,F(xiàn)在,最終的坐標(biāo)正確地將光標(biāo)的位置從窗體坐標(biāo)映射到OpenGL坐標(biāo)。如果把光標(biāo)放到OpenGL控件的中心,Input類(lèi)將報(bào)告位置(0,0)。
在結(jié)束對(duì)窗體代碼的討論之前,還需要編寫(xiě)最后一項(xiàng)功能:必須把新的輸入對(duì)象添加到圓的狀態(tài)的構(gòu)造函數(shù)中。
_system.AddState("circle_state", new CircleIntersectionState(_input));
還必須修改狀態(tài)的構(gòu)造函數(shù)。
Input _input;
public CircleIntersectionState(Input input)
{
_input = input;
將輸入傳遞給狀態(tài)以后,就可以使用光標(biāo)的位置了。有必要確認(rèn)代碼都在正確工作。最簡(jiǎn)單的方法是,使用OpenGL在光標(biāo)所在的位置繪點(diǎn)。
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();
}
運(yùn)行程序,光標(biāo)總是會(huì)帶著一個(gè)小方塊。注意代碼中添加了一個(gè)glClear命令。試著刪除glClear命令,看看會(huì)發(fā)生什么事情。
現(xiàn)在鼠標(biāo)指針已經(jīng)可以工作,接下來(lái)返回到相交性代碼。狀態(tài)的更新循環(huán)將執(zhí)行相交性測(cè)試。
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函數(shù)的用法,接下來(lái)就實(shí)際編寫(xiě)該函數(shù)。這個(gè)測(cè)試需要使用大量向量操作,所以把指針對(duì)象轉(zhuǎn)換成了一個(gè)向量。
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;
}
運(yùn)行程序,觀察光標(biāo)移入和移出圓時(shí)會(huì)發(fā)生什么情況。