شروع برنامه نویسی و کدنویسی در محیط XNA
سلام
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
ضربت خوردن و شهادت مولای متقیان، امیر المومنین، علی بن ابی طالب (علیه السلام) را بر عموم دوستان تسلیط میگم.
علی ای همای رحمت تو چه آیتی خدا را ///// که به ماسوا فکندی همه سایهی هما را
دل اگر خداشناسی همه در رخ علی بین ///// به علی شناختم به خدا قسم خدا را
به خدا که در دو عالم اثر از فنا نماند ///// چو علی گرفته باشد سر چشمهی بقا را
مگر ای سحاب رحمت تو بباری ارنه دوزخ ///// به شرار قهر سوزد همه جان ماسوا را
برو ای گدای مسکین در خانهی علی زن ///// که نگین پادشاهی دهد از کرم گدا را
جز از علی که گوید به پسر که قاتل من ///// چو اسیر تست اکنون به اسیر کن مدارا
بجز از علی که آرد پسری ابوالعجائب ///// که علم کند به عالم شهدای کربلا را
چو به دوست عهد بندد ز میان پاکبازان ///// چو علی که میتواند که بسر برد وفا را
نه خدا توانمش خواند نه بشر توانمش گفت ///// متحیرم چه نامم شه ملک لافتی را
بدو چشم خون فشانم هله ای نسیم رحمت ///// که ز کوی او غباری به من آر توتیا را
به امید آن که شاید برسد به خاک پایت ///// چه پیامها سپردم همه سوز دل صبا را
چو تویی قضای گردان به دعای مستمندان ///// که ز جان ما بگردان ره آفت قضا را
چه زنم چونای هردم ز نوای شوق او دم / که لسان غیب خوشتر بنوازد این نوا را
همه شب در این امیدم که نسیم صبحگاهی ///// به پیام آشنائی بنوازد و آشنا را
ز نوای مرغ یا حق بشنو که در دل شب ///// غم دل به دوست گفتن چه خوشست شهریارا
========================================
قرار بود مطالب دیگری برای این پست اختصاص دهم ولی دیدم داریم وارد کد نویسی میشویم ولی هنوز مبانی و متدهای مهم و چگونگی آغاز کدنویسی XNA را توضیح نداده ایم.
کدنویسی در محیط XNA3.1 با وراثتی از کلاس XNA.Game آغاز میشود.
کلاس مذکور متدها و توابعی دارد که میتوان با بازتعریف انها عملیاتهای پایه ای خود را پیاده سازی کرد.
تک تک این پرکاربردترین متدها را در زیر بررسی خواهیم کرد.
==============
سازنده کلاس (در VB.Net با نام New و در C#.Net با نام خود کلاس)
طبیعتاً این اولین متد اجرایی است که دقیقاً بعد از ایجاد کلاس XNA.Game میتوانیم کدهای خودمان را در ان مستقر کنیم.
(پر شدن اشاره گر this در C#.Net و Me در VB.Net)
در این محل هنوز همه اشیا ایجاد نشده و نمیتوان هر کاری کرد و در اصل برای خیلی از دستورات زود است!
ولی معمولاً XNA.Game.Content.RootDirectory در یک پروژه عادی اینجا مقدار دهی میشود و نمونه ای از شی XNA.GraphicsDeviceManager هم برای کارهای اتی ساخته میشود.
(برخی از عملیات های New سازی عادی و مجزا را هم میتوان در این محل یا در متد بعدی انجام داد.)
کد:
//C#.Net
private XNA.GraphicsDeviceManager m_Graphics;
public Game1()
{
this.m_Graphics = new XNA.GraphicsDeviceManager(this);
this.Content.RootDirectory = "Content";
}
'VB.Net
Private m_Graphics As XNA.GraphicsDeviceManager
Public Sub New()
Me.m_Graphics = New XNA.GraphicsDeviceManager(Me)
Me.Content.RootDirectory = "Content"
End Sub
برخی از کاربرهای شی GraphicsDeviceManager را در متد بعدی خواهیم گفت.
XNA.Game.Content.RootDirectory هم پوشه کاری شامل دیتهای xnb برنامه را (در کنار exe یا dll) مشخص میکند.
همانطوری که گفتیم XNA تمام فایلهای دیتا (شامل سوت و تصویر و شی سه بعدی و افکت و فونت و...) را به روش خاص پردازش و همه را به پسوند xnb.* سریالی میکند.
تنظیم مقدار مذکور نام پوشه ریشه حاوی این xnb.* ها را مشخص میکند.
تا در دستورات عادی دیگر ما نیازی نباشد مسیر فایلها را بدهیم و خود XNA بداند فایلها را از کجا میتواند پیدا کند.
(
مثلاً میتوان برای کیفیت و دستگاه مختلف چندین پوشه ریشه Content مانند ایجاد کرد و برای کیفیت تصویری زیاد (پردازش بیشتر و سرعت کمتر) و کیفیت تصویر کمتر (پردازش کمتر و سرعت بیشتر) چندین Content داشت
)
ولی ما در این آموزش همواره یک Content با همین نام "Content" داریم که همینوطری تنظیمش میکنیم (پیش فرض XNA)
==============
متد Initialize :
این متد اولین متد رسمی است که بعد از New اجرا میشود و در این مرحله کارهای بیشتری میتوان انجام داد و تنظیمات خاصی را برای برنامه اعمال کرد.
مثلاً میتوان Resolution مانیتور را تنظیم کرد (پیش فرض XNA برای محیط Windows مقدار 800-600 است)
و یا مشخص کرد که ماوس مرئی باشد یا نه و نیز وضعیت اجرای تمام صفحه را مشخص کرد.
(
هسته DirectX برای تحت کنترلر گرفتن کل صفحه نمایش و اجرای fullscreen بهینه سازی شده و در حالت واقعی حالت fullscreen میتواند بازدهی برنامه شمار ا افزایش دهد.
ولی DirectX مشکلاتی بابت خروج نابهنگام و یکباره از حالت fullscreen پیش می آورد و در این حالت استفاده از فرامینی که پنجره ویندوزی را ظاهر کند باعث مشکل برای برنامه میشود ...
مثلاً وسط حالت fullscreen دکمه Win و یا Alt+Ctrl+Delete و... را بزنید در بازهای رایانه ای دیگر هم میبینید مشکل ایجاد میکند.
این وضعیت برای trace و debug در داخل VS هم وجود دارد و برای debug راحت در VS در حین مراحل طراحی بهتر است fullscreen نباشد.
)
تنظیمات فوق از موارد کاربرهای XNA.GraphicsDeviceManager هستند.
یا در این متد میتوان مشخصات و پارامترهای کلی دوربین و فضای دید را مشخص کرد.
کد:
//C#.Net
private XNA.Matrix m_ProjectionMatrix;
protected override void Initialize()
{
//this.m_Graphics.PreferredBackBufferWidth = 1024;
//this.m_Graphics.PreferredBackBufferHeight = 768;
this.m_Graphics.IsFullScreen = true;
this.m_Graphics.ApplyChanges();
this.Window.Title = "Title";
this.IsMouseVisible = true;
XNA.Matrix.CreatePerspectiveFieldOfView(XNA.MathHelper.PiOver4, (float)this.Window.ClientBounds.Width / (float)this.Window.ClientBounds.Height, 1.0F, 1000.0F, out this.m_ProjectionMatrix);
base.Initialize();
}
'VB.Net
Private m_ProjectionMatrix As XNA.Matrix
Protected Overrides Sub Initialize()
'Me.m_Graphics.PreferredBackBufferWidth = 1024
'Me.m_Graphics.PreferredBackBufferHeight = 768
Me.m_Graphics.IsFullScreen = True
Me.m_Graphics.ApplyChanges()
Me.Window.Title = "Title"
Me.IsMouseVisible = True
XNA.Matrix.CreatePerspectiveFieldOfView(XNA.MathHelper.PiOver4, CSng(Me.Window.ClientBounds.Width) / CSng(Me.Window.ClientBounds.Height), 1.0F, 1000.0F, Me.m_ProjectionMatrix)
MyBase.Initialize()
End Sub
گمانم دستورات فوق واضح هستند.
فقط دستورات ابتدایی تنظیم دوربین باید به این دستورات اضافه شود که در پست مخصوص کنترل دوربین این دستورات بیان خواهد شد و در خصوص ProjectionMatrix و تک تک مقاویر داده شده به CreatePerspectiveFieldOfView هم در همان پست توضیح داده خواهد سد.
==============
متد LoadContent
این متد بعد از فراخوانی Initialize از کلاس base اجرا خواهد شد و همانطور کهع از نامش مشخص است، محل پیشفرض برای بارگذاری Content ها (همان فایلهای xnb.*) داخل اشیای مناسب به داخل برنامه است.
برای بارگذاری دیتاهای فایلی برنامه از متد XNA.Game.Content.Load استفاده میکنیم که Generic است و نوع شی تولیدی و نام فایل xnb.* را میگیرد.
در صورت نیاز میتوان کراهای لازم دیگر را هم انجام داد، مثل تولید XNA.Graphics.SpriteBatch جهت ترسیمات دوبعدی
کد:
//C#.Net
private XNA.Graphics.SpriteBatch m_SpriteBatch;
private XNA.Graphics.SpriteFont m_Font;
private XNA.Graphics.Texture2D m_Image;
private XNA.Graphics.Model m_3DModel;
protected override void LoadContent()
{
this.m_SpriteBatch = new XNA.Graphics.SpriteBatch(this.GraphicsDevice);
this.m_Font = this.Content.Load<XNA.Graphics.SpriteFont>("xnbfontfilename");
this.m_Image = this.Content.Load<XNA.Graphics.Texture2D>("xnbbmpfilename");
this.m_3DModel = this.Content.Load<XNA.Graphics.Model>("xnb3dfilename");
//...
}
'VB.Net
Private m_SpriteBatch As XNA.Graphics.SpriteBatch
Private m_Font As XNA.Graphics.SpriteFont
Private m_Image As XNA.Graphics.Texture2D
Private m_3DModel As XNA.Graphics.Model
Protected Overrides Sub LoadContent()
Me.m_SpriteBatch = new XNA.Graphics.SpriteBatch(Me.GraphicsDevice)
Me.m_Font = Me.Content.Load(Of XNA.Graphics.SpriteFont)("xnbfontfilename")
Me.m_Image = Me.Content.Load(Of XNA.Graphics.Texture2D)("xnbbmpfilename")
Me.m_3DModel = Me.Content.Load(Of XNA.Graphics.Model)("xnb3dfilename")
'...
End Sub
میتوان فایلهای دیتاها در زیر پوشه های Content هم قرار داد و انها را منظم و دسته بندی کرد که در این صورت نام زیر پوشه ها مثل حالت عادی مسیر فایلها با یک اسلش اضافه خواهد شد.
(متدها و نحوه استفاده XNA.Graphics.SpriteBatch در پست ویژه ترسیمات دوبعدی بیان خواهد شد.)
==============
متد UnloadContent
این متد برعکس متد قبلی است و از ان میتوان در پایان برنامه برای آزاد سازی منابع و حافظه و... استفاده کرد.
کد:
//C#.Net
protected override void UnloadContent()
{
//...
this.Content.Unload();
//...
}
'VB.Net
Protected Overrides Sub UnloadContent()
'...
Me.Content.Unload()
'...
End Sub
==============
متد Update
این متد مدام تا انتهای برنامه و قبل از رسم هر فریم اجرا میشود.
باید در این متد دستورات پردازشی مدام خود را مستقر کرد.
مثلاً گرفتن فرامین ورودی کاربر از ماوس و کیبورد و جوی استیک و... و ترتیب اثر دادن به فرامین کاربر ...
در صورت نیاز :
حرکت دوربین و چرخش آن به محل جدبد
حرکت یا چرخش اشیای صجنه به مختصات های جدید
برسی و پردازش برخورد اشیا و انجام عمل و دستور مناسب و...
و...
خلاصه تمام بار پردازش برنامه بر دوش این متد است.
(
اگر شما هر یک از متدهای قبلی را سنگین بنویسید و در آنها دقت کافی نکنید، خیلی ایراد ندارد، چون انها یکبار اجرا میشوند و فوقش برنامه میخواهید 5 ثانیه ای لود شود 6 قانیه ای لود میشود!
ولی این متد و متد بعدی حیاتی هستند.
این متد و متد بعدی مدام توسط XNA در یک حلقه تا تمام شدن برنامه اجرا میشوند و شامل همان بحث بازدهی و حلقه های پنهان میشود.
این دو متد ضمن پیاده سازی تمام نیازها باید تا حد نهایی خود سبک و سریع الاجرا باشد و از هر ترفندی برای افزایش بازدهی و سرعت در انها استفاده کرد.
)
چون این متد بار پردازشی زیادی دارد در جهت شفافیت کدها و لایه بندی و استفاده از قدرت شی گرایی میتوان کد این بخش را در کلاسهای مجزایی شکست و از واسط XNA.IUpdateable هم در انها استفاده کرد و در این متد فقط این کلاسها فراخوانی شوند.
مثلاً ...
یک کلاس مجزا فقط برای کنترلر و گرفتن فرامین کاربر و map کردن انها به فرامین برنامه
یک کلاس مجزای دیگر جهت محاسبه و کنترلر موقعیت دوربین با توجه به شرایط و فرامین کاربر.
یک کلاس دیگر جهت مدیریت و کنترلر کاراکتر اصلی بازی (در بازی های اول شخص که بازیکن یک کاراکتر انسانی یا ماشینی نظیر در محیط بازی دارد.)
و...
=====
این متد آرگومانی از نوع XNA.GameTime هم میگیرد که حاوی اطلاعاتی زمانی بازی است که میتواند معیار حرکت و پردازش قرار بگیرید.
مثلاً شاید نیاز باشد شی ای از نقظه A به B رود ولی این حرکت نباید لحظه ای باشد و نباید در رایانه قوی تر و سریعتر و رایانه ضعیف تر و کندتر فرقی کند، مثل حرکت یک خودرو
در مواردی از این دست میتوان از XNA.GameTime پاس داده شده در پردازش ها استفاده کرد.
کد:
//C#.Net
protected override void Update(XNA.GameTime gametime)
{
var keyboardstate = XNA.Input.Keyboard.GetState();
if (keyboardstate.IsKeyDown(XNA.Input.Keys.Escape))
{
this.Exit();
return;
}
//...
//this.m_InputCommandControl.Update(gametime);
//this.m_CameraControl.Update(gametime);
//this.m_UserPlayerControl.Update(gametime);
//this.m_ComputerPlayerControl.Update(gametime);
//this.m_PhysicControl.Update(gametime);
//...
base.Update(gametime);
}
//VB.Net
Protected Overrides Sub Update(ByVal gametime As XNA.GameTime)
Dim keyboardstate = XNA.Input.Keyboard.GetState()
If (keyboardstate.IsKeyDown(XNA.Input.Keys.Escape)) Then
Me.Exit()
Return
End If
'...
'Me.m_InputCommandControl.Update(gametime)
'Me.m_CameraControl.Update(gametime)
'Me.m_UserPlayerControl.Update(gametime)
'Me.m_ComputerPlayerControl.Update(gametime)
'Me.m_PhysicControl.Update(gametime)
'...
MyBase.Update(gametime)
End Sub
==============
متد Draw
این متد از خیلی از لحاظ شبیه متد قبلی است ولی شما در این متد وظیفه نوشتن دستورات ترسیم برای هر فریم را دارید.
بازدهی هم در این متد بسیار مهم است و باید تمام کنترلرهای دوبعدی و اجزای سه بعدی و زره ای در این متد ترسیم شوند.
برای یک برنامه حقیقی این متد هم میتواند بسیار طولانی و پیچیده شود و اصل نگه دارید کد را کاهش دهد.
نتیجتاً در جهت استفاده از امکانات شی گرایی میتوانید موارد مختلف را یک کلاس مجزا با واسط XNA.IDrawable کنید و هر ترسیم را جدا کنید.
یک کلاس برای کنترلرهای دوبعدی روی صفحه ...
یک کلاس برای کاراکتر سه بعدی بازیکن (برای بازی های اول شخص)
یک کلاس برای رسم زمین و آسمان
و...
هر بخش که دیدید دارد پیچیده میشود یا منطق شی گرایی برنامه تان اقتضا میکند میتوانید یک کلاس دیگر و مجزا کنید.
کد:
protected override void Draw(XNA.GameTime gametime)
{
var graphicsdevice = this.GraphicsDevice;
graphicsdevice.Clear(XNA.Graphics.Color.CornflowerBlue);
//graphicsdevice.RenderState... = ...
//...
//this.m_Ground3D.Draw(gametime);
//this.m_Sky3D.Draw(gametime);
//this.m_UserPlayer3D.Draw(gametime);
//this.m_ComputerPlayer3D.Draw(gametime);
//this.m_UiControl2D.Draw(gametime);
//...
base.Draw(gametime);
}
//VB.Net
Protected Overrides Sub Draw(ByVal gametime As XNA.GameTime)
Dim graphicsdevice = Me.GraphicsDevice
graphicsdevice.Clear(XNA.Graphics.Color.CornflowerBlue)
'graphicsdevice.RenderState... = ...
'...
'Me.m_Ground3D.Draw(gametime)
'Me.m_Sky3D.Draw(gametime)
'Me.m_UserPlayer3D.Draw(gametime)
'Me.m_ComputerPlayer3D.Draw(gametime)
'Me.m_UiControl2D.Draw(gametime)
'...
MyBase.Draw(gametime)
End Sub
==============
کدهای فوق به همراه نمونه کد ساده رسم دوبعدی در قالب پوشه XNAEmpty به نمونه کدهای پک تاپیک افزوده شده.
support.h02.ir/fwlink/?LinkId=1005808167
در سطح pm ، دوستان در خصوص pdf شده مطالب همین تاپیک پرسیده بودند، که متاسفانه و با عرض شرمندگی هنوز حاضر نشده.
تصمیمم بر این است که کلیه مطالب تاپیک را pdf کنم ولی وقت نکردم.
موفق باشید.
ترسیمات دوبعدی شناور روی صفحه (بخش اول)
سلام
تریسمات دوبعدی XNA در واقع محدود به تصویر دوبعدی است.
البته امکان ساده ترسیم متن هم وجود دارد ولی در واقع خود متون هم توسط XNA به تصویر دوبعدی تبدیل شده و به هسته ترسیم ارسال میشوند.
محور مختصات برای ترسیمات دوبعدی هم همانطورکه در مطالب قبلی بیان شد، به صورت شکل زیر است.
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
برای ترسیمات دوبعدی نیاز به تعریف یک نمونه از شی XNA.Graphics.SpriteBatch است.
نمونه سازی این شی میتواند با کدی مثل این و یکبار در شروع برنامه (یعنی متد XNA.Game.Initialize یا XNA.Game.LoadContent) صورت بگیرید.
کد:
//C#.Net
private XNA.Graphics.SpriteBatch m_SpriteBatch;
//...
this.m_SpriteBatch = new XNA.Graphics.SpriteBatch(this.GraphicsDevice);
//...
'VB.Net
Private m_SpriteBatch As XNA.Graphics.SpriteBatch
'...
Me.m_SpriteBatch = new XNA.Graphics.SpriteBatch(Me.GraphicsDevice)
'...
متدهای ترسیمی XNA.Graphics.SpriteBatch طبیعتاً باید در متد XNA.Game.Draw کدنویسی شوند.
- متد Begin
این متد باید اجباراً قبل از انجام هر ترسیم دوبعدی توسط این کلاس و یکبار فراخوانی شود.
- متد End
این متد باید اجباراً پس از انجام همه ترسیمات دوبعدی و در پایان کار ترسیم دوبعدی و یکبار فراخوانی شود.
- متد Draw
این متد وظیفه ترسیم تصاویر دوبعدی را بر عهده دارد.
(همانطور که در پست قبلی بیان شد تصاویر را میتوانید در Content قرار دهید و با کدی که بیان شد بارگذاری کنید)
این متد Overloads های متعدد دارد که در اینجا به اختصار به توضیح هر پارامتر با نامش خواهیم پرداخت:
texture As XNA.Graphics.Texture2D
شی تصویری که باید ترسیم شود.
position As XNA.Vector2
موقعیت دوبعدی نقطه شروع ترسیم در روی صفحه نمایش
sourceRectangle As XNA.Rectangle
محدوده مربعی از فایل تصویر اصلی که باید ترسیم شود، اگر محدوده ای داده نشود کل تصویر ترسیم خواهد شد.
با کمک این پارامتر میتوانید یک تصویر بزرگ داشته باشید که از بخشهای مختلف آن در جاهای متعدد برنامه با دادن مختصاتش استفاده کنید.
color As XNA.Graphics.Color
فیلتر رنگی برای ترسیم که به عنوان نمونه میتوانید تصویر را نیمه شفاف ترسیم کنید.
rotation As Single
یک زاویه چرخش به رادیگان را دوران ترسیم مشخص میکند.
origin As XNA.Vector2
یک نقطه مختصات مبنا برای ترسیم مشخص میکند.
scale As XNA.Vector2
یک عدد تناسب برای هر بعد ترسیم مشخص میکنند.
(
در واقع همان بزرگنمایی و Zoom است که به درصد و یک صدم الفاظ گفتاری انسانی است (!)
مثلاً عدد 0/75 یعنی همان 75% خودمان که باعث کوچک شدن تصویر میشود
)
- متد DrawString
این متد وظیفه ترسیم متون یا همان نوشته و String را بر عهده دارد.
البته اگر نوشته هایی در برنامه شما ثابت و فیکس و همیشگی هستند شاید بد نباشد که آنها را به تصویر png تبدیل کنید و با همان متد Draw ترسیمش کنید.
(این متد و ترسیم متون در پست بعدی بررسی خواهد شد.)
برای کد نمونه و سمپل همانطور که در پست قبلی بیان شد:
نقل قول:
نوشته شده توسط _H2
کدهای فوق به همراه نمونه کد ساده رسم دوبعدی در قالب پوشه XNAEmpty به نمونه کدهای پک تاپیک افزوده شده.
support.h02.ir/fwlink/?LinkId=1005808167
==============
ترسیمات دوبعدی به کمک ghnet.xna.dll
چندنکته در استفاده از ghnet.xna.dll
1) کلاس اصلی شما به جای وراثت از XNA.Game باید از GHNet.Xna.Engine وراثت بگیرد.
2) در جهت سرعت بیشتر مستقیماً اکثر خود فیلدهای کلاسها در dll مذکور Public و در دسترس هستند و برای خواندن از انها Property-Get و لایه اضافه ای وجود دارد تا سرعت به حداکثر ممکن برسد ولی برای تغییر این فیلد ها باید از متد های SetXXXXX استفاده کنید.
(این عمل کدنویسی مطمئنی نیست و توصیه نمیشود و عامل خطای انسانی را به شدت افزایش میدهد ولی اول انکه قصد نداشتم dll مذکور باعث افت سرعت شود و دوم هم اصلاً قصد انتشار عمومی dll مذکور را نداشتم.)
کد اشتباه در استفاده از ghnet.xna.dll
کد:
//C#.Net
var obj = new GHNet.Xna.AAA...CCC();
obj.FieldName = x;
var value = obj.FieldName;
'VB.Net
Dim obj As New GHNet.Xna.AAA...CCC()
obj.FieldName = x
Dim value = obj.FieldName
کد صحیح در استفاده از ghnet.xna.dll
کد:
//C#.Net
var obj = new GHNet.Xna.AAA...CCC();
obj.SetFieldName(x);
var value = obj.FieldName;
'VB.Net
Dim obj As New GHNet.Xna.AAA...CCC()
obj.SetFieldName(x)
Dim value = obj.FieldName
=====
در ghnet.xna.dll مکانیزمی بسیار شبیه خود دات نت در مدیریت فرمهای ویندوزی پیاده سازی شده.
شما میتوانید مثل طراحی فرمها کنترلرهای متعدد دو بعدی روی برنامه داشته باشید که وراثتی از GHNet.Xna.Drawable2D هستند.
کافی است کنترلر را بسازید و خصیصه ها را Set کنید و رویدادهای مورد نیاز را هندلر کنید و در نهایت ان را به مجموعه Objects اضافه کنید.
کلاس GHNet.Xna.Drawable2D خصیصه های تنظیمی فراوانی دارد و حتی مدیریت رویدادگرایی ماوس را هم دارد.
در ضمن امکان تغییر تصویر پسضمینه با توجه به وضعیت ماوس را هم دارد (غیر فعال-فعال-ماوس روی کنترلر-ماوس فشرده شده)
مثلاً برای داشتن یک دکمه دو با قابلیت کلیک و کدنویسی برای زمان کلیک میتوان همچین دستوراتی نوشت:
کد:
//C#.Net
//...
var c = new GHNet.Xna.Drawable2D();
c.SetBackgroundTexture(this.Content.Load<XNA.Graphics.Texture2D>("image4"));
c.SetMultiTextureMode(GHNet.Xna.UI.MultiTextureMode.Horizontal4);
c.SetBounds(200, 250, 50, 50);
c.Click += this.Button_Click;
this.Objects.Add(c);
//...
private void Button_Click(object sender, EventArgs e)
{
//...
}
'VB.Net
'...
Dim c As New GHNet.Xna.Drawable2D
c.SetBackgroundTexture(MyBase.Content.Load(Of XNA.Graphics.Texture2D)("image4"))
c.SetMultiTextureMode(GHNet.Xna.UI.MultiTextureMode.Horizontal4)
c.SetBounds(200, 250, 50, 50)
AddHandler c.Click, New EventHandler(AddressOf Me.Button_Click)
Me.Objects.Add(c)
'...
Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs)
'...
End Sub
خط اول) کنترلر را میسازد.
خط دوم) تصویر را از Content بارگذاری و تحویل میدهد.
خط سوم) اجازه تغییر پس ضمینه را با 4 تکه کرد افقی تصویر میدهد. (به سمپل دانلودی دقت کنید.)
خط چهارم موقعیت و ابعاد کنترلر را تایین میکند.
خط پنجم) رویداد کلیک را هندلر میکند
خط شش) کنترلر را به Objects اضافه میکند
=====
در نهایت برای ترسیم اشیای دوبعدی داخل Objects باید متد (Draw2D(gameTime در داخل متد Draw اصلی کلاس اضافه شود.
پروژه نمونه در همان پک support.h02.ir/fwlink/?LinkId=1005808167 موجود است.
==============
نقل قول:
نوشته شده توسط L u K e !
فکر نمی کنم اینجا کسی با Vb.net xna کار کنه
من مثل شما مطمئن نیستم.
اول آنکه خود من پروه سه بعدی را قبول کردم که با XNA انجام دادم و با تاکید و سفارش مشتری که سورس VB.Net میخواست من هم برایش با VB.Net نوشتم.
دوم انکه (همانطور که احتمالاً متوجه شدید) دوستان و همکاران VB.Net کار همچنان در این تالار و انجمن حضور فعال دارند.
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
همین تاپیک:
نقل قول:
نوشته شده توسط _H2
کاملاً برای استفاده در دات نت مجهز و آماده و یک دست است ولی برای سایر زبانها و محیطهای غیر دات نتی قابل استفاده نیست
نقل قول:
نوشته شده توسط L u K e !
خوب Xna مخصوص C# هست و در VB کاربرد چندانی ندارد
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
همین تاپیک:
نقل قول:
نوشته شده توسط _H2_
گرچه به ظاهر زبان کاری XNA زبان C#.Net است ولی جالب است که اگر جستجو کنید حتی سایتهایی پیدا میکنید که در خصوص طراحی بازی با XNA تحت Delphi.Net آموزش داده اند!
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
همین تاپیک:
نقل قول:
نوشته شده توسط _H2_
در واقع XNA خیلی شبیه خود Framework است، چیز عجیب غریبی نیست!
یک مجموعه از کلاسهای آماده است که حدودا (و کیلویی !) یک سوم Framework2.0 میشود به پروزه شما Reference میشوند و شما میتوانید از آن کلاسها و متدها استفاده کنید.
نقل قول:
نوشته شده توسط L u K e !
یه چیز دیگه بدون Content چطوری می شه Spritefont یا Model یا ... رو Load کرد ؟
اگر منظورتان در VB.Net است این مسئله کامل در
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
بررسی شده و پک فوق العاده کوچکی معرفی شده که این مشکل را در VB.Net بکل حل میکند.
و حتی اگر VB.Netر ا نصب داشته و سمپلهای این تاپیک را باز کرده باشید، متوجه میشدید که پروژه های VB.Net این تاپیک حاوی Content کامل و عین C#.Net هستند.
یک نسخه کامل پروژه تبدیل شده به VB.Net هم در پست 15 موجود است (تبدیل شده با همین سایتهای معمولی تبدیل کد)
نقل قول:
نوشته شده توسط L u K e !
اگه می شه یکم در مورد این حلقه هایی که زیاد اجرا می شن بگین ، چطورین ؟
گمانم توضیحات کافی بوده؟؟؟
این مطالب در پست های 20 تا 30 بررسی شده اند.
باز هم چشم، کوتاه به عنوان نمونه و مثال عرض میکنم:
نمونه های متدهای اجرای مکرر در خود XNA میتواند متدهای Update و Draw باشد که تا اخر برنامه مدام اجرا خواهند شد.
نمونه های حلقه های پنهانی سایر کدها هم میتواند دسترسی به عناصر داخل یک Collection-Dictionary باشد که معمولاً کلیدی داده شده و Collection در داخل خود حلقه را اغاز میکند تا عنصر نظیر ان کلید را پیدا کند.
پست 20 -> سرعت و بازدهی کدهای مختلف 1 -> رابطه خصاصت و تنبلی و تعریف متغییر !
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
=====
سعی میکنم پست بعدی در خصوص ترسیم متون را هر چه سریعتر (تا حد امکان در دو الی سه روز اینده) حاضر کنم و این بحث را بسته و به سراغ فضای سه بعدی و کنترلر دوربین برویم.
موفق باشید.
ترسیمات دوبعدی متن (بخش دوم و پایانی)
سلام
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
فرا رسیدن ایام سوگواری، شهادت سالار شهیدان حضرت ابا عبدا... الحسین (علیه السلام) را به دوستان خودم تسلیط عرض میکنم.
باز این چه شورش است که در خلق عالم است /// باز این چه نوحه و چه عزا و چه ماتماست
باز این چه رستخیز عظیم است کز زمین /// بی نفخ صور خاسته تا عرش اعظماست
... (محتشم کاشانی)
خودمانیم، این پست های من هم همش می افتد وسط یک مناسبتی!!!
==============
فونت در XNA:
برای ترسیم متون و نوشته ها طبق عادت ویندوزی نیاز به Font است.
ولی Font در XNA تفاوتهای پیاده سازی با انچه قبلاً دیده بودید دارد.
برای اضافه کردن فونت و استفاده از فونت های رایانه شما باید یک فایل spritefont.* به پروژه تان اضافه کنید.
برای ان کار آیتم Content را SolutionExplorer انتخاب کرده و فرامین زیر را دنبال کنید:
Project->Add New Item->Sprite Font
فایلی که خواهید دید یک XML است که در واقع نام و مشخصات فونت دلخواه شما باید در ان درج شود.
چیزی شبیه این:
کد:
<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">
<FontName>Kootenay</FontName>
<Size>14</Size>
<Spacing>0</Spacing>
<UseKerning>true</UseKerning>
<Style>Regular</Style>
<CharacterRegions>
<CharacterRegion>
<Start>& # 3 2 ;</Start>
<End>& # 1 2 6 ;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
(فاصله (Space) بین اعداد را حذف کنید. بدون فاصله اینجا خراب نشان داده میشد.)
[[[
(اختیاری)
اجازه دهید کمی بیشتر در مورد ساختار داخلی پردازش فونت ها در XNA بدانیم ...
Pipline مربوط به SpriteFont در XNA در واقع از این XML فقط به عنوان تنظیمات استفاده میکند و xnb.* نهایی کاملاً متفاوتی میسازد.
در زمان کامپایل و با توجه به مشخصاتی که در XML تان درج کرده اید XNA پردازشی حلقه ای را شروع میکند و یک تصویر png مانند بزرگ تولید میکند که همه کاراکترهای مورد نیاز فونت مورد نظر شما در روی آن رسم شده اند ...
یک تصویر که پر است از حروف الفبا و علائم و نشانه ها ...
و در واقع این تصویر است که به xnb.* نهایی تبدیل شده و به پروژه شما اضافه میشود.
و در واقع در زمان ترسیم XNA می آید و محل کاراکتر به کاراکتر String شما را در این تصویر طبق یک جدول Sort شده و سریع به دست اورده و یک دستور ترسیم تصویر روی صفحه برای همان یک کاراکتر و در محلهای مشخص فایل تصویر فونت و صفحه نمایش اجرا میکند و بعد کاراکتر بعد ...
این الگوریتم چندین پیامد منطقی دارد:
]]]
1) مثل برنامه های عادی ویندوزی و وبی نیاز به وجود فایل فونت در مقصد نیست و در واقع فایل فونت شما همان xnb.* است که همراه exe تان قرار دارد، نتیجتاً میتوانید با خیال راحت و بدون نگرانی از هر فونتی که دوست دارید استفاده کنید.
2) فونت های شما در هر سیستم Windows و XBox و Zune با بالاترین تضمین و بدون نگرانی کار خواهد کرد.
3) فونت و سایز و حتی محدوده کاراکتری مورد نیازی که قصد استفاده از آن را دارید باید در زمان کامپایل مشخص باشد ولی میتوانید به تعداد دلخواه spritefont.* داشته باشید.
=====
مطلب مهم دیگری که وجود دارد ان است که اگر قرار است متن همواره ثابت و مشخصی را در محیط سه بعدی خود استفاده کنید که تغییری ندارد، از نظر بازدهی و سرعت و حتی گرافیک بهتر است متن مورد نظر را خود به وسیله برنامه های کمکی مثل Paint.Net یا Photoshop و... به فایل تصویر شفاف با فرمت png تبدیل کنید و سپس به جای دستور ترسیم متن، در کدها دستور ترسیم تصویر را در مختصات مورد نظر بدهید.
این کار هم خیلی مطمئن تر است و میتوانید به سادگی به متن سایه و سایر افکت ها را بدهد و هم سرعت و بازدهی ترسیم هم بیشتر خواهد بود.
=====
و اما کد ...
برای رسم باز هم نیاز به یک SpriteBatch و استفاده از متد DrawString وجود دارد.
متد DrawString:
یکی از ساده ترین Overload های این متد چهار پارامتر میگیرد.
spriteFont As XNA.Graphics.SpriteFont
که همان شی فونت بارگذاری شده است.
text As String
که متنی است که باید نمایش داده شود.
position As XNA.Vector2
محل نمایش متن است
color As XNA.Graphics.Color
رنگ متن است.
طبق معمول برای بارگذاری xnb.* ها از Content میتوانید در متد LoadContent عمل کنید و در متد Draw هم ترسیم مورد نظر را انجام دهید:
کد:
//C#.Net
private XNA.Graphics.SpriteBatch m_SpriteBatch;
private XNA.Graphics.SpriteFont m_Font;
protected override void LoadContent()
{
this.m_SpriteBatch = new XNA.Graphics.SpriteBatch(this.GraphicsDevice);
//...
this.m_Font = this.Content.Load<XNA.Graphics.SpriteFont>("xnbfontfilename");
//...
}
protected override void Draw(XNA.GameTime gametime)
{
var graphicsdevice = this.GraphicsDevice;
graphicsdevice.Clear(XNA.Graphics.Color.CornflowerBlue);
//...
this.m_SpriteBatch.Begin();
this.m_SpriteBatch.DrawString(this.m_Font, "Microsoft XNA Game Studio 3.1", XNA.Vector2.Zero, XNA.Graphics.Color.Red);
this.m_SpriteBatch.End();
//...
base.Draw(gametime);
}
'VB.Net
Private m_SpriteBatch As XNA.Graphics.SpriteBatch
Private m_Font As XNA.Graphics.SpriteFont
Protected Overrides Sub LoadContent()
Me.m_SpriteBatch = New XNA.Graphics.SpriteBatch(Me.GraphicsDevice)
'...
Me.m_Font = Me.Content.Load(Of XNA.Graphics.SpriteFont)("xnbfontfilename")
'...
End Sub
Protected Overrides Sub Draw(ByVal gametime As XNA.GameTime)
Dim graphicsdevice = Me.GraphicsDevice
graphicsdevice.Clear(XNA.Graphics.Color.CornflowerBlue)
'...
Me.m_SpriteBatch.Begin()
Me.m_SpriteBatch.DrawString(Me.m_Font, "Microsoft XNA Game Studio 3.1", XNA.Vector2.Zero, XNA.Graphics.Color.Red)
Me.m_SpriteBatch.End()
'...
MyBase.Draw(gametime)
End Sub
این کد فایل فونت xnbfontfilename.spritefont را بارگذاری کرده و متن "Microsoft XNA Game Studio 3.1" در مختصات صفر و صفر ترسیم میکند.
=====
ترسیم متن با کمک GHNet.Xna.dll:
کد:
//C#.Net
protected override void LoadContent()
{
this.Drawable2DRoot.SetFont(this.Content.Load<XNA.Graphics.SpriteFont>("xnbfontfilename"));
//----------
var a = new GHNet.Xna.Drawable2D();
a.SetText("مهدی 14");
//a.SetBounds(0, 0, 200, 200); //محل و ابعاده مستطیل محدوده نمایش
//a.SetEnabledRightToLeftPersianText(true); //فعال سازی پشتیبانی از راست به چپ فارسی
//a.SetTextAlign(GHNet.Xna.Graphics.ContentAlignment.TopLeft); //تراز 9 جهته نمایش متن در مستطیل مشخص شده
//a.SetForeColor(XNA.Graphics.Color.Red); //رنگ متن
this.Objects.Add(a);
}
protected override void Draw(XNA.GameTime gameTime)
{
this.GraphicsDevice.Clear(XNA.Graphics.Color.CornflowerBlue);
base.Draw2D(gameTime);
base.Draw(gameTime);
}
'VB.Net
Protected Overrides Sub LoadContent()
MyBase.Drawable2DRoot.SetFont(MyBase.Content.Load(Of XNA.Graphics.SpriteFont)("xnbfontfilename"))
'--------------
Dim a As New GHNet.Xna.Drawable2D
a.SetText("مهدی 14")
'a.SetBounds(0, 0, 200, 200) 'محل و ابعاده مستطیل محدوده نمایش
'a.SetEnabledRightToLeftPersianText(True) 'فعال سازی پشتیبانی از راست به چپ فارسی
'a.SetTextAlign(GHNet.Xna.Graphics.ContentAlignment.TopLeft) 'تراز 9 جهته نمایش متن در مستطیل مشخص شده
'a.SetForeColor(XNA.Graphics.Color.Red) 'رنگ متن
MyBase.Objects.Add(a)
End Sub
Protected Overrides Sub Draw(ByVal gameTime As XNA.GameTime)
Me.GraphicsDevice.Clear(XNA.Graphics.Color.CornflowerBlue)
Me.Draw2D(gameTime)
MyBase.Draw(gameTime)
End Sub
=====
ترسیم متون فارسی و RightToLeft:
همانطور که گفته شد سعی کنید تا حد امکان برای متون ثابت از تصاویر png استفاده میکنید. متاسفانه XNA3.1 جاری از ترسیم Runtime اعداد و متن فارسی RightToLeft پشتیبانی نمیکند.
ولی جای نگرانی هم وجود دارد. میتوان با کدنویسی این قابلیت را اضافه کرد.
تابعی در GHNet.Xna.dll و در مسیر GHNet.Text.PersianText.GetDrawablePersianText وجود دارد که قابلیت مذکور را ارائه خواهد کرد.
شما میتوانید بدون استفاده از سایر امکانات این dll فقط با همین یک تابع مشکل نمایش متون Runtime فارسی را حل کنید.
قبل از بررسی کد لازم است فایل spritefont.* مجاز را برای ترسیم کلیه حروف استاندارد زبان فارسی بررسی کنیم.
همانطور که میدانید بخش CharacterRegion در XML این فایل محدوده کاراکترهای مورد نیاز را ثبت میکند که باید کاراکترهای فارسی را به آن اضافه کرد.
یک فایل spritefont.* صحیح با پشتیبانی هم کاراکترهای استاندارد انگلیسی و هم فارسی میتواند چیزی شبیه این باشد:
کد:
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">
<FontName>Tahoma</FontName>
<Size>14</Size>
<Spacing>0</Spacing>
<UseKerning>true</UseKerning>
<Style>Regular</Style>
<CharacterRegions>
<CharacterRegion>
<Start>& # 3 2 ;</Start>
<End>& # 1 2 6 ;</End>
</CharacterRegion>
<CharacterRegion>
<Start>& # 1 6 3 2 ;</Start>
<End>& # 1 6 4 2 ;</End>
</CharacterRegion>
<CharacterRegion>
<Start>& # 6 4 3 4 2 ;</Start>
<End>& # 6 4 3 4 5 ;</End>
</CharacterRegion>
<CharacterRegion>
<Start>& # 6 4 3 7 8 ;</Start>
<End>& # 6 4 4 0 5 ;</End>
</CharacterRegion>
<CharacterRegion>
<Start>& # 6 5 1 5 3 ;</Start>
<End>& # 6 5 2 6 8 ;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
(فاصله (Space) بین اعداد را حذف کنید. بدون فاصله اینجا خراب نشان داده میشد.)
که چهار بخش قسمت پر رنگ آخر، حروف و کاراکترهای فارسی را طبق استاندارد جهانی Unicode اضافه میکند.
(البته میتوان فاصله بین 64345 تا 64378 که حدود 33 کاراکتر است به هم چسباند و یک تکه کرد کار را ساده تر میکند ولی فایل .*xnb نهایی را کمی حجیم تر میکند.)
اما کد لازم:
استفاده از تابع GHNet.Text.PersianText.GetDrawablePersianText خیلی ساده است.
همانطور که گفته شد برای ترسیم عادی یک متن میتوان از کدی شبیه این استفاده کرد:
کد:
//C#.Net
string text = "Microsoft XNA Game Studio 3.1";
this.m_SpriteBatch.DrawString(this.m_Font, txt, new XNA.Vector2(5, 5), XNA.Graphics.Color.Red);
'VB.Net
Dim text As String = "Microsoft XNA Game Studio 3.1"
Me.m_SpriteBatch.DrawString(Me.m_Font, txt, New XNA.Vector2(5, 5), XNA.Graphics.Color.Red)
حالا برای ترسیم حروف و متون مخلوط فارسی و انگلیسی بعد از اضافه کردن Reference فایل GHNet.Xna.dll کدی مثل این کافی است:
کد:
//C#.Net
string text = GHNet.Text.PersianText.GetDrawablePersianText("برنامه نویسی با XNA نسخه 3", true);
this.m_SpriteBatch.DrawString(this.m_Font, txt, new XNA.Vector2(5, 5), XNA.Graphics.Color.Red);
'VB.Net
Dim text As String = GHNet.Text.PersianText.GetDrawablePersianText("برنامه نویسی با XNA نسخه 3", True)
Me.m_SpriteBatch.DrawString(Me.m_Font, txt, New XNA.Vector2(5, 5), XNA.Graphics.Color.Red)
که نتیجه این کد نمایش متن "برنامه نویسی با XNA نسخه 3" خواهد بود.
(میتوان برای بازدهی بیشتر خروجی این تابع را هم کش کرد)
البته اگر کسی بخواهد از امکانات کامل GHNet.Xna.dll و کلاسهای GHNet.Xna.Engine و GHNet.Xna.Drawable2D و... استفاده کند، برای پشتیبانی فارسی و RightToLeft فقط کافی است EnabledRightToLeftPersianText لایه مورد نظر را True کند.
(خود کلاس Drawable2D برای بازدهی بیشتر کش را انجام میدهد)
کد:
//C#.Net
layervariant.SetEnabledRightToLeftPersianText(true);
//VB.Net
layervariant.SetEnabledRightToLeftPersianText(True)
کد نمونه مرتبط با مباحث این پست را میتوانید در پک مختص این آموزش پیدا کنید:
support.h02.ir/fwlink/?LinkId=1005808167
==============
از دوستان و سروران عزیز خودم در سایت واقعاً عضر خواهی میکنم که تکمیل تاپیک زمان بر شده است. :11:
متاسفانه حجم کار شخصی ام زیاد است و تهیه این مطالب هم به وقت خالی یک تکه ای نیاز دارد تا بتوان پیوستگی مطالب را تضمین کرد.
انشاا... با صبر دوستان تاپیک همچنان ادامه دارد.
جمیعاً موفق و پیروز و سربلند باشید.
ارائه یک سمپل سه بعدی ساده - Ship
سلام
فعلاً و بدون توضیحات یک سمپل بسیار ساده نمایش شی سه بعدی طراحی شده در 3DS-MAX را به پک مخصوص تاپیک اضافه کردم.
خیلی ساده است ولی امیدوارم مفید باشد.
این سمپل در قالب چهار پروژه ارائه شده است.
دو سمپل با VB.Net و دو سمپل با C#.Net
دو سمپل با ghnet.xna.dll و دو سمپل بدون آن.
که در نهایت میشود چهار پروژه نمونه برای یک کار ثابت.
(Ship_CS و Ship_VB و Ship_GHNet_CS و Ship_GHNet_VB)
خروجی دیداری هر چهار پروژه دقیق مثل یکدیگر است، یک ناوچه جنگی طراحی شده با 3DS-MAX است که در برنامه و از محور وسط (حول محور Y) با سرعت یک دور در شش ثانیه میچرخد.
در پوشه یا دایرکتوری _EXE_ میتوانید نسخه های کامپایل شده و exe سمپل ها را پیدا کنید.
(((
لینک دانلود معرفی شده در پست اول: (حجم تا این پست و فعلاً 2MB)
support.h02.ir/fwlink/?LinkId=1005808167
)))
روز خوش.
:10:
Sample های XNA Game Studio
سلام دوستان خسته نباشید.
چند تا Sample براتون آپ کردم ای شالله مورد استفاده قرار بگیره.
کار با سایه و نور:
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
دانلود:
کد:
http://up.--------.com/Files/0aa39943af3845e3b457.zip
ُُکار با Sample آب:
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
دانلود:
کد:
http://up.--------.com/Files/44128684155f4fc99859.zip
بدون شرح !!!:
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
دانلود:
کد:
http://up.--------.com/Files/238a001f02594203a7ce.zip
موفق باشید و سربلند:11:.
کنترل دوربین در فضای سه بعدی (بخش اول)
سلام
در محیط DirectX و XNA کنترل کاملی روی دوربین خواهید داشت ولی نباید انتظار شیء خاصی برای دوربین را داشته باشید!
در واقع کل دوربین با تمام پارامترهایش فقط یک ماتریس عادی است.
روی مقادیر و چگونگی ایجاد این ماتریس صحبت خواهیم کرد.
------
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مفهوم دوربین حداقل بر سه بردار اصلی در فضای سه بعدی استوار است.
(یادآوری: هر بردار، سه عدد مشخص x, y, z دارد و مانند یک پیکان نوک تیز در فضای سه بعدی است.)
این سه بردار (9 عدد) همان مقادیری هستند که شما برای حرکت در محیط بازی آنها را به کرات تغییر خواهید داد.
(
بجز سه بردار فوق چند پارامتر تأثیر گذار دیگر هم وجود دارد که معمولا فقط یکبار در شروع برنامه تنظیم و اجرا میشوند.
)
سه بردار دوربین:
1) بردار مکان
این در واقع موقعیت خود دوربین را در فضای سه بعدی مشخص میکند.
مثلا وقت راه رفتن کاراکتر اول شخص، شما این بردار را تغییر میدهید تا دوربین در مکان جدیدی مستقر شود.
(شروع پیکان مبدا مختصات و نوک آن محل دوربین است.)
2) هدف دید
این بردار سمت و جهت دید را مشخص میکند.
(
که برابر است با جمع بردار مکان با بردار جهت دید.
در شرایط و الگوریتم های مختلف گاهاً به جای بردار هدف از بردار جهت استفاده میشود که با توجه به نحوه کنترل دوربین در بازی شاید یکی از این دو ساده تر باشد و اختلاف انها هم فقط در یک جمع و تفریق ساده با بردار مکان خود دوربین است.
فعلاً بدانید که بردار مهم دوم، مکان هدف را مشخص میکند.
)
مثلا وقتی کاراکتر اول شخص شما ایستاده و سرش را به اطراف میچرخاند، این بردار را تغییر میدهید.
(شروع پیکان، صفر مختصات است و پایان پیکان محل هدفی است که دوربین به ان سمت نشانه وری شده است)
3) بردار نرمال
بیشتر اشیا در فضای سه بعدی بردار نرمالی دارند که سمت بالا را مشخص میکند و به نوعی مکان هندسی شی را ثابت میکند.
این بردار در دوریین هم سمت بالا را مشخص میکند.
(شروع پیکان، محل دوربین است و جهت آن سمت بالای دوربین+تصویر را مشخص میکند.)
مثلا شما میتوانید در نقطه باشید و به مکان ثابتی هم نگاه کنید....
ولی در مکان نقطه میتوانید به همان مکان هدف، سروته نگاه کنید! مثل زمانی که روی دستهایتان ایستاده اید!س
یا در بازیهای هواپیمایی وقتی گردش میکند و کل صحنه را کج می بینید، این بردار تغییر میکند.
-----
فعلا امیدوارم حداقل در ذهنتان بتوانید این سه بردار و تاثیر آنها را بر حرکت دوربین و تصویری که کاربر روی مانیتور میبینید درک کرده باشید.
سعی کنید حالات مختلف گردش در محیط سه بعدی و بازی را تصور کنید و در هر مورد ببینید چه بردارهایی باید تغییر کنند.
ساخت ماتریس دوربین:
ماتریس دوربین شی نهایی مشخص کنند دوربین است که از ادقام این سه بردار با تابع CreateLookAt ایجاد میشود:
کد:
//C#.Net
XNA.Vector3 vPosition = ...;
XNA.Vector3 vTarget = ...;
XNA.Vector3 vUp = ...;
XNA.Matrix cameramatrix = XNA.Matrix.CreateLookAt(vPosition, vTarget, vUp);
'VB.Net
Dim vPosition As XNA.Vector3 = ...
Dim vTarget As XNA.Vector3 = ...
Dim vUp As XNA.Vector3 = ...
Dim cameramatrix As XNA.Matrix = XNA.Matrix.CreateLookAt(vPosition, vTarget, vUp)
برای اعمال و استفاده از این ماتریس باید آن را قبل از رندر همه اشیا، تک به تک به خصیصه View شی های (BasicEffect یا مشتقات) آن بدهید.
بدیهی است هر شی که BasicEffect آن تنظیم نشود در رندر این ماترسیس روی آن اثری ندارد.
مثلا در حالت عادی برای رسم یک شی ممکن است همچین کدی نوشته شود:
کد:
//C#.Net
var mesh = model.Meshes[0];
foreach (XNA.Graphics.BasicEffect effect in mesh.Effects)
{
effect.World = modelmatrix; //ماتریس موقعیت (مکان+دوران+نسبت) خود شی
effect.View = cameramatrix; //ماتریس دوربین
}
mesh.Draw();
'VB.Net
Dim mesh = Me.m_Model.Meshes(0)
For Each effect As XNA.Graphics.BasicEffect In mesh.Effects
effect.World = modelmatrix 'ماتریس موقعیت (مکان+دوران+نسبت) خود شی
effect.View = cameramatrix 'ماتریس دوربین
Next
mesh.Draw()
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
اگر دقت کنید متوجه خواهید شد که ماتریس دوربین در این پروزه ثابت است و یکبار در شروع برنامه در متد Initialize مقداردهی شده است.
(((((
گردش کشتی در این پروژه ناشی از دوران ماتریس modelmatrix خودش (خود کشتی) در متد Update است.
یک سوال! میتوانید هم اسمش را تمرین بگذارید!!!
سعی کنید در پروژه Ship ماتریس modelmatrix را ثابت کنید (در واقع خود شی را ثابت کنید) و به جای آن دوربین، (یا همان ماتریس cameramatrix را) طوری در متد Update اصلاح کنید که دوربین دور کشتی یا همان ناو بچرخد؟؟؟
با انجام و یا حداقل سعی در انجام این کار ساده، خیلی خوب با توابع ریاضی و درک فضای سه بعدی درگیر خواهید شد و میتواند شروع خوبی برای درک دوربین باشد.
بعد هم به راحتی میتوانید دوربین را در جهت دیگری گردش دهید یا کنترل آن را به دست کیبورد یا ماوس بسپارید و...
اگر به فرض این کار را صحیح انجام دهید، نباید در اجرای برنامه تفاوتی حاصل شود.
چرا؟
چون فقط یک شی (همان ناو یا کشتی) در صحنه وجود دارد و دوران آن حول خودش با چرخیدن دوربین دورش تفاوتی از دید ناظر پشت لنز ایجاد نمیکند.
ولی اگر یک شی دیگر به صحنه اضافه شود (:46:) آنگاه تفاوت چرخیدن یک شی دور خودش با چرخیدن دوربین دور محیط مشخص میشود.
)))))
=====
در پست های بعدی باید دقیق تر به این مسئله بپردازیم و کمی هم درمورد الگوریتم های خاص کنترل دوربین در بازی یا برنامه های اول شخص ، سوم شخص و هواپیمایی صحبت کنیم.
هر کدام از این سه الگوریتم و کنترل خاصی را بر دوربین دارند.
موفق باشید.
:10:
آموزش های جدید Xna + آموزش های تصویری
سلام دوستان:11:.
تاپیکمون یکم خاک گرفته بود گفتم یه گردگیری کنم:10:.
آموزش های این پست همه انگلیسی هستند.
دوتا کتاب آموزش Xna به انگلیسی:
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
دانلود:
کد:
http://mediafire.com/?4129b0fqgef49i1
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
دانلود:
کد:
http://mediafire.com/?vb7fus3ml1h595u
آموزش های تصویری XNA Game Studio:
1.معرفی:
کد:
http://snip.ms/dwxna01
2.ایجاد پروژه ها لینک کردن XNA و XSI:
کد:
http://snip.ms/dwxna02
3.ایجاد یک مدل ساده:
کد:
http://snip.ms/dwxna03
4.نمایش مدل ساده در XNA:
کد:
http://snip.ms/dwxna04
5.تکسچر برای XNA:
کد:
http://snip.ms/dwxna05
6.کار با Bridge (ساخت مدل برای قسمت 6)
کد:
http://snip.ms/dwxna06b
6.2.آموزش Rigging, Weighting, and Animating:
کد:
http://snip.ms/dwxna06
7.ساخت بازی:
کد:
http://snip.ms/dwxna07
8.ساخت آهنگ:
کد:
http://snip.ms/dwxna08
9.صدا در XNA با استفاده از XACT:
کد:
http://snip.ms/dwxna09
Gathering Input from Guitar Controller.10:
کد:
http://snip.ms/dwxna10
Programming Input / Final Code Walkthrough.11:
کد:
http://snip.ms/dwxna11
12.برنامه نویسی برای XBox 360:
کد:
http://snip.ms/dwxna12
یه سری آموزش در مورد XNA دارم دانلود میکنم که حدود 2 گیگ میشه.
تموم که شد براتون آپلود میکنم:46:.
دوستان در صورت فیلتر بودن لینک های مدیا فایر یک cdn به اول سایت اضافه کنید.
مثلاً:
کد:
http://cdn.mediafire.com/?4129b0fqgef49i1
التماس دعا.
موفق باشید.
زمین و عوارض (پستی و بلندی) آن
سلام
میلاد حضرت مهدی (ع) را خدمت دوستان تبریک عرض میکنم.
می باید در این پست در مورد ادامه "کنترل دوربین" صحبت میکردم (البته خیلی هم بیربط نیست) ولی دوستی چند روز قبل سوالی پرسید که با توجه به تعطیلی موجود تصمیم گرفتم بجای یک پاسخ کوتاه،مطلب کامل تری در غالب یک پست تهیه و بصورت عمومی ارائه دهم.
==============
شاید لزومی به گفتن نداشته باشد که کارت گرافیک و DirectX مسئول ترسیم اشکال شما هستند و این کد شما است که باید اشیا را درست چیدمان کنید تا برخورد تشخیص داده شده و اشیا در هم فرو نروند.
روش مورد بحث در اینجا ساده و موثر است.
برای پیاده سازی ارتفاعات میتوان از یک فایل تصویری سیاه/سفید استفاده کرد.
با این روش ساده میتوان عوارض زمین را تشخیص داد و حتی ترسیم کرد.
میتوانید کاربر اول شخص را مجبور کرد روی زمین حرکت کند و نتواند از شیب زیاد یا دیوار رد شود و...
(((
البته برای ساخت یک شهر با ساختمان و... برای عوارض زمین تکنیک زیر مناسب است ولی شاید نیاز شود ساختمان ها خود هویت مستقل داشته باشند.
)))
در این روش زمین به قطعات کوچک مربعی شکسته میشود و رنگ هر پیکسل در عکس مذکور نشانگر ارتفاع زمین در نقطه معادل است.
برای سادگی و عدم ارتباط با فرمت فایلها معمولا از تصاویر Raw (خام و بی فرمت)
تصاویر Raw بدون هدر میباشند و مستقیما در برنامه با خواندن بایتها قابل استفاده هستند.
نمونه کد مبحث جاری پروژه Ground از همان اینک دانلود قبل دردسترس است،البته اینبار تحت XNA4
در مثال فوق با توجه به داشتن ارتفاع هرنقطه، میتوان حداکثر شیب سعود را مشخص کرد و یا حداکثر تفاوت ارتفاعی که کاراکتر میتواند بپیماید.
اگر کد را دانلود کنید،در نمونه برنامه مورد بحث چند ثابت تاثیر گذار داریم که مختصراً توضیح میدهم
HEIGHTMIN
فاصله ارتفاع کاراکتر بازی را مشخص میکند، بالاخره چه کاراکتر ما یک انسان و چه یک خودرو باشد، کف زمین و روی ارتفاع صفر حرکت نمیکند و یک فاصله ثابت و معقولی به دلیل ارتفاع خودش از زمین دارد که عدد مذکور همین مقدار را مشخص میکند.
MOVESTEP
سرعت حرکت و پیمایش کاراکتر در جلو و عقب رفتن را مشخص میکند که هرچه بیشتر باشد کاراکتر سریعتر حرکت میکند.
ANGLESTEP
زاویه چرخش کاراکتر در حرکت چپ و راست را مشخص میکند که هرچه بیشتر باشد کاراکتر سریعتر گردش میکند.
MOVEHEIGHTMAX
همان فاصله حداکثر تفاوت ارتفاعی است که کاراکتر میتواند از آن بالا برود.
یعنی هر اختلاف ارتفاعی که بیش از این مقدار باشد کاراکتر نخواهد توانست از آن بالا برود.
افزایش این عدد موجب میشود کاراکتر بتواند از هر پستی و بلندی بالا برود.
GROUNDHEGHTMAX
حداکثر ارتفاع زمین است.
یعنی ارتفاع هر نقطه زمین بسته به فایل عکس ذکر شده بین صفر تا این عدد متغییر خواهد بود.
افزایش این عدد موجب مرتفع تر شدن عوارض زمین خواهد شد.
DEFAULTGROUNDFILE
نام فایل raw زمین را مشخص میکند که چندتایی برای دیدن و آزمایش در برنامه قرار دارد و میتوانید امتحان کنید.
برای درک بهتر مطلب، مثلاً اگر آواتار من فایل زمین باشد(!) زمین همچین شکلی خواهیم داشت!
یا تصویر سایه سفید زیر، زمین و ساختمانی می سازد که در زیر میبینید.
این هم زمین تولید شده آن:
البته من فرصت کافی برای تنظیم تصویر (تکسچر) مناسب نداشتم، ضمن اینکه اگر نخواهیم تصویر روکش شده یکنواخت باشد، کمی کدنویسی میخواهد، در نتیجه پروژه را میتوانید در حالت رندر سیمی آزمایش کنید و در چند زمین بازی موجود حرکت کنید و به توقف دوربین در رسیدن به شیب زیاد یا دیوار و... دقت کنید.
(((
البته میتوان فایل زمین را هم مثل هر شی دیگر در برنامه های مدل سازی قوی ای مثل 3DSMAX تولید کرد و در برنامه مصرف کرد که بحث مجزایی میطلبد.
)))
فایل CGround.cs مسئول ساخت زمین و ترسیم و... است و متدی دارد که میگوید هر نقطه زمین چه اتفاعی دارد.
فایل CCamera.cs حاوی توابع لازم برای حرکت و چرخش و کلاً کنترل دوربین است.
در خصوص ساخت زمین بازی از فایل عکس هم توضیح کوتاهی میدهم.
ما به ازای هر پیکسل در تصویر مرجع یک راس ایجاد میکنیم و x و y و z آن را ست میکنیم و نتیجه نهایی کل راس ها را در m_VB میریزیم.
سپس (میدانیم که اصول دنیای سه بعدی بر اساس مثلث ها بنا شده است) در حلقه دیگری چگونگی ترتیب قرار گیری راس های قبلی را طوری که مدام مثلث های کوچکی بسازند تایین میکنیم و در m_IB میریزیم.
(((
با این تکنیک Index یک راس را که شاید عضو چندین مثلث دورش باشد، چند بار تکرار نخواهیم کرد و فقط به ایندکس آن ارجاع میدهیم تا دنباله ای از مثلث ها ایجاد شود.
این کار به نوعی ایجاد یک شی سه بعدی در زمان اجرا است.
)))
کدی که در تابع Update قرار دارد باعث میشود دوربین (یا همان کاراکتر ما) روی زمین جاری بماند و در دیوار هم فرو نرود.
بنظرم بقیه کد واضح است و توضیح خاصی نمیخواهد.
http://support.h02.ir/fwlink/?LinkId=1005808167
موفق باشید.
سرعت و بازدهی کد در ایجاد کلاس ها
بنام خدا..
سلام دوستان خسته نباشید...:10:.
یه مبحثی رو من بعد چند وقت تجربه برنامه نویسی متوجه شدم...چون خیلی وقت پیش(یعنی حدود 6 ماه) دیزاین پترن ها رو خونده بودم الان یادم نمیاد که این بحثی که میخوام بگم رو توی دیزاین پترن ها توضیح داده اند یا خیر...
من میگم اگه که گفتن چه خوب اگه هم که نگفتن چه بهتر....:31:
نمیدونم اسمشو چی بذارم ولی شما از تیتر موضوع باید همه چیز رو متوجه شده باشید.
خوب من یک کد به شما میدم و شما اون رو تست میکنید ان شاءالله و متوجه بحث سرعت و بازدهی خواهید شد به امید خدا.
خوب به کلاس های زیر نگاه کنید:
برای مثال کلاس زیر کلاسی است که شما عملیات پیچیده ی خود را در آن انجام میدهید:
کد:
public static class MathH
{
public static int GetExecute()
{
double Q = int.MaxValue;
for (int i = 0; i < 100000; i++)
{
Q = Math.Cosh(Q);
}
return (int)Q;
}
}
و این هم کلاس معمولی شماست که برای نمایش یا استفاده آن را به در برنامه خود بکار میبرید:
کد:
public class Person
{
string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
object _Value = MathH.GetExecute();
public object Value
{
get
{
return _Value;
}
set { _Value = value; }
}
}
شاید در نگاه اول خیلی ساده و به چشم بیاید......:20:.
اما حالا کد را تست کنید:
کد:
List<Person> lstPersons = new List<Person>();
for (int i = 0; i < 10000; i++)
{
lstPersons.Add(new Person());
}
چقدر زمان برد تا فقط 1000 کلاس در حافظه ی سیستم شما قرار بگیرد؟
یک نگاه دیگر به کدها بیاندازید اگر متوجه اشتباه در سیستم کلاس نویسی بالا دیده اید آنرا درست کنید وگرنه ادامه را بخوانید....
روشی که مارا دچار مشکل کرده است مقدار دهی اولیه کدهایمان است....
به پروپرتی زیر دقت کنید:
کد:
object _Value = MathH.GetExecute();
public object Value
{
get
{
return _Value;
}
set { _Value = value; }
}
همیشه یادمان باشد تا زمانی که از پروپرتی خاصی در کلاسمان استفاده نمیکنیم آنرا بلافاصله مقدار دهی نکنیم...
کد بالا را در کلاس Person پیدا کنید و آنرا اینگونه تغییر دهید:
کد:
object _Value = null;
public object Value
{
get
{
if (_Value == null)
_Value = MathH.GetExecute();
return _Value;
}
set { _Value = value; }
}
حال با همان کد اجرایی که قبلاً داده بودم برنامه را تست کنید:
کد:
List<Person> lstPersons = new List<Person>();
for (int i = 0; i < 10000; i++)
{
lstPersons.Add(new Person());
}
آیا تغییری در سرعت دیده اید؟:46:.
موفق و سربلند باشید در پناه حق.