การเขียนโปรแกรมด้วย PocketC# ตอนที่ 9-Game:II

หลังจากเพื่อน ๆ ได้สนุกกับการสร้าง sprite และเห็นภาพเคลื่อนไหวของเครื่องบินสีฟ้าของเราแล้ว ตอนนี้เราจะมาควบคุมเครื่องบินให้บินไปในทิศทางที่เราต้องการ

You can control your airplane by Stylus or by arrow keys.

วิธีการแรกคือใช้ปากกาจิ้มทิศทางที่ต้องการให้เครื่องบินบินไป เรียกว่าจิ้มที่ไหนบินตามไปถึงนั่น ทำได้ง่าย ๆ ครับ โดยเขียนคำสั่งใน method OnMouseMove() ดังนี้

..

protected override void OnMouseMove(MouseEventArgs e)

{

controlX=e.X;

controlY=e.Y;

}

..

แค่นี้ก็เรียบร้อยแล้วครับ ลองจิ้ม stylus บนหน้าจอดู เครื่องบินของเราก็จะบินไปหาทันทีเลย

อีกวิธีหนึ่งคือใช้ปุ่มทิศทางในการควบคุมเครื่องบินครับ โดยใช้ method OnKeyDown() จับการกดปุ่มว่าเป็นปุ่มขึ้น ลง ซ้าย ขวา แล้วก็กำหนด controlX, controlY ให้ชี้ไปที่ทิศทางตามปุ่มที่กด ลองเขียนโปรแกรมตามนี้ครับ

..

protected override void OnKeyDown(KeyEventArgs e)

{

switch(e.KeyCode)

{

case Keys.Right:

{

controlX=190;

break;

}

case Keys.Left:

{

controlX=0;

break;

}

case Keys.Down:

{

controlY=250;

break;

}

case Keys.Up:

{

controlY=0;

break;

}

}

}

…

นับจำนวนวงเล็บปีกกาให้ดีนะครับ เมื่อ build และ run แล้ว ลองใช้ปุ่มทิศทางควบคุมเครื่องบินของเราดูครับ ง่ายมากใช่ไหมครับ

เพื่อให้เกมของเรามีความน่าสนใจมากขึ้น เราจะสร้าง Background ที่เคลื่อนที่ได้ ซึ่งจะทำให้เครื่องบินสีฟ้าของเราบินไปข้างหน้ายามค่ำคืนผ่านแสงไฟจากบ้านเรือนบนพื้นดินที่เคลื่อนไปทางด้านล่างอย่างสวยงามครับ

You can build moving background in the same way as building moving sprite. Write code to update background before updating sprite. I use Random() to generate random number to locate red light spot into the background.

การสร้าง background ก็ใช้หลักการเดียวกับการสร้าง sprite นั่นเองครับ แต่เป็น sprite ขนาดใหญ่เท่ากับจอภาพเลย แล้วเราก็วาดจุดสีแดงขนาดต่าง ๆ แบบสุ่มลงไป จากนั้น ก็ใช้คำสั่งเลื่อน background ลงด้านล่างเล็กน้อย ก่อนที่จะเอาไปแปะไว้ใน buffer แค่นี้เราก็ได้ background ที่เคลื่อนที่ได้แบบง่าย ๆ แล้วครับ

เริ่มแรกเราต้องประกาศการใช้ Graphics สำหรับใช้วาด background และประกาศ Bitmap สำหรับ background ขนาด 240,320 และต้องประกาศใช้ Random ซึ่งเป็น control สำหรับสร้างตัวเลขสุ่ม เพื่อสุ่มหาตำแหน่งแสงไฟที่จะวาดลงบน background ตามต้องการ ขอให้เพื่อน ๆ เพิ่มคำสั่งลงใน class grx : Form ดังนี้ครับ

…

//Graphics declaration

Graphics grBuffer;

Graphics grBackground;

…

Bitmap background =new Bitmap(240,320);

…

//Random light

Random rand=new Random();

//light position and size

int rndX,rndSize;

…

จากนั้นเราก็เพิ่ม method updateBackground ลงใน method OnTimerTick() เพื่อให้ไปวาด background ก่อน แล้วจึงวาด sprite รูปเครื่องบินของเรา

..

private void OnTimerTick(object sender, EventArgs evArgs)

