Wednesday, September 29, 2010

XNA: Lesson4: 2D Graphics 2

الدرس الرابع
2D Graphics 2

بسم الله و الصلاة و السلام علي رسول الله صلي الله عليه و سلم ...

نكمل في هذا الدرس باذن الله مفاهيم و اساسيات التعامل مع كائنات ال 2D...

  • تغيير مقاس الشاشة: Changing Windows Size:
لتغيير ابعاد الشاشة الي 500 * 300 مثلا نكتب الكود التالي في ملف Game1.CS في ال Constructor:
public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 500;
            graphics.PreferredBackBufferHeight = 300;

            Content.RootDirectory = "Content";
        }


  • تطبيق:
    • غير ابعاد الشاشة لاي مقاس جديد تريده ...


  • Moving the sprite on the screen:
  • تحريك العنصر علي الشاشة:
اتفقنا ان في نظام الاحداثيات يوجد x و يوجد y ....
طبعا نستخدم x لتحريك العنصر بشكل افقي ... و نستخدم ال y  للتحريك بشكل عمودي ...
و اتفقنا ايضا ان ال x تبدا من الشمال يعني اول نقطة علي الشاشة في الشمال تساوي صفر ... و بالتالي اذا اردنا تحريك العنصر لليمين ماذا سنفعل ؟؟؟ سنزيد ال x بالقيمة التي نريد التحريك بها ... و كذلك في ال y نقطة الصفر تبدا من اول نقطة علي الشاشة بالاعلي و بالتالي اذا اردنا تحريك العنصر لتحت سنزيد ال y .

نفترض اننا نريد تحريك العنصر لليمين مثلا سنكتب الكود التالي:
mySprite1.position.X += 1;
ماذا فعنا هنا؟ قمنا بزيادة ال x بمقدار 1 ... و بالتالي سيتحرك العنصر لليمين بمقدار 1 في التكرار الواحد ...

  • دعونا نطبق ... افتحوا المشروع الخاص بالدرس الثالث ...
نفتح الكلاس clsSprite.CS و نعرف خاصية جديدة به:
public Vector2 velocity { get; set; }
ما هي ال velocity : هي تمثل سرعة الكائن علي الشاشة ... و عرفناها ب vector2 حيث ال x هي قيمة السرعة للتحريك الافقي و ال y هي قيمة السرعة للتحريك الراسي ...



  • ثم نبدا وظيفة جديدة في الكلاس و هي Move اي تحرك و التي ننفذها في كل تكرار في اللعبة بحيث يتحرك الكائن بالسرعة التي حددناها و هذه ال Method ستكون كالتالي:
        public void Move()
        {
            position += velocity;
  }

و هنا اضفنا قيمة السرعة الي مكان الكائن و هكذا في كل تكرار في اللعبة يتم زيادة احداثيات الكائن بمقدار السرعة ...

  • الان نفتح ملف ال Game1.CS:
ثم نذهب الي الحدث 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

            spriteBall = new clsSprite(Content.Load<Texture2D>("ball"),
                Vector2.Zero);

            spriteBall.velocity = new Vector2(1, 1);
        }

كما ترون يوجد سطر اضافي بعد تعريف object   من كلاس ال clsSprite و هو:
            spriteBall.velocity = new Vector2(1, 1);
و هنا تم تعريف السرعة بمقدار 1,1 يعني في كل تكرار في اللعبة ستزيد قيمة ال x بمقدار 1 و ستزيد قيمة ال y بقيمة 1.



ثم نذهب الي حدث ال Update() و نعدل الكود ليصبح كالتالي:
        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
            spriteBall.Move();

            base.Update(gameTime);
        }
نلاحظ السطر التالي:
spriteBall.Move();
و لا ننسي ان حدث ال update يتم تنفيذه في كل تكرار في اللعبة ... و بالتالي ننفذ كود التحرك Move فيه ليتحرك الكائن ...


  • خلاصة الدرس:
تم التدريب علي تحريك كائنات ال 2D في اللعبة ... و في الدرس القادم سنتعلم كيف نتحكم في الحركة بحيث لا يخرج الكائن خارج حدود اللعبة ...

التطبيق:
قم بانشاء 3 كائنات من نوع clsSprite و قم بتحريكهم في اتجاهات مختلفة ...
التطبيق بالانجليزي لمن يفهم اكثر بها:
Create 3 objects of the clsSprite class, and move them towards different ways …

و صلي الله و سلم علي سيدنا محمد و السلام عليكم ...

Monday, September 27, 2010

XNA: Lesson3: 2D Graphics

