الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[جديد] الدرس الخامس من سلسلة دروس تعلم ال Xna

بدأه *خلدون خالد* في 2 مارس 2009 · 6 رد · 2,218 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بســم الله الـرحمــن الرحيــم

الدرس الخامس

<<== إذهب إلى الدرس السابق

أهلا بكم في الدرس الخامس من سلسلة دروس تعلم ال Xna , سوف نقوم في هذا الدرس برسم المدفع و عمل التدوير “Rotation” عليه, إن شاء الله.

لقد قمنا حتى الآن تقريبا بتغطية غالبية المفاهيم حول الرسم الثنائي الأبعاد , إلا مفهوم واحد ألا وهو التدوير. في هذا الدرس سوف نقوم برسم المدفع على ظهر حاملة المدفع التي رسمناها في الدرس السابق, بناء على زاوية التدوير التي سوف نخزنها في المصفوفة PlayerDat.

من المفروض أنك قد قمت فعليا بإستيراد صورة المدفع و قمت بربطها مع المتغير cannonTexture قبل درسين. دعنا الآن نناقش كيف سنقوم بتدوير هذا المدفع.

كما ذكر في الدرس السابق فإن ال Xna تعتبر أن نقطة الأصل للصورة ثنائية الأبعاد تمثل الركن العلوي الأيسر. هذا مهم بالنسبة لنا لسببين, حيث قمنا بتغطية السبب الأول في الدرس السابق:

•تقوم ال Xna برسم الصورة على الشاشة بحيث تكون نقطة الأصل لها فوق النقطة التي نقوم بإرسالها إلى الدالة SpriteBatch.Draw().

•السبب الثاني , أنك عندما تقوم بتدوير الصورة, تقوم ال Xna بتدويرها حول نقطة الأصل الخاصة بها. و هذه نتيجة طبيعية مربتطة مباشرة بالسبب الأول بحيث: أنه و بهذه الطريقة: نقطة الأصل تبقى نفسها في الموقع الذي تقوم بتحديده, بغض النظر عن طبيعة التدوير.

الصورة التالية توضح ذلك:

post-133895-1236003254_thumb.jpg

في الجزء العلوي, تم رسم المدفع بإعتبار أن نقطة الأصل له هي الركن الاعلى الأيسر. الآن عندما نريد تطبيق التدوير على الصورة كما الحال في الصورة العلويه على اليمين, سيتم تدوير المدفع حول نقطة الأصل الخاصة به. تخيل لو أننا قمنا بتدوير المدفع 90 درجه اخرى, سيظهر المدفع و كأنه خارج منطقة الحمالة !

ما نحتاجه هو تحديد نقطة الأصل في مركز التدوير, بحيث يكون موقع هذه النقطة ثابت أثناء عملية التدوير. هذه النقطة تمثل النقطة الزرقاء في الجزء الأسفل من الرسم السابق, الآن عندما يتم تدوير المدفع بزاوية 90 درجة, سوف تكون النتيجة أفضل بكثير, كما يظهر في القسم الأسفل على اليمين من الصورة.

إذن كيف يمكننا عمل ذلك في الXna؟ بسهولة جدا :wink: . قم بإيجاد السطر في الكود الذي يقوم برسم حاملة المدفع (موجود في الدالة DrawPlayers()) , وقم بإضافة الكود التالي مباشرة قبل ذلك السطر:

 int xPos = (int)player.Position.X;
 int yPos = (int)player.Position.Y;
 Vector2 cannonOrigin = new Vector2(11, 50);

 spriteBatch.Draw(cannonTexture, new Vector2(xPos + 20, yPos - 10), null, player.Color, player.Angle, cannonOrigin, playerScaling, SpriteEffects.None, 1);

نحن بحاجة إلى تحديد موقعين:

•نقطة الأصل الجديدة الخاصة بصورة المدفع

•الموقع على الشاشة الذي يعبر عن موقع رسم النقطة السابقة.

حجم صورة المدفع هو 70 * 20 بكسل, لهذا قمت بإختيار الإحداثي (11,50) كنقطة الأصل. حاول فتح الصورة و الوصول إلى هذه النقطة سوف تجد أنها موجوده على المركز التدويري للصورة (مقبض التدوير). يجب أن تلاحظ أن هذا الموقع يجب تحديده على الصورة بحجمها الأصلي.

بعدها يلزمنا تحديد أين على الشاشة سوف يتم رسم هذه النقطة. حيث نريد أن يتم ذلك على بعد 20 بكسل من اليمين و 10 بكسل للأعلى, بالنسبة إلى موقع اللاعب, الذي يمثل الركن الأعلى الأيسر من صورة حامل المدفع.

أخيرا, قمنا بوضع زاوية الدوران بدلا من الصفر. يمكنك أن تجرب بعض القيم بنفسك, بإستخدام الدالة MathHelper.ToRadians(). في السطر الأخير قمنا بأخذ قيمة الدوران و اللون المخزنان في مصفوفة ال PlayerData .

الآن دعنا نجرب تشغيل الكود, سترى أن كل المدافع موجهة إلى اليمين كما في الصورة, أي أنها مدورة بزاوية 90 درجة كما فعلنا سابقا.

في الدرس القادم سوف نتعلم كيف نقرأ المدخلات من لوحة المفاتيح, بحيث يمكننا تعديل الزاويه أثناء تنفيذ البرنامج!

post-133895-1236003284_thumb.jpg

كود المشروع حتى الآن:

 using [color= #990000;]System[color= #339933;];

 using [color= #990000;]System[color= #339933;].Collections[color= #339933;].Generic[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Audio[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Content[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].GamerServices[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Graphics[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Input[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Net[color= #339933;];

 using Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Storage[color= #339933;];

 

 namespace XNAtutorial

 [color= #009900;]{

     [color= #000000; font-weight: bold;]public struct PlayerData

     [color= #009900;]{

         [color= #000000; font-weight: bold;]public Vector2 Position[color= #339933;];

         [color= #000000; font-weight: bold;]public bool IsAlive[color= #339933;];

         [color= #000000; font-weight: bold;]public Color Color[color= #339933;];

         [color= #000000; font-weight: bold;]public float Angle[color= #339933;];

         [color= #000000; font-weight: bold;]public float Power[color= #339933;];

     [color= #009900;]}

 

     [color= #000000; font-weight: bold;]public [color= #000000; font-weight: bold;]class Game1 [color= #339933;]: Microsoft[color= #339933;].Xna[color= #339933;].Framework[color= #339933;].Game

     [color= #009900;]{

         GraphicsDeviceManager graphics[color= #339933;];

         SpriteBatch spriteBatch[color= #339933;];

         GraphicsDevice device[color= #339933;];

 

         int screenWidth[color= #339933;];

         int screenHeight[color= #339933;];

 

         Texture2D backgroundTexture[color= #339933;];

         Texture2D foregroundTexture[color= #339933;];

         Texture2D carriageTexture[color= #339933;];

         Texture2D cannonTexture[color= #339933;];

 

         PlayerData[color= #009900;][[color= #009900;]] players[color= #339933;];

         int numberOfPlayers [color= #339933;]= [color= #cc66cc;]4[color= #339933;];

         float playerScaling[color= #339933;];

 

         [color= #000000; font-weight: bold;]public Game1[color= #009900;]([color= #009900;])

         [color= #009900;]{

             graphics [color= #339933;]= [color= #000000; font-weight: bold;]new GraphicsDeviceManager[color= #009900;](this[color= #009900;])[color= #339933;];

             Content[color= #339933;].RootDirectory [color= #339933;]= [color= #0000ff;]"Content"[color= #339933;];

         [color= #009900;]}

 

         protected override void Initialize[color= #009900;]([color= #009900;])

         [color= #009900;]{

             graphics[color= #339933;].PreferredBackBufferWidth [color= #339933;]= [color= #cc66cc;]500[color= #339933;];

             graphics[color= #339933;].PreferredBackBufferHeight [color= #339933;]= [color= #cc66cc;]500[color= #339933;];

             graphics[color= #339933;].IsFullScreen [color= #339933;]= [color= #000000; font-weight: bold;]false[color= #339933;];

             graphics[color= #339933;].ApplyChanges[color= #009900;]([color= #009900;])[color= #339933;];

             Window[color= #339933;].Title [color= #339933;]= [color= #0000ff;]"Riemer's 2D XNA Tutorial"[color= #339933;];

 

             base[color= #339933;].Initialize[color= #009900;]([color= #009900;])[color= #339933;];

         [color= #009900;]}

 

         protected override void LoadContent[color= #009900;]([color= #009900;])

         [color= #009900;]{

             device [color= #339933;]= graphics[color= #339933;].GraphicsDevice[color= #339933;];

             spriteBatch [color= #339933;]= [color= #000000; font-weight: bold;]new SpriteBatch[color= #009900;](device[color= #009900;])[color= #339933;];

 

             screenWidth [color= #339933;]= device[color= #339933;].PresentationParameters[color= #339933;].BackBufferWidth[color= #339933;];

             screenHeight [color= #339933;]= device[color= #339933;].PresentationParameters[color= #339933;].BackBufferHeight[color= #339933;];

 

 

            backgroundTexture [color= #339933;]= Content[color= #339933;].Load[color= #339933;]<Texture2D[color= #339933;]> [color= #009900;]([color= #0000ff;]"background"[color= #009900;])[color= #339933;];

            foregroundTexture [color= #339933;]= Content[color= #339933;].Load[color= #339933;]<Texture2D[color= #339933;]> [color= #009900;]([color= #0000ff;]"foreground"[color= #009900;])[color= #339933;];

            carriageTexture [color= #339933;]= Content[color= #339933;].Load[color= #339933;]<Texture2D[color= #339933;]> [color= #009900;]([color= #0000ff;]"carriage"[color= #009900;])[color= #339933;];

            cannonTexture [color= #339933;]= Content[color= #339933;].Load[color= #339933;]<Texture2D[color= #339933;]> [color= #009900;]([color= #0000ff;]"cannon"[color= #009900;])[color= #339933;];

            SetUpPlayers[color= #009900;]([color= #009900;])[color= #339933;];

            playerScaling [color= #339933;]= [color= #cc66cc;]40[color= #339933;].0f [color= #339933;]/ [color= #009900;](float[color= #009900;])carriageTexture[color= #339933;].Width[color= #339933;];

        [color= #009900;]}

 

        [color= #000000; font-weight: bold;]private void SetUpPlayers[color= #009900;]([color= #009900;])

        [color= #009900;]{

            Color[color= #009900;][[color= #009900;]] playerColors [color= #339933;]= [color= #000000; font-weight: bold;]new Color[color= #009900;][[color= #cc66cc;]10[color= #009900;]][color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]0[color= #009900;]] [color= #339933;]= Color[color= #339933;].Red[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]1[color= #009900;]] [color= #339933;]= Color[color= #339933;].Green[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]2[color= #009900;]] [color= #339933;]= Color[color= #339933;].Blue[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]3[color= #009900;]] [color= #339933;]= Color[color= #339933;].Purple[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]4[color= #009900;]] [color= #339933;]= Color[color= #339933;].Orange[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]5[color= #009900;]] [color= #339933;]= Color[color= #339933;].Indigo[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]6[color= #009900;]] [color= #339933;]= Color[color= #339933;].Yellow[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]7[color= #009900;]] [color= #339933;]= Color[color= #339933;].SaddleBrown[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]8[color= #009900;]] [color= #339933;]= Color[color= #339933;].Tomato[color= #339933;];

            playerColors[color= #009900;][[color= #cc66cc;]9[color= #009900;]] [color= #339933;]= Color[color= #339933;].Turquoise[color= #339933;];

 

            players [color= #339933;]= [color= #000000; font-weight: bold;]new PlayerData[color= #009900;][numberOfPlayers[color= #009900;]][color= #339933;];

            [color= #b1b100;]for [color= #009900;](int i [color= #339933;]= [color= #cc66cc;]0[color= #339933;]; i [color= #339933;]< numberOfPlayers[color= #339933;]; i[color= #339933;]++[color= #009900;])

            [color= #009900;]{

                players[color= #009900;][i[color= #009900;]][color= #339933;].IsAlive [color= #339933;]= [color= #000000; font-weight: bold;]true[color= #339933;];

                players[color= #009900;][i[color= #009900;]][color= #339933;].Color [color= #339933;]= playerColors[color= #009900;][i[color= #009900;]][color= #339933;];

                players[color= #009900;][i[color= #009900;]][color= #339933;].Angle [color= #339933;]= MathHelper[color= #339933;].ToRadians[color= #009900;]([color= #cc66cc;]90[color= #009900;])[color= #339933;];

                players[color= #009900;][i[color= #009900;]][color= #339933;].Power [color= #339933;]= [color= #cc66cc;]100[color= #339933;];                

            [color= #009900;]}

 

            players[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;].Position [color= #339933;]= [color= #000000; font-weight: bold;]new Vector2[color= #009900;]([color= #cc66cc;]100[color= #339933;], [color= #cc66cc;]193[color= #009900;])[color= #339933;];

            players[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;].Position [color= #339933;]= [color= #000000; font-weight: bold;]new Vector2[color= #009900;]([color= #cc66cc;]200[color= #339933;], [color= #cc66cc;]212[color= #009900;])[color= #339933;];

            players[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;].Position [color= #339933;]= [color= #000000; font-weight: bold;]new Vector2[color= #009900;]([color= #cc66cc;]300[color= #339933;], [color= #cc66cc;]361[color= #009900;])[color= #339933;];

            players[color= #009900;][[color= #cc66cc;]3[color= #009900;]][color= #339933;].Position [color= #339933;]= [color= #000000; font-weight: bold;]new Vector2[color= #009900;]([color= #cc66cc;]400[color= #339933;], [color= #cc66cc;]164[color= #009900;])[color= #339933;];

        [color= #009900;]}

 

        protected override void UnloadContent[color= #009900;]([color= #009900;])

        [color= #009900;]{

        [color= #009900;]}

 

        protected override void Update[color= #009900;](GameTime gameTime[color= #009900;])

        [color= #009900;]{

            [color= #b1b100;]if [color= #009900;](GamePad[color= #339933;].GetState[color= #009900;](PlayerIndex[color= #339933;].One[color= #009900;])[color= #339933;].Buttons[color= #339933;].Back [color= #339933;]== ButtonState[color= #339933;].Pressed[color= #009900;])

                this[color= #339933;].[color= #990000;]Exit[color= #009900;]([color= #009900;])[color= #339933;];

 

            base[color= #339933;].Update[color= #009900;](gameTime[color= #009900;])[color= #339933;];

        [color= #009900;]}

 

        protected override void Draw[color= #009900;](GameTime gameTime[color= #009900;])

        [color= #009900;]{

            graphics[color= #339933;].GraphicsDevice[color= #339933;].Clear[color= #009900;](Color[color= #339933;].CornflowerBlue[color= #009900;])[color= #339933;];

 

            spriteBatch[color= #339933;].Begin[color= #009900;]([color= #009900;])[color= #339933;];

            DrawScenery[color= #009900;]([color= #009900;])[color= #339933;];

            DrawPlayers[color= #009900;]([color= #009900;])[color= #339933;];

            spriteBatch[color= #339933;].[color= #990000;]End[color= #009900;]([color= #009900;])[color= #339933;];

 

            base[color= #339933;].Draw[color= #009900;](gameTime[color= #009900;])[color= #339933;];

        [color= #009900;]}

 

        [color= #000000; font-weight: bold;]private void DrawScenery[color= #009900;]([color= #009900;])

        [color= #009900;]{

            Rectangle screenRectangle [color= #339933;]= [color= #000000; font-weight: bold;]new Rectangle[color= #009900;]([color= #cc66cc;]0[color= #339933;], [color= #cc66cc;]0[color= #339933;], screenWidth[color= #339933;], screenHeight[color= #009900;])[color= #339933;];

            spriteBatch[color= #339933;].Draw[color= #009900;](backgroundTexture[color= #339933;], screenRectangle[color= #339933;], Color[color= #339933;].White[color= #009900;])[color= #339933;];

            spriteBatch[color= #339933;].Draw[color= #009900;](foregroundTexture[color= #339933;], screenRectangle[color= #339933;], Color[color= #339933;].White[color= #009900;])[color= #339933;];

        [color= #009900;]}

 

        [color= #000000; font-weight: bold;]private void DrawPlayers[color= #009900;]([color= #009900;])

        [color= #009900;]{

            [color= #b1b100;]foreach [color= #009900;](PlayerData player in players[color= #009900;])

            [color= #009900;]{

                [color= #b1b100;]if [color= #009900;](player[color= #339933;].IsAlive[color= #009900;])

                [color= #009900;]{

 

                     int xPos [color= #339933;]= [color= #009900;](int[color= #009900;])player[color= #339933;].Position[color= #339933;].X[color= #339933;];

                     int yPos [color= #339933;]= [color= #009900;](int[color= #009900;])player[color= #339933;].Position[color= #339933;].Y[color= #339933;];

                     Vector2 cannonOrigin [color= #339933;]= [color= #000000; font-weight: bold;]new Vector2[color= #009900;]([color= #cc66cc;]11[color= #339933;], [color= #cc66cc;]50[color= #009900;])[color= #339933;];

 

                     spriteBatch[color= #339933;].Draw[color= #009900;](cannonTexture[color= #339933;], [color= #000000; font-weight: bold;]new Vector2[color= #009900;](xPos [color= #339933;]+ [color= #cc66cc;]20[color= #339933;], yPos [color= #339933;]- [color= #cc66cc;]10[color= #009900;])[color= #339933;], [color= #000000; font-weight: bold;]null[color= #339933;], p
layer[color= #339933;].Color[color= #339933;], player[color= #339933;].Angle[color= #339933;], cannonOrigin[color= #339933;], playerScaling[color= #339933;], SpriteEffects[color= #339933;].None[color= #339933;], [color= #cc66cc;]1[color= #009900;])[color= #339933;];

                     spriteBatch[color= #339933;].Draw[color= #009900;](carriageTexture[color= #339933;], player[color= #339933;].Position[color= #339933;], [color= #000000; font-weight: bold;]null[color= #339933;], player[color= #339933;].Color[color= #339933;], [color= #cc66cc;]0[color= #339933;], 
new Vector2[color= #009900;]([color= #cc66cc;]0[color= #339933;], carriageTexture[color= #339933;].Height[color= #009900;])[color= #339933;], playerScaling[color= #339933;], SpriteEffects[color= #339933;].None[color= #339933;], [color= #cc66cc;]0[color= #009900;])[color= #339933;];

                 [color= #009900;]}

             [color= #009900;]}

         [color= #009900;]}

     [color= #009900;]}

 [color= #009900;]}

نسخة عن الدرس بصيغة ال PDF

Learn_Xna5.pdf

تم تعديل هذه المشاركة بواسطة خلدون خالد2 في 3 مارس 2009 في 17:28

#2

السلام عليكم ,

بارك الله فيك أخي ,

الموضوع مهم , كنت أتمنى أن اطبق ثم اضيف على الموضوع , لكن لامانع من ان أبدأ بالحديث أولا :

لو أردنا تدوير الـ sprite ( الصورة ) حول نقطة معينة .. ( خارج الصورة ) , كيف يمكن أن نقوم بذلك ؟

بحثت في MSDN , وأظن أنه يمكن حل هذه المشكلة بطريقتين /

1- باستخدام Matrix .

2- باستخدام الدوال المثلثية ( طريقة يدوية بدون دوال جاهزة ) .

من يمكنه حل هذه المعضلة :D

post-42837-1236096585_thumb.png

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#3

أهلا و سهلا بك أخي الشمري

اقتباس
من يمكنه حل هذه المعضلة

وضعت تصور للحل و هو بسيط جدا.

ولكن لن أقول , سأنتظر الأعضاء الآخرين :):)

#4

:D :hmm: :nose_pick: :resentful:

وين الحركه ؟؟

حل المشكله من وجهة نظري , أننا نقوم بإرسال لدالة الرسم نقطة خارج الصورة (بإعتبارها نقطة المركز) و تكون هي النقطة التي تريد التدوير حولها

spriteBatch.Draw(Texture, new Vector2(xPos, yPos), null, p
layer.Color, player.Angle, new vector(rotation point Cordination x,y), playerScaling, SpriteEffects.None, 1);

ببساطه :)

#5

لايبدو أخي أن الموضوع بهذه السهولة :D .

بعد التحريات , واضح أن Sprite يعتمد على نقطة الأصل origin point ليس فقط في الدوران وحسب , بل في تحديد موقع الصورة نفسها .. وهناك حسابات يجريها ..

- لاحظت التالي :

		  // players[0].Position.X = 0;
		   // players[0].Position.Y = 0;
			players[0].Position.X = 250;
			players[0].Position.Y = 250;
		   // players[0].Position.X = 500;
		   // players[0].Position.Y = 500;

			base.Update(gameTime);
		}


		private void DrawPlayers()
		{

				if (players[0].IsAlive)
				{

					spriteBatch.Draw(carriageTexture, players[0].Position, null, Color.White, 0, new Vector2(250,250), 1, SpriteEffects.None, 1);
				}
		}

في الكود السابق .. وضعت نقطة الاصل 250 للاحداثي السيني والصادي , ووضعت ثلاثة تجارب لتحديد موقع الصورة position .

( x pos , y pos )  - ( x origin  point  , y origin  point   ) 

// wil not be displayed
( 0 ,  0 )  - ( 250 , 250 ) = ( -250 , -250 ) 

// في الزاوية العلوية اليسرى
( 250 , 250 ) - ( 250 ,250 ) = ( 0,0)

// في منتصف النافذة
( 500 , 500 ) - ( 250 , 250) = (250 , 250 )

الان الدوران حول نقطة معينة :D :

من خلال ما سبق .. نستنتج بأننا بحاجة لعملية ازاحة .. قبل الدوران حول النقطة المعينة .. فلو أردنا الدوران حول منتصف النافذة 250 - 250

	
protected override void Update(GameTime gameTime)
		{
			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
				this.Exit();
			angle += 0.01f;
		   // players[0].Position.X = 0;
		   // players[0].Position.Y = 0;
			players[0].Position.X = 250; 
			players[0].Position.Y = 250;
		   // players[0].Position.X = 500;
		   // players[0].Position.Y = 500;

			base.Update(gameTime);
		}


		private void DrawPlayers()
		{

				if (players[0].IsAlive)
				{

spriteBatch.Draw(carriageTexture, players[0].Position, null, Color.White, angle, new Vector2(250,250), 1, SpriteEffects.None, 1);
				}
		}

الان الصورة تدور حول نقطة معينة ( منتصف النافذة ) .. لكن لازلنا بحاجة للتحكم بشكل أكبر بنصف القطر بين النقطة و الصورة ... لتقليله مثلا ...

لذلك , من الصعب أن ندور حول نقطة معينة .. بالتعديل على نقطة الأصل الموجودة في البارمترات .. أفضل حل هو استخدام طريقة يدوية , لاننا نملك الاحداثي السيني والصادي للصورة ..

تم تعديل هذه المشاركة بواسطة الشمري في 6 مارس 2009 في 06:16

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#6

الطريقة اليدوية ...

باستخدام معادلة الدوران .. نستطيع أن نتحكم بكل شيء :D

لاحظ الدالة update

عموما .. قد لاتكون هذه أفضل طريقة .. !! ولكنها تعمل على كل حال ..

  1.  
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Audio;
  7. using Microsoft.Xna.Framework.Content;
  8. using Microsoft.Xna.Framework.GamerServices;
  9. using Microsoft.Xna.Framework.Graphics;
  10. using Microsoft.Xna.Framework.Input;
  11. using Microsoft.Xna.Framework.Net;
  12. using Microsoft.Xna.Framework.Storage;
  13.  
  14. namespace XNAtutorial
  15. {
  16. public struct PlayerData
  17. {
  18. public Vector2 Position;
  19. public bool IsAlive;
  20. public Color Color;
  21. public float Angle;
  22. public float Power;
  23. }
  24.  
  25. public class Game1 : Microsoft.Xna.Framework.Game
  26. {
  27. GraphicsDeviceManager graphics;
  28. SpriteBatch spriteBatch;
  29. GraphicsDevice device;
  30.  
  31. int screenWidth;
  32. int screenHeight;
  33.  
  34. Texture2D backgroundTexture;
  35. Texture2D foregroundTexture;
  36. Texture2D carriageTexture;
  37. PlayerData players;
  38. float angle ;
  39.  
  40. public Game1()
  41. {
  42. graphics = new GraphicsDeviceManager(this);
  43. Content.RootDirectory = "Content";
  44. }
  45.  
  46. protected override void Initialize()
  47. {
  48. graphics.PreferredBackBufferWidth = 500;
  49. graphics.PreferredBackBufferHeight = 500;
  50. graphics.IsFullScreen = false;
  51. graphics.ApplyChanges();
  52. Window.Title = "Riemer's 2D XNA Tutorial";
  53. angle = 0;
  54. base.Initialize();
  55. }
  56.  
  57. protected override void LoadContent()
  58. {
  59. device = graphics.GraphicsDevice;
  60. spriteBatch = new SpriteBatch(device);
  61.  
  62. screenWidth = device.PresentationParameters.BackBufferWidth;
  63. screenHeight = device.PresentationParameters.BackBufferHeight;
  64.  
  65.  
  66. backgroundTexture = Content.Load<Texture2D>("background");
  67. foregroundTexture = Content.Load<Texture2D>("foreground");
  68.  
  69. carriageTexture = Content.Load<Texture2D>("carriage");
  70. SetUpPlayers();
  71.  
  72. }
  73.  
  74. private void SetUpPlayers()
  75. {
  76. Color[] playerColors = new Color[10];
  77. playerColors[0] = Color.Red;
  78.  
  79.  
  80. players = new PlayerData();
  81. players.IsAlive = true;
  82. players.Color = Color.Red;
  83. players.Angle = 0;
  84.  
  85.  
  86. players.Position = new Vector2(100, 193);
  87.  
  88. }
  89.  
  90. protected override void UnloadContent()
  91. {
  92. }
  93.  
  94. protected override void Draw(GameTime gameTime)
  95. {
  96. graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
  97.  
  98. spriteBatch.Begin();
  99. DrawScenery();
  100. DrawPlayers();
  101. spriteBatch.End();
  102.  
  103. base.Draw(gameTime);
  104. }
  105.  
  106.  
  107. private void DrawScenery()
  108. {
  109. Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);
  110. spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
  111. spriteBatch.Draw(foregroundTexture, screenRectangle, Color.White);
  112. }
  113.  
  114. //---------------------------------------------- هنا ال
    1578;عديل -----------------------------------
  115.  
  116. protected override void Update(GameTime gameTime)
  117. {
  118. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  119. this.Exit();
  120.  
  121. angle += 1; // change this to increase/decrease the rotation speed.
  122.  
  123. // radius ( the distance from X point to the image)
  124. int xRadius = 100;
  125. int yRadius = 100;
  126.  
  127. double newX = xRadius * Math.Cos(MathHelper.ToRadians(angle));
  128. double newY = yRadius * Math.Sin(MathHelper.ToRadians(angle));
  129. // to rotate around window center.
  130. int AroundX = screenWidth/2;
  131. int AroundY = screenHeight/2;
  132.  
  133. players.Position.X = (float)newX + AroundX;
  134. players.Position.Y = (float)newY + AroundY;
  135.  
  136. base.Update(gameTime);
  137. }
  138.  
  139.  
  140. private void DrawPlayers()
  141. {
  142.  
  143. if (players.IsAlive)
  144. {
  145.  
  146. spriteBatch.Draw(carriageTexture, players.Position, null, players.Color, 0,
    new Vector2(carriageTexture.Width/2 ,carriageTexture.Height/2), 1, SpriteEffects.None, 1);
  147. }
  148. }
  149. }
  150. }
  151.  
  152.  
  153.  

تم تعديل هذه المشاركة بواسطة الشمري في 6 مارس 2009 في 06:21

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#7

السلام عليكــم ورحمـة الله وبركاتــة ،،

أهلا بك من جديد أخي :happy:

أولا : شكرا على شرح الطريقة اليدوية للتدوير , وهي الطريقة الاصليه (و هي طريقة رسم الدائره في الرسم الحاسوبي :) )

ثانيا : الطريقة التي اشرت اليها في مشاركتي السابقه هي ببساطه بمثال:

post-133895-1236345388_thumb.jpg

على فرض في الصورة السابقة نريد تدوير المربع البرتقالي حول النقطة السوداء (إحداثياتها معروفه طبعا)

كل ما علينا هو أن نقوم بإيجاد المسافة X و المسافه Y بغض النظر إن تم ذلك يدويا او عن طريق الحسابات , ما نريدة بالضبط إحداثيات نقطة المركز الإفتراضيه (الركن العلوي الأيسر) مطروح منها إحداثيات النقطة السوداء .

إحداثيات النقطة الإفتراضيه يمكن الوصول إليها من خلال نصف قطر الدائرة التي سوف يدور عليها الشكل (يعني بالطريقة التقليديه :lol: )

و بعدها نرسل لدالة الرسم إحداثيات النقطه السوداء للرسم عليها , و نرسل إحداثيات نقطة المركز المتمثله ب x و y طبعا سوف يكونو بالسالب في هذه الحاله.

spriteBatch.Draw(box, new Vector2(200, 200), null, Color.White, MathHelper.ToRadians(x++), new Vector2(-10,-10), 1, SpriteEffects.None, 1);

الملف المرفق يطبق يحتوي الكود

Test.zip

تم تعديل هذه المشاركة بواسطة خلدون خالد2 في 6 مارس 2009 في 16:16

مواضيع مشابهة