تشارككم الأمثلة في هذه المقالة مع رمز تنفيذ Java المحدد Tetris للرجوع إليه. المحتوى المحدد كما يلي
أفكار تصميم Tetris
تلعب Tetris منذ الطفولة. الجميع يعرف القواعد. في الماضي ، اعتقدت أن هذا الشيء كان ممتعًا للغاية ، لكنني لم أستطع الفوز. الآن تعلمت أن أكتب بنفسي وأمارسه كل يوم!
تشغيل لوحة المفاتيح:
مفتاح اليسار: تحرك يسارًا ؛ المفتاح الصحيح: تحرك يمينًا ؛
مفتاح UP: قم بتغيير الشكل والمفتاح السفلي: تسريع الانخفاض (لا توجد مشكلة ، لا يوجد تصحيح إضافي)
إذا كانت المربعات من أي صف ممتلئة ، فسيتم القضاء على هذا الخط. القضاء على صف من المربعات سيحصل على 10 نقاط. في الوقت الحاضر ، لم أضع المستويات. يمكن للأطفال الذين يحبونها تعيين المستويات بأنفسهم ؛
إذن من أين أتت تلك الأشكال المربعة؟ إنه مصمم من قبلنا. الأشكال الشائعة هي: أنا اكتب ، نوع t ، نوع L ، نوع شبكة Tianzi ، وما إلى ذلك ، أضفها بنفسك!
إذن ماذا حدث؟ في الواقع ، إنها مجرد صفيف 4*4. بالطبع ، يمكنك تصميم n*n بسعادة ، لديك القول النهائي!
لذا ، أعطيت مثالاً أدناه لإخبارك لماذا يمكن تغيير الأشكال التي تراها مسبقًا ، 0 فارغ و 1 هو حشو ، بحيث يمكنك إنشاء أشكال في لعبتك!
ننسى ذلك: فقط ضع الصورة وشاهد نتائج تشغيل الكود أولاً:
مثله؟ إذا أعجبك ذلك ، فقط افعل ذلك مباشرة. ربما لا يتم كتابة الرمز بشكل جيد بما فيه الكفاية. رجائاً أعطني. سألخص المزيد عندما أنظر إلى الوراء وسأواصل تحديث الرمز ؛
فئة Gamepanel: فئة واجهة اللعبة ، يتم إسقاط الكتلة بأكملها وعرضها ، ويتم تنفيذ منطق اللعبة البطيء في هذه الفئة ؛
حزمة tetris ؛ استيراد java.awt.graphics ؛ استيراد java.awt.event.actionevent ؛ استيراد java.awt.event.actionlistener ؛ import java.awt.event.keyevent ؛ import java.awt.event.keylistener ؛ import java.Util.random ؛ import javax.jopane. javax.swing.timer ؛ فئة public gamepanel يمتد jpanel تنفذ keylistener {private int maprow = 21 ؛ الخاص int mapcol = 12 ؛ private int mapgame [] [] = new int [maprow] [mapcol] ؛ // افتح مساحة صفيف ثنائية الأبعاد لتخزين مؤقت خاص معلومات الخريطة الخاص بنا ؛ Private int Score = 0 ؛ // سجل النتيجة عشوائية عشوائية = new Random () ؛ private int curshapeType = -1 ؛ private int curshapestate = -1 ؛ // قم بتعيين نوع الشكل الحالي وحالة الشكل الحالية int nextShapeType = -1 ؛ private int nextShapeState = -1 ؛ // قم بتعيين نوع وحالة مجموعة الكتلة التي تظهر في المرة القادمة posx posx = 0 ؛ Private int posy = 0 ؛ يتم تخزين أشكال int نهائية خاصة [] [] =] {{0،0،0،0 ، 1،1،1،1،1،0،0،0،0 ، 0،0،0،0} ، {0،1،0،0،0 ، 0،1،0،0 ، 0،1،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، {0،1،1،0 ، 1،1،0،0 ، 0،0،0،0،0،0} ، {1،0،0،0 ، 1،1،0،0،0،0،0} ، 1،0،0،0،0،0} ، {1،1،0،0 ، 0،1،1،0،0،0،0،0} ، {1،1،0،0 ، 0،1،1،0،0،0،0،0،0،0،0 ، في عكس اتجاه عقارب الساعة {{0،1،0،0 ، 0،1،0،0 ، 1،1،0،0 ، 0،0،0،0،0،0،0،0،0 ، {1،0،0،0 ، 1،1،0،0،0،0،0،0} ، {1،0،0،0 ، 1،1،0،0،0،0،0،0 ، 1،1،0،0،0،0،0،0} ، {0،0،1،0 ، 1،1،0،0 ، 1،1،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0 ، 0،0،0،0،0،0،0} ، {1،1،0،0 ، 0،1،0،0،0،0،0} ، {1،1،0 ، 1،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0، ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،. 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0، ، 0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،0،. 0،0،0،0،0،0،0،0}}}} ؛ private int rowrect = 4 ؛ private int colrect = 4 ؛ // هنا نعتبر الصورة المخزنة بمثابة صفيف ثنائي الأبعاد 4*4. على الرغم من أننا نستخدم صفيفًا أحادي البعد لتخزينه أعلاه ، إلا أننا ما زلنا بحاجة إلى اعتباره صفيفًا ثنائي الأبعاد لتنفيذ Rectwidth = 10 ؛ public gamepanel () // constructor ---- إنشاء خريطة جيدة {createrect () ؛ initMap () ؛ // تهيئة هذه الخريطة setWall () ؛ // set wall // createrect () ؛ Timer = Timer جديد (500 ، TimerListener () جديد) ؛ Timer.Start () ؛ } class timerListener تنفذ ActionListener {public void actionperformed (ActionEvent e) {addown () ؛ }} public void setWall () // العمود 0 و 11 كلا الجدران ، والصف 20 هو أيضًا الجدران {for (int i = 0 ؛ i <maprow ؛ i ++) // ارسم العمود أولاً {mapgame [i] [0] = 2 ؛ mapgame [i] [11] = 2 ؛ } لـ (int j = 1 ؛ j <mapcol-1 ؛ j ++) // ارسم السطر الأخير {mapgame [20] [j] = 2 ؛ }} public void initmap () // تهيئة هذه الخريطة ، معرف الجدار هو 2 ، معرف المساحة هو 0 ، ومعرف الكتلة هو 1 {for (int i = 0 ؛ i <maprow ؛ i ++) {for (int j = 0 ؛ j <mapcol ؛ j ++) {mapgame [i] = 0 ؛ }}} public void createrect () // إنشاء كتلة --- في حالة وجود نوع الكتلة الحالي وحالة ، قم بتعيين في المرة التالية ، إذا لم يكن الأمر كذلك ، قم بتعيين الحالة الحالية ونوع {if (curshapeType == -1 && curshapeState == -1) // حالة الكتلة الحالية هي 1 ، مما يدل على أن اللعبة قد بدأت للتو {curshapeype = rollownextin) ؛ curshapestate = random.nextint (الأشكال [0]. الطول) ؛ } آخر {curshapeType = nextShapeType ؛ curshapestate = nextShapeTtate ؛ } nextShapeType = random.nextint (Shapes.Length) ؛ NextShapeState = random.nextint (الأشكال [0]. الطول) ؛ POSX = 0 ؛ posy = 1 ؛ // قم بإنشاء مربع في الركن الأيسر العلوي من الجدار إذا (posx ، posy ، curshapeType ، curshapestate)) {joptionpane.showconfirmdialog (null ، "game end!" ، "tip" ، joptionpane.ok_option) ؛ System.exit (0) ؛ }} public boolean gameover (int x ، int y ، int ShapeType ، int massestate) // upply ما إذا كانت اللعبة تنتهي {if (isornomove (x ، y ، ShapeType ، ShapeState)) {return false ؛ } إعادة صواب ؛ } iSornomove المنطقي العام (int x ، int y ، int appetype ، int massestate) // ugn armain ما إذا كان يمكن نقل الرقم الحالي. نؤكد هنا أن إحداثيات X و Y تشير إلى الهدف الأيسر العلوي لمصفوفة ثنائية الأبعاد من 4*4 (الصفيف الذي يصف الشكل) {for (int i = 0 ؛ i <rowrect ؛ i ++) {for (int j = 0 ؛ j <colrect ؛ j ++) MapGame [x+i] [y+j] == 1 || الأشكال [ShapeType] [i*colrect+j] == 1 && mapgame [x+i] [y+j] == 2) {return false ؛ }}} إرجاع صحيح ؛ } باطل باطل عام () // تدوير {int temp = curshapestate ؛ curshapestate = (curshapestate+1) ٪ أشكال [0]. الطول ؛ if (iSornomove (posx ، posy ، curshapeType ، curshapestate)) {} else {curshapestate = temp ؛ } repaint () ؛ } public void quoDown () // تحرك لأسفل {if (iSornomove (posx+1 ، posy ، curshapeType ، curshapestate)) {posx ++ ؛ } آخر {addTomap () ؛ // إصلاح هذا السطر في خط الفحص الخريطة () ؛ createrect () ؛ // إعادة إنشاء كتلة جديدة} repaint () ؛ } public void moveleft () // نقل اليسار {if (isornomove (posx ، posy-1 ، curshapeType ، curshapestate)) {posy-- ؛ } repaint () ؛ } public void moveright () // تحرك يمينًا {if (isornomove (posx ، posy+1 ، curshapeType ، curshapeTtate)) {posy ++ ؛ } repaint () ؛ } public void addtomap () // إصلاح الصورة الساقطة في الخريطة {for (int i = 0 ؛ i <rowrect ؛ i ++) {for (int j = 0 ؛ j <colrect ؛ j ++) {if (الأشكال [curshapeType] [curshapestate] [i*colrect+j] == 1) الأشكال [curshapeType] [curshapestate] [i*colrect+j] ؛ }}}} خط الفراغ العام () // تحقق مما إذا كانت هناك صفوف كاملة في هذه الأسطر {int count = 0 ؛ لـ (int i = maprow-2 ؛ i> = 0 ؛ i--) {count = 0 ؛ لـ (int j = 1 ؛ j <mapcol-1 ؛ j ++) {if (mapGame [i] [j] == 1) {count ++ ؛ } استراحة أخرى ؛ } if (count> = mapcol-2) {for (int k = i ؛ k> 0 ؛ k--) {for (int p = 1 ؛ p <mapcol-1 ؛ p ++) {mapgame [k] [p] = mapgame [k-1] [p] ؛ }} النتيجة += 10 ؛ i ++ ؛ }}} public void paint (Graphics g) // Repaint Window {super.paint (g) ؛ لـ (int i = 0 ؛ i <rowrect ؛ i ++) // ارسم الكتلة المتساقطة {for (int j = 0 ؛ j <colrect ؛ j ++) {if (الأشكال [curshapeType] [curshapestate] [i*colrect+j] == 1) Rectwidth) ؛ }}} لـ (int i = 0 ؛ i <maprow ؛ i ++) // ارسم معلومات الكتلة التي تم تثبيتها على الخريطة {for (int j = 0 ؛ Rectwidth) ؛ } if (mapGame [i] [j] == 1) // ارسم مربع صغير {g.fillRect ((j+1)*rectwidth ، (i+1)*rectwidth ، rectwidth ، rectwidth) ؛ }}} g.drawString ("Score ="+ Score ، 225 ، 15) ؛ G.DrawString ("Square Next Square:" ، 225 ، 50) ؛ لـ (int i = 0 ؛ j <colrect ؛ j ++) {if (الأشكال [nextShapeType] [nextShapeState] [i*colrect+j] == 1) {g.fillRect (225+ (j*rectwidth) ، 100+ (i*rectwidth) ، rectwidth ، rectwidth) ؛ }}}} public void newGame () // تبدأ اللعبة مرة أخرى {score = 0 ؛ initMap () ؛ setwall () ؛ createrect () ؛ REPAINT () ؛ } public void stopGame () // تتوقف اللعبة {timer.stop () ؛ } public void contergame () {timer.start () ؛ } Override public void keytytyped (keyevent e) {} override public void keypressed (keyevent e) {switch (e.getKeyCode ()) {case keyevent.vk_up: // up ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ keyevent.vk_right: // right ---- moveright () ؛ استراحة؛ }} Override public void keyreleSeped (keyevent e) {// todo method method method}} GameFrame Class: منفذ الدخول للعبة بأكملها ، حسنًا ، لوضعها بصراحة ، إنها فئة ذات وظيفة Main (). ينفذ هذا الفصل بعض تصميمات واجهة اللعبة ، والتي يمكنك فهمها كواجهة مستخدم صغيرة ؛
حزمة tetris ؛ استيراد java.awt.event.actionevent ؛ استيراد java.awt.event.actionlistener ؛ استيراد javax.swing.jframe ؛ import javax.swing.jmenu ؛ استيراد gavax.swing.jmenubar ؛ استيراد javax.swing.jmenuitem ؛ ActionListener {private int widthframe = 500 ؛ Private Int Heightframe = 600 ؛ قائمة Jmenu الخاصة = New Jmenu ("Game") ؛ // إنشاء قائمة خاصة JMenuitem newGame = Menu.add ("RESTART") ؛ // إنشاء خيار قائمة مدمج jmenuitem exitgame = menu.add ("game exit") ؛ private jmenuitem stopGame = menu.add ("Game Pause") ؛ private jmenuitem goongame = menu.add ("Game Contens") ؛ Private Jmenu Menutwo = New Jmenu ("Help") ؛ // إنشاء قائمة ثانية jmenuitem aboutgame = menutwo.add ("حول اللعبة") ؛ gamepanel gamepanel = new gamepanel () ؛ gameframe public () // constructor {addKeyListener (gamepanel) ؛ newgame.addActionListener (this) ؛ exitgame.addActionListener (هذا) ؛ stopGame.AddActionListener (هذا) ؛ goongame.addActionListener (هذا) ؛ aboutgame.addActionListener (هذا) ؛ this.Add (gamepanel) ؛ قائمة Jmenubar = New Jmenubar () ؛ Menu.add (Menuone) ؛ menu.add (menutwo) ؛ this.setjmenubar (قائمة) ؛ this.settitle ("tetris") ؛ this.setBounds (50 ، 10 ، widthframe ، heightframe) ؛ this.setVisible (صحيح) ؛ this.setDefaultCloseOperation (jframe.exit_on_close) ؛ } public void actionperformed (ActionEvent e) {if ( } if ( } if ( } if ( } if ( }} public static void main (string [] args) {new GameFrame () ؛ }}ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.