418383: game programming xna content pipeline
DESCRIPTION
418383: Game Programming XNA Content Pipeline. Pramook Khungurn [email protected]. Content. Content = เนื้อหา รูป เพลง เสียง 3D Model แผนที่ ฯลฯ ว่าไปคือสิ่งที่ศิลปินสร้าง อ่านเข้ามาในเกมในเมธอด LoadContent. เป้าหมายของวันนี้. เขียนโปรแกรมให้ - PowerPoint PPT PresentationTRANSCRIPT
418383: Game ProgrammingXNA Content Pipeline
Pramook [email protected]
Content
• Content = เนอหา– รป– เพลง– เสยง– 3D Model– แผนท– ฯลฯ
• วาไปคอสงทศลปนสราง• อานเขามาในเกมในเมธอด LoadContent
เปาหมายของวนน• เขยนโปรแกรมให– เราสามารถประกาศคลาสสำาหรบแทน content ของ
ตนเอง– เราสามารถใส content นนในโฟลเดอร Content ของ
เกมได– เราสามารถอาน content นนดวย
ContentManager.Load ดวย
Content ทเราเคยใช• Texture2D
– whiteTexture = Game.Content.Load<Texture2D>("white");
• SpriteFont– font = Game.Content.Load<SpriteFont>("Vera32");
• โหลดผานเมธอด Load ของคลาสContentManager
XNA Content Pipeline• ขนตอนอาน content เขาสเกม• การจดการ content ใน XNA แบงเปน 4 ขนตอน– การ Import
• อานไฟลทศลปนสราง (.jpg, .png, .3ds, ฯลฯ)– การ Process
• ประมวลผล content ทอานมา• สวนมากใชสำาหรบแปลง content เปนคลาสทใชจรง
– การ Write• เขยน content ทเปนผลลพธของ processor ลงไฟล .xnb
– การ Read• อานไฟล .xnb กอนนำามาใชจรง• ถกเรยกใชตอนสง Content.Load
Content Pipeline FlowBuild Time
Importer
IntermediateObject Model
Processor
RuntimeObject Model
ContentWriter
Run Time
Game
ContentManager
RuntimeObject Model
ContentReader
Original Asset
XNB File
ตวอยาง content• รายละเอยดของตวละครเกม RPG
public class CharacterInfo{ private string name; private int hitPoint; private int strength; private int agility; private int defense; private int magic; : :}
ขอมลทศลปนสรางมาให• ขอมลประเภท XML (merlin.xml)
<?xml version="1.0" encoding="utf-8"?><character> <name>Merlin</name> <strength>33</strenght> <agility>24</agility> <defense>46</defense> <magic>51</magic></character>
Content Pipeline Extension Library (CPEL)
• ไลบรารสำาหรบประมวลผลและเขยน content สำาหรบเนอหาทอยในรปแบบทเรากำาหนดไดเอง
• ใชงานตอนคอมไพลโปรแกรม• เปน project แบบหนงท XNA อนญาตใหเราสราง
ได
ขนตอนการสรางระบบ content ของเราเอง
• สรางเกมไลบรารทมคลาสของ content นน (A)– ไลบรารนควรมคลาสสำาหรบอาน content นนดวย
• สราง CPEL (B)– ม reference ไปยง A– Importer– Processor– Writer
ขนตอนการสรางระบบ content ของเราเอง
• สราง content project (C)– ม reference ไปยงสองไลบรารแรก
• สราง game– ม reference ไปยง A– หามม reference โดยตรงไปยง CPEL– ม content reference ไปยง C
References ระหวางสวนประกอบของโปรแกรม
CharacterInfoLib• CharecterInfo• CharacterInfoReader
CharacterInfoContentPipeline• CharecterInfoImporter• CharacterInfoProcessor• CharacterInfoWriter
CharacterInfoExampleContent• merlin.xml
CharacterInfoExample (game)• Game1
ทำาไมถงตองไมม reference จากเกมไปยงCPEL?
• เวลาแจกจายเกม เราสง XNA Redistribuble ใหกบผใช
• แตโคดทใชพฒนา CPEL ไมไดอยใน XNA Redistributable– มนอยใน XNA Game Studio
• ดงนนถาม reference จากเกมไป CPELเกมจะรนบนเครองผใชไมได
สราง Content Pipeline Extension Library
สราง Importer
สราง Processor
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
ชนดของขอมลทcontent importerอานจากไฟล
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
นามสกลของไฟล content
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
นามสกลของไฟล content
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
ชอของ content importer
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }}
Processor ทจะรบ contentไปประมวลผลตอ
โคด Importer ท XNA สรางให// TODO: replace this with the type you want to import.using TImport = System.String;
namespace CharacterInfoContentPipeline{ [ContentImporter(".abc", DisplayName = "ABC Importer", DefaultProcessor = "AbcProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { // TODO: read the specified file into an instance of the imported type. throw new NotImplementedException(); } }} เมธอดสำาหรบอาน file
โคด Processor ท XNA สรางให// TODO: replace these with the processor input and output types.using TInput = System.String;using TOutput = System.String;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName =
"CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { // TODO: process the input object, and return the modified data. throw new NotImplementedException(); } }}
โคด Processor ท XNA สรางให// TODO: replace these with the processor input and output types.using TInput = System.String;using TOutput = System.String;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName =
"CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { // TODO: process the input object, and return the modified data. throw new NotImplementedException(); } }}
ชนดขอมลท importer สงมา
โคด Processor ท XNA สรางให// TODO: replace these with the processor input and output types.using TInput = System.String;using TOutput = System.String;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName =
"CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { // TODO: process the input object, and return the modified data. throw new NotImplementedException(); } }}
ชนดขอมลท processor สงออก
โคด Processor ท XNA สรางให// TODO: replace these with the processor input and output types.using TInput = System.String;using TOutput = System.String;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName =
"CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { // TODO: process the input object, and return the modified data. throw new NotImplementedException(); } }}
ชอ content processor
โคด Processor ท XNA สรางให// TODO: replace these with the processor input and output types.using TInput = System.String;using TOutput = System.String;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName =
"CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { // TODO: process the input object, and return the modified data. throw new NotImplementedException(); } }} เมธอดสำาหรบประมวลผล content
แกไข Importer ใหอานเอกสาร XMLusing System.Xml;
using TImport = System.Xml.XmlDocument;
namespace CharacterInfoContentPipeline{ [ContentImporter(".xml", DisplayName = "Character Info Importer", DefaultProcessor = "CharacterInfoProcessor")] public class CharacterInfoImporter : ContentImporter<TImport> { public override TImport Import(string filename, ContentImporterContext context) { XmlDocument doc = new XmlDocument(); doc.Load(filename); return doc; } }}
แก Processor ใหแปลงเอกสาร XML เปนCharacterInfo
using TInput = System.Xml.XmlDocument;using TOutput = CharacterInfoLib.CharacterInfo;
namespace CharacterInfoContentPipeline{ [ContentProcessor(DisplayName = "CharacterInfoContentPipeline.CharacterInfoProcessor")] public class CharacterInfoProcessor : ContentProcessor<TInput, TOutput> { public override TOutput Process(TInput input, ContentProcessorContext context) { CharacterInfo charInfo = new CharacterInfo(); XmlElement characterElement = (XmlElement)input.DocumentElement;
charInfo.Name = characterElement["name"].FirstChild.Value; charInfo.Strength = Convert.ToInt32(characterElement["strength"].FirstChild.Value); charInfo.Agility = Convert.ToInt32(characterElement["agility"].FirstChild.Value); charInfo.Defense = Convert.ToInt32(characterElement["defense"].FirstChild.Value); charInfo.Magic = Convert.ToInt32(characterElement["magic"].FirstChild.Value);
return charInfo; } }}
สราง Writer
โคด Writer ท XNA สรางให// TODO: replace this with the type you want to write out.using TWrite = System.String;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { // TODO: write the specified value to the output ContentWriter. throw new NotImplementedException(); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { // TODO: change this to the name of your ContentTypeReader // class which will be used to load this data. return "MyNamespace.MyContentReader, MyGameAssembly"; } }}
โคด Writer ท XNA สรางให// TODO: replace this with the type you want to write out.using TWrite = System.String;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { // TODO: write the specified value to the output ContentWriter. throw new NotImplementedException(); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { // TODO: change this to the name of your ContentTypeReader // class which will be used to load this data. return "MyNamespace.MyContentReader, MyGameAssembly"; } }}
ชนดขอมลทจะเขยน
โคด Writer ท XNA สรางให// TODO: replace this with the type you want to write out.using TWrite = System.String;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { // TODO: write the specified value to the output ContentWriter. throw new NotImplementedException(); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { // TODO: change this to the name of your ContentTypeReader // class which will be used to load this data. return "MyNamespace.MyContentReader, MyGameAssembly"; } }}
เมธอดสำาหรบเขยนขอมล
โคด Writer ท XNA สรางให// TODO: replace this with the type you want to write out.using TWrite = System.String;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { // TODO: write the specified value to the output ContentWriter. throw new NotImplementedException(); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { // TODO: change this to the name of your ContentTypeReader // class which will be used to load this data. return "MyNamespace.MyContentReader, MyGameAssembly"; } }} เมธอดสำาหรบคนชอของ Reader
โคด Writer ท XNA สรางให// TODO: replace this with the type you want to write out.using TWrite = System.String;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { // TODO: write the specified value to the output ContentWriter. throw new NotImplementedException(); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { // TODO: change this to the name of your ContentTypeReader // class which will be used to load this data. return "MyNamespace.MyContentReader, MyGameAssembly"; } }} ชอและ asssemby ของ Reader
แก Writer ใหเขยนขอมลลงไฟล .xnbusing TWrite = SampleLib.CharacterInfo;
namespace CharacterInfoContentPipeline{ [ContentTypeWriter] public class CharacterInfoWriter : ContentTypeWriter<TWrite> { protected override void Write(ContentWriter output, TWrite value) { output.Write(value.Name); output.Write(value.Strength); output.Write(value.Agility); output.Write(value.Defense); output.Write(value.Magic); }
public override string GetRuntimeReader(TargetPlatform targetPlatform) { return "CharacterInfoContentPipeline.CharacterInfoReader,
CharacterInfoContentPipeline"; } }}
สราง Reader• ตองสรางเอง• คลกขวาทชอ Project แลว Add New Item… Class…• ควรอยในไลบรารเดยวกบคลาสทเราตองการอาน
• คลาสทสรางตองเปน subclass ของContentTypeReader< คลาสทคณตองการอาน >
ซงอยใน Microsoft.XNA.Framework.Content
• ตองม method คลาสของคณ Read(
ContentReader input, คลาสของคณ existingInstance);
โครง Readernamespace CharacterInfoContentPipeline{ class CharacterInfoReader : ContentTypeReader<SampleLib.CharacterInfo> { protected override SampleLib.CharacterInfo Read( ContentReader input, SampleLib.CharacterInfo existingInstance) { return null; } }}
แก Reader ใหอานขอมลจากไฟล .xnbnamespace CharacterInfoContentPipeline{ class CharacterInfoReader : ContentTypeReader<SampleLib.CharacterInfo> { protected override SampleLib.CharacterInfo Read( ContentReader input, SampleLib.CharacterInfo existingInstance) { CharacterInfo charInfo = new CharacterInfo();
charInfo.Name = input.ReadString(); charInfo.Strength = input.ReadInt32(); charInfo.Agility = input.ReadInt32(); charInfo.Defense = input.ReadInt32(); charInfo.Magic = input.ReadInt32();
return charInfo; } }}
ContentWriter และ ContentReader
• ใชสำาหรบเขยนขอมลและอานขอมลจากไฟล .xnb• ContentWriter มเมธอด Write ใชเขยนขอมลพน
ฐาน (string, int, long, float, double)• ContentReader มเมธอด ReadXXX สำาหรบอาน
ขอมลพนฐานท ContentWriter เขยน– ReadString, ReadInt32, ReadFloat, ฯลฯ
• เวลาเขยน Content Pipeline ตองทำาใหลำาดบการอานตรงกบลำาดบทเขยน
นำาไปใช• เพม Content Pipeline ทเราสรางเขาใน Reference ของ
Content ในเกมทจะสราง
• นอกจากนใหเพมมนลงใน Reference ของตวเกมเองดวย
นำาไปใช• หลงจากนนให import file content ทศลปนสราง
ให
นำาไปใช• เซต Content Import และ Content Processor
นำาไปใช• โหลด content ดวย Content.Load ในเมธอด
LoadContent
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 merlin = Content.Load<CharacterInfo>("merlin");}
นำาไปใช
XML ใน C#
XML
• Extensible Markup Language• ใชสำาหรบเกบขอมลทมโครงสรางเปนตนไม• ประกอบดวย– tag – ขอมลซงแทรกอยระหวาง tag
Tag
• ขนตนดวย “<“ “และจบดวย >”
• มสามแบบ– Start tag เชน <selection>– End tag เชน </selection>– Empty-element tag เชน <line-break/>
• Start tag กบ end tag จะอยคกน โดย start จะมากอนเสมอ
Tag
• ระหวาง start tag กบ end tag อาจม– ขอความ– tag อนๆ
• ดวยเหตน XML ถงสามารถใชแทนขอมลทโครงสรางเปนตนไมได
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting>
Document Type Declaration (DTD)
• ขอมลเกยวกบรปแบบของตวเอกสารเอง• สวนมากจะบอกวา– ใช XML version อะไร– encoding ทใชในเอกสารคออะไร
• เรมตนดวย <?xml version=• จบดวย ?>
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting>
DTD
Element
• สวนประกอบของเอกสารท– เรมตนจาก start tag แลวจบดวย end tag หรอ– ม empty element tag แคอนเดยว
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting>
element
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting>
element
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting> element
ตวอยาง<?xml version="1.0" encoding="UTF-8" ?><painting> <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/> <caption>This is Raphael's "Foligno" Madonna, painted in <date>1511</date>-<date>1512</date>. </caption></painting> element
Attribute
• คของชอกบคาใน start tag และ empty-element tag
• ตวอยาง<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
ม 2 attributes– src– alt
มอง XML เปนตนไม<text>This text is <b>bold</b>, not italic.</text>
text
“This text is “ b
“bold”
“, not italic.”
XML ใน C#
• ม namespace ชอ System.Xml• คลาสทใชบอย– XmlDocument– XmlElement– XmlNode
XmlDocument
• แทนเอกสาร XML ทงเอกสาร
• public virtual void LoadXml(string sml);– เอาเอกสาร XML ทอยใน string ทใหมาเปนเนอหาของ
XmlDocument ตวน– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<hello>abc</hello>”);
XmlDocument
• public virtual void Save(string filename);– เซฟ XmlDocument ลงในไฟลทมชอตามทกำาหนดให– ตวอยาง
XmlDocument doc = new XmlDocument(); doc.LoadXml(“<hello>abc</hello>”);doc.Save(“sample.xml”);
XmlDocument
• public virtual void Load(string filename);– อานไฟลทมชอตามทกำาหนดให แลวเอาเนอหามาใสใน
XmlDocument– ตวอยาง
XmlDocument doc = new XmlDocument();doc.Load(“sample.xml”);
XmlDocument
• public XmlDocument DocumentElement;– คน root element ของ XmlDocument– Root element คอ element ท element อนอยขางใน
มนทงหมด ( ไมรวม DTD)– ตวอยาง
XmlDocument doc = new XmlDocument(); doc.LoadXml(“<hello>abc</hello>”);XmlDocument root = doc.DocumentElement;
XmlElement
• public string Name;– ชอของ tag ของ element นน– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<hello>abc</hello>”);XmlDocument root = doc.DocumentElement;string name = root.Name; // “ได hello”
XmlNode
• คลาสบรรพบรษของสวนประกอบของเอกสารXML ตางๆ– ขอความ– XmlElement– XmlDocument– XmlAttribute– ฯลฯ
XmlNode
• public XmlNodeType NodeType;– คนชนดของ node มาให– คาทคนมามชนดเปน enum XmlNodeType– คาทเปนไปได เชน XmlNodeType.Text,
XmlNodeType.Element, XmlNodeType.Document
XmlNode
• public XmlNode FirstChild;– ลกตวแรกของ node นน– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<hello>abc</hello>”);XmlDocument root = doc.DocumentElement;XmlNode firstChild = root.FirstChild;
ไดเปน node แบบ text “ทเกบขอความ abc” อย
XmlNode
• public string Value;– ขอความทเปนคาของ node– ใชไดกบ node ประเภท text– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<hello>abc</hello>”);XmlDocument root = doc.DocumentElement;string text = root.FirstChild.Value; // “ได abc”
XmlNode
• public XmlNode this[string name];– เอา element ลกตวแรกทมชอของ tag เทากบ name– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<a><b>1</b><c>2</c><b>3</b></a>”);XmlDocument root = doc.DocumentElement;XmlNode firstB = root[“b”];
ได node ทแทน <b>1</b>
XmlNode
• public XmlNodeList getElementsByTagName( string name);– คนลสตของ element ลกทงหมดทมชอ text เทากบ name– เราสามารถเรยกดลกตวท i ไดโดยการเรยกเมธอด Item(i)– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<a><b>1</b><c>2</c><b>3</b></a>”);XmlDocument root = doc.DocumentElement;XmlNodeList bList = root.getElementsByTagName(“b”);XmlNode b1 = bList.Item(0); // <b>1</b>XmlNode b2 = bList.Item(1); // <b>3</b>
XmlElement
• public string GetAttribute(string name);– คนขอความทเปนคาของ attribute ทมชอตามท
กำาหนด– ตวอยาง
XmlDocument doc = new XmlDocument();doc.LoadXml(“<hello a=“x” b=“y” />”);XmlDocument root = doc.DocumentElement;string aval = root.GetAttribute(“a”);
string bval = root.GetAttribute(“b”);
แผนทสองมต
Tiled
Tiled
• โปรแกรมสำาหรบสรางแผนทสองมตโดยเฉพาะ• ขอด– แบงแผนทออกไดเปนหลาย layer– สามารถสราง object (บรเวรณสเหลยมใชแทน
สงของ) ได– สามารถเซฟแผนทเปนไฟล XML ได
การเซฟแผนทเปน XML
• เลอก Edit Preferences..• เปลยน Store tile layer data as: เปน XML