程序清单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所示。
注:以上内容图略,图片内容请参考原图书