Archive

Archive for June, 2011

XNA first steps [ เริ่มต้นกับ XNA ]

ช่วงนี้เป็นช่วงที่ผม เรียนเรื่องการเขียนเกมส์ อืม ไม่ได้ความว่าผมจะไปทำเกมส์ขายที่ไหน หรอก ผมทำงานอยู่ในทีมพัฒนาระบบจำลองยุทธ์ และเราก็เล็งเห็นแล้วว่าอีกไม่นาน เทคโนโลยีที่เราใช้กับ ระบบของเรามันกำลังล้าแล้ว เราก็มองหาเทคโนโลยีที่ดีกว่า ใหม่กว่า และยืนยาวกว่า นั่นเอง

พูดแค่นี้ทุกคนก็คงเห็นด้วยเพราะการจะทำระบบอะไรสักอย่าง เงื่อนไขที่ผมกล่าวถือว่าเป็นพื้นฐานแลกที่เราจะมองกัน แล้วค่อยไปพิจาณาเรื่องอื่น ๆ ต่อไป

ครับเอาเป็นว่า ตัวที่ผมสนใจก็คือ XNA
กล่าวโดยย่อนะครับ XNA เป็น Framework ในการพัฒนาเกมส์ที่ผลิตโดย บริษัท Microsoft แน่นอนครับ มันเป็น เทคโนโลยีที่ทำงานบน .NET Framework ซึ่งตัว XNA นั่นประกอบด้วย library และเครื่งมือ ที่จะช่วยให้ผู้พัฒนาเกมส์สามารถทำงานได้รวดเร็ว และสามารถพัฒนาเกมส์ให้สามารถใช้งานได้ บน Windows Xbox 360 รวมถึง Windows Phone 7 ส่วนในรายละเอียดของ XNA ก็ไปอ่านเพิ่มเติมต่อที่นี่ก็แล้วกันนะครับ  http://en.wikipedia.org/wiki/Microsoft_XNA  [ อะไร อะไรก็ wiki นะครับเดี๊ยวนี้ ]

เอาเป็นว่าผมมองตัวนี้ก็เพราะว่า ผมไม่ต้องไปกังวลในเรื่องของการแสดงภาพ เสียง รวมถึงการจัดการกับ input device ต่าง ๆเลย และที่สำคัญ มันทำงานบน development platform ที่ผมใช้งานอยู่แล้ว แค่นี้เป็นอันว่า จบประเด็นข้อเหตุผลในการเลือก

ลองมามองในด้านของ การพัฒนาเกมส์กันบ้างครับ
– เกมส์ programming นั้นจะแตกต่างจากการเขียนโปรแกรม windows  ตามที่เราทราบกันนะครับ การเขียน โปรแกรมบนwindows นั้นเป็นเขียนแบบ event driven หมายถึง code ที่เราเขียน จะอยู่ใน event handler ซึ่งจะถูกเรียกใช้ก็ต่อเมื่อ มีเหตุการณ์อะไรสักอย่างเกิดขึ้น กับ control เช่นการ click mouse เป็นต้น ขี้เกียจ
– เกมส์ programming นั้นเป็น real-time ครับ และก็ไม่มีการรอ event เพื่อการทำงาน  การทำงานจะเป็น loop ที่เราเรียกว่า game loop มีการคำนวณ game status มีการตรวจสอบ input ภายใน loop ในแต่ระรอบของการทำงาน เพราะฉะนั้นการทำงาน programmer จะต้องเขียนโปรแกรมเพื่อ ตรวจสอบ และสั่งการภายใน loop นั่นเองครับ
ดังนั้น typical game loop ประกอบด้วย ขั้นตอน ตามที่แสดงรูปด้านล่าง
จะเห็นว่า loop นั้นเกิดขึ้นใน ส่วนสีเหลือง ซึ่งก็จะมีการรับค่า input คำนวณสถานะต่าง ๆ ของเกมส์ ตรวจสอบ กฎเกณฑ์ต่าง ที่เกมส์กำหนด update ค่า แล้วจึง ให้ feedback กลับไป เช่นการแสดงหล หรือเสียงเป็นต้น ทำอย่างนี้ไปเรื่อย ๆ จนกว่าจะออกจากเกมส์
ส่วน วงรอบเกมส์ของ XNA จะเห็นดังภาพ ครับ


