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

الدرس الثاني عشر من سلسلة دروس تعلم ال Xna

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

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

الدرس الثاني عشر

أهلا بكم في الدرس الثاني عشر من سلسلة دروس تعلم الXna , سوف نقوم في هذا الدرس بإنشاء التضاريس بشكل عشوائي, "بلشنا الجد" :) .

النتيجة من الدرس السابق غير مرضية أبدا. كتطوير أولي,سوف نقوم بتغيير إنحدار التضاريس. لن نشير إلى ميزات جديده في ال Xna, لكن سوف نعرض كيف بإمكاننا أن نستغل بعض الأرقام العشوائية في اللعبة.

بدلا من التضاريس المستوية, دعنا نقوم بتغيير الكود لكي يقوم بإنشاء إنحدارات التضاريس. قم بإستبدال الكود في الدالة GenerateTerrainContour :

 private void GenerateTerrainContour()
 {
	 terrainContour = new int[screenWidth];

	 float offset = screenHeight / 2;
	 float peakheight = 100;
	 float flatness = 50;
	 for (int x = 0; x < screenWidth; x++)
	 {
		 double height = peakheight * Math.Sin((float)x / flatness)+offset;
		 terrainContour[x] = (int)height;
	 }
 }

أولا قم بتشغيل الكود, يجب أن ترى أن التضاريس تشبه الصورة التالية. الإحداثي Y يتم حسابه بإستخدام إقتران الجيب “Sine”, الذي يعتبر رياضيا مقابل للأمواج. هناك بعض المتغيرات التي يمكننا تغييرها:

•الإزاحة “Offset” هي اسهلها, لأنها ببساطه تحدد المسافة بين موقع منتصف الموجة على الشاشة.

•قيمة إرتفاع القمة “peakheight” يتم ضربها بناتج إقتران الجيب, مما يحدد إرتفاع الموجة.

•أخيرا, قيمة الإنسطاح “flatness” لها تأثيرا قوة (فاعلية) القيمة X , بحيث تسرع أو تبطئ من الموجة. هذا يزيد أو يقلل طول الموجة “wavelength”.

post-133895-1237038849_thumb.jpg

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

post-133895-1237038890_thumb.jpg

في الكود الخاص بنا, سوف نقوم بإضافة موجة ثالثة. لإنتاج بشكل مختلف في كل مره, سوف نقوم بالتأثير على 3 عوامل لكل موجة بقيم عشوائية. هذا ما يجب أن تبدو عليه دالة GenerateTerrainContour :

 private void GenerateTerrainContour()
 {
	 terrainContour = new int[screenWidth];

	 double rand1 = randomizer.NextDouble() + 1;
	 double rand2 = randomizer.NextDouble() + 2;
	 double rand3 = randomizer.NextDouble() + 3;

	 float offset = screenHeight / 2;
	 float peakheight = 100;
	 float flatness = 70;

	 for (int x = 0; x < screenWidth; x++)
	 {
		 double height = peakheight / rand1 * Math.Sin((float)x / flatness * rand1 + rand1);
		 height += peakheight / rand2 * Math.Sin((float)x / flatness * rand2 + rand2);
		 height += peakheight / rand3 * Math.Sin((float)x / flatness * rand3 + rand3);
		 height += offset;
		 terrainContour[x] = (int)height;
	 }
 }

لكل موجة, قمنا أولا بإختيار قيمة عشوائية بين ال 0 و 1. بعدها قمنا بإزاحتها قليلا, بحيث أصبحت القيمة الأولى في المجال [0-1], و القيمة الثاينة بين ال [1-2], و الأخيره بين ال [2-3]. للموجات الثلاثة , هذه القيم سوف يتم تقسيمها على ال “peakheight” وعلى ال “flatness”, إذن الموجة الثالثة سوف تكون أقصر و أخفض من الموجة الأولى و الثانية. علاوة على ذلك, يجب أن تلاحظ أننا قمنا بإضافة القيم العشوائية داخل دالة الجيب. من ناحية أخرى كل الموجات الثلاثة يجب أن يبدءون بالإحداثي Y المحدد بال “offset”, مما يجعل هذه النقطة ثابته في كل مره نبدأ فيها اللعبة.

