正文

游戲數(shù)學(xué)(22)

精通C#游戲編程 作者:(英)斯庫(kù)勒


 

首先需要一個(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ā)生什么情況。


上一章目錄下一章

Copyright ? 讀書(shū)網(wǎng) ranfinancial.com 2005-2020, All Rights Reserved.
鄂ICP備15019699號(hào) 鄂公網(wǎng)安備 42010302001612號(hào)