用java写一个俄罗斯方块 源代码
时间: 2023-12-31 19:07:11 浏览: 67
这里提供一个简单的俄罗斯方块的Java源代码:
```
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
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 final int WIDTH = 10;
private final int HEIGHT = 20;
private final int BLOCK_SIZE = 30;
private int[][] board = new int[HEIGHT][WIDTH];
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 Shape curPiece;
private Shape.Tetrominoes[] boardArray = Shape.Tetrominoes.values();
private Random random = new Random();
public Tetris() {
setPreferredSize(new Dimension(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE));
setBackground(Color.BLACK);
setFont(new Font("Arial", Font.BOLD, 24));
addKeyListener(this);
}
private void start() {
isStarted = true;
isPaused = false;
numLinesRemoved = 0;
clearBoard();
newPiece();
timer = new Timer(400, this);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e) {
if (isFallingFinished) {
isFallingFinished = false;
newPiece();
} else {
oneLineDown();
}
}
private void clearBoard() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
board[i][j] = 0;
}
}
}
private void newPiece() {
curPiece = new Shape(boardArray[random.nextInt(7)]);
curX = WIDTH / 2 - 1;
curY = 0;
if (!tryMove(curPiece, curX, curY)) {
curPiece = null;
timer.stop();
isStarted = false;
}
}
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][x] = curPiece.getShape();
}
removeFullLines();
if (!isFallingFinished)
newPiece();
}
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 (board[i][j] == 0) {
lineIsFull = false;
break;
}
}
if (lineIsFull) {
numFullLines++;
for (int k = i; k < HEIGHT - 1; k++) {
for (int j = 0; j < WIDTH; j++) {
board[k][j] = board[k + 1][j];
}
}
for (int j = 0; j < WIDTH; j++) {
board[HEIGHT - 1][j] = 0;
}
}
}
if (numFullLines > 0) {
numLinesRemoved += numFullLines;
isFallingFinished = true;
curPiece.setShape(Shape.Tetrominoes.NoShape);
}
}
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 (board[y][x] != 0)
return false;
}
curPiece = newPiece;
curX = newX;
curY = newY;
repaint();
return true;
}
@Override
public void keyPressed(KeyEvent e) {
if (!isStarted || curPiece.getShape() == Shape.Tetrominoes.NoShape) {
return;
}
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_P) {
pause();
}
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 KeyEvent.VK_D:
oneLineDown();
break;
}
}
private void dropDown() {
int newY = curY;
while (newY > 0) {
if (!tryMove(curPiece, curX, newY - 1))
break;
newY--;
}
pieceDropped();
}
private void pause() {
isPaused = !isPaused;
if (isPaused) {
timer.stop();
showMessage("Paused");
} else {
timer.start();
showMessage("");
}
repaint();
}
private void showMessage(String message) {
Graphics g = getGraphics();
g.setColor(Color.WHITE);
g.drawString(message, (WIDTH * BLOCK_SIZE - g.getFontMetrics().stringWidth(message)) / 2,
HEIGHT * BLOCK_SIZE / 2);
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void paint(Graphics g) {
super.paint(g);
Dimension size = getSize();
int boardTop = (int) size.getHeight() - HEIGHT * BLOCK_SIZE;
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
Shape.Tetrominoes shape = Shape.Tetrominoes.values()[board[i][j]];
drawSquare(g, j * BLOCK_SIZE, boardTop + i * BLOCK_SIZE, 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, x * BLOCK_SIZE, boardTop + (HEIGHT - y - 1) * BLOCK_SIZE, 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, BLOCK_SIZE - 2, BLOCK_SIZE - 2);
g.setColor(color.brighter());
g.drawLine(x, y + BLOCK_SIZE - 1, x, y);
g.drawLine(x, y, x + BLOCK_SIZE - 1, y);
g.setColor(color.darker());
g.drawLine(x + 1, y + BLOCK_SIZE - 1, x + BLOCK_SIZE - 1, y + BLOCK_SIZE - 1);
g.drawLine(x + BLOCK_SIZE - 1, y + BLOCK_SIZE - 1, x + BLOCK_SIZE - 1, y + 1);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Tetris");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(320, 640);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(new Tetris());
frame.setVisible(true);
}
}
```
这个源代码实现了一个简单的俄罗斯方块游戏,可以通过上下左右键控制方块的移动和旋转,空格键可以直接让方块落到底部。
阅读全文