{

…

spriteY-=3;

updateBackground();

grBuffer.DrawImage(spritePlane,spriteX,spriteY);

…

}

 

private void updateBackground()

{

rndX=rand.Next(240);

rndSize=rand.Next(3);

grBackground=Graphics.FromImage(background);

grBackground.FillRectangle(new SolidBrush(Color.Red),rndX,5,rndSize,rndSize);

grBackground.DrawImage(background,0,2);

grBuffer.DrawImage(background,0,0);

grBackground.Dispose();

}

เพื่อน ๆ ลอง build และ run จะเห็นเครื่องบินของเราบินผ่านพื้นดินยามค่ำคืนไปอย่างราบรื่นครับ โดยคำสั่ง rndX=rand.Next(240); จะหาเลขสุ่มตั้งแต่ 0-240 แล้วใส่ไว้ใน rndX เพื่อนำไปวาดสี่เหลี่ยมสีแดงลงใน background ส่วนคำสั่ง grBackground.DrawImage(background,0,2); จะวาด background โดยเลื่อนลงมาตามแกนY อีก 2 pixels เพื่อให้ background เคลื่อนที่ แล้วจึงแปะ background ของเราลงใน buffer ด้วยคำสั่ง grBuffer.DrawImage(background,0,0);

I use grBackground.DrawImage(background,0,2); to move whole background 2 pixels down to make sense of moving.

อย่างไรก็ดี หากเพื่อน ๆ ช่างสังเกต จะเห็นว่า เครื่องบินสีฟ้าของเรามีกรอบทึบสีดำล้อมรอบอยู่ นั่นคือกรอบของ sprite ซึ่งจะไปบังพื้นดินที่เป็น background ทำให้ขาดความสมจริงลงไป เราสามารถแก้ไขจุดนี้ได้ด้วยการทำให้กรอบ sprite นี้โปร่งใส สามารถมองทะลุลงไปที่ background ได้ครับ

วิธีการคือต้องกำหนด ImageAttributes คือกำหนดสีที่ต้องการให้โปร่งใส เรียกว่ากำหนด ColorKey ซึ่งอยู่ในกลุ่มคำสั่งของ System.Drawing.Imaging จึงต้องเรียกใช้คำสั่งในกลุ่มนี้ก่อน

using System.Drawing.Imaging;

จากนั้นจึงกำหนดการใช้ ImageAttributes ลงใน class grx : Form ดังนี้

class grx : Form

{

…

//transparency

ImageAttributes imgattr=new ImageAttributes();

…

จากนั้นเราก็ set ColorKey โดยใช้สีที่จุดบนซ้ายสุดที่ตำแหน่ง 0,0 ของ spritePlane คือสีดำ เป็นตัวกำหนดให้โปร่งใส และต้องแก้ไขคำสั่ง grBuffer.DrawImage(spritePlane,spriteX,spriteY) โดยเพิ่ม parameter ภายในคำสั่งให้ใช้ ImageAttribute ด้วย เพื่อสั่งว่าเวลาเราแปะภาพเครื่องบินลงใน buffer ให้แปะเฉพาะลำตัวเครื่องบินโดยไม่ต้องแปะกรอบสีดำลงไปด้วยครับ

To make the airplane frame to be transparent. I use ImageAttribute to set ColorKey of the airplane frame and add more parameters to grBuffer.DrawImage(…). These parameters tell grBuffer.DrawImage(..) to draw airplane with transparent ColorKey.

private void OnTimerTick(object sender, EventArgs evArgs)

{

…

updateBackground();

imgattr.SetColorKey(spritePlane.GetPixel(0,0),spritePlane.GetPixel(0,0));

grBuffer.DrawImage(spritePlane,new Rectangle(spriteX,spriteY,60,60,0,0,60,60,GraphicsUnit.Pixel,imgattr);

Invalidate();

grBuffer.Dispose();

}

 

เรียบร้อยแล้วครับ ตอนต่อไป เราจะหาศัตรูมาโจมตีเครื่องบินของเราสักหน่อย เตรียมตัวให้พร้อมนะครับ

Done!! Next time I will create enemy plane to attack you!!!

ขอให้สนุกครับ

[email protected]

20 สิงหาคม 2550

 

 

 

 

 

 

Hosted by www.Geocities.ws

1