อันที่จริง มันก็ไม่ได้ต่างกัน นัก เพียงแต่ XNA ทำ loop ไว้ให้ โดยทีกำหนดว่า ภายใน update() function ผู้พัฒนาต้อง ตรวจสอบ input คำนวณสถานะ และตรวจสอบ กฎ ต่าง ๆ  และการ feedback ต่าง ๆ ให้ทำใน Draw() function
คงพอได้ concept นะครับ

ลองมาดูการ implement กันบ้างนะครับ

ก่อนที่เราจะทำงาน กับ XNA ได้ก็ต้องมีการ ติดตั้งกันเสียก่อนนะครับ สามารถไป download ได้ที่  http://creators.xna.com/en-US/downloads ตรวจสอบให้ดีนะครับ ท่านควรจะ download version ไหน ขึ้นอยู่กับว่าท่านใช้ visual studio version ไหน ครับซึ่งมันก็หมายถึงท่านใช้ framework version ไหนนั่นเอง 2.0 3.5 หรือ 4.0 ท่าก็เลือก XNA ให้เหมาะสมกับท่าน ได้เลย หลังจากติดตั้งแล้ว ก็มาเริ่มกันเลยนะครับ ( ของผมเองใช้  version 4.0 เพราะผมใช้ visual studio 2010 .Net framework version 4.0  code เป็น C# .net นะครับ)

เริ่มด้วยการ Project ใหม่นะครับ แล้วเลือก Windows Game เราจะพบว่า template ได้มีการสร้าง ไฟล์ให้เรา หลายไฟล์ที่สำคัญก็คือ Game1.cs ซึ่งเป็น file ที่มี game loop และก็ยังมี Content folder ซึ่งมีไว้สำหรับเก็บ พวก resources ต่าง ๆเช่น รูป sprite ที่เราจะใช้งานเป็นต้น

การเพิ่ม หรือ เอารูปที่เตรียมไว้มาใส่ ใน content ก็เพียงแต่ click mouse ขวาที่ content แล้วเลือก “Add/Existing item…” แล้วก็วิ่งไปหา Image file ที่ต้องการ (ship3 คลิก ขวาแล้วเลือก save linke as…)  อ่านตรงนี้ให้ เข้าใจนะครับ เมื่อ เพิ่ม image เข้ามาใน content แล้วลอง click รูปแล้วดู properties จะเห็นว่า มี Asset Name ที่เป็นชื่อของ รูปภาพ ชื่อเหล่านี้จะเก็บไว้สำหรับอ้างอิงในการ เรียกใช้ต่อไป ครับ

สิ่งที่เราต้องการทำใน Project นี้ก็คือการ load ภาพแล้วแสดงในหน้าจอนั่นเอง ครับ ดังนั้นเราก็แค่ ใส่ code ลงใน LoadContent() method เพื่อ load รูป และใส่ code ใน UnloadContent() เพื่อ เอาสิ่งที่ load ออกไป เรายังไม่มีการ ทำอะไรใน Update() เพราะว่าเราแค่แสดงรูปเท่านั้น   และเพื่อแสดงภาพเราก็จะใส code ลงใน Draw() method ตามนี้เลย ครับ

เพื่อให้มันสั้น ผม ลบ comment ออกนะครับ code ที่เราเพิ่มจะอยู่ระหว่าง // — our code #1,2,3,4,5 นะครับ


public class Game1 : Microsoft.Xna.Framework.Game
{
 GraphicsDeviceManager graphics;
 SpriteBatch spriteBatch;
 // -- our code #1 --------------------------
 private Texture2D ship;
 private Vector2 ship_pos;
 // -----------------------------------------
 public Game1()
 {
   graphics = new GraphicsDeviceManager(this);
   // -- our code #2------------------------------
   graphics.PreferredBackBufferHeight = 600;
   graphics.PreferredBackBufferWidth = 800;
   Window.Title = "Game Test ver. 1.0 - Teerapong S.";
   // ------------------------------------------
   Content.RootDirectory = "Content";
 }

 protected override void Initialize()
 {
   // TODO: Add your initialization logic here
   base.Initialize();
 }

 protected override void LoadContent()
 {
   // Create a new SpriteBatch, which can be used to draw textures.
   spriteBatch = new SpriteBatch(GraphicsDevice);

   // TODO: use this.Content to load your game content here
   // --- our code #3 ------------------------------------
    ship = Content.Load<Texture2D>("ship3");  // using asset name นะครับ
  // -----------------------------------------------------

 }

