频道栏目
读书频道 > 软件开发 > C# > 精通C#游戏编程
8.1.1 绘制图形
2012-08-01 16:12:16     我来说两句
收藏   我要投稿

本文所属图书 > 精通C#游戏编程

本书通过引导读者创建一个基本的游戏,展示了如何使用c#和OpenGL一步步地开发出简单、整洁而可靠的代码。C#是一种高级编程语言,而OpenGL是业界显示图形最常用的方法。本书概述了创建优秀游戏项目时采用的方法和...  立即去当当网订购

了解cosine和sine的用途的最佳方式是创建一个沙盒程序(sandbox program),在其中可自由尝试各个值。在一个图形上绘制sine和cosine波形的程序是一个不错的起点。下面的游戏状态将绘制两条轴,并绘制一个图形。并不需要创建一个新项目,可以把这个状态添加到已有的代码中,然后将其设置为默认状态。

 

class WaveformGraphState : IGameObject

{

double _xPosition = -100;

double _yPosition = -100;

double _xLength = 200;

double _yLength = 200;

double _sampleSize = 100;

double _frequency = 2;

public delegate double WaveFunction(double value);

 

public WaveformGraphState()

{

Gl.glLineWidth(3);

Gl.glDisable(Gl.GL_TEXTURE_2D);

}

 

public void DrawAxis()

{

Gl.glColor3f(1, 1, 1);

 

Gl.glBegin(Gl.GL_LINES);

{

// X axis

Gl.glVertex2d(_xPosition, _yPosition);

Gl.glVertex2d(_xPosition + _xLength, _yPosition);

// Y axis

Gl.glVertex2d(_xPosition, _yPosition);

Gl.glVertex2d(_xPosition, _yPosition + _yLength);

}

Gl.glEnd();

}

 

 

public void DrawGraph(WaveFunction waveFunction, Color color)

{

double xIncrement = _xLength / _sampleSize;

double previousX = _xPosition;

double previousY = _yPosition + (0.5 * _yLength);

Gl.glColor3f(color.Red, color.Green, color.Blue);

Gl.glBegin(Gl.GL_LINES);

{

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

{

 

// Work out new X and Y positions

double newX = previousX + xIncrement; // Increment one unit on the x

// From 0-1 how far through plotting the graph are we?

double percentDone = (i / _sampleSize);

double percentRadians = percentDone * (Math.PI * _frequency);

 

// Scale the wave value by the half the length

double newY = _yPosition + waveFunction(percentRadians) *

(_yLength / 2);

 

// Ignore the first value because the previous X and Y

// haven't been worked out yet.

if (i > 1)

{

Gl.glVertex2d(previousX, previousY);

Gl.glVertex2d(newX, newY);

}

 

// Store the previous position

previousX = newX;

previousY = newY;

}

}

Gl.glEnd();

} // Empty Update and Render methods omitted

}


成员变量_xPosition、_yPosition、_xLength和_yLength用于定位和描述图的大小。_sampleSize变量决定了图的平滑度。采样大小是指用于绘制图中的线的顶点数。每个顶点的y位置由特定的一个函数决定,例如sine或cosine。_frequency变量用于计算波形震荡的频率,频率越高,震荡次数越多。

默认值描述了一个位于(x:-100,y:-100)、每个轴长200像素的图。得到的图足够大,方便查看,但是DrawGraph函数会认为图的x轴和y轴的范围为0~1。

在成员变量后定义了一个委托。

public delegate double WaveFunction(double value);

图经常被定义为x=x',y=f(x'),其中x'是x的下一个值,普通的x是前一个值。x值通常递增固定的数值,而y值从x值计算得出。WaveFunction委托描述了公式中的f,该函数接受一个double值作为参数,并返回一个double值。这与cosine和sine函数的签名相同。通过使用WaveFunction类型,DrawGraph函数可以接受cosine、sine或其他任意波形函数作为参数,并不需要编写其他代码。

状态的构造函数将线宽设置为3像素,这样就更容易看到图中的线。它还关闭了纹理的状态。如果打开了纹理状态,线看上去可能有点暗,因为它们被错误地赋予了无效的纹理。

DrawGraph函数是游戏状态中最重要的函数,它负责绘制图。DrawGraph使用采样率决定如何分布顶点,使任意一条线都会占据整个图的长度。定义角度有两种常见的方式:度数和弧度。人们都很熟悉度数,知道整个圆周是360?,半个圆周是180?。弧度是使用Pi衡量度数的一种方法,整个圆周是2×Pi,半个圆周是Pi。C#中的Sin和Cos函数接受以弧度表示的角度作为参数,因此,计算y轴的值时,x轴的0~1之间的值会乘以Pi。

DrawGraph函数的内循环从原来的位置计算出新位置,然后绘制一条从原来的位置连接到新位置的线。为了实际演示代码,需要编写一个Render函数来为正弦函数和系弦函数调用DrawGraph。图的输出如图8-1所示。

public void Render()

{

DrawAxis();

DrawGraph(Math.Sin, new Color(1,0,0,1));

DrawGraph(Math.Cos, new Color(0, 0.5f, 0.5f, 1));


DrawGraph函数有两个参数,一个是用于绘制图的函数,另一个是决定图的颜色的颜色值。正弦和余弦是波形,将这两个波形加起来,很容易产生有趣的新波形。通过使用匿名方法,可以创建一个新的波形函数。下面的代码段创建了一个图,将余弦和正弦加起来,并把结果缩小了一半。

DrawGraph(delegate(double value)

{

return (Math.Sin(value) + Math.Cos(value)) *0.5;

}, new Color(0.5f, 0.5f, 1, 1));

尝试运行下面的代码段,然后观察得到的结果。

DrawGraph(delegate(double value)

{

return (Math.Sin(value) + Math.Sin(value + value))*0.5;

}, new Color(0.5f, 0.5f, 1, 1));

这些图看起来很有趣,但如果在游戏中没有应用,它们看上去就有点学术化。接下来,我们就使用这些函数来使精灵动起来。

您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:8.1 三角函数
下一篇:8.1.2 使用三角函数实现特殊效果
相关文章
图文推荐
排行
热门
最新书评
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站