تشارككم الأمثلة في هذه المقالة مع رمز تنفيذ Java المحدد Tetris للرجوع إليه. المحتوى المحدد كما يلي
احفظ خريطة اللعبة باستخدام صفيف ثنائي الأبعاد:
// شبكة خريطة اللعبة ، كل شبكة تنقذ مربعًا واحدًا ، قم بتسجيل حالة خريطة الحالة الخاصة [] [] = حالة جديدة [صفوف] [أعمدة] ؛
تهيئة جميع الشبكات في الخريطة لتفريغها قبل اللعبة:
/* تهيئة جميع الكتل إلى فارغة*/for (int i = 0 ؛ i <map.length ؛ i ++) {for (int j = 0 ؛ j <map [i] .length ؛ j ++) {map [i] [j] = state.empty ؛ }}خلال اللعبة ، يمكننا أن نرى الكتل الموجودة على الواجهة ، لذلك يتعين علينا رسم جميع الكتل في الخريطة. بالطبع ، بالإضافة إلى رسم الكتل ، يجب أيضًا رسم نقاط اللعبة ونهاية اللعبة عند الضرورة:
/*** ارسم محتوى النموذج ، بما في ذلك كتل اللعبة ، ونقاط اللعبة أو السلسلة النهائية*/@OutdRidepublic Void Paint (Graphics G) {super.paint (g) ؛ لـ (int i = 0 ؛ i <rows ؛ i ++) {for (int j = 0 ؛ j <أعمدة ؛ j ++) {if (map [i] == state.active) {// ارسم الكتلة النشطة g.setColor (activecolor) ؛ G.FillRoundRect (j * block_size ، i * block_size + 25 ، block_size - 1 ، block_size - 1 ، block_size / 5 ، block_size / 5) ؛ } آخر if (map [i] [j] == state.stoped) {// ارسم كتلة ثابتة g.setColor (stopedColor) ؛ G.FillRoundRect (j * block_size ، i * block_size + 25 ، block_size - 1 ، block_size - 1 ، block_size / 5 ، block_size / 5) ؛ }}} /* print score* / g.setColor (ScoreColor) ؛ G.SetFont (خط جديد ("Times New Roman" ، font.bold ، 30)) ؛ G.DrawString ("SCORE:" + TotalScore ، 5 ، 70) ؛ // تنتهي اللعبة ، وطباعة السلسلة النهائية if (! is is eSgoNon) {g.setColor (color.red) ؛ G.SetFont (خط جديد ("Times New Roman" ، font.bold ، 40)) ؛ G.DrawString ("Game Over!" ، this.getWidth () / 2 - 140 ، this.getheight () / 2) ؛ }}يتم إنشاء عدة أنواع من الرسومات المكونة من المربعات بأرقام عشوائية. بشكل عام ، سبعة أنواع من الرسومات: شريط ، حقل ، 7 ، عكس 7 ، 7 ، على شكل حرف T ، على شكل Z على شكل Z ، على شكل Z ، مثل توليد أشرطة:
MAP [0] [RANDPOS] = MAP [0] [RANDPOS - 1] = MAP [0] [RANDPOS + 1] = MAP [0] [RANDPOS + 2] = State.Active ؛
بعد إنشاء الرسومات ، يتم تنفيذ مكان وجوده. إذا واجهت عقبات ، لا يمكنك الاستمرار في السقوط:
isfall = صحيح ؛ // ما إذا كان يمكن أن يسقط // التحقق من السطر الحالي ، توقف عن السقوط إذا تمت مواجهة عقبة (int i = 0 ؛ i <blockrows ؛ i ++) {for (int j = 0 ؛ j <أعمدة ؛ j ++) 1] [j] == state.stoped) {isfall = false ؛ // توقف عن استراحة الخريف ؛ }} if (! isfall) break ؛}إذا لم تتم مواجهة عقبة ، فسيتحرك مخطط الكتلة إلى أسفل سطر واحد ككل:
// يسقط الرسم البياني صفًا لـ (int i = 0 ؛ i <blockrows ؛ i ++) {for (int j = 0 ؛ j <أعمدة ؛ j ++) {if (map [rowIndex - i] [j] == state.active) {// تحرك الكتلة النشطة أسفل خريطة الصف الواحد [rowIndex - i] = j] = state.empty ؛ // تصبح الكتلة النشطة الأصلية خريطة كتلة فارغة [rowindex - i + 1] [j] = state.active ؛ // يصبح السطر التالي من الكتلة كتلة نشطة}}}عملية مماثلة هي عند الانتقال إلى اليسار واليمين:
/*** اذهب إلى اليسار*/private void left () {// mark ما إذا كانت هناك عقبة على boolean hasblock = false ؛ /* تحقق مما إذا كانت هناك عقبة على اليسار*/ لـ (int i = 0 ؛ i <blockrows ؛ i ++) {if (map [rowindex - i] [0] == state.active) {// تحقق مما إذا كان اليسار هو جدار hasblock = true ؛ استراحة؛ // هناك عقبة ، لا تحتاج إلى حلقة للحكم على الصف} آخر {لـ (int j = 1 ؛ j <أعمدة ؛ j ++) {// استراحة؛ // هناك عقبة ، لا حاجة لإعادة تدوير عمود الحكم}} إذا كان (hasblock) استراحة ؛ . i] [j - 1] = state.action ؛عند التحرك لأسفل ، فإنه يقلل من الفاصل الزمني لكل حالة طبيعية تسقط:
/*** اذهب لأسفل لأسفل*/private void لأسفل () {// العلامات يمكن أن تسريع السقوط على الفور = true ؛}كيفية تغيير اتجاه الرسم البياني ، يتم استخدام طريقة بسيطة للغاية هنا لتحقيق تحويل الاتجاه. بالطبع ، يمكن أن يكون هناك خوارزمية أفضل لتنفيذ عمليات تحويل الاتجاه. يمكنك دراستها بنفسك:
/*** قم بتدوير الشكل المربع*/private void rotate () {try {if (lape == 4) {// square ، يتم إرجاع نفس الشكل قبل وبعد الدوران ؛ } آخر إذا (الشكل == 0) {// strip // صفيف مؤقت ، ضع الشكل بعد حالة الدوران [] [] tmp = حالة جديدة [4] [4] ؛ int startColumn = 0 ؛ // ابحث عن الموضع المربع الأول في بداية الشكل لـ (int i = 0 ؛ i <أعمدة ؛ i ++) {if (map [rowindex] [i] == state.active) {startColumn = i ؛ استراحة؛ }} // اكتشف ما إذا كانت هناك عقبة بعد الدوران. إذا كانت هناك عقبة ، فلا تدور لـ (int i = 0 ؛ i <4 ؛ i ++) {for (int j = 0 ؛ j <4 ؛ j ++) {if (map [rowindex - 3+i] [j+startColumn] == state.stoped) {return ؛ }}}} if (map [rowIndex] [startColumn+1] == state.active) {// شريط أفقي ، يتحول إلى شريط عمودي لـ (int i = 0 ؛ i <4 ؛ i ++) {tmp [i] [0] = state.active ؛ لـ (int j = 1 ؛ j <4 ؛ j ++) {tmp [i] [j] = state.empty ؛ }} blockrows = 4 ؛ } آخر {// شريط عمودي ، يتحول إلى شريط أفقي لـ (int j = 0 ؛ j <4 ؛ j ++) {tmp [3] [j] = state.active ؛ لـ (int i = 0 ؛ i <3 ؛ i ++) {tmp [i] [j] = state.empty ؛ }} blockrows = 1 ؛ } // قم بتعديل الرسم البياني في الخريطة الأصلية إلى رسم بياني محول لـ (int i = 0 ؛ i <4 ؛ i ++) {for (int j = 0 ؛ j <4 ؛ j ++) {map [rowindex - 3+i] [startColumn+j] = tmp [i] [j] ؛ }}} آخر {// صفيف مؤقت ، ضع دوران حالة الشكل [] [] tmp = حالة جديدة [3] [3] ؛ int startColumn = الأعمدة ؛ // ابحث عن وضع الكتلة الأولى في بداية الشكل لـ (int j = 0 ؛ j <3 ؛ j ++) {for (int i = 0 ؛ i <أعمدة ؛ i ++) {if (map [rowindex - j] أنا: StartColumn ؛ }}} // حدد ما إذا كانت هناك عقبات بعد التحول لـ (int i = 0 ؛ i <3 ؛ i ++) {for (int j = 0 ؛ j <3 ؛ j ++) {if (map [rowindex - 2+j] [startColumn+2 - i] == state.stoped) ؛ }} // transform for (int i = 0 ؛ i <3 ؛ i ++) {for (int j = 0 ؛ j <3 ؛ j ++) {tmp [2 - j] [i] = map [rowindex - 2+i] [startColumn+j] ؛ }} // قم بتعديل الرسم البياني في الخريطة الأصلية إلى الرسم البياني المحول لـ (int i = 0 ؛ i <3 ؛ i ++) {for (int j = 0 ؛ j <3 ؛ j ++) {map [rowindex - 2+i] [startColumn+j] = tmp [i] [j] ؛ }} // إعادة التكرار () ؛ // قم بإزالة مؤشر السطر لـ (int i = 0 ؛ i <3 ؛ i ++) {for (int j = 0 ؛ j <3 ؛ j ++) {if (map [rowIndex - i] [startColumn+j]! = null || map [rowIndex - i] blockrows = 3 ؛ يعود؛ }}} سترعندما يسقط الشكل ويتوقف عندما يواجه عقبات ، نحتاج إلى تحديد ما إذا كان هناك خط معين أو عدة خطوط يمكن القضاء عليها. في هذا الوقت ، يمكننا أولاً الحصول على عدد المربعات في كل سطر ، ثم إصدار حكم:
int [] blockscount = new int [الصفوف] ؛ // سجل عدد الأعمدة مع كتل لكل صف int lextiveaterows = 0 ؛ // عدد الصفوف التي تم إلغاؤها/* حساب عدد الكتل لكل صف*/لـ (int i = 0 ؛ i <rows ؛ i ++) {blockscount [i] = 0 ؛ لـ (int j = 0 ؛ j <أعمدة ؛ j ++) {if (map [i] [j] == state.stoped) blockscount [i] ++ ؛ }}إذا كان هناك صف كامل من الكتل ، فسيتم القضاء على صف الكتل:
/* تنفيذ عملية التخلص من الكتلة مع الصفوف الكاملة*/لـ (int i = 0 ؛ i <الصفوف ؛ i ++) {if (blockscount [i] == أعمدة) {// مسح خط لـ (int m = i ؛ m> = 0 ؛ m--) {for (int n = 0 ؛ n <columns ؛ n ++) {map [m] [n] = m == 0)؟ state.empty: خريطة [m - 1] [n] ؛ }} extrleatealoats ++ ؛ // سجل عدد الصفوف القليلة}}أخيرًا ، يمكننا إعادة طلاء النقاط وعرضها.
كرر العمليات المذكورة أعلاه لتوليد الرسومات ، والرسومات المتساقطة ، والانتقال إلى اليسار واليمين ، والحكم على خط القضاء ، وسيتم إكمال Tetris بسيط.
تأثير الجري:
أكمل نموذج رمز: Tetris
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.