 protected override void UnloadContent()
 {
  // TODO: Unload any non ContentManager content here
  // --- our code #4 ------------
   ship.Dispose();     // free resources, and release memory ไม่มีก็ยังได้
  // -----------------------------
 }

 protected override void Update(GameTime gameTime)
 {
  // Allows the game to exit
  if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  this.Exit();

  // TODO: Add your update logic here
  base.Update(gameTime);
 }

 protected override void Draw(GameTime gameTime)
 {
   GraphicsDevice.Clear(Color.CornflowerBlue);

   // TODO: Add your drawing code here
   // --- our code # 5 ------------------------
   spriteBatch.Begin();
   spriteBatch.Draw(ship, ship_pos, Color.White);
   spriteBatch.End();
   // -----------------------------------------
   base.Draw(gameTime);
 }
}

จะเห็นว่าเราประกาศ ตัวแปร 2 ตัว  ship และ ship_pos นะครับ เป็น Texture2D กับ Vector2 จะยังไม่ขอ พูดอะไรเกี่ยว variable type ครับแล้วเรามีการกำหนด ค่าเริ่มต้น ใน constructor นิดหน่อย เป็นการกำหนด ขนาด windows สำหรับแสดงภาพ  our code #2

ต่อมาใน loadContent เราทำการ load resource ชื่อว่า ship3 ตรวจสอบ asset name ของresources ให้ดีนะครับ ไม่จะเป็นต้องตรงกับชื่อไฟล์ก็ได้ ถ้าหากเราไม่ได้มีการแกไขส่วนใหญ่จะต้องกลับชื่อไฟล์

ใน UnloadContent ใส่ไว้เพื่อ unload resource นั่น ๆ นะครับ ผมเข้าใจว่าอาจไม่ต้อง ก็ได้ ปล่อยให้ framework มันจัดการเอง [ ปกติถ้าเรา เขียน c++ หรือ c ต้องกำจัดให้หมด ]

สุดท้ายเรา draw เพื่อแสดงรูป นะครับ

สังเกตว่าการแสดงผลใด ๆ ก็ตามต้อง อยู่ระหว่าง spriteBatch.Begin() และ spriteBatch.End()

ลอง run ดู จะได้รูปเรือ ขนาดเท่าต้นฉบับบ แสดงอยู่ที่ตำแหน่ง x = 400 , y = 300  ( นับจากมุม บนซ้าย x เป็นแนวนอน y เป็น แนวตั้งนะครับ ,มุมบนซ้าย เป็นตำแหน่ง x = 0 , y = 0 )

พอได้ใหม  ครับ  ในหน้าจอเราก็จะเห็น การแสดงผล เรือ ค้างอยู่ตำแหน่งนั้น ไม่ย้ายไปไหน การแสดงผลที่เห็น ไม่ได้เป็นการสั่งการ ครั้งเดียวนะครับ เป็นสั่งการในรูป เพราะฉะนั้น จะถูกสั่งให้แสดงรูป ทุกรอบ และเร็วมาก ๆ ที่ตำแหน่งเดิม

หากต้องการให้มีการเคลื่อนที่จะต้องทำอย่างไร ลองคิดดูครับ …………………………….. ใช้แล้วเปลี่ยน ค่า ship_pos

Ship_pos instance ของ  class Vector2 เป็นซึ่ง coordinate ในระนาบ 2 มิติ มีแค่ค่า x,y เท่านั้น เพราะฉะนั้นการเคลือน ภาพก็ต้องทำการ บวกหรือ ลบ ค่า X หรือ Y นี่แหละครับ และจะต้องทำภายใน Update() mehtod ตาม code ที่แสดงด้านล่าง นะครับ


protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
// ourcode #6 ----------------------------
KeyboardState keystate = Keyboard.GetState();
//ขึ้นบน
if (keystate.IsKeyDown(Keys.Up))
ship_pos = new Vector2(ship_pos.X, ship_pos.Y - 0.5f);
//ลงล่าง
if (keystate.IsKeyDown(Keys.Down))
ship_pos = new Vector2(ship_pos.X, ship_pos.Y + 0.5f);