الدرس الثالث
2D Graphics

  • هدف الدرس: في هذا الدرس سنتعلم كيف نكون كائن 2D و عرضه في اللعبة ...
  • دعونا في البداية نتعرف علي مصطلحات هامة في عالم ال 2D:
    • Sprite:
    • هذا العنصر يمثل الكائن ال 2D الذي سنقوم برسمه علي الشاشة و هذا الكائن سنقوم بتحميله ب:
      • الصورة Texture كما سنري بعد ذلك ان شاء الله.
      • الموضع Position: مكان الكائن في اللعبة.
      • طول و عرض الكائن.
      • السرعة velocity.
    • و هذا الكائن طبعا يقوم برسم الصورة بدون الاماكن الفارغة فيها لان هناك مشكلة في الحاسب انه يقوم باعتبار اي صورة علي انها مربع ... و لكن هناك برامج تمكننا من عمل الصورة Transparent اي تكون شفافة لما تحتها و كائن ال sprite يمكننا من رسم الصورة بشكلها الشفاف و ليس كمربع.
    • Textures:
    • هي الصورة نفسها ال 2D التي سنقوم برسمها بواسطة ال Sprite... طبعا ستسالوني ما الفرق بين ال srite و ال texture ... ال sprite هو الكائن الذي يقوم برسم ال texture علي الشاشة و ال texture محمل بالصورة من مخزن البيانات Content... وصلت ؟؟؟
    • Background:
    • طبعا هي خلفية اللعبة التي سيتم رسم كافة الكائنات الاخري فوقها...

  • 2D and Screen Coordinates Systems:
  • الرسم ثنائي الابعاد و علاقته باحداثيات الشاشة:
  • كلنا طبعا نذكر هذا الشكل البياني:

و هو يمثل المحور السيني و الصادي ... شاشة الحاسب مقسمة ايضا الي هذا ... فكل نقطة علي شاشة الحاسب تمثل برقمين ... الاحداث السيني X ... و الاحداث الصادي Y ... و لكن في الشاشة هذا الشكل البياني يكون بالعكس اي نقطة الصفر (0,0) تكون في الشمال الاعلي كالاتي:



و كما نري فان نقطة الصفر في الشاشة تكون في اعلي الشمال ... يعني اذا اردنا ان نضع صورة في اللعبة و اردنا تحديد مكانها في الشمال فستكون مثلا في النقطة (3, 5) يعني x=3 و y=5   حاولوا رسمها علي الرسم البياني و تخيلوا موضعها اين ...




  • Drawing a Sprite using XNA:
  • هنا بدا الجد اخوتي و اخواتي ... لاننا سنقوم الان ببدء اول تجربة برسم كائنات 2D في اللعبة...
  • سنبدا بانشاء مشروع لعبة جديد كما تعلمنا.
  • سنقوم بعد ذلك بانشاء كلاس Class جديدة لتمثل لنا كائن ال 2D الذي نريد رسمه في اللعبة:
  • انشأ كلاس جديدة Class اسمها clsSprite عن طريق الاتي:
    • في solution explorer نضغط كليك يمين ثم نختر
    • Add è Class
    • ثم نكتب اسمها clsSprite.CS.
  • و ستحتوي هذه الكلاس علي التالي:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Chapter2_2D
{
    class clsSprite
    {
        public Texture2D texture { get; set; }
        public Vector2 position { get; set; }

        public clsSprite(Texture2D newTexture, Vector2 newPosition)
        {
            texture = newTexture;
            position = newPosition;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, Color.White);
        }
    }
}



  • نشرح الكود:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
  • قمنا باستيراد نطاقات الاسماء هذه لاحتوائها علي :
  • Texture2D لتحميل الصورة
  • Vector2 لتخزين السرعة و الحجم


public Texture2D texture { get; set; }
هذا العنصر يمثل الصورة ...
public Vector2 position { get; set; }
و هذا هو مكان الكائن علي الشاشة

public clsSprite(Texture2D newTexture, Vector2 newPosition)
        {
            texture = newTexture;
            position = newPosition;
        }

و هذا طبعا يسمي Constructor و هو ينفذ عند تعريف نسخة من هذا الكائن ... و عند تعريف اي نسخة من هذا الكائن يجب ان نعطيه الصورة و المكان و الحجم ثم نسلم هذه المتغيرات للصفات الداخلية للعنصر كما ترون ...


        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, Color.White);
        }

