GDI图形编程(15)

 

程序清单3-13  采用颜色键来绘制位图

private void Form1_Paint(object sender, PaintEventArgs e)

{

// Create the destination rectangle at double the size of the source 

// rectangle.

Rectangle destRect = new Rectangle(100, 100, myBitmap.Width, myBitmap.Height);

// Create an ImageAttributes object

using (ImageAttributes imgAttributes = new ImageAttributes())

{

// Set the color key to White.

imgAttributes.SetColorKey(Color.White, Color.White);

// Draw the bitmap

e.Graphics.DrawImage(myBitmap, destRect, 0, 0, myBitmap.Width, myBitmap.Height,GraphicsUnit.Pixel, imgAttributes);

}

}

令人不愉快的是,这个版本的DrawImage参数与前面我们已经用过的那些版本的参数不一致,要为源图像提供单独的坐标及尺寸,而不是使用一个源Rectangle对象。除此之外,该函数其他版本中提供的功能,该版本也可以提供,包括对位图的部分复制或者根据需要执行缩放。

3.3.4  位图示例

要实际体验我们这里所讨论的Bitmap的诸多功能,请查看本书配套下载代码中的3_3_Bitmaps示例项目。它会创建两个不同的位图,一个使用基本图形功能,一个使用嵌入资源。然后使用一个颜色键在屏幕上显示图像。

3.4  平滑的动画

本章到目前为止,所有例子都是关于静态图像的。现在,我们来看看如何处理动画以及如何在屏幕上移动图像。我们开始使用移动图像时会面临一些挑战,所以要先解释下可能会碰到的难题,并一一找出解决方案。我们将创建一个简单的例子,该例子中有一个填充了颜色的小块围绕着屏幕进行移动,当碰到屏幕的每个边界时会反弹。我们可以通过将颜色块的当前位置坐标及要移动的方向保存起来(它的速度)实现该功能。

为了得到对象的速度,需要知道它移动的方向及速率。我们可以通过两种简单的方法来描述一个对象的速度:一种是保存该对象的方向(为一个0°~360°的角度)及对象在该方向上的移动速率。第二种方法是保存该对象在每个坐标轴(x轴与y轴)上的速度值。

第一种方法是对运动进行模拟,与物体的实际运动方式接近,它是适合使用的。然而,为了使本例尽量简单,我们将使用第二种方法。即在每次更新时,简单地对物体移动时在x方向的距离及y方向的距离进行跟踪。为了实现对象在碰到屏幕的边缘能进行反弹的效果,可以使对象在某个坐标轴上的速度变为相反的值:如果我们将对象在x轴上的坐标加1,然后碰到了屏幕的右边界,那么接着要将该对象在x轴上的坐标减1,使它再向左移动。减1意味着加–1,所以将x轴上的速度从1修改为–1将使该物体在x坐标轴上的方向发生反转。同样的方法也适用于y轴,图3-15演示了计算过程。

图3-15  颜色块的运动,对x轴和y轴上的速度进行控制

使用程序清单3-14中的代码,可以制作一个简单的弹跳块动画。

程序清单3-14  对颜色块的位置进行更新

// The position of our box

private int xpos, ypos;

// The direction in which our box is moving

private int xadd = 1, yadd = 1;

// The size of our box

private const int boxSize = 50;

/// <summary>

/// Update the position of the box that we are rendering

/// </summary>

private void UpdateScene()

{

// Add the velocity to the box's position

xpos += xadd;

ypos += yadd;

// If the box has reached the left or right edge of the screen,

// reverse its horizontal velocity so that it bounces back into the screen.

if (xpos <= 0) xadd = -xadd;

if (xpos + boxSize >= this.Width) xadd = -xadd;

// If the box has reached the top or bottom edge of the screen,

// reverse its vertical velocity so that it bounces back into the screen.

if (ypos <= 0) yadd = -yadd;

if (ypos + boxSize >= this.Height) yadd = -yadd;

}

这段程序只关心颜色块的移动,所以接下来需要实际进行绘制。该操作基于我们曾经使用过的Graphics对象中的方法,所需代码如程序清单3-15所示。

注:以上内容图略,图片内容请参考原图书

读书导航