tscRubbish

 

 1 package Tetris;
 2 import java.awt.BorderLayout;
 3 import java.awt.EventQueue;
 4 import javax.swing.JFrame;
 5 import javax.swing.JLabel;
 6 
 7 public class Tetris extends JFrame {
 8 
 9     private JLabel statusbar;
10 
11     public Tetris() {
12         initUI();
13     }
14     private void initUI() {
15 
16         statusbar= new JLabel(" 0");
17         add(statusbar, BorderLayout.SOUTH);
18 
19         var board = new Board(this);
20         add(board);
21         board.start();
22 
23         setTitle("Tetris");
24         setSize(200, 400);
25         setDefaultCloseOperation(EXIT_ON_CLOSE);
26         setLocationRelativeTo(null);
27     }
28     JLabel getStatusBar() {
29         return statusbar;
30     }
31     public static void main(String[] args) {
32         EventQueue.invokeLater(() -> {
33             var game = new Tetris();
34             game.setVisible(true);
35         });
36     }
37 }

 

 1 package Tetris;
 2 import java.util.Random;
 3 
 4 public class Shape {
 5     protected enum Tetrominoe {
 6         NoShape, ZShape, SShape, LineShape,
 7         TShape, SquareShape, LShape, MirroredLShape
 8     }
 9     private Tetrominoe pieceShape;
10     private int[][] coords;
11     public Shape() {
12         coords = new int[4][2];
13         setShape(Tetrominoe.NoShape);
14     }
15     void setShape(Tetrominoe shape) {
16         int[][][] coordsTable = new int[][][]{
17                 {{0, 0}, {0, 0}, {0, 0}, {0, 0}},
18                 {{0, -1}, {0, 0}, {-1, 0}, {-1, 1}},
19                 {{0, -1}, {0, 0}, {1, 0}, {1, 1}},
20                 {{0, -1}, {0, 0}, {0, 1}, {0, 2}},
21                 {{-1, 0}, {0, 0}, {1, 0}, {0, 1}},
22                 {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
23                 {{-1, -1}, {0, -1}, {0, 0}, {0, 1}},
24                 {{1, -1}, {0, -1}, {0, 0}, {0, 1}}
25         };
26         for (int i = 0; i < 4; i++) {
27             System.arraycopy(coordsTable[shape.ordinal()], 0, coords, 0, 4);
28         }
29         pieceShape = shape;
30     }
31     private void setX(int index, int x) {
32         coords[index][0] = x;
33     }
34     private void setY(int index, int y) {
35         coords[index][1] = y;
36     }
37     int x(int index) {
38         return coords[index][0];
39     }
40     int y(int index) {
41         return coords[index][1];
42     }
43     Tetrominoe getShape() {
44         return pieceShape;
45     }
46     void setRandomShape() {
47         var r = new Random();
48         int x = Math.abs(r.nextInt()) % 7 + 1;
49 
50         Tetrominoe[] values = Tetrominoe.values();
51         setShape(values[x]);
52     }
53     public int minX() {
54         int m = coords[0][0];
55 
56         for (int i=0;i<4;i++) {
57             m = Math.min(m, coords[i][0]);
58         }
59         return m;
60     }
61     int minY() {
62         int m = coords[0][1];
63         for (int i = 0; i < 4; i++) {
64             m = Math.min(m, coords[i][1]);
65         }
66         return m;
67     }
68     Shape rotateLeft() {
69         if (pieceShape == Tetrominoe.SquareShape) {
70             return this;
71         }
72         var result = new Shape();
73         result.pieceShape = pieceShape;
74 
75         for (int i = 0; i < 4; i++) {
76             result.setX(i, y(i));
77             result.setY(i, -x(i));
78         }
79         return result;
80     }
81     Shape rotateRight() {
82         if (pieceShape == Tetrominoe.SquareShape) {
83             return this;
84         }
85         var result = new Shape();
86         result.pieceShape = pieceShape;
87         for (int i = 0; i < 4; i++) {
88             result.setX(i, -y(i));
89             result.setY(i, x(i));
90         }
91         return result;
92     }
93 }

 

  1 package Tetris;
  2 import Tetris.Shape.Tetrominoe;
  3 import javax.swing.JLabel;
  4 import javax.swing.JPanel;
  5 import javax.swing.Timer;
  6 import java.awt.Color;
  7 import java.awt.Graphics;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.ActionListener;
 10 import java.awt.event.KeyAdapter;
 11 import java.awt.event.KeyEvent;
 12 
 13 public class Board extends JPanel {
 14     private final int BOARD_WIDTH = 10;
 15     private final int BOARD_HEIGHT = 22;
 16     private final int PERIOD_INTERVAL = 300;
 17 
 18     private Timer timer;
 19     private boolean isFallingFinished = false;
 20     private boolean isPaused = false;
 21     private int numLinesRemoved = 0;
 22     private int curX = 0;
 23     private int curY = 0;
 24     private JLabel statusbar;
 25     private Shape curPiece;
 26     private Tetrominoe[] board;
 27 
 28     public Board(Tetris parent) {
 29         initBoard(parent);
 30     }
 31     private void initBoard(Tetris parent) {
 32         setFocusable(true);
 33         statusbar = parent.getStatusBar();
 34         addKeyListener(new TAdapter());
 35     }
 36     private int squareWidth() {
 37         return (int) getSize().getWidth() / BOARD_WIDTH;
 38     }
 39     private int squareHeight() {
 40         return (int) getSize().getHeight() / BOARD_HEIGHT;
 41     }
 42     private Tetrominoe shapeAt(int x, int y) {
 43         return board[(y * BOARD_WIDTH) + x];
 44     }
 45     void start() {
 46         curPiece=new Shape();
 47         board=new Tetrominoe[BOARD_WIDTH * BOARD_HEIGHT];
 48         clearBoard();
 49         newPiece();
 50         timer=new Timer(PERIOD_INTERVAL, new GameCycle());
 51         timer.start();
 52     }
 53     private void pause() {
 54         isPaused = !isPaused;
 55         if (isPaused) {
 56             statusbar.setText("paused");
 57         } else {
 58             statusbar.setText(String.valueOf(numLinesRemoved));
 59         }
 60         repaint();
 61     }
 62     @Override
 63     public void paintComponent(Graphics g) {
 64         super.paintComponent(g);
 65         doDrawing(g);
 66     }
 67     private void doDrawing(Graphics g) {
 68         var size = getSize();
 69         int boardTop = (int) size.getHeight() - BOARD_HEIGHT * squareHeight();
 70         for (int i = 0; i < BOARD_HEIGHT; i++) {
 71             for (int j = 0; j < BOARD_WIDTH; j++) {
 72                 Tetrominoe shape = shapeAt(j, BOARD_HEIGHT - i - 1);
 73                 if (shape != Tetrominoe.NoShape) {
 74                     drawSquare(g, j * squareWidth(),
 75                             boardTop + i * squareHeight(), shape);
 76                 }
 77             }
 78         }
 79         if (curPiece.getShape() != Tetrominoe.NoShape) {
 80             for (int i = 0; i < 4; i++) {
 81                 int x = curX + curPiece.x(i);
 82                 int y = curY - curPiece.y(i);
 83                 drawSquare(g, x * squareWidth(),
 84                         boardTop + (BOARD_HEIGHT - y - 1) * squareHeight(),
 85                         curPiece.getShape());
 86             }
 87         }
 88     }
 89     private void dropDown() {
 90         int newY = curY;
 91         while (newY > 0) {
 92             if (!tryMove(curPiece, curX, newY - 1)) {
 93                 break;
 94             }
 95             newY--;
 96         }
 97         pieceDropped();
 98     }
 99     private void oneLineDown() {
100         if (!tryMove(curPiece, curX, curY - 1)) {
101             pieceDropped();
102         }
103     }
104     private void clearBoard() {
105         for (int i = 0; i < BOARD_HEIGHT * BOARD_WIDTH; i++) {
106             board[i] = Tetrominoe.NoShape;
107         }
108     }
109     private void pieceDropped() {
110         for (int i = 0; i < 4; i++) {
111             int x = curX + curPiece.x(i);
112             int y = curY - curPiece.y(i);
113             board[(y * BOARD_WIDTH) + x] = curPiece.getShape();
114         }
115         removeFullLines();
116         if (!isFallingFinished) {
117             newPiece();
118         }
119     }
120 
121     private void newPiece() {
122         curPiece.setRandomShape();
123         curX = BOARD_WIDTH / 2 + 1;
124         curY = BOARD_HEIGHT - 1 + curPiece.minY();
125         if (!tryMove(curPiece, curX, curY)) {
126             curPiece.setShape(Tetrominoe.NoShape);
127             timer.stop();
128             var msg = String.format("Game over. Score: %d", numLinesRemoved);
129             statusbar.setText(msg);
130         }
131     }
132     private boolean tryMove(Shape newPiece, int newX, int newY) {
133 
134         for (int i = 0; i < 4; i++) {
135             int x = newX + newPiece.x(i);
136             int y = newY - newPiece.y(i);
137             if (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) {
138                 return false;
139             }
140             if (shapeAt(x, y) != Tetrominoe.NoShape) {
141                 return false;
142             }
143         }
144         curPiece = newPiece;
145         curX = newX;
146         curY = newY;
147         repaint();
148         return true;
149     }
150     private void removeFullLines() {
151         int numFullLines = 0;
152         for (int i = BOARD_HEIGHT - 1; i >= 0; i--) {
153             boolean lineIsFull = true;
154             for (int j = 0; j < BOARD_WIDTH; j++) {
155                 if (shapeAt(j, i) == Tetrominoe.NoShape) {
156                     lineIsFull = false;
157                     break;
158                 }
159             }
160             if (lineIsFull) {
161                 numFullLines++;
162                 for (int k = i; k < BOARD_HEIGHT - 1; k++) {
163                     for (int j = 0; j < BOARD_WIDTH; j++) {
164                         board[(k * BOARD_WIDTH) + j] = shapeAt(j, k + 1);
165                     }
166                 }
167             }
168         }
169         if (numFullLines > 0) {
170 
171             numLinesRemoved += numFullLines;
172 
173             statusbar.setText(String.valueOf(numLinesRemoved));
174             isFallingFinished = true;
175             curPiece.setShape(Tetrominoe.NoShape);
176         }
177     }
178     private void drawSquare(Graphics g, int x, int y, Tetrominoe shape) {
179 
180         Color colors[] = {new Color(0, 0, 0), new Color(204, 102, 102),
181                 new Color(102, 204, 102), new Color(102, 102, 204),
182                 new Color(204, 204, 102), new Color(204, 102, 204),
183                 new Color(102, 204, 204), new Color(218, 170, 0)
184         };
185 
186         var color = colors[shape.ordinal()];
187 
188         g.setColor(color);
189         g.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2);
190 
191         g.setColor(color.brighter());
192         g.drawLine(x, y + squareHeight() - 1, x, y);
193         g.drawLine(x, y, x + squareWidth() - 1, y);
194 
195         g.setColor(color.darker());
196         g.drawLine(x + 1, y + squareHeight() - 1,
197                 x + squareWidth() - 1, y + squareHeight() - 1);
198         g.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
199                 x + squareWidth() - 1, y + 1);
200     }
201     private class GameCycle implements ActionListener {
202         @Override
203         public void actionPerformed(ActionEvent e) {
204             doGameCycle();
205         }
206     }
207     private void doGameCycle() {
208         update();
209         repaint();
210     }
211     private void update() {
212         if (isPaused) {
213             return;
214         }
215         if (isFallingFinished) {
216             isFallingFinished = false;
217             newPiece();
218         } else {
219             oneLineDown();
220         }
221     }
222     class TAdapter extends KeyAdapter {
223         @Override
224         public void keyPressed(KeyEvent e) {
225 
226             if (curPiece.getShape() == Tetrominoe.NoShape) {
227                 return;
228             }
229             int keycode = e.getKeyCode();
230             // Java 12 switch expressions
231             switch (keycode) {
232                 case KeyEvent.VK_P : pause();break;
233                 case KeyEvent.VK_LEFT : tryMove(curPiece, curX - 1, curY);break;
234                 case KeyEvent.VK_RIGHT : tryMove(curPiece, curX + 1, curY);break;
235                 case KeyEvent.VK_DOWN : tryMove(curPiece.rotateRight(), curX, curY);break;
236                 case KeyEvent.VK_UP : tryMove(curPiece.rotateLeft(), curX, curY);break;
237                 case KeyEvent.VK_SPACE : dropDown();break;
238                 case KeyEvent.VK_D : oneLineDown();
239             }
240         }
241     }
242 }

 

分类:

技术点:

相关文章: