正文

游戏数学(18)

精通C#游戏编程 作者:(英)斯库勒


 

8.2.8  关于向量结构的最后一点内容

现在已经完成了一个很不错的、功能完善的向量结构,但是稍加一些处理,还可以使这个结构更加容易使用。首先,可以重写ToString方法,使其输出一些有用的内容。在Visual Studio中使用调试器时,将自动调用ToString方法。重写这个方法后,可以立刻了解向量,而不需要仔细分析向量的定义并查看它可以取的各个值。

public override string ToString()

{

return string.Format("X:{0}, Y:{1}, Z:{2}", X, Y, Z);

}

0向量是一个特殊的向量,它没有单位向量。0向量不代表方向,也没有大小。它有些类似于向量中的null。因此,把它定义为一个常量是很有帮助的。

[StructLayout(LayoutKind.Sequential)]

public struct Vector

{

public static Vector Zero = new Vector(0, 0, 0);

这是所需的全部向量操作。通过这个简单的结构,可以构建并操作一个完整的3D世界。如果现在还不能完全理解向量的所有特性,也不用担心,这是一个熟能生巧的过程。

8.3  二维相交

相交用于判断两个形状何时重叠或相交。在所有的图形编程(包括游戏)中这都很重要。检测鼠标指针是否在一个按钮上就是一种相交测试。在游戏中,检测一个导弹是否击中飞船也是一种相交性测试。2D相交十分简单,可以作为一个不错的起点。

8.3.1  圆

圆通过位置和弧度定义。相交以图形化方式显示最容易理解。接下来就创建一个游戏状态CircleIntersectionState,使其成为默认加载的状态。

class CircleIntersectionState : IGameObject

{

public CircleIntersectionState()

{

Gl.glLineWidth(3);

Gl.glDisable(Gl.GL_TEXTURE_2D);

}

#region IGameObject Members

public void Update(double elapsedTime)

{

}

public void Render()

{

}

#endregion

}

现在状态只是准备好OpenGL,使其可以画线。接下来需要创建Circle类。

public class Circle

{

Vector Position { get; set; }

double Radius { get; set; }

public Circle()

{

Position = Vector.Zero;

Radius = 1;

}

public Circle(Vector position, double radius)

{

Position = position;

Radius = radius;

}

public void Draw()

{

// Determines how round the circle will appear.

int vertexAmount = 10;

double twoPI = 2.0 * Math.PI;

// A line loop connects all the vertices with lines

// The last vertex is connected to the first vertex

// to make a loop.

Gl.glBegin(Gl.GL_LINE_LOOP);

{

for (int i = 0; i <= vertexAmount; i++)

{

double xPos = Position.X + Radius * Math.Cos(i * twoPI /

vertexAmount);

double yPos = Position.Y + Radius * Math.Sin(i * twoPI /

vertexAmount);

Gl.glVertex2d(xPos, yPos);

}

}

Gl.glEnd();

}

}

默认情况下,在原点位置定义一个圆,其半径为1个单位。现在还没有编写绘制圆的代码。绘制圆时,将使用OpenGL的立即模式,即只绘制圆的轮廓。正弦和余弦函数用于确定在什么位置绘制组成圆周的各个顶点。

为了在CircleIntersectionState内测试绘图函数,应在类中添加一个成员_circle。

Circle _circle = new Circle(Vector.Zero, 200);

现在以原点为圆心、创建一个半径为200的圆。为了看到圆,需要修改渲染方法。

public void Render()

{

_circle.Draw();

}


上一章目录下一章

Copyright © 读书网 www.dushu.com 2005-2020, All Rights Reserved.
鄂ICP备15019699号 鄂公网安备 42010302001612号