java写一个俄罗斯方块游戏
时间: 2023-12-19 22:07:39 浏览: 64
好的,下面是一个简单的Java俄罗斯方块游戏示例:
```java
import java.awt.Color;
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 KeyListener, ActionListener {
private static final long serialVersionUID = 1L;
private final int BOARD_WIDTH = 10;
private final int BOARD_HEIGHT = 22;
private 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) {
initBoard(parent);
}
private void initBoard(JFrame parent) {
setFocusable(true);
curPiece = new Shape();
timer = new Timer(400, this);
timer.start();
statusbar = new JLabel(" 0");
parent.add(statusbar, BorderLayout.SOUTH);
board = new Shape.Tetrominoes[BOARD_WIDTH * BOARD_HEIGHT];
addKeyListener(this);
clearBoard();
}
private int squareWidth() { return (int) getSize().getWidth() / BOARD_WIDTH; }
private int squareHeight() { return (int) getSize().getHeight() / BOARD_HEIGHT; }
private Shape.Tetrominoes shapeAt(int x, int y) { return board[(y * BOARD_WIDTH) + x]; }
public void start() {
if (isPaused) return;
isStarted = true;
isFallingFinished = false;
numLinesRemoved = 0;
clearBoard();
newPiece();
timer.start();
}
private void pause() {
if (!isStarted) return;
isPaused = !isPaused;
if (isPaused) {
timer.stop();
statusbar.setText("paused");
} else {
timer.start();
statusbar.setText(String.valueOf(numLinesRemoved));
}
repaint();
}
private void doDrawing(Graphics g) {
Dimension size = getSize();
int boardTop = (int) size.getHeight() - BOARD_HEIGHT * squareHeight();
for (int i = 0; i < BOARD_HEIGHT; i++) {
for (int j = 0; j < BOARD_WIDTH; j++) {
Shape.Tetrominoes shape = shapeAt(j, BOARD_HEIGHT - i - 1);
if (shape != Shape.Tetrominoes.NoShape) {
drawSquare(g, 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, x * squareWidth(),
boardTop + (BOARD_HEIGHT - y - 1) * squareHeight(),
curPiece.getShape());
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
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 clearBoard() {
for (int i = 0; i < BOARD_HEIGHT * BOARD_WIDTH; i++) {
board[i] = Shape.Tetrominoes.NoShape;
}
}
private void pieceDropped() {
for (int i = 0; i < 4; i++) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
board[(y * BOARD_WIDTH) + x] = curPiece.getShape();
}
removeFullLines();
if (!isFallingFinished) newPiece();
}
private void newPiece() {
curPiece.setRandomShape();
curX = BOARD_WIDTH / 2 + 1;
curY = BOARD_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 >= BOARD_WIDTH || y < 0 || y >= BOARD_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 = BOARD_HEIGHT - 1; i >= 0; i--) {
boolean lineIsFull = true;
for (int j = 0; j < BOARD_WIDTH; j++) {
if (shapeAt(j, i) == Shape.Tetrominoes.NoShape) {
lineIsFull = false;
break;
}
}
if (lineIsFull) {
numFullLines++;
for (int k = i; k < BOARD_HEIGHT - 1; k++) {
for (int j = 0; j < BOARD_WIDTH; j++) {
board[(k * BOARD_WIDTH) + j] = shapeAt(j, k + 1);
}
}
}
}
if (numFullLines > 0) {
numLinesRemoved += numFullLines;
statusbar.setText(String.valueOf(numLinesRemoved));
isFallingFinished = true;
curPiece.setShape(Shape.Tetrominoes.NoShape);
}
}
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);
}
@Override
public void actionPerformed(ActionEvent event) {
if (isFallingFinished) {
isFallingFinished = false;
newPiece();
} else {
oneLineDown();
}
}
@Override
public void keyPressed(KeyEvent event) {
if (!isStarted || curPiece.getShape() == Shape.Tetrominoes.NoShape) { return; }
int keycode = event.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':
oneLineDown();
break;
case 'D':
oneLineDown();
break;
}
}
@Override
public void keyReleased(KeyEvent event) {
}
@Override
public void keyTyped(KeyEvent event) {
}
}
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;
}
}
public class TetrisGame extends JFrame {
private static final long serialVersionUID = 1L;
public TetrisGame() {
initUI();
}
private void initUI() {
Tetris board = new Tetris(this);
add(board);
setTitle("Tetris Game");
setSize(320, 640);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
TetrisGame game = new TetrisGame();
game.setVisible(true);
}
}
```
该示例使用了Java的Swing库和AWT事件处理程序,可以在JFrame中显示俄罗斯方块游戏。在游戏中,玩家需要旋转和移动下落的方块,使它们落在一起并填满一行,以消除它们并获得分数。
阅读全文