هنا قمنا بعمل دالة الرسم Draw و التي سنستخدمها في اللعبة لرسم الكائن علي الشاشة و هنا قام باستقبال بارامتر من نوع SpriteBatch و هو كما ذكرنا كلاس الوصول الي كارت الشاشة ... قم قمنا بتنفيذ الدالة
spriteBatch.Draw
و التي ستقوم بالرسم الفعلي علي الشاشة و تحتوي علي:
texture:الصورة
Position: المكان
Color.White: ليس مجالها الان و نكتبها كما هي





  • مرحلة رسم الصورة:
  • يمكنكم تحميل الصورة من خلال الرابط التالي:
    • http://www.mytruebluehomes.com/xsites/Agents/AggusRealty/content/uploadedFiles/TBR_Ball_transparent.png

  • نضيف الصورة الي المشروع عن طريق الاتي:
    • اضغط كليك يمين علي مجلد Content طبعا لانه كما اتفقنا المخزن الخاص باللعبة ثم :
    • Add è Existing Item:
    • ثم نختار الصورة و نضغط OK


  • نبدا الان في العمل في ملف اللعبة Game1.CS:
    • نعرف كائن جديد بعد السطر:
    • SpriteBatch spriteBatch;
    • نكتب هذا الكود:
    • clsSprite spriteBall;
ما الذي فعناه هنا؟
قمنا بتعريف كائن جديد من الكلاس التي قمنا بعمها ...


    • ثم بعد ذلك نذهب الحدث LoadContent
    • بعد هذا السطر:
    • // TODO: use this.Content to load your game content here
    • نكتب السطر الاتي:
    • spriteBall = new clsSprite(Content.Load<Texture2D>("ball"), Vector2.Zero);
    • ما الذي نفعله هنا؟ هنا نقوم باخذ نسخة جديدة من الكلاس clsSprite و حملناها من المخزن بالصورة عن طريق الكود:

    • Content.Load<Texture2D>("ball")
و هنا قمنا بامر ال Content او المخزن بتنفيذ امر التحميل Load من نوع Texture2D و هو نوع الملف الذي سنحمله ثم اعطيناه اسم الصورة ball و نلاحظ هنا قاعدة عامة ...

  • قاعدة عامة:
عند تحميل اي ملف في ال Content.Load يكون بدون الامتداد الخاص به...

يعني هنا في هذه الحالة كتبنا اسم الصورة ball و ليس ball.png  و ال XNA  سيفهم بمفرده صيغة الصورة....

  • نذهب بعد ذلك الي حدث ال Draw في نفس الكلاس Game1.CS:
    • و نكتب قبل
    • base.Draw(gameTime);
    • هذا الكود:
            spriteBatch.Begin();

            spriteBall.Draw(spriteBatch);

            spriteBatch.End();
    • ماذا فعلنا هنا؟
قلنا مسبقا ان هذا هو حدث الرسم ... و سننفذ الاتي فيه:
            spriteBatch.Begin();
يجب ... يجب ... يجب قبل رسم اي شئ علي الشاشة ان نكتب هذا السطر الذي يأمر ال spriteBatch ببدء العمل و بدونه لن تعمل اللعبة...

ثم ...
            spriteBall.Draw(spriteBatch);
نفذنا حدث الرسم الخاص بال spriteBall و الذي قمنا بعمله في الكلاس ...

            spriteBatch.End();
يجب ... يجب ... يجب بعد رسم اي شئ علي الشاشة ان نكتب هذا السطر الذي يأمر ال spriteBatch ببدء العمل و بدونه لن تعمل اللعبة...


طبعا لو هنرسم عدة كائنات و ليس كائن واحد علي الشاشة فسنكتب كل الكود بين:
            spriteBatch.Begin();
            spriteBatch.End();



الكود الكامل حتي الان:
clsSprite.cs:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Chapter2_2D
{
    class clsSprite
    {
        public Texture2D texture { get; set; }
        public Vector2 position { get; set; }

        public clsSprite(Texture2D newTexture, Vector2 newPosition)
        {
            texture = newTexture;
            position = newPosition;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, Color.White);
        }
    }
}



Game1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Chapter2_2D
{
    ///
    /// This is the main type for your game
    ///
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        clsSprite spriteBall;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        ///
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        ///
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        ///
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        ///
        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

            spriteBall = new clsSprite(Content.Load<Texture2D>("ball"), Vector2.Zero);
        }

        ///
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        ///
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        ///
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        ///
        ///
Provides a snapshot of timing values.
        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);
        }

        ///
        /// This is called when the game should draw itself.
        ///
        ///
Provides a snapshot of timing values.
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();

            spriteBall.Draw(spriteBatch);

            spriteBatch.End();


            base.Draw(gameTime);
        }
    }
}




تطبيق اليوم:
قم برسم كائن اخر في اللعبة بجانب الكرة التي رسمناها ....