// ไปซ้าย
if (keystate.IsKeyDown(Keys.Left))
ship_pos = new Vector2(ship_pos.X - 0.5f , ship_pos.Y );
// ไปขวา
if (keystate.IsKeyDown(Keys.Right))
ship_pos = new Vector2(ship_pos.X + 0.5f, ship_pos.Y );
// ---------------------------------------
base.Update(gameTime);
}

Code มีความหมาย ตาม remark ไว้ไห้

เป็นการตรวจจับ keyboard ว่ามีการ กดปุ่ม หัวลูกศรหรือป่าว และเป็น หัวลูกศรทิศไหน ก็ ดำเนินการกับ ดำแปร ship_pos ในด้านที่ ควรจะเป็น ถ้าไม่เข้าใจ ลอง ร่างหน้าจอใน กระดาษดูนะครับ แล้วจะเข้าใจเอง ขี้เกียจอธิบาย lazy  อะ
เอาดูจากรูป ก็แล้วกัน

ส่วนใคร ไม่เข้าใจการเพิ่มค่า shiop_pos.X และ ship_pos.Y ลองทำแบบนี้แทนก็ได้

Ship_pos.Y -= 0.5f ;

หรือ

Ship_pos.Y = Ship_pos.Y – 0.5f ;

ใครไม่เข้าใจอะไร ก็ลอง mail มาคุยกันก็ได้ หรือ คุยกันผ่านทาง blog ก็ได้

ขอให้สนุกสนานกับการเริ่มต้น กับ XNA  นะครับ

ธีระพงษ สนธยามาลย์

Teerapong Sontayaman

s_teerapong2000@yahoo.com


Categories: C# .NET, game development, XNA Tags:

XNA Game Development [เริ่มต้นกับ XNA]

June 10, 2011 Leave a comment

Categories: game development, XNA

UML for C# programmers [ UML สำหรับ C# โปรแกรมเมอร์ ] ตอน 1

   นี่คงจะเป็น บทความขนาดยาวที่ผมจะลองเขียนอีกสักที เพื่อแบ่งปันประสบการณ์ ให้กับเพื่อนโปรแกรมเมอร์ รวมถึง ขัดเกลาความรู้ให้มันอยู่เป็นระเบียบ หน่อย  ครับ เรื่องของเรื่อง ก็มาจากปัญหา นั่นแหละครับเมื่อใดก็ตามที่ต้องทำงานเป็นทีมไหญ่ การติดต่อสื่อสารเป็นเรื่องสำคัญและมักเป็นปัญหาจาก ขอบเขตเล็ก ๆ ไปสู่ขอบเขตใหญ่ ๆ ได้  ครับ

สิ่งที่เราต้องการพูดถึง ก็คือ การทำงานกับ UML Diagram และสื่อสาร กันระหว่าง นักวิเคราะห์ระบบ กับโปรแกรมเมอ์ (หรือ นักเขียนรหัสโปรแกรม ฮิ ฮิ ตั้งชื่อให้มัน โก้ ๆ ) หลายคน เห็นคำพูดนี้ก็จะร้องว่า เออ ใช่ แล้วไงหล่ะ ก็ นักวิเคราะห์ระบบ วิเคราะห์ เสร็จก็จะเขียน UML diagram เช่น class diagram ซึ่งมันเป็น conceptual level มันไม่ได้ให้ความหมายใด ใด เกี่ยวกับ ข้อมูล หรือโปรแกรม เช่น ตัวอย่าง diagram ข้างล่าง

   ในความหมายทาง OOP ของเรา ก็หมายถึง Dog is animal หรือ หมาเป็นสัตว์ ครับ diagram บอกแค่นี้แหละครับ แต่ในรายละเอียดของ Implementation level นั้น มันจะต้องถอดรหัสออกมา ให้แม่นยำมาก เพื่อให้ได้ตามความหมายที่ต้องการ ในที่นี้ ก็จะได้ออก มาเป็น  ( ท่านควรจะมีพื้นฐาน OOP ก่อน ที่ท่านจะมาอ่านเรื่องนี้นะครับ ขอบอก)

  public class Animal { … }
  public class Dog : Animal { … }

