📄 tetris.java
字号:
/**
* <p>Title: 俄罗斯方块</p>
*
* <p>Description: Just have for fun</p>
*
* @author: argentmoon
* @version 1.1
*/
package game;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
import javax.swing.event.*;
public class Tetris extends JFrame implements KeyListener, Runnable{
//Menu and Item
private JMenuBar bar;
private JMenu fileMenu, speedMenu, directionMenu, helpMenu;
private JMenuItem newGame, pause, exit, about;
private JRadioButtonMenuItem speedButton[], clockwise, anticlockwise;
private ButtonGroup speedGroup, directionGroup;
//game status
private final int PLAY = 1, PAUSE = 2, STOP = 3, TOBEGIN = 4, OVER = 5;
private int speed, gameStatus, score, beginSpeed;
private JLabel statusLabel;
//information of block and grid
private final int gridSize = 18;
private final int horizontalGameBlocks = 10, horizontalStauesBlocks = 5,
verticalBlocks = 20;
private final int TOP = 52, LEFT = 3;
//the game tabel
private boolean table[][];
private Point blockPos[][];
//game information
private int direction;
private final int XMAX = horizontalGameBlocks - 1, YMAX = verticalBlocks - 1;
private int currentShape[][][], nextShape[][][];
private int currentStatus, nextStatus, tmpStatus;
private int currentX, currentY, nextX, nextY, points;
private boolean canMoveDown;
//about information
final String aboutString =
"Developed by argentmoon\nEmail to: argentmoon@gmail.com\nVersion 1.1";
public Tetris(){
super("Tetris");
bar = new JMenuBar();
setJMenuBar(bar);
fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
bar.add(fileMenu);
speedMenu = new JMenu("Speed");
speedMenu.setMnemonic('S');
directionMenu = new JMenu("Direction");
directionMenu.setMnemonic('D');
bar.add(directionMenu);
bar.add(speedMenu);
helpMenu = new JMenu("Help");
helpMenu.setMnemonic('H');
bar.add(helpMenu);
newGame = new JMenuItem("New Game");
newGame.setMnemonic('N');
fileMenu.add(newGame);
newGame.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
gameStatus = TOBEGIN;
changeStatus();
init();
repaint();
}
}
);
pause = new JMenuItem("Pause");
pause.setMnemonic('P');
fileMenu.add(pause);
pause.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
if(PLAY == gameStatus)
gameStatus = PAUSE;
else if(PAUSE == gameStatus || TOBEGIN == gameStatus)
gameStatus = PLAY;
changeStatus();
repaint();
}
}
);
exit = new JMenuItem("Exit");
exit.setMnemonic('x');
fileMenu.add(exit);
exit.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
System.exit(0);
}
}
);
speedButton = new JRadioButtonMenuItem[9];
speedGroup = new ButtonGroup();
for(int i = 0; i < speedButton.length; i++){
speedButton[i] = new JRadioButtonMenuItem("speed " + (i + 1));
speedMenu.add(speedButton[i]);
speedGroup.add(speedButton[i]);
speedButton[i].addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
for(int j = 0; j < speedButton.length; j++){
if(speedButton[j].isSelected())
beginSpeed = speed = j + 1;
}
repaint();
}
}
);
}
directionGroup = new ButtonGroup();
clockwise = new JRadioButtonMenuItem("Clockwise");
clockwise.setMnemonic('C');
directionMenu.add(clockwise);
directionGroup.add(clockwise);
clockwise.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
if(clockwise.isSelected())
direction = 1;
repaint();
}
}
);
anticlockwise = new JRadioButtonMenuItem("Anticlockwise");
anticlockwise.setMnemonic('A');
directionMenu.add(anticlockwise);
directionGroup.add(anticlockwise);
anticlockwise.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
if(anticlockwise.isSelected())
direction = -1;
repaint();
}
}
);
about = new JMenuItem("About");
about.setMnemonic('A');
helpMenu.add(about);
about.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
repaint();
JOptionPane.showMessageDialog(null, aboutString, "About",
JOptionPane.INFORMATION_MESSAGE);
}
}
);
//the postion of every block in the table;
blockPos = new Point[verticalBlocks][horizontalGameBlocks];
for(int i = 0; i < horizontalGameBlocks; i++)
blockPos[verticalBlocks - 1][i] = new Point(LEFT + i * gridSize, TOP);
for(int i = verticalBlocks - 2; i >= 0; i--){
for(int j = 0; j < horizontalGameBlocks; j++){
blockPos[i][j] = new Point();
blockPos[i][j].x = blockPos[i + 1][j].x;
blockPos[i][j].y = blockPos[i + 1][j].y + gridSize;
}
}
//init
beginSpeed = speed = 1;
gameStatus = STOP;
direction = 1;
getContentPane().setBackground(Color.gray);
statusLabel = new JLabel();
getContentPane().add(statusLabel, BorderLayout.SOUTH);
statusLabel.setText("Get ready to begin!");
statusLabel.setBackground(Color.white);
statusLabel.setOpaque(true);
addKeyListener(this);
setSize(gridSize * (horizontalGameBlocks + horizontalStauesBlocks) + 4,
gridSize * (verticalBlocks) + 72);
setResizable(false);
setVisible(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((int)(screenSize.getWidth()/3),
(int)(screenSize.getHeight()/4));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//let the thread begin
Thread game = new Thread(this);
game.start();
}
public void init(){
gameStatus = TOBEGIN;
score = 0;
canMoveDown = true;
//at first,there are none of the blocks filled
table = new boolean[verticalBlocks][horizontalGameBlocks];
for(int i = verticalBlocks - 1; i >= 0; i--)
for(int j = 0; j < horizontalGameBlocks; j++)
table[i][j] = false;
getPreBlock();
getNextBlock();
}
public boolean getNextBlock(){
//copy preBlock to currentBlock
currentX = nextX;
currentY = nextY;
currentShape = nextShape;
currentStatus = nextStatus;
//get a new PreBlock and repaint it
getPreBlock();
repaint(gridSize * horizontalGameBlocks + 5,
gridSize * (verticalBlocks - 20) + 72,
gridSize * 5, gridSize * 5);
for(int i = 0; i < currentShape.length; i++){
if(table[getY(i)][getX(i)])
return false;
}
return true;
}
public void getPreBlock(){
int i;
nextStatus = (int) (Math.random() * BlockShape.blockShape.length);
nextShape = new int [BlockShape.blockShape[nextStatus].length][4][2];
System.arraycopy(BlockShape.blockShape[nextStatus], 0, nextShape, 0,
BlockShape.blockShape[nextStatus].length);
nextStatus = (int) (Math.random() * nextShape.length);
//set the new block top
int top = 0;
for(i = 0; i < nextShape[nextStatus].length; i++)
if(nextShape[nextStatus][i][1] > top)
top = nextShape[nextStatus][i][1];
nextY = YMAX - top;
nextX = 3;
for(i = 0; i < nextShape[nextStatus].length; i++)
if(nextShape[nextStatus][i][1] + nextY + 1 > YMAX)
break;
if(i >= nextShape[nextStatus].length) nextY++;
}
public void moveRight(){
int i;
for(i = 0; i < currentShape[currentStatus].length; i++)
if(getX(i) + 1 > XMAX ||
table[getY(i)][getX(i) + 1]
)
break;
if(i >= currentShape[currentStatus].length){
currentX++;
for(i = 0; i < currentShape[currentStatus].length; i++){
repaint(blockPos[getY(i)][getX(i)].x, blockPos[getY(i)][getX(i)].y,
gridSize, gridSize);
repaint(blockPos[getY(i)][getX(i) - 1].x, blockPos[getY(i)][getX(i) - 1].y,
gridSize, gridSize);
}
}else
canMoveDown = true;
}
public void moveLeft(){
int i;
for(i = 0; i < currentShape[currentStatus].length; i++)
if(getX(i) - 1 < 0 ||
table[getY(i)][getX(i) - 1]
)
break;
if(i >= currentShape[currentStatus].length){
currentX--;
for(i = 0; i < currentShape[currentStatus].length; i++){
repaint(blockPos[getY(i)][getX(i)].x, blockPos[getY(i)][getX(i)].y,
gridSize, gridSize);
repaint(blockPos[getY(i)][getX(i) + 1].x, blockPos[getY(i)][getX(i) + 1].y,
gridSize, gridSize);
}
}else
canMoveDown = true;
}
public boolean moveDown(){
int i;
for(i = 0; i < currentShape[currentStatus].length; i++)
if(getY(i) - 1 < 0 ||
table[getY(i) - 1][getX(i)]
)
return false;
currentY--;
for(i = 0; i < currentShape[currentStatus].length; i++){
repaint(blockPos[getY(i) + 1][getX(i)].x, blockPos[getY(i) + 1][getX(i)].y,
gridSize, gridSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -