ตัวอย่างในบทความนี้แบ่งปันรหัสเฉพาะของการใช้งาน Java Tetris สำหรับการอ้างอิงของคุณกับคุณ เนื้อหาเฉพาะมีดังนี้
แนวคิดการออกแบบ Tetris
Tetris เล่นมาตั้งแต่เด็ก ทุกคนรู้กฎ ในอดีตฉันคิดว่าสิ่งนั้นสนุกมาก แต่ฉันก็ไม่สามารถชนะได้ ตอนนี้ฉันได้เรียนรู้ที่จะเขียนด้วยตัวเองและฝึกฝนทุกวัน!
การดำเนินการแป้นพิมพ์:
คีย์ซ้าย: เลื่อนไปทางซ้าย; คีย์ขวา: เลื่อนไปทางขวา;
คีย์ขึ้น: เปลี่ยนรูปร่างและคีย์ล่าง: เร่งการลดลง (ไม่มีปัญหาไม่มีการแก้ไขเพิ่มเติม)
หากสี่เหลี่ยมของแถวใด ๆ เต็มบรรทัดนี้จะถูกกำจัด การกำจัดสี่เหลี่ยมแถวจะได้รับ 10 คะแนน ในปัจจุบันฉันยังไม่ได้กำหนดระดับ ทารกที่ชอบมันสามารถกำหนดระดับเองได้
รูปร่างสี่เหลี่ยมเหล่านั้นมาจากไหน? มันถูกออกแบบโดยเราเอง รูปร่างทั่วไปคือ: I Type, T type, ประเภท L, ประเภท Tianzi Grid ฯลฯ เพิ่มด้วยตัวคุณเอง!
แล้วเกิดอะไรขึ้น? อันที่จริงมันเป็นเพียงอาร์เรย์ 4*4 แน่นอนคุณสามารถออกแบบ n*n อย่างมีความสุขคุณมีคำพูดสุดท้าย!
ดังนั้นฉันให้ตัวอย่างด้านล่างเพื่อบอกคุณว่าทำไมรูปร่างที่คุณเห็นสามารถเปลี่ยนแปลงได้ถูกออกแบบมาล่วงหน้า 0 ว่างเปล่าและ 1 เป็นฟิลเลอร์เพื่อให้คุณสามารถสร้างรูปร่างในเกมของคุณ!
ลืมมัน: เพียงแค่ใส่รูปภาพและดูรหัสการรันผลลัพธ์ก่อน:
ชอบ? ถ้าคุณชอบเพียงทำมันโดยตรง บางทีรหัสอาจเขียนได้ไม่ดีพอ โปรดยกโทษให้ฉัน ฉันจะสรุปเพิ่มเติมเมื่อมองย้อนกลับไปและจะอัปเดตรหัสต่อไป
คลาส Gamepanel: คลาสอินเตอร์เฟสเกมบล็อกทั้งหมดถูกทิ้งและแสดงและตรรกะของเกมช้าถูกนำไปใช้ในคลาสนี้
แพ็คเกจ tetris; นำเข้า java.awt.graphics; นำเข้า java.awt.event.actionevent; นำเข้า java.awt.event.actionlistener; นำเข้า java.awt.event.keyEvent; นำเข้า java.awt.event.keylistener; javax.swing.jpanel; นำเข้า Javax.swing.timer; Gamepanel ระดับสาธารณะขยาย JPanel ใช้ keyListener {Private Int Maprow = 21; MAPCOL INT ส่วนตัว = 12; mapgame int ส่วนตัว [] [] = int ใหม่ [maprow] [MAPCOL]; // เปิดพื้นที่อาร์เรย์สองมิติเพื่อจัดเก็บข้อมูลแผนที่ตัวจับเวลาส่วนตัวของเรา; คะแนน INT ส่วนตัว = 0; // บันทึกคะแนนสุ่มสุ่ม = ใหม่สุ่ม (); ส่วนตัว int curshapetype = -1; ส่วนตัว int curshapestate = -1; // ตั้งค่าประเภทรูปร่างปัจจุบันและสถานะรูปร่างปัจจุบันสถานะส่วนตัว int nextshapetype = -1; Private Int NextShapestate = -1; // ตั้งค่าประเภทและสถานะของกลุ่มบล็อกที่ปรากฏในครั้งต่อไป INT ส่วนตัว POSX = 0; ส่วนตัว int posy = 0; รูปทรง int สุดท้ายส่วนตัว [] [] [] = new int [] [] {// t glyphs ถูกเก็บไว้ในลำดับทวนเข็มนาฬิกา {{0,1,0,0, 1,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,0s คำสั่งซื้อ {{0,0,0,0, 1,1,1,1,1,1,0,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,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0s {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,0}, // z-{{1,1,0,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,0s 1,0,0,0,0,0}, {1,1,0,0, 0,1,1,0,0,0,0,0,0,0}, {1,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,0s ในลำดับทวนเข็มนาฬิกา {{0,1,0,0, 0,1,0,0, 1,1,0,0, 0,0,0,0,0,0}, {1,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,0s0 {1,0,0,0, 1,1,0,0,0,0,0,0,0}, {1,0,0,0, 1,1,0,0,0,0,0,0,0,0,0}, // l glyphs ถูกเก็บไว้ในลำดับทวน 1,1,0,0,0,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,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0s ,, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s ,, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0}, {1,1,0,0, 0,1,0,0,0,0,0,0,0,0}, {1,1,1,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s ,, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0s ,, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0,0,0,0s 0,0,0,0,0,0,0,0}}}}}; INT ROWRECT ส่วนตัว = 4; ส่วนตัว int colrect = 4; // ที่นี่เราถือว่าภาพที่เก็บไว้เป็นอาร์เรย์สองมิติ 4*4 แม้ว่าเราจะใช้อาร์เรย์หนึ่งมิติเพื่อจัดเก็บไว้ด้านบน แต่เราก็ยังต้องพิจารณาว่ามันเป็นอาร์เรย์สองมิติเพื่อใช้งาน INT rectwidth ส่วนตัว = 10; public gamepanel () // constructor ---- สร้างแผนที่ที่ดี {createRect (); initmap (); // เริ่มต้นแผนที่นี้ setwall (); // ตั้ง wall // createRect (); ตัวจับเวลา = ตัวจับเวลาใหม่ (500, TimerListener ใหม่ ()); timer.start (); } คลาส TimerListener ใช้ ActionListener {โมฆะสาธารณะ ActionPerformed (ActionEvent E) {Movedown (); }} โมฆะสาธารณะ setwall () // คอลัมน์ 0 และ 11 เป็นทั้งผนังและแถว 20 ยังเป็นผนัง {สำหรับ (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; }} โมฆะสาธารณะ initmap () // เริ่มต้นแผนที่นี้ ID ผนังคือ 2, ID อวกาศคือ 0 และบล็อก ID คือ 1 {สำหรับ (int i = 0; i <maprow; i ++) {สำหรับ (int j = 0; j <mapcol; j ++) {mapgame [i] [j] = 0; }}} public void createRect () // สร้าง block --- ถ้าประเภทบล็อกปัจจุบันและสถานะมีอยู่ให้ตั้งค่าในครั้งต่อไปถ้าไม่ตั้งสถานะปัจจุบันและประเภท {ถ้า (curshapetype == -1 && curshapestate == -1) // สถานะบล็อกปัจจุบันคือ 1 curshapestate = random.nextint (รูปร่าง [0] .length); } else {curshapetype = nextshapetype; curshapestate = nextshapestate; } nextshapetype = random.nextint (shapes.length); nextShapestate = random.nextint (รูปร่าง [0] .length); posx = 0; posy = 1; // สร้างสี่เหลี่ยมจัตุรัสที่มุมซ้ายบนของผนังถ้า (gameover (posx, posy, curshapetype, curshapestate)) {joptionpane.showconfirmdialog (null, "เกมจบ!", "ปลาย", joptionpane.ok_option); System.Exit (0); }} gameover บูลีนสาธารณะ (int x, int y, int shapetype, int spapestate) // ตัดสินว่าเกมจบลง {ถ้า (isornomove (x, y, shapetype, shapestate)) {return false; } return true; } บูลีนสาธารณะ isornomove (int x, int y, int shapetype, int shapestate) // ตัดสินว่าสามารถเคลื่อนย้ายตัวเลขปัจจุบันได้หรือไม่ ที่นี่เราเน้นว่าพิกัดของ x และ y อ้างถึงเป้าหมายซ้ายบนของอาร์เรย์สองมิติของ 4*4 (อาร์เรย์ที่อธิบายรูป) {สำหรับ (int i = 0; i <Rowrect; i ++) {สำหรับ (int j = 0; j <colrect; j ++) {ถ้า MapGame [x+i] [y+j] == 1 || รูปร่าง [shapetype] [shapestate] [i*colrect+j] == 1 && mapgame [x+i] [y+j] == 2) {return false; }}} ส่งคืนจริง; } โมฆะสาธารณะเทิร์น () // หมุน {int temp = curshapestate; curshapestate = (curshapestate+1) % รูปร่าง [0] .length; if (isornomove (posx, posy, curshapetype, curshapestate)) {} else {curshapestate = temp; } repaint (); } โมฆะสาธารณะ movedown () // เลื่อนลง {ถ้า (isornomove (posx+1, posy, curshapetype, curshapestate)) {posx ++; } else {addTomap (); // แก้ไขบรรทัดนี้ในแผนที่แผนที่ (); CreateRect (); // สร้างบล็อกใหม่} repaint (); } โมฆะสาธารณะ moveleft () // ย้ายไปทางซ้าย {ถ้า (isornomove (posx, posy-1, curshapetype, curshapestate)) {posy--; } repaint (); } โมฆะสาธารณะ moveright () // ย้ายขวา {ถ้า (isornomove (posx, posy+1, curshapetype, curshapestate)) {posy ++; } repaint (); } โมฆะสาธารณะ addtomap () // แก้ไขภาพที่ตกลงมาลงในแผนที่ {สำหรับ (int i = 0; i <rowrect; i ++) {สำหรับ (int j = 0; j <colrect; j ++) {ถ้า (รูปร่าง [curshapetype] [curshapestate] รูปร่าง [curshapetype] [curshapestate] [i*colrect+j]; }}}} การตรวจสอบโมฆะสาธารณะ () // ตรวจสอบว่ามีแถวเต็มในบรรทัดเหล่านี้ {int count = 0; สำหรับ (int i = maprow-2; i> = 0; i--) {count = 0; สำหรับ (int j = 1; j <mapcol-1; j ++) {ถ้า (mapgame [i] [j] == 1) {count ++; } else break; } if (count> = mapCol-2) {สำหรับ (int k = i; k> 0; k--) {สำหรับ (int p = 1; p <mapcol-1; p ++) {mapgame [k] [p] = mapgame [k-1] [p]; }} คะแนน += 10; i ++; }}} สีโมฆะสาธารณะ (กราฟิก g) // หน้าต่างทาสี {super.paint (g); สำหรับ (int i = 0; i <rowrect; i ++) // วาดบล็อกที่ตกลงมา {สำหรับ (int j = 0; j <colrect; j ++) {ถ้า (รูปร่าง [curshapetype] [curshapestate] [i*colrect+j] == 1) rectwidth, rectwidth); }}} สำหรับ (int i = 0; i <maprow; i ++) // วาดข้อมูลบล็อกที่ได้รับการแก้ไขบนแผนที่ {สำหรับ (int j = 0; j <mapcol; j ++) {ถ้า (mapgame [i] [j] == 2) // วาดผนัง {g.drawrect (j+1)* rectwidth); } if (mapgame [i] [j] == 1) // วาดสี่เหลี่ยมเล็ก ๆ {g.fillrect ((j+1)*rectwidth, (i+1)*rectwidth, rectwidth, rectwidth); }}} G.DrawString ("คะแนน ="+ คะแนน, 225, 15); G.DrawString ("Next Square:", 225, 50); สำหรับ (int i = 0; j <colrect; j ++) {ถ้า (รูปร่าง [nextshapetype] [nextshapestate] [i*colrect+j] == 1) {g.fillrect (225+ (j*rectwidth), 100+ (i*rectwidth), rectwidth, rectwidth }}}} โมฆะสาธารณะ newGame () // เกมเริ่มต้นอีกครั้ง {score = 0; initmap (); setwall (); CreateRect (); ทาสีใหม่ (); } โมฆะสาธารณะ stopgame () // เกมหยุดชั่วคราว {timer.stop (); } โมฆะสาธารณะต่อเนื่อง () {timer.start (); } @Override โมฆะสาธารณะ KeyTyped (KeyEvent E) {} @Override โมฆะสาธารณะเป็นโมฆะคีย์กด (KeyEvent E) {switch (e.getKeyCode ()) {กรณี keyevent.vk_up: // up -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - keyevent.vk_right: // right ---- moveright (); หยุดพัก; }} @Override โมฆะสาธารณะเป็นโมฆะ Keylelesed (KeyEvent E) {// วิธีการที่สร้างอัตโนมัติแบบอัตโนมัติ stub}}}} คลาส GameFrame: พอร์ตรายการทั้งหมดของเกมทั้งหมดที่จะนำมันไปตรงมามันเป็นคลาสที่มีฟังก์ชั่นหลัก () คลาสนี้ใช้การออกแบบบางส่วนของอินเทอร์เฟซเกมซึ่งคุณสามารถเข้าใจว่าเป็น UI ขนาดเล็ก
แพ็คเกจ tetris; นำเข้า java.awt.event.actionEvent; นำเข้า java.awt.event.ActionListener; นำเข้า Javax.swing.jframe; นำเข้า Javax.swing.jmenu; นำเข้า Javax.swing.jmenubar; ActionListener {ส่วนตัว int widthFrame = 500; ความสูง int ส่วนตัว = 600; เมนู jmenu ส่วนตัว = new JMenu ("game"); // สร้างเมนูส่วนตัว jmenuitem private jmenuitem newGame = menu.add ("รีสตาร์ท"); // สร้างตัวเลือกเมนูในตัว JMenuitem ExitGame = Menu.add ("Game Exit"); jmenuitem private stopgame = menu.add ("เกมหยุดชั่วคราว"); ส่วนตัว jmenuitem goongame = menu.add ("เกมดำเนินการต่อ"); ส่วนตัว jmenu menutwo = new jmenu ("help"); // สร้างเมนูที่สองส่วนตัว jmenuitem ส่วนตัวเกี่ยวกับ game = menutwo.add ("เกี่ยวกับเกม"); gamepanel gamepanel = new gamepanel (); public gameframe () // constructor {addkeyListener (gamepanel); newGame.addactionListener (นี่); exitgame.addactionListener (นี้); stopgame.addactionListener (นี้); goongame.addactionListener (นี้); AboutGame.addactionListener (นี้); this.add (gamepanel); เมนู jmenubar = new JMenubar (); menu.add (เมนู one); menu.add (menutwo); this.setjmenubar (เมนู); this.settitle ("tetris"); this.setbounds (50, 10, WidthFrame, Highframe); this.setVisible (จริง); this.setDefaultCloseOperation (jframe.exit_on_close); } โมฆะสาธารณะ ActionPerformed (ActionEvent E) {ถ้า (e.getSource () == newGame) // เกมเริ่มต้นอีกครั้ง {gamepanel.newgame (); } if (e.getSource () == exitGame) // game exit {system.exit (0); } if (e.getSource () == stopGame) // เกมหยุดชั่วคราว {gamepanel.stopGame (); } if (e.getSource () == goongame) // เกมดำเนินการต่อ {gamepanel.continueGame (); } if (e.getSource () == เกี่ยวกับ Game) // เกี่ยวกับข้อมูลเกม {JoptionPane.ShowMessageDialog (null, "ย้ายปุ่มซ้ายและขวาสร้างการหมุนขึ้น", "พรอมต์", joptionpane.ok_option); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {gameframe ใหม่ (); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น