1. وصف المتطلبات
1. المتطلبات الوظيفية
في مرحلة تحليل المتطلبات الوظيفية ، تتمثل مهمتنا الرئيسية في تحديد الخدمات التي يجب على النظام تقديمها ، وتحديد الوظائف التي يكملها البرنامج ، وتزويدهم بهؤلاء الأشخاص. المتطلبات الوظيفية هي شرط أساسي لتطوير البرمجيات وجزء لا غنى عنه من تحليل الطلب. Tank War هي لعبة كلاسيكية. لقد تعلمت هذه اللعبة بعض تجارب السلف. وعموما ، تنقسم اللعبة إلى جانبي العدو والولايات المتحدة. يتم التحكم في الدبابات التي تشارك بشكل أساسي في المعركة من قبل اللاعبين. يمكن أن تظهر خزانات العدو بذكاء وعشوائي على الشاشة والتحرك ، مع إطلاق عدد معين من الرصاص ؛ يمكن للاعبين نقل الخزانات في الإرادة في المنطقة المحددة. عندما تضرب الرصاصة اللاعب ، يموت اللاعب وينتهي اللعبة ؛ دبابات العدو تعمل بذكاء. نظرًا لأنهم بحاجة إلى الحصول على درجة معينة من الذكاء ، فإنها تظهر بشكل عشوائي على الشاشة ، وتدور بحرية ، مثل: معرفة التوجيه عند مواجهة الحدود ؛ تشغيل الرصاص: يتم التحكم في الخزانات من قبل اللاعبين ورصاص النار وفقًا لمواقع الخزان المختلفة. إذا وصلوا إلى الهدف ، سيتم إنتاج تأثير الانفجار ؛ سوف تختفي أيضا على الشاشة.
2. متطلبات أداء النظام
تتمثل متطلبات تكوين أداء اللعبة القائمة على أنظمة الكمبيوتر في التأكد من أن البرنامج يمكن أن يعمل بسرعة وبثبات ويمكنه الاستجابة في الوقت المناسب عند التشغيل. عندما يتم تدمير خزان اللاعب في اللعبة ، يطالب على الفور بمعلومات حول فشل اللعبة والرد في الوقت المناسب لتلبية متطلبات قاعدة اللعبة. بالإضافة إلى ذلك ، من الضروري أيضًا التأكد من أنه لا يمكن تغيير حجم النافذة الرئيسية عند الرغبة عند لعب اللعبة ، مما يضمن إمكانية اللعب.
3. الحلول الوظيفية
معدل استخدام الكود جيد جدًا في اللعبة. بعد كل شيء ، إنه عمل في الوقت الفعلي. كل ميلي ثانية ، سيكون هناك العديد من الرصاصات التي تم إطلاقها ، وحركة الإحداثيات للعديد من الدبابات. قارنت عدد الرصاص الذي يصل إلى الخزان مرات لا تحصى ، وأحداث مراقبة لوحة المفاتيح ، وتنفيذ واجهة الخيط ، ورسم إعادة رسم وتقليل ؛ يجب أن يكون الشعور بالمنطق قويًا ، ويتم عرض الشاشة الموجهة نحو الكائن بالكامل ؛ حتى العلاقة بينهما غير واضحة ، ومن السهل أن يكون لديك مواقف غير متوقعة ؛ من أجل جعل إضافة الجمال وإضافة انفجار في اللعبة ، يتطلب ذلك عندما يموت خزان العدو ، وهو عبارة عن كاروسيل قصير وسريع للأماكن الثابتة على اللوحة الخارجية لتحقيق تأثير انفجار ؛
بشكل عام ، تشمل الوظائف الأساسية التي يجب إكمالها في معارك الخزانات: الواجهة الرسومية ، والاختلافات في أنماط الدبابات من العدو إلى مي ، ويمكن للدبابات أن تطلق النار على الرصاص لمهاجمة الخصم ، ولكن لا يمكنها مهاجمة زملائه في الفريق ، وتضع الدبابات نقاط صحية معينة ؛
2. تحليل الوظائف الرئيسية
في عملية تطوير لعبة حرب الخزانات ، يتم توفير الوظائف الرئيسية للمستخدمين للاستخدام ، لذلك يجب عليك أولاً رسم الخزان.
1. ارسم دبابة اللاعب: تحتاج إلى ضبط Paint () على لوحة JPanel ورسم الشكل التقريبي للخزان بفرشاة ؛
2. يمكن أن تتحرك خزانات اللاعبين: إذا تحركت الخزان ، فيجب عليها تغيير إحداثيات الخزان وإعادة طلاء اللوحة باستمرار. ومع ذلك ، عندما تتحرك الخزانات ، يمكن تنفيذ واجهة آلية مراقبة الأحداث (مراقبة لوحة المفاتيح) في فئة اللوحة. عندما يضغط اللاعب على مفتاح W/D/S/A ، يمكن أن يتحرك لأعلى ولأسفل ، يسارًا ويمينًا ؛
3. ورسم خزانات العدو على طلاء ورق الرسم الخاص بي () ؛ نظرًا لأن دبابات العدو وخزانات اللاعبين موجودة على نفس الواجهة ، يجب رسمها على لوحة الرسم نفسها ؛
4. يمكن لدبابات اللاعبين النار على الرصاص: إذا أراد اللاعب إطلاق الرصاص ، فيجب أن يكون لديهم مصدر حدث. عندما يضغط المستخدم على مفتاح J ، ستطلق مراقبة الحدث رصاصة على الفور ، ولكن يجب عرضها أمام عيون المستخدم لرؤية التأثير ، لذا فإن Paint () يرسم الرصاصة على اللوحة ؛ نظرًا لأن الرصاصة يتم إطلاقها وتتحرك باستمرار نحو الإطلاق ، يجب تغيير إحداثيات الرصاصة باستمرار ، ويجب أن تكون سرعة الرصاص مناسبة ، لذلك يجب تنفيذها مع خيوط ويتم إعادة رسم اللوحة باستمرار لرؤية التأثير ؛
5. يمكن للاعبين إطلاق النار على الرصاص على التوالي وإطلاق النار حتى خمسة: إذا كان اللاعب يريد التحكم في عدد الرصاص ، فهو بحاجة إلى معرفة ما إذا كان عدد الرصاص الباقين على قيد الحياة أقل من 5 عندما يضغط اللاعب على مفتاح J. عند استيفاء الظروف ، سيتم إنشاء رصاصة واحدة. عندما يطلق اللاعب أكثر من خمس رصاصات ، لن يتم استدعاء وظيفة حريق النظام ؛ نظرًا لأن إطلاق الرصاص لا يطلق رصاصة واحدة فحسب ، بل قم بإعداد مجموعة من الرصاص لتوليد رصاصة واحدة في وقت واحد لمعرفة أن الرصاص تموت عندما يصلون إلى الحدود وتموت ؛
6. عندما يضرب دبابة اللاعب خزان العدو ، فإنه يختفي وينتج تأثير انفجار ؛ أولاً ، من الضروري تحديد ما إذا كانت رصاصة دبابة اللاعب تضرب العدو ، لذلك هناك وظيفة للحكم باستمرار على العدو. عندما تعمل الرصاصة على خزان العدو ، يجب أن تنتهي حياة الخزان ، ويتم إنشاء قنبلة ، ويتم رسم قنبلة في الطلاء () ؛
7. يمكن أن يتحرك خزان العدو بذكاء: إذا كان الخزان يمكن أن يتحرك فقط ، فإنه يحتاج إلى توليد اتجاه الحركة بشكل عشوائي. بسبب الحركة المستمرة ، تتم كتابة الطريقة في وظيفة تشغيل مؤشر الترابط ويتم التحكم في مؤشر الترابط للنوم لتحقيق مشكلة سرعة الحركة ؛
8. يمكن أن تطلق خزانات العدو الرصاص: أثناء رسم العدو ، وضع ندوة معينة في الخيط لتوليد رصاصات ذات اتجاهات مختلفة وأعداد مختلفة من الدبابات ، وأخرج كل رصاصة على اللوحة ورسمها ؛
9. عندما تضرب رصاصة العدو اللاعب ، يختفي اللاعب: استمر في إخراج كل رصاصة من العدو ومقارنتها بخزان اللاعب. عندما تلمس الرصاصة اللاعب ، يختفي انفجار اللاعب ؛
3. التصميم الموجز
• إعدادات سمة الدور
الخزان: الموقع الذي يتم فيه إنشاء الخزان ، ولون أنواع مختلفة من الخزانات ، ومعرف حياة الخزان ، وسرعة حركة الخزان ، والدبابات في اتجاهات مختلفة ؛
دبابة اللاعب: بعد وراثة السمات الأساسية للخزان ، يتم تحقيقه على أساس الأساس الثاني ، ويتحرك خزان اللاعب بحرية لأعلى ولأسفل واليمين ؛ ويحتوي دبابة اللاعب على وظيفة إطلاق النار وإطلاق الرصاص ؛
دبابة العدو: بعد وراثة سمات الخزان الأساسية ، من الضروري إدراك الحركة الذكية لخزان العدو ، وفي الوقت نفسه ، يجب أن تطلق أيضًا خيوط رصاصة على الخزانات من مواقع مختلفة ؛
الرصاص: يجب أن يكون الرصاصة تنسيق الموقف ، يجب أن تكون السرعة والصحة والرصاص قادرة على التحرك ، ويجب أن تنفذ الرصاص طريقة وظائف الوفاة ؛
قنبلة: إحداثيات القنبلة والحياة وأسلوب التأثير في الحياة التي تختفي تدريجياً ؛
• إعدادات الممتلكات الوظيفية
رسم الرسم: يجب أن يرسم Paint () خزان اللاعب وخزان العدو وعرض تأثير الانفجار لخزان الموت ؛
مراقبة الأحداث: عندما يضغط المستخدم على WDSA ، يجب أن يغير خزان المشغل المقابل الاتجاه. عندما يطلق المستخدم J ، هناك رصاصة في اتجاه الإطلاق ، ويجب أن تعمل حتى الموت ، ما لم يضرب العدو ؛
ضرب الخزان: عندما تضرب الرصاصة خزان عدو ، يتم إنشاء انفجار وإضافته إلى مجموعة الانفجار ، ويتم رسم معلومات الانفجار على السطح ؛
ضرب الأعداء اللاعب: أخرج ما يسمى الأعداء في اللعبة وتطابق رصاصات كل عدو إلى دبابة لي لتحديد ما إذا كان سيتم ضربها ؛
يضرب اللاعبون العدو: أخرج كل رصاصة من اللاعب ، وتوافق مع كل خزان عدو لتحديد ما إذا كان سيتم ضربه ؛ ووضع الأحكام المتعلقة بضرب الخزان في تشغيل الخيط () لإصدار أحكام متزامنة مستمرة ؛
مخطط التحليل الوظيفي المحدد هو كما يلي:
• مخطط تحليل سمة حرف الخزان
مخطط تحليل لوحة الرسم الوظيفي
مخطط التحليل الشامل للدبابات XMind
سمة حرف الخزان مخطط Xmind
تُسمم وظيفة الخزان مخطط Xmind
رابعا. تنفيذ النظام
• الأعضاء
//members.javapackage mytank9 ؛ import java.util.*؛ class bomb {// تحديد إحداثيات القنابل int x ، y ؛ // حياة القنبلة هي الحياة int = 9 ؛ منطقية isLive = صواب ؛ قنبلة عامة (int x ، int y) {this.x = x ؛ this.y = y ؛ } // تقليل Health Public void LifeDown () {if (life> 0) {life-- ؛ } آخر {this.islive = false ؛ }}} تنفس لقطة الفئة {int x ؛ int y ؛ int مباشرة سرعة int = 1 ؛ منطقية isLive = صواب ؛ اللقطة العامة (int x ، int y ، int direct) {this.x = x ؛ this.y = y ؛ this.direct = direct ؛ } public void run () {بينما (true) {try {thread.sleep (50) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } switch (direct) {case 0: y- = speed ؛ استراحة؛ الحالة 1: x+= السرعة ؛ استراحة؛ الحالة 2: y+= السرعة ؛ استراحة؛ الحالة 3: x- = السرعة ؛ استراحة؛ } // تحديد ما إذا كان الحقل يضرب الحافة إذا (x <0 || x> 400 || y <0 || y> 300) {this.islive = false ؛ استراحة؛ }}}} فئة الخزان {// tank fenizontal Coversate int x = 0 ؛ // g الإحداثي العمودي int y = 0 ؛ منطقية isLive = صواب ؛ public int getColor () {return color ؛ } public void setColor (int color) {color = color ؛ } public int getSpeed () {return speed ؛ } public void setSpeed (int speed) {this.speed = speed ؛ } public int getDirect () {return direct ؛ } public void setDirect (int direct) {this.direct = direct ؛ } الخزان العام (int x ، int y) {this.x = x ؛ this.y = y ؛ } public int getx () {return x ؛ } public void setx (int x) {this.x = x ؛ } public int gety () {return y ؛ } public void sety (int y) {this.y = y ؛ }} // عدو دبابة فئة العدو يمتد أدوات الخزان {int times = 0 ؛ // تحديد ناقل يمكنه تخزين ناقلات العدو المتجه <flow> ss = new vector <flow> () ؛ // يضيف العدو رصاصات بعد خزان العدو فقط ؛ } Override public void run () {// todo method method method chogred بينما (صواب) {switch (this.direct) {case 0: // يشير إلى أن الخزان يتحرك لأعلى (int i = 0 ؛ i <30 ؛ i ++) {// تحركات خزان العدو في نطاقي إذا (y> 0) {y- = y- = السرعة ؛ } جرب {thread.sleep (50) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } } استراحة؛ الحالة 1: لـ (int i = 0 ؛ i <30 ؛ i ++) {if (x <400) {x+= speed ؛ } جرب {thread.sleep (50) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } } استراحة؛ الحالة 2: لـ (int i = 0 ؛ i <30 ؛ i ++) {if (y <300) {y+= speed ؛ } جرب {thread.sleep (50) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } } استراحة؛ الحالة 3: لـ (int i = 0 ؛ i <30 ؛ i ++) {if (x> 0) {x- = speed ؛ } جرب {thread.sleep (50) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } } استراحة؛ } // حدد ما إذا كنت بحاجة إلى إضافة رصاصة جديدة إلى الخزان this.times ++ ؛ if (times ٪ 2 == 0) {if (isLive) {if (ss.size () <5) {shot s = null ؛ Switch (direct) {case 0: // إنشاء رصاصة s = new shot (x+10 ، y ، 0) ؛ // أضف الرصاصة إلى المتجه ss.add (s) ؛ استراحة؛ الحالة 1: s = لقطة جديدة (x+30 ، y+10 ، 1) ؛ Ss.Add (s) ؛ استراحة؛ الحالة 2: s = لقطة جديدة (x+10 ، y+30 ، 2) ؛ Ss.Add (s) ؛ استراحة؛ الحالة 3: s = لقطة جديدة (x ، y+10 ، 3) ؛ Ss.Add (s) ؛ استراحة؛ }. T.Start () ؛ }}} // دع الخزان يولد بشكل عشوائي اتجاهًا جديدًا this.direct = (int) (Math.Random ()*4) ؛ // }}}}. لقطة S = فارغة ؛ البطل العام (int x ، int y) {super (x ، y) ؛ }. استراحة؛ الحالة 1: s = لقطة جديدة (x+30 ، y+10 ، 1) ؛ Ss.Add (s) ؛ استراحة؛ الحالة 2: s = لقطة جديدة (x+10 ، y+30 ، 2) ؛ Ss.Add (s) ؛ استراحة؛ الحالة 3: s = لقطة جديدة (x ، y+10 ، 3) ؛ Ss.Add (s) ؛ استراحة؛ } thread t = new thread (s) ؛ T.Start () ؛ }. } // tank moveright () {x+= speed ؛ } public void quadown () {y+= speed ؛ } public void moveleft () {x- = speed ؛ }} • mytankgame4.java
. الانفجار: 1 قم بإعداد ثلاث صور أولاً ؛ java.awt.event.*؛ java.io.file ؛ java.util. mp = new mypanel () ؛ T.Start () ؛ this.add (mp) ؛ // register للاستماع إلى this.addKeyListener (mp) ؛ this.setsize (400 ، 300) ؛ this.setDefaultCloseOperation (jframe.exit_on_close) ؛ this.setVisible (صحيح) ؛ }} class mypanel يمتد jpanel يطبق keylistener ، runnable {// تحديد بطل الدبابة الخاص بي = null ؛ // تحديد متجه دبابة العدو <EnemyTank> ets = new vector <Sehtank> () ؛ تحديد تبديل ثلاث صور لتشكيل صورة قنبلة Image1 = NULL ؛ Image Image2 = null ؛ Image Image3 = null ؛ // construct public mypanel () {Hero = New Hero (100،100) ؛ // تهيئة خزان العدو لـ (int i = 0 ؛ i <ensize ؛ i ++) {// إنشاء كائن عدو عدو العدو et = جديد reemtank ((i+1)*50 ، 0) ؛ et.setColor (0) ؛ et.setDirect (2) ؛ // ابدأ مؤشر ترابط خزان العدو t = مؤشر ترابط جديد (ET) ؛ T.Start () ؛ // التفاوض على رصاصة إلى لقطة عدو لقطة S = طلقة جديدة (et.x+10 ، et.y+30،2) ؛ et.ss.add (s) ؛ الموضوع T2 = مؤشر ترابط (مؤشر ترابط) جديد ؛ t2.start () ؛ // الانضمام إلى ets.add (et) ؛ } try {image1 = imageio.read (ملف جديد ("bomb_1.gif")) ؛ image2 = imageio.read (ملف جديد ("bomb_2.gif")) ؛ Image3 = imageio.read (ملف جديد ("bomb_3.gif")) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } // تهيئة ثلاث صور // image1 = toolkit.getDefaultToolkit (). getImage (panel.class.getResource ("/bomb_1.gif")) ؛ toolkit.getDefaultToolkit (). getImage (panel.class.getResource ("/bomb_3.gif")) ؛ } // REPAINT Public Void Paint (Graphics g) {super.paint (g) ؛ G.FillRect (0 ، 0 ، 400 ، 300) ؛ // ارسم الخزان الخاص بك إذا (hero.islive == true) {this.drawtank (hero.getx () ، hero.gety () ، g ، this.hero.direct ، 1) ؛ }. كيف ترسم رصاصات متعددة؟ اجتياز إذا (myshot! = null && myshot.islive == true) {g.draw3drect (myshot.x ، myshot.y ، 1 ، 1 ، false) ؛ } if (myshot.islive == false) {// قم بإزالة الرصاصة من SS Vector Hero.ss.remove (myshot) ؛ }} // ارسم القنبلة لـ (int i = 0 ؛ i <bombs.size () ؛ i ++) {bomb b = bombs.get (i) ؛ if (B.Life> 6) {g.drawImage (image1 ، bx ، by ، 30،30 ، this) ؛ } else if (b.life> 4) {g.drawImage (image2 ، bx ، by ، 30،30 ، this) ؛ } آخر {g.drawImage (image3 ، bx ، by ، 30،30 ، this) ؛ } // تقليل قيمة صحة B B.Lifedown () ؛ // إذا كانت القيمة الصحية للقنبلة == 0 ، قم بإخراجها إذا ( }} // ارسم خزان العدو لـ (int i = 0 ؛ i <ets.size () ؛ i ++) {eSeMtank et = ets.get (i) ؛ if (et.islive) {this.drawtank (et.getx () ، et.gety () ، g ، et.getDirect () ، 0) ؛ // ارسم رصاصة العدو لـ (int j = 0 ؛ j <et.ss.size () ؛ j ++) if (emeremyshot.islive) {g.draw3drect (heeremyshot.x ، heeremyshot.y ، 1 ، 1 ، false) ؛ } آخر {// توفي دبابة العدو et.ss.remove (العدو) ؛ }}}}}}}}} // ما إذا كانت رصاصة العدو تضربني hitme () {// قم بإزالة كل خزان عدو لـ (int i = 0 ؛ i <this.ets.size () ؛ i ++) {// take the reemy anemytank et = ets.get (i) ؛ if (et.islive == true) {for (int j = 0 ؛ j <et.ss.size () ؛ j ++) {// take the bullet shot heeremyshot = et.ss.get (j) ؛ if (emeremyshot.islive == true) {this.hittank (reemyshot ، Hero) ؛ }}}}}}}} ستر خارج كل دبابة وقاضي لـ (int j = 0 ؛ j <ets.size () ؛ j ++) {reemytank et = ets.get (j) ؛ if (et.islive == true) {this.hittank (myshot ، et) ؛ }}}}}}}}}}}} // لكتابة وظيفة خصيصًا لتحديد ما إذا كانت الرصاصة تضرب الخزان العام hittank (shot s ، tank et) {switch (et.direct) {// إذا كان اتجاه خزان العدو هو الحالة العلوية أو السفلية 0: الحالة 2: الحالة 2: if (sx> et.x && s.x <et.x+20 && s.y> et.y && s.y <et.y+30) {// hit death s.islive = false ؛ // tank death et.islive = false ؛ القنابل. } الحالة 1: الحالة 3: if (sx> et.x && s.x <et.x+30 && s.y> et.y && s.y <et.y+20) {{// hit death s.islive = false ؛ // enemy tank death et.islive = false ؛ قنبلة B = قنبلة جديدة (et.x ، et.y) ؛ القنابل. }}}}} ستر استراحة؛ الحالة 1: G.SetColor (color.yellow) ؛ استراحة؛ }. y+10 ، 10 ، 10) ؛ // ارسم الخط المستقيم g.drawline (x+10 ، y+15 ، x+10 ، y) ؛ استراحة؛ الحالة 1: // إلى اليمين // ارسم المستطيل العلوي G.Fill3Drect (x ، y ، 30 ، 5 ، false) ؛ // ارسم المستطيل السفلي g.fill3drect (x ، y+15 ، 30 ، 5 ، false) ؛ استراحة؛ الحالة 2: // ارسم الخزان أدناه G.Fill3Drect (x+15 ، y+10 ، x+30 ، y+10) ؛ // ارسم الخزان على اليمين g.fill3drect (x+15 ، y+10 ، x+30 ، y+10) ؛ // ارسم الخزان على اليمين g.fill3drect (x+15 ، y ، 5 ، 30 ، false) ؛ 10 ، 20 ، false) ؛ // ارسم المستطيل G.Fill3Drect (x+5 ، y+5 ، 10 ، 20 ، false) ؛ // drawline (x+10 ، y+10 ، 10 ، 10) ؛ استراحة؛ الحالة 3: // إلى اليسار // ارسم المستطيل العلوي G.Fill3Drect (x ، y ، 30 ، 5 ، false) ؛ // ارسم المستطيل السفلي g.fill3drect (x ، y+15 ، 30 ، 5 ، false) ؛ drawline (x+15 ، y+10 ، x ، y+10) ؛ استراحة؛ }} // اضغط على المفتاح وقم بمعالجته. اليسار لأسفل د إلى اليمين مع. Override public void keytytyped (keyevent e) {// todo method method method clud} override public void keypressed (keyevent e) {// todo method method method tuto clud if ( this.hero.moveup () ؛ } آخر if ( this.hero.foveright () ؛ } آخر if ( this.hero.movedown () ؛ } if if ( this.hero.moveleft () ؛ } if ( }} // يجب إعادة طلاء لوحة this.repaint () ؛ } Override public void keyreleSeped (keyevent e) {// todo method method method method}} public void run () {when (true) {try {thread.sleep (100) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } this.hitenemytank () ؛ // وظيفة تحدد ما إذا كانت رصاصة العدو تضربني this.hitme () ؛ this.repaint () ؛ }}}5. نتائج الاختبار
الأصفر هو اللاعب ، ضرب اللاعب
أعداء الرصاص النار
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.