程序清單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);
}
}
令人不愉快的是,這個(gè)版本的DrawImage參數(shù)與前面我們已經(jīng)用過的那些版本的參數(shù)不一致,要為源圖像提供單獨(dú)的坐標(biāo)及尺寸,而不是使用一個(gè)源Rectangle對象。除此之外,該函數(shù)其他版本中提供的功能,該版本也可以提供,包括對位圖的部分復(fù)制或者根據(jù)需要執(zhí)行縮放。
3.3.4 位圖示例
要實(shí)際體驗(yàn)我們這里所討論的Bitmap的諸多功能,請查看本書配套下載代碼中的3_3_Bitmaps示例項(xiàng)目。它會(huì)創(chuàng)建兩個(gè)不同的位圖,一個(gè)使用基本圖形功能,一個(gè)使用嵌入資源。然后使用一個(gè)顏色鍵在屏幕上顯示圖像。
3.4 平滑的動(dòng)畫
本章到目前為止,所有例子都是關(guān)于靜態(tài)圖像的?,F(xiàn)在,我們來看看如何處理動(dòng)畫以及如何在屏幕上移動(dòng)圖像。我們開始使用移動(dòng)圖像時(shí)會(huì)面臨一些挑戰(zhàn),所以要先解釋下可能會(huì)碰到的難題,并一一找出解決方案。我們將創(chuàng)建一個(gè)簡單的例子,該例子中有一個(gè)填充了顏色的小塊圍繞著屏幕進(jìn)行移動(dòng),當(dāng)碰到屏幕的每個(gè)邊界時(shí)會(huì)反彈。我們可以通過將顏色塊的當(dāng)前位置坐標(biāo)及要移動(dòng)的方向保存起來(它的速度)實(shí)現(xiàn)該功能。
為了得到對象的速度,需要知道它移動(dòng)的方向及速率。我們可以通過兩種簡單的方法來描述一個(gè)對象的速度:一種是保存該對象的方向(為一個(gè)0°~360°的角度)及對象在該方向上的移動(dòng)速率。第二種方法是保存該對象在每個(gè)坐標(biāo)軸(x軸與y軸)上的速度值。
第一種方法是對運(yùn)動(dòng)進(jìn)行模擬,與物體的實(shí)際運(yùn)動(dòng)方式接近,它是適合使用的。然而,為了使本例盡量簡單,我們將使用第二種方法。即在每次更新時(shí),簡單地對物體移動(dòng)時(shí)在x方向的距離及y方向的距離進(jìn)行跟蹤。為了實(shí)現(xiàn)對象在碰到屏幕的邊緣能進(jìn)行反彈的效果,可以使對象在某個(gè)坐標(biāo)軸上的速度變?yōu)橄喾吹闹担喝绻覀儗ο笤趚軸上的坐標(biāo)加1,然后碰到了屏幕的右邊界,那么接著要將該對象在x軸上的坐標(biāo)減1,使它再向左移動(dòng)。減1意味著加–1,所以將x軸上的速度從1修改為–1將使該物體在x坐標(biāo)軸上的方向發(fā)生反轉(zhuǎn)。同樣的方法也適用于y軸,圖3-15演示了計(jì)算過程。
圖3-15 顏色塊的運(yùn)動(dòng),對x軸和y軸上的速度進(jìn)行控制
使用程序清單3-14中的代碼,可以制作一個(gè)簡單的彈跳塊動(dòng)畫。
程序清單3-14 對顏色塊的位置進(jìn)行更新
// 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;
}
這段程序只關(guān)心顏色塊的移動(dòng),所以接下來需要實(shí)際進(jìn)行繪制。該操作基于我們曾經(jīng)使用過的Graphics對象中的方法,所需代碼如程序清單3-15所示。
注:以上內(nèi)容圖略,圖片內(nèi)容請參考原圖書