java俄罗斯方块源代码
时间: 2023-10-04 14:12:35 浏览: 88
以下是一个简单的Java俄罗斯方块游戏的源代码:
```java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Tetris extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 10;
private static final int HEIGHT = 22;
private static final int BLOCK_SIZE = 30;
private Timer timer;
private boolean isFallingFinished = false;
private boolean isStarted = false;
private boolean isPaused = false;
private int numLinesRemoved = 0;
private int curX = 0;
private int curY = 0;
private JLabel statusbar;
private Shape curPiece;
private Shape.Tetrominoes[] board;
public Tetris(JFrame parent) {
initTetris(parent);
}
private void initTetris(JFrame parent) {
setFocusable(true);
curPiece = new Shape();
timer = new Timer(400, this);
timer.start();
statusbar = new JLabel(" 0");
addKeyListener(this);
board = new Shape.Tetrominoes[WIDTH * HEIGHT];
clearBoard();
}
private int squareWidth() {
return (int) getSize().getWidth() / WIDTH;
}
private int squareHeight() {
return (int) getSize().getHeight() / HEIGHT;
}
private Shape.Tetrominoes shapeAt(int x, int y) {
return board[(y * WIDTH) + x];
}
public void start() {
if (isPaused)
return;
isStarted = true;
isFallingFinished = false;
numLinesRemoved = 0;
clearBoard();
newPiece();
timer.start();
statusbar.setText(String.valueOf(numLinesRemoved));
}
private void pause() {
if (!isStarted)
return;
isPaused = !isPaused;
if (isPaused) {
timer.stop();
statusbar.setText("paused");
} else {
timer.start();
statusbar.setText(String.valueOf(numLinesRemoved));
}
repaint();
}
@Override
public void actionPerformed(ActionEvent ae) {
if (isFallingFinished) {
isFallingFinished = false;
newPiece();
} else {
oneLineDown();
}
}
private void clearBoard() {
for (int i = 0; i < HEIGHT * WIDTH; i++) {
board[i] = Shape.Tetrominoes.NoShape;
}
}
private void dropDown() {
int newY = curY;
while (newY > 0) {
if (!tryMove(curPiece, curX, newY - 1))
break;
newY--;
}
pieceDropped();
}
private void oneLineDown() {
if (!tryMove(curPiece, curX, curY - 1))
pieceDropped();
}
private void pieceDropped() {
for (int i = 0; i < 4; i++) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
board[(y * WIDTH) + x] = curPiece.getShape();
}
removeFullLines();
if (!isFallingFinished)
newPiece();
}
private void newPiece() {
curPiece.setRandomShape();
curX = WIDTH / 2 + 1;
curY = HEIGHT - 1 + curPiece.minY();
if (!tryMove(curPiece, curX, curY)) {
curPiece.setShape(Shape.Tetrominoes.NoShape);
timer.stop();
isStarted = false;
statusbar.setText("game over");
}
}
private boolean tryMove(Shape newPiece, int newX, int newY) {
for (int i = 0; i < 4; i++) {
int x = newX + newPiece.x(i);
int y = newY - newPiece.y(i);
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
return false;
if (shapeAt(x, y) != Shape.Tetrominoes.NoShape)
return false;
}
curPiece = newPiece;
curX = newX;
curY = newY;
repaint();
return true;
}
private void removeFullLines() {
int numFullLines = 0;
for (int i = HEIGHT - 1; i >= 0; i--) {
boolean lineIsFull = true;
for (int j = 0; j < WIDTH; j++) {
if (shapeAt(j, i) == Shape.Tetrominoes.NoShape) {
lineIsFull = false;
break;
}
}
if (lineIsFull) {
numFullLines++;
for (int k = i; k < HEIGHT - 1; k++) {
for (int j = 0; j < WIDTH; j++) {
board[(k * WIDTH) + j] = shapeAt(j, k + 1);
}
}
}
}
if (numFullLines > 0) {
numLinesRemoved += numFullLines;
statusbar.setText(String.valueOf(numLinesRemoved));
isFallingFinished = true;
curPiece.setShape(Shape.Tetrominoes.NoShape);
repaint();
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
Dimension size = getSize();
int boardTop = (int) size.getHeight() - HEIGHT * squareHeight();
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
Shape.Tetrominoes shape = shapeAt(j, HEIGHT - i - 1);
if (shape != Shape.Tetrominoes.NoShape)
drawSquare(g, 0 + j * squareWidth(),
boardTop + i * squareHeight(), shape);
}
}
if (curPiece.getShape() != Shape.Tetrominoes.NoShape) {
for (int i = 0; i < 4; i++) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
drawSquare(g, 0 + x * squareWidth(),
boardTop + (HEIGHT - y - 1) * squareHeight(),
curPiece.getShape());
}
}
}
private void drawSquare(Graphics g, int x, int y, Shape.Tetrominoes shape) {
Color colors[] = { new Color(0, 0, 0), new Color(204, 102, 102),
new Color(102, 204, 102), new Color(102, 102, 204),
new Color(204, 204, 102), new Color(204, 102, 204),
new Color(102, 204, 204), new Color(218, 170, 0)
};
Color color = colors[shape.ordinal()];
g.setColor(color);
g.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2);
g.setColor(color.brighter());
g.drawLine(x, y + squareHeight() - 1, x, y);
g.drawLine(x, y, x + squareWidth() - 1, y);
g.setColor(color.darker());
g.drawLine(x + 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + squareHeight() - 1);
g.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + 1);
}
@Override
public void keyPressed(KeyEvent e) {
if (!isStarted || curPiece.getShape() == Shape.Tetrominoes.NoShape) {
return;
}
int keycode = e.getKeyCode();
if (keycode == 'p' || keycode == 'P') {
pause();
return;
}
if (isPaused)
return;
switch (keycode) {
case KeyEvent.VK_LEFT:
tryMove(curPiece, curX - 1, curY);
break;
case KeyEvent.VK_RIGHT:
tryMove(curPiece, curX + 1, curY);
break;
case KeyEvent.VK_DOWN:
tryMove(curPiece.rotateRight(), curX, curY);
break;
case KeyEvent.VK_UP:
tryMove(curPiece.rotateLeft(), curX, curY);
break;
case KeyEvent.VK_SPACE:
dropDown();
break;
case 'd':
case 'D':
oneLineDown();
break;
case 'r':
case 'R':
start();
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
public static void main(String[] args) {
JFrame frame = new JFrame("Tetris");
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
frame.getContentPane().add(panel);
Tetris tetris = new Tetris(frame);
panel.add(tetris);
JLabel statusbar = new JLabel(" 0");
statusbar.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.add(statusbar, BorderLayout.SOUTH);
tetris.statusbar = statusbar;
frame.setSize(200, 400);
frame.setVisible(true);
}
}
class Shape {
enum Tetrominoes {
NoShape, ZShape, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape
};
private Tetrominoes pieceShape;
private int coords[][];
private int[][][] coordsTable;
public Shape() {
coords = new int[4][2];
setShape(Tetrominoes.NoShape);
}
public void setShape(Tetrominoes shape) {
coordsTable = new int[][][] {
{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, -1 }, { 0, 0 }, { -1, 0 }, { -1, 1 } },
{ { 0, -1 }, { 0, 0 }, { 1, 0 }, { 1, 1 } },
{ { 0, -1 }, { 0, 0 }, { 0, 1 }, { 0, 2 } },
{ { -1, 0 }, { 0, 0 }, { 1, 0 }, { 0, 1 } },
{ { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } },
{ { -1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } },
{ { 1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } }
};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; ++j) {
coords[i][j] = coordsTable[shape.ordinal()][i][j];
}
}
pieceShape = shape;
}
private void setX(int index, int x) {
coords[index][0] = x;
}
private void setY(int index, int y) {
coords[index][1] = y;
}
public int x(int index) {
return coords[index][0];
}
public int y(int index) {
return coords[index][1];
}
public Tetrominoes getShape() {
return pieceShape;
}
public void setRandomShape() {
Random r = new Random();
int x = Math.abs(r.nextInt()) % 7 + 1;
Tetrominoes[] values = Tetrominoes.values();
setShape(values[x]);
}
public int minX() {
int m = coords[0][0];
for (int i = 0; i < 4; i++) {
m = Math.min(m, coords[i][0]);
}
return m;
}
public int minY() {
int m = coords[0][1];
for (int i = 0; i < 4; i++) {
m = Math.min(m, coords[i][1]);
}
return m;
}
public Shape rotateLeft() {
if (pieceShape == Tetrominoes.SquareShape)
return this;
Shape result = new Shape();
result.pieceShape = pieceShape;
for (int i = 0; i < 4; ++i) {
result.setX(i, y(i));
result.setY(i, -x(i));
}
return result;
}
public Shape rotateRight() {
if (pieceShape == Tetrominoes.SquareShape)
return this;
Shape result = new Shape();
result.pieceShape = pieceShape;
for (int i = 0; i < 4; ++i) {
result.setX(i, -y(i));
result.setY(i, x(i));
}
return result;
}
}
```
这只是一个基本的俄罗斯方块游戏,如果需要更高级的功能,可以尝试添加更多的游戏规则和动画效果。
阅读全文