ตาม code อธิบายได้ว่า มี class Animal และ class Dog โดยที่  class Dog สืบทอดมากจาก Animal ก็หมาย ฟามว่า Dog มีคุณสมบัติทุกอยาก รวมถึงพฤติกรรมเหมือน Animal และก็จะต้องคุณสมบัติบางอย่างหรือ พฤติกรรมบางอย่างที่บ่งบอก ว่ามันเป็น Dog ครับ นั่นนะซิ ( เช่น หมาต้องกิน ขี้ หรือป่าว ฮิ ฮิ อันนี้ไร้สาระ แล้ว)

ก็จะสรุปว่า Diagram นั้น มันเป็น conceptual level ครับ มันสามารถเป็นปัญหาใหญ่ได้หาก โปรแกรมเมอร์ ถอดรหัสออกมาเป็น code ได้ไม่ถูกต้อง

ในที่นี้ก็เลยอยากจะ แสดง การถอดรหัส จาก diagram ไปเป็น code ให้เพื่อน ๆ ได้ติดตามอ่าน กันก็แล้วกันครับ

สำหรับ UML diagram ที่เราจะกล่าวถึง ก็จะเป็น ตัวที่เราใช้ในการ วิเคราะห์ระบบ หลัก ๆ สวนที่ไม่ได้กล่าวถึง นั้น ก็ไม่ได้กล่าวถึง ฮิ ฮิ
UML นั้นมีอยู่ 3 กลุ่ม diagrams นะครับ ประกอบด้วย

  • Static diagram อธิบาย โครงสร้างที่มันไม่เป็นแปลงหรือเคลื่อนไหว โดยใช้ class โครงสร้างของข้อมูล รวมถึงความสัมพันธ์ระหว่าง กัน
  • Dynamic diagram อธิบาย การทำงานของ entities ต่าง ๆ ในระหว่างการประมวลผล โดยการแสดงภาพของ flow การประมวลผล
  • Physical diagrams อธิบายโครงสร้างที่ ไม่มีการเปลี่ยนแปลง ในภาพของ sources files  หรือ libraries และความสัมพันธ์ที่เกิดขึ้น ระหว่าง กัน ครับ

ลองมาดูตัวอย่างกันนะครับ ด้านล่างแสดง code การทำ binary trees แบบหนึ่ง ดูให้เข้าใจแล้วค่อยไปดู ไปไล่ดู diagram กันนะครับ

public class TreeMap{
  TreeMapNode topNode = null;
  public void add(Comparable key, Object value)
  {
    If(topNode == null)
      topNode = new TreeMapNode(key, value)
    else
      topNode.add(key,value)
   }

  public Object get(Comparable key)
  {
    return topNode == null ? null : topNode.find(key) ;
  }
}

class TreeMapNode {

  private final static int LESS = 0;
  private final static int GREATER = 1;
  private Comparable itsKey;
  private Object itsValue;
  private TreeMapNode nodes [] = new TreeMapNode[2]

  public TreeMapNode(Comprarable key, Object value)
  {
     itsKey = key;
     itsValue = value;
  }

  public Object find(Comparable key)
  {
     if(key.compareTo(itsKey) == 0) return itsValue;
     return findSubNodeForkey(selectSubNode(key),key);
  }

   public int selectSubNodeForKey(int node, Comparable key) {
     return node[nodes] == null ? null : node[node].find(key) ;
   }

  public void add(Comparable key, Object vlaue)
  {
     if(key.compareTo(itskey) == 0)
        itsValue = value;
     else
        addSubNode(selectSubNode(key),key,value);
   }

   public void addSubNode( int node, Comparable key, Object value){
      if( nodes[node] == null)
         nodes[node] = new TreeMap(key, vlaue);
      else
         nodes[node].add(key,value);
    }
}

เอาละครับ คราวนี้เรามาดูกันที่ diagram ว่าจะเป็น อย่างไรกันบ้าง

Class Diagram

      class diagram จะแสดง class หลัก และความสัมพันธ์ของ class เหล่านั้น ครับ จากตัวอย่างโปรแกรม นะครับ เราจะเห็น ว่ามี class อยู่ 2 class  คือ TreeMap และ TreeMapNode  กล่าวคือ class TreeMap นั้น มีความสัมพันธ์เชื่อมโยง ไปยัง TreeeMapNode ในลักษณะที่ TreeMapNode เป็น member ของ TreeMap  ในตัวแปรที่ชื่อว่า topNode  ในขณะเดียวกัน TreeMapNode ก็ อ้างอิงไปที่ TreeMapNode ก็คือตัวเอง ลองมาดูว่าในลักษณะนี้เราจะเขียน class diagram และ relation ระหว่างกันอย่าไร