الآن عندما تحاول تشغيل الكود, سوف تحصل على تضاريس مع إنحدارات أفضل, كما يظهر في الصورة في آخر الدرس.

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

لحل هذه المشكلة , إبحث عن الأسطر الأربعة المسؤولين عن تحديد أماكن اللاعبين في الدالة SetUpPlayers , وقم بحذفهم. بدلا من ذلك , سوف نقوم بحساب المواقع في داخل التكرار في تلك الدالة , يجب أن يكون الكود على النحو التالي:

 for (int i = 0; i < numberOfPlayers; i++)
 {
	 players.IsAlive = true;
	 players.Color = playerColors;
	 players.Angle = MathHelper.ToRadians(90);
	 players.Power = 100;
	 players.Position = new Vector2();
	 players.Position.X = screenWidth / (numberOfPlayers + 1) * (i + 1);
	 players.Position.Y = terrainContour[(int)players.Position.X];
 }

الإحداثي X للاعبين يمكن إيجاده بسهولة عن طريق تقسيم عرض الشاشة على عدد اللاعبين. ال “+1” يلزم لكي نتأكد أنه لا يوجد أي لاعب على يمين أو يسار حدود الشاشة. الإحداثي Y يمكن إيجاده بسهولة أيضا من خلال معرفة إرتفاع التضاريس في الموقع الحالي (الإحداثي X الحالي).

على كل حال, لكي يعمل هذا الكود يجب أن تستطيع الدالة SetUpPlayers الوصول إلى مصفوفة ال terrainContour النهائية. هذا يعني أنه في داخل دالة LoadContent ,يجب علينا ان نستدعي الدالة SetUpPlayers بعد إستدعائنا للدالة GenerateTerrainContour :

 GenerateTerrainContour();
 SetUpPlayers();
 CreateForeground();

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

 private void FlattenTerrainBelowPlayers()
 {
	 foreach (PlayerData player in players)
		 if (player.IsAlive)
			 for (int x = 0; x < 40; x++)
				 terrainContour[(int)player.Position.X + x] = terrainContour[(int)player.Position.X];
 }

لكل لاعب, الأرضية تحت المدفع تم تسويتها إلى نفس الإرتفاع الخاص بالركن السفلي الأيسر للمدفع. سوف نحتاج لإستدعاء هذه الدالة من داخل دالة ال LoadContent, و لكن يجب أن نبقي شيئا في بالنا هو أن إستدعاء هذه الدالة يجب أن يتم بعد إستدعاء دالة ال GenerateTerrainContour و دالة ال SetUpPlayers , بما أنها تستخدم البيانات التي يتم تعريفها في تلك الدوال. من ناحية أخرى يجب أن يتم إستدعائها قبل إستدعاء الدالة CreateForeground , بما أنه هذه الدالة (الاخيره) تستخدم مخرجات الدالة TerrainContour , التي تم تعديلها بإستخدام دالة ال FlattenTerrainBelowPlayers :

 GenerateTerrainContour();			
 SetUpPlayers();
 FlattenTerrainBelowPlayers();
 CreateForeground();

عند تشغيل الكود هذه المرة, يجب أن يكون إنحدار التضاريس ممتازا -_-

post-133895-1237038914_thumb.jpg 

التمرين في هذا الدرس: هو محاولة التدرب على إستخدام دالة الجيب في رسم التضاريس.

في الدرس القادم سوف نجد حلا للون الأخضر, إن شاء الله.

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

 using System;

 using System.[color= #202020;]Collections.[color= #202020;]Generic;

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

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

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

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

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

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

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

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

 

 namespace XNAtutorial

 [color= #009900;]{

     public [color= #993333;]struct PlayerData

     [color= #009900;]{

         public Vector2 Position;

         public bool IsAlive;

         public Color Color;

         public [color= #993333;]float Angle;

         public [color= #993333;]float Power;

     [color= #009900;]}

 

     public class Game1 [color= #339933;]: Microsoft.[color= #202020;]Xna.[color= #202020;]Framework.[color= #202020;]Game

     [color= #009900;]{

         GraphicsDeviceManager graphics;

         SpriteBatch spriteBatch;

         GraphicsDevice device;

 

         [color= #993333;]int screenWidth;

         [color= #993333;]int screenHeight;

 

         Texture2D backgroundTexture;

         Texture2D foregroundTexture;

         Texture2D carriageTexture;

         Texture2D cannonTexture;

         Texture2D rocketTexture;

         Texture2D smokeTexture;

         SpriteFont font;

 

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

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

         [color= #993333;]float playerScaling;

         [color= #993333;]int currentPlayer [color= #339933;]= [color= #cc66cc;]0;

 

         bool rocketFlying [color= #339933;]= [color= #000000; font-weight: bold;]false;

         Vector2 rocketPosition;        

         Vector2 rocketDirection;

         [color= #993333;]float rocketAngle;

         [color= #993333;]float rocketScaling [color= #339933;]= [color= #cc66cc;]0.1f;

 

        List<Vector2> smokeList [color= #339933;]= new List<Vector2> [color= #009900;]([color= #009900;]);        

        Random randomizer [color= #339933;]= new Random[color= #009900;]([color= #009900;]);

        [color= #993333;]int[color= #009900;][[color= #009900;]] terrainContour;

 

        public Game1[color= #009900;]([color= #009900;])

        [color= #009900;]{

            graphics [color= #339933;]= new GraphicsDeviceManager[color= #009900;](this[color= #009900;]);

            Content.[color= #202020;]RootDirectory [color= #339933;]= [color= #ff0000;]"Content";

        [color= #009900;]}

 

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

        [color= #009900;]{

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

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

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

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

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

 

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

        [color= #009900;]}

 

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

        [color= #009900;]{

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

            spriteBatch [color= #339933;]= new SpriteBatch[color= #009900;](device[color= #009900;]);

 

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

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

 

 

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

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

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

            rocketTexture [color= #339933;]= Content.[color= #202020;]Load<Texture2D> [color= #009900;]([color= #ff0000;]"rocket"[color= #009900;]);

            smokeTexture [color= #339933;]= Content.[color= #202020;]Load<Texture2D> [color= #009900;]([color= #ff0000;]"smoke"[color= #009900;]);

            font [color= #339933;]= Content.[color= #202020;]Load<SpriteFont> [color= #009900;]([color= #ff0000;]"myFont"[color= #009900;]);                        

            playerScaling [color= #339933;]= [color= #cc66cc;]40.0f [color= #339933;]/ [color= #009900;]([color= #993333;]float[color= #009900;])carriageTexture.[color= #202020;]Width;

 

             GenerateTerrainContour[color= #009900;]([color= #009900;]);            

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

             FlattenTerrainBelowPlayers[color= #009900;]([color= #009900;]);

             CreateForeground[color= #009900;]([color= #009900;]);

         [color= #009900;]}

 

         private [color= #993333;]void SetUpPlayers[color= #009900;]([color= #009900;])

         [color= #009900;]{

             Color[color= #009900;][[color= #009900;]] playerColors [color= #339933;]= new Color[color= #009900;][[color= #cc66cc;]10[color= #009900;]];

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

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

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

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

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

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

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

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

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

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

 

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

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

             [color= #009900;]{

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

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

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

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

                 players[color= #009900;][i[color= #009900;]].[color= #202020;]Position [color= #339933;]= new Vector2[color= #009900;]([color= #009900;]);

                 players[color= #009900;][i[color= #009900;]].[color= #202020;]Position.[color= #202020;]X [color= #339933;]= screenWidth [color= #339933;]/ [color= #009900;](numberOfPlayers [color= #339933;]+ [color= #cc66cc;]1[color= #009900;]) [color= #339933;]* [color= #009900;](i [color= #339933;]+ [color= #cc66cc;]1[color= #009900;]);

                 players[color= #009900;][i[color= #009900;]].[color= #202020;]Position.[color= #202020;]Y [color= #339933;]= terrainContour[color= #009900;][[color= #009900;]([color= #993333;]int[color= #009900;])players[color= #009900;][i[color= #009900;]].[color= #202020;]Position.[color= #202020;]X[color= #009900;]];

             [color= #009900;]}

         [color= #009900;]}

 

         private [color= #993333;]void GenerateTerrainContour[color= #009900;]([color= #009900;])

         [color= #009900;]{

             terrainContour [color= #339933;]= new [color= #993333;]int[color= #009900;][screenWidth[color= #009900;]];

 

             [color= #993333;]double rand1 [color= #339933;]= randomizer.[color= #202020;]NextDouble[color= #009900;]([color= #009900;]) [color= #339933;]+ [color= #cc66cc;]1;

             [color= #993333;]double rand2 [color= #339933;]= randomizer.[color= #202020;]NextDouble[color= #009900;]([color= #009900;]) [color= #339933;]+ [color= #cc66cc;]2;

             [color= #993333;]double rand3 [color= #339933;]= randomizer.[color= #202020;]NextDouble[color= #009900;]([color= #009900;]) [color= #339933;]+ [color= #cc66cc;]3;

 

             [color= #993333;]float offset [color= #339933;]= screenHeight [color= #339933;]/ [color= #cc66cc;]2;

             [color= #993333;]float peakheight [color= #339933;]= [color= #cc66cc;]100;

             [color= #993333;]float flatness [color= #339933;]= [color= #cc66cc;]70;

 

             [color= #b1b100;]for [color= #009900;]([color= #993333;]int x [color= #339933;]= [color= #cc66cc;]0; x < screenWidth; x[color= #339933;]++[color= #009900;])

             [color= #009900;]{

                 [color= #993333;]double height [color= #339933;]= peakheight [color= #339933;]/ rand1 [color= #339933;]* Math.[color= #202020;]Sin[color= #009900;]([color= #009900;]([color= #993333;]float[color= #009900;])x [color= #339933;]/ flatness [color= #339933;]* rand1 [color= #339933;]+ ra
nd1[color= #009900;]);

                 height [color= #339933;]+= peakheight [color= #339933;]/ rand2 [color= #339933;]* Math.[color= #202020;]Sin[color= #009900;]([color= #009900;]([color= #993333;]float[color= #009900;])x [color= #339933;]/ flatness [color= #339933;]* rand2 [color= #339933;]+ rand2[color= #009900;]);

                 height [color= #339933;]+= peakheight [color= #339933;]/ rand3 [color= #339933;]* Math.[color= #202020;]Sin[color= #009900;]([color= #009900;]([color= #993333;]float[color= #009900;])x [color= #339933;]/ flatness [color= #339933;]* rand3 [color= #339933;]+ rand3[color= #009900;]);

                 height [color= #339933;]+= offset;

                 terrainContour[color= #009900;][x[color= #009900;]] [color= #339933;]= [color= #009900;]([color= #993333;]int[color= #009900;])height;

             [color= #009900;]}

         [color= #009900;]}

 

         private [color= #993333;]void FlattenTerrainBelowPlayers[color= #009900;]([color= #009900;])

         [color= #009900;]{

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

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

                     [color= #b1b100;]for [color= #009900;]([color= #993333;]int x [color= #339933;]= [color= #cc66cc;]0; x < [color= #cc66cc;]40; x[color= #339933;]++[color= #009900;])

                         terrainContour[color= #009900;][[color= #009900;]([color= #993333;]int[color= #009900;])player.[color= #202020;]Position.[color= #202020;]X [color= #339933;]+ x[color= #009900;]] [color= #339933;]= terrainContour[color= #009900;][[color= #009900;]([color= #993333;]int[color= #009900;])playe
r.[color= #202020;]Position.[color= #202020;]X[color= #009900;]];

         [color= #009900;]}

 

         private [color= #993333;]void CreateForeground[color= #009900;]([color= #009900;])

         [color= #009900;]{

             Color[color= #009900;][[color= #009900;]] foregroundColors [color= #339933;]= new Color[color= #009900;][screenWidth [color= #339933;]* screenHeight[color= #009900;]];

 

             [color= #b1b100;]for [color= #009900;]([color= #993333;]int x [color= #339933;]= [color= #cc66cc;]0; x < screenWidth; x[color= #339933;]++[color= #009900;])

             [color= #009900;]{

                 [color= #b1b100;]for [color= #009900;]([color= #993333;]int y [color= #339933;]= [color= #cc66cc;]0; y < screenHeight; y[color= #339933;]++[color= #009900;])

                 [color= #009900;]{

                     [color= #b1b100;]if [color= #009900;](y > terrainContour[color= #009900;][x[color= #009900;]][color= #009900;])

                         foregroundColors[color= #009900;][x [color= #339933;]+ y [color= #339933;]* screenWidth[color= #009900;]] [color= #339933;]= Color.[color= #202020;]Green;

                     [color= #b1b100;]else                        

                         foregroundColors[color= #009900;][x [color= #339933;]+ y [color= #339933;]* screenWidth[color= #009900;]] [color= #339933;]= Color.[color= #202020;]TransparentBlack;

                 [color= #009900;]}

             [color= #009900;]}

 

             foregroundTexture [color= #339933;]= new Texture2D[color= #009900;](device, screenWidth, screenHeight, [color= #cc66cc;]1, TextureUsa
ge.[color= #202020;]None, SurfaceFormat.[color= #202020;]Color[color= #009900;]);

             foregroundTexture.[color= #202020;]SetData[color= #009900;](foregroundColors[color= #009900;]);

         [color= #009900;]}

 

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

         [color= #009900;]{

         [color= #009900;]}

 

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

         [color= #009900;]{

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

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

 

             ProcessKeyboard[color= #009900;]([color= #009900;]);

             UpdateRocket[color= #009900;]([color= #009900;]);

 

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

         [color= #009900;]}

 

         private [color= #993333;]void ProcessKeyboard[color= #009900;]([color= #009900;])

         [color= #009900;]{

             KeyboardState keybState [color= #339933;]= Keyboard.[color= #202020;]GetState[color= #009900;]([color= #009900;]);

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Left[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle [color= #339933;]-= [color= #cc66cc;]0.01f;

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Right[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle [color= #339933;]+= [color= #cc66cc;]0.01f;

 

             [color= #b1b100;]if [color= #009900;](players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle > MathHelper.[color= #202020;]PiOver2[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle [color= #339933;]= [color= #339933;]-MathHelper.[color= #202020;]PiOver2;

             [color= #b1b100;]if [color= #009900;](players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle < [color= #339933;]-MathHelper.[color= #202020;]PiOver2[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle [color= #339933;]= MathHelper.[color= #202020;]PiOver2;

 

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Down[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]-= [color= #cc66cc;]1;

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Up[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]+= [color= #cc66cc;]1;

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]PageDown[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]-= [color= #cc66cc;]20;

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]PageUp[color= #009900;])[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]+= [color= #cc66cc;]20;

 

             [color= #b1b100;]if [color= #009900;](players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power > [color= #cc66cc;]1000[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]= [color= #cc66cc;]1000;

             [color= #b1b100;]if [color= #009900;](players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power < [color= #cc66cc;]0[color= #009900;])

                 players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]= [color= #cc66cc;]0;

 

             [color= #b1b100;]if [color= #009900;](keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Enter[color= #009900;]) || keybState.[color= #202020;]IsKeyDown[color= #009900;](Keys.[color= #202020;]Space[color= #009900;])[color= #009900;])

             [color= #009900;]{

                 rocketFlying [color= #339933;]= [color= #000000; font-weight: bold;]true;

                 rocketPosition [color= #339933;]= players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Position;

                 rocketPosition.[color= #202020;]X [color= #339933;]+= [color= #cc66cc;]20;

                 rocketPosition.[color= #202020;]Y [color= #339933;]-= [color= #cc66cc;]10;

                 rocketAngle [color= #339933;]= players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Angle;

                 Vector2 up [color= #339933;]= new Vector2[color= #009900;]([color= #cc66cc;]0, [color= #cc66cc;]-1[color= #009900;]);

                 Matrix rotMatrix [color= #339933;]= Matrix.[color= #202020;]CreateRotationZ[color= #009900;](rocketAngle[color= #009900;]);

                 rocketDirection [color= #339933;]= Vector2.[color= #202020;]Transform[color= #009900;](up, rotMatrix[color= #009900;]);

                 rocketDirection [color= #339933;]*= players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]Power [color= #339933;]/ [color= #cc66cc;]50.0f;

             [color= #009900;]}

         [color= #009900;]}

 

         private [color= #993333;]void UpdateRocket[color= #009900;]([color= #009900;])

         [color= #009900;]{

             [color= #b1b100;]if [color= #009900;](rocketFlying[color= #009900;])

             [color= #009900;]{

                 Vector2 gravity [color= #339933;]= new Vector2[color= #009900;]([color= #cc66cc;]0, [color= #cc66cc;]1[color= #009900;]);

                 rocketDirection [color= #339933;]+= gravity [color= #339933;]/ [color= #cc66cc;]10.0f;

                 rocketPosition [color= #339933;]+= rocketDirection;

                 rocketAngle [color= #339933;]= [color= #009900;]([color= #993333;]float[color= #009900;])Math.[color= #202020;]Atan2[color= #009900;](rocketDirection.[color= #202020;]X, [color= #339933;]-rocketDirection.[color= #202020;]Y[color= #009900;]);

 

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

                 [color= #009900;]{

                     Vector2 smokePos [color= #339933;]= rocketPosition;

                     smokePos.[color= #202020;]X [color= #339933;]+= randomizer.[color= #202020;]Next[color= #009900;]([color= #cc66cc;]10[color= #009900;]) [color= #339933;]- [color= #cc66cc;]5;

                     smokePos.[color= #202020;]Y [color= #339933;]+= randomizer.[color= #202020;]Next[color= #009900;]([color= #cc66cc;]10[color= #009900;]) [color= #339933;]- [color= #cc66cc;]5;

                     smokeList.[color= #202020;]Add[color= #009900;](smokePos[color= #009900;]);

                 [color= #009900;]}

             [color= #009900;]}

         [color= #009900;]}

 

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

         [color= #009900;]{

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

 

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

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

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

             DrawText[color= #009900;]([color= #009900;]);

             DrawRocket[color= #009900;]([color= #009900;]);

             DrawSmoke[color= #009900;]([color= #009900;]);

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

 

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

         [color= #009900;]}

 

         private [color= #993333;]void DrawScenery[color= #009900;]([color= #009900;])

         [color= #009900;]{

             Rectangle screenRectangle [color= #339933;]= new Rectangle[color= #009900;]([color= #cc66cc;]0, [color= #cc66cc;]0, screenWidth, screenHeight[color= #009900;]);

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

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

         [color= #009900;]}

 

         private [color= #993333;]void DrawPlayers[color= #009900;]([color= #009900;])

         [color= #009900;]{

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

             [color= #009900;]{

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

                 [color= #009900;]{

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

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

                     Vector2 cannonOrigin [color= #339933;]= new Vector2[color= #009900;]([color= #cc66cc;]11, [color= #cc66cc;]50[color= #009900;]);

 

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

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

                 [color= #009900;]}

             [color= #009900;]}

         [color= #009900;]}

 

         private [color= #993333;]void DrawText[color= #009900;]([color= #009900;])

         [color= #009900;]{

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

             [color= #993333;]int currentAngle [color= #339933;]= [color= #009900;]([color= #993333;]int[color= #009900;])MathHelper.[color= #202020;]ToDegrees[color= #009900;](player.[color= #202020;]Angle[color= #009900;]);

             spriteBatch.[color= #202020;]DrawString[color= #009900;](font, [color= #ff0000;]"Cannon angle: " [color= #339933;]+ currentAngle.[color= #202020;]ToString[color= #009900;]([color= #009900;]), new Vecto
r2[color= #009900;]([color= #cc66cc;]20, [color= #cc66cc;]20[color= #009900;]), player.[color= #202020;]Color[color= #009900;]);

             spriteBatch.[color= #202020;]DrawString[color= #009900;](font, [color= #ff0000;]"Cannon power: " [color= #339933;]+ player.[color= #202020;]Power.[color= #202020;]ToString[color= #009900;]([color= #009900;]), new Vecto
r2[color= #009900;]([color= #cc66cc;]20, [color= #cc66cc;]45[color= #009900;]), player.[color= #202020;]Color[color= #009900;]);

         [color= #009900;]}

 

         private [color= #993333;]void DrawRocket[color= #009900;]([color= #009900;])

         [color= #009900;]{

             [color= #b1b100;]if [color= #009900;](rocketFlying[color= #009900;])

                 spriteBatch.[color= #202020;]Draw[color= #009900;](rocketTexture, rocketPosition, [color= #000000; font-weight: bold;]null, players[color= #009900;][currentPlayer[color= #009900;]].[color= #202020;]C
olor, rocketAngle, new Vector2[color= #009900;]([color= #cc66cc;]42, [color= #cc66cc;]240[color= #009900;]), [color= #cc66cc;]0.1f, SpriteEffects.[color= #202020;]None, [color= #cc66cc;]1[color= #009900;]);

         [color= #009900;]}

 

         private [color= #993333;]void DrawSmoke[color= #009900;]([color= #009900;])

         [color= #009900;]{

             foreach [color= #009900;](Vector2 smokePos in smokeList[color= #009900;])

                 spriteBatch.[color= #202020;]Draw[color= #009900;](smokeTexture, smokePos, [color= #000000; font-weight: bold;]null, Color.[color= #202020;]White, [color= #cc66cc;]0, new Vector2[color= #009900;]([color= #cc66cc;]40,
 [color= #cc66cc;]35[color= #009900;]), [color= #cc66cc;]0.2f, SpriteEffects.[color= #202020;]None, [color= #cc66cc;]1[color= #009900;]);

         [color= #009900;]}

     [color= #009900;]}

 [color= #009900;]}

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

Learn_Xna12.pdf

#2

للإستزادة و التذكير :

http://en.wikipedia.org/wiki/Sine_wave

أقرب شي للموضوع بالعربيه:(:( :( , في ويكي

http://ar.wikipedia.org/wiki/مو...;ات

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

#3
اقتباس
التمرين في هذا الدرس: هو محاولة التدرب على إستخدام دالة الجيب في رسم التضاريس.

بارك الله فيك أخي على هذا الجهد المتواصل :) ,

- في الحقيقة .. خطرت ببالي فكرة أثناء قراءة مقالتك ... لماذا لانستخدم طرق أسهل من SIN , بحيث نتحكم بشكل التضاريس كما نحب .

- الفكرة هي شبيهة بفكرة التضاريس الثلاثية الابعاد التي تعتمد على صورة RAW , على ما أظن تسمّى بالـheight map .

* قم بعمل صورة في الفوتوشوب مثلا .. ( بأي ارتفاع تريد .. مثلا 1 بكسل :) , أو 100 بكسل .. فقط لتتمكن من تحرير الصورة ..و العرض يكون عرض التضاريس المطلوب .

* الصورة تكون بتدرج رمادي grayscale .

* اعمل تدرج لوني شبيه بهذا التدرج :

post-42837-1237451790_thumb.jpg

* قم بقراءة الصورة .. وتحميل بكسلاتها ..

* الان نقرأ بكسل واحد في كل عمود ... وننتقل الى العمود التالي :

int y= 1;
int i=0;
for( int x=0;x<image.width(); x++)
{
i++;
terrain.y = image.getPixel(x).toInteger(); // حول لون البكسل الى رقم .. مثلا لو كان لو البكسل 200 - 200 - 200 فهذا يعني ان الارتفاع = 200 بكسل
terrain.x++;
}

هذه الفكرة هي نفسها المطبقة في العالم ثلاثي الابعاد .. ولكن ممكن ننقلها الى العالم الثنائي الابعاد .. ونكسب براءة اختراع أيضا :D

أتمنى تنفيذ هذه الفكرة , لكن في الوقت الحالي لا أملك الوقت + لا أعرف الكثير عن قراءة الملفات والصور في السي شارب , لازلت في مرحلة تعلّم اللغة نفسها ..

هذه مجرد فكرة ;)

تم تعديل هذه المشاركة بواسطة الشمري في 19 مارس 2009 في 11:38

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#4

أهلا بك أخ شمري من جديد :)

الفكره جيدة جدا, أذكر إستخدمنا شيئا من هذا القبيل (في ال 3Ds Max)

ولكنها لا تحقق لنا متطلباتنا هنا :P لأنها لا تعطينا تضاريس عشوائية في كل مرة نشغل اللعبة

اقتباس
أتمنى تنفيذ هذه الفكرة , لكن في الوقت الحالي لا أملك الوقت

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

شكرا للمتابعة..

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