จาก Code นั้นก็จะได้อย่าง diagram ที่เห็น ด้านบนนี้ นะครับ จากรูป สิ่งที่เราควรจะทราบก็คือ

  • กล่องสี่เหลี่ยม จะแทน class ชื่อ class จะอยู่ด้านบนสุด ตามด้วย attribute และ method อยู่ล่างสุด
  • ใน diagram relationship ทั้งหมด เป็น association ซึ่งเป็น relation ship แบบง่ายสุด ใช้การสร้างตัวแปล object เพื่อที่จะ อ้างอิง และเรียกใช้ method ของ class ที่ต้องการ
  • ชื่อที่กำกับ association เป็นชื่อ ตัวแปร object ของ class  ที่ต้องการอ้างอิง
  • ตัวเลขที่กำกับ เป็นตัวเลขบอก จำนวน instance ที่ relationship สามารถอ้างอิง ได้

Object diagram

  ภาพด้านล่างเป็นการแสดง Object Diagram และ relation ship ในเวลาใดเวลาหนึ่งของการประมวลผล หรือเราอาจเรียกได้ว่าเป็นการทำ snapshot ของ memory มาแสดง นั่นเอง

จากภาพ รูปสี่เหลี่ยมแทน Object นะครับ จะสังเกตุเห็นว่า เป็น ชื่อ class จะขีดเส้นใต้นะครับ  ซึ่งเป็น class ที่ เป็น object นั้น ๆ ด้านล่างของ object แทน ตัวแปร object ซึ่งจะเห็นว่าบ้างตัวจะถูกกำหนดค่าให้  และ  relation ระหว่าง object เราเรียกว่า link ซึ่งเป็นตัวเดียวกับ association ครับ

Sequence Diagrams

    สำหรับ sequence diagram นั้น จะเป็นการแสดง ว่า method ต่าง ๆ นั้น implement อย่างไร

จากรูปจะเห็น ว่า เริ่มแรกจะต้องมีการ เรียก add() method ของ TreeMap ถ้า topNode มีค่าเป็น null TreeMap จะresponse ด้วย การสร้าง TreeMapNode ใหม่ แล้วกำหนดให้ topNode ถ้า topNode มีค่าไม่เท่ากีบ null TreeMap จะเรียก add() method ของ topNode

นิพจน์ที่อยู่ในวงเล็บ สี่เหลี่ยม เรียกว่า guardห สำหรับการแสดง ทางเลือกกำกับ   และ หัวลูกศรที่จบที่  TreeMapNode icon นั้นแทน construction  และ bar สี่เหลี่ยม ใต้ Treemap เรียกว่า activation ใช้แสดงห้วงเวลาที่ add method ทำงาน

Collaboration Diagram

      Diagram ต่อไปเรียกว่า collaboration Diagram ซึ่งเป็น diagram ที่แสดงข้อมูลคล้ายกันกับ Sequence diagram  กล่าวคือ sequence diagram นั้นเป็นตัวแสดงให้เห็นลำดับการทำงานของ การเรียก message แต่ใน collaboration diagram นั้นจะแสดงให้เห็น ความสัมพันธ์ระหว่าง object ดังรูป

จากรูป object ถูกเชื่อมเข้าด้วยกัน ด้วย สัญลักษณ์ที่เรียกว่า link ดังนั้น link จะเกิดขึ้นได้ก็ต่อเมื่อ object หนึ่งสามารถ ส่ง message ถึง อีก object หนึ่งได้  สัญลักษณ์ หัวลูกศร คู่กับ message จะกำกับอยู่กับ link แสดงให้เห็น ชื่อ message และทิศทางที่เรียก หมายเลข ด้านหน้าและมี dot นั้นแสดงให้เห็น ลำดับของการเรียก เป็นชั้น

จะเห็นว่า TreeMap.add Function (message 1)  เรียก TreeMapNode.add Function (message 1.1)  พูดได้อีกอย่างหนึ่งว่า message 1.1 นั้น เป็น message แรกที่ ที่เรียกจาก message 1 ครับ

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

s_teerapong2000@yahoo.com

Teerapong Sontayaman

ธีระพงษ์ สนธยามาลย์

Categories: C# .NET, OOP