Tetris/Java: Difference between revisions
Content added Content deleted
(→{{headerJava}}: added Java) |
(→{{header|Java}}: cleaned up code a bit) |
||
Line 10: | Line 10: | ||
public static final int EMPTY = -1; |
public static final int EMPTY = -1; |
||
public static final int BORDER = -2; |
public static final int BORDER = -2; |
||
final Color[] colors = {Color.green, Color.red, Color.blue, Color.pink, |
|||
Color.orange, Color.cyan, Color.magenta}; |
|||
// for centering the shapes in the preview window |
|||
final int[][] previewOffets = {{16, 15}, {-15, 15}, {0, 0}, {0, 0}, |
|||
{-15, 5}, {16, 15}, {-15, 15}}; |
|||
int[][] grid; |
int[][] grid; |
||
Shape |
Shape fallingShape; |
||
Shape preSelectedShape; |
Shape preSelectedShape; |
||
// position of falling shape |
|||
int |
int fallingShapeRow; |
||
int |
int fallingShapeCol; |
||
int shapeRow; |
|||
int |
int blockSize = Config.blockSize; |
||
int |
int nRows = Config.nRows; |
||
int |
int nCols = Config.nCols; |
||
int topMargin = Config.topMargin; |
|||
int leftMargin = Config.leftMargin; |
|||
Thread fallingThread; |
Thread fallingThread; |
||
Scoreboard scoreboard; |
Scoreboard scoreboard; |
||
Font smallFont; |
|||
Rectangle gridRect, previewRect; |
|||
public Tetris() { |
public Tetris() { |
||
setPreferredSize( |
setPreferredSize(Config.dim); |
||
setBackground( |
setBackground(Config.bgColor); |
||
setFont(new Font("Monospaced", Font.BOLD, 48)); |
|||
setFocusable(true); |
setFocusable(true); |
||
smallFont = getFont().deriveFont(Font.BOLD, 18); |
|||
gridRect = new Rectangle(46, 47, 308, 517); |
|||
previewRect = new Rectangle(387, 47, 200, 200); |
|||
scoreboard = new Scoreboard(); |
scoreboard = new Scoreboard(); |
||
Line 75: | Line 61: | ||
case KeyEvent.VK_UP: |
case KeyEvent.VK_UP: |
||
if (canRotate( |
if (canRotate(fallingShape)) |
||
rotate( |
rotate(fallingShape); |
||
break; |
break; |
||
case KeyEvent.VK_LEFT: |
case KeyEvent.VK_LEFT: |
||
if (canMove( |
if (canMove(fallingShape, -1, 0)) |
||
move( |
move(fallingShape, -1, 0); |
||
break; |
break; |
||
case KeyEvent.VK_RIGHT: |
case KeyEvent.VK_RIGHT: |
||
if (canMove( |
if (canMove(fallingShape, 1, 0)) |
||
move( |
move(fallingShape, 1, 0); |
||
break; |
break; |
||
Line 92: | Line 78: | ||
if (!fastDown) { |
if (!fastDown) { |
||
fastDown = true; |
fastDown = true; |
||
while (canMove( |
while (canMove(fallingShape, 0, 1)) { |
||
move( |
move(fallingShape, 0, 1); |
||
repaint(); |
repaint(); |
||
} |
} |
||
Line 110: | Line 96: | ||
void selectShape() { |
void selectShape() { |
||
fallingShapeRow = 1; |
|||
fallingShapeCol = 5; |
|||
fallingShape = preSelectedShape; |
|||
Shape[] shapes = Shape.values(); |
|||
preSelectedShape = shapes[(int) (Math.random() * shapes.length)]; |
|||
if (selectedShape != null) |
|||
if (fallingShape != null) |
|||
fallingShape.reset(); |
|||
} |
} |
||
Line 155: | Line 142: | ||
if (!scoreboard.isGameOver()) { |
if (!scoreboard.isGameOver()) { |
||
if (canMove( |
if (canMove(fallingShape, 0, 1)) { |
||
move( |
move(fallingShape, 0, 1); |
||
} else { |
} else { |
||
shapeHasLanded(); |
shapeHasLanded(); |
||
Line 166: | Line 153: | ||
void drawStartScreen(Graphics2D g) { |
void drawStartScreen(Graphics2D g) { |
||
g.setFont( |
g.setFont(Config.mainFont); |
||
g.setColor( |
g.setColor(Config.titlebgColor); |
||
g. |
g.fill(Config.titleRect); |
||
g. |
g.fill(Config.clickRect); |
||
g.setColor( |
g.setColor(Config.textColor); |
||
g.drawString("Tetris", |
g.drawString("Tetris", Config.titleX, Config.titleY); |
||
g.setFont(smallFont); |
g.setFont(Config.smallFont); |
||
g.drawString("click to start", |
g.drawString("click to start", Config.clickX, Config.clickY); |
||
} |
} |
||
void drawSquare(Graphics2D g, |
void drawSquare(Graphics2D g, int colorIndex, int r, int c) { |
||
g. |
g.setColor(Config.colors[colorIndex]); |
||
g.setColor(color); |
|||
g.fillRect(leftMargin + c * blockSize, topMargin + r * blockSize, |
g.fillRect(leftMargin + c * blockSize, topMargin + r * blockSize, |
||
blockSize, blockSize); |
blockSize, blockSize); |
||
g. |
g.setStroke(Config.smallStroke); |
||
g.setColor(Config.squareBorder); |
|||
g.drawRect(leftMargin + c * blockSize, topMargin + r * blockSize, |
g.drawRect(leftMargin + c * blockSize, topMargin + r * blockSize, |
||
blockSize, blockSize); |
blockSize, blockSize); |
||
Line 192: | Line 178: | ||
void drawUI(Graphics2D g) { |
void drawUI(Graphics2D g) { |
||
// grid background |
|||
g.setColor( |
g.setColor(Config.gridColor); |
||
g.fill(gridRect); |
g.fill(Config.gridRect); |
||
g.setColor(new Color(0x7788AA)); |
|||
g.draw(gridRect); |
|||
g.draw(previewRect); |
|||
// the blocks dropped in the grid |
|||
for (int r = 0; r < nRows; r++) { |
for (int r = 0; r < nRows; r++) { |
||
for (int c = 0; c < nCols; c++) { |
for (int c = 0; c < nCols; c++) { |
||
int |
int idx = grid[r][c]; |
||
if ( |
if (idx > EMPTY) |
||
drawSquare(g, |
drawSquare(g, idx, r, c); |
||
} |
} |
||
} |
} |
||
// the borders of grid and preview panel |
|||
g.setColor(Color.black); |
|||
g. |
g.setStroke(Config.largeStroke); |
||
g.setColor(Config.gridBorderColor); |
|||
g.drawString(format("hiscore %6d", scoreboard.getTopscore()),400, 330); |
|||
g.draw(Config.gridRect); |
|||
g.drawString(format("level %6d", scoreboard.getLevel()), 400, 360); |
|||
g.draw(Config.previewRect); |
|||
g.drawString(format("lines %6d", scoreboard.getLines()), 400, 390); |
|||
g.drawString(format("score %6d", scoreboard.getScore()), 400, 420); |
|||
} |
|||
// scoreboard |
|||
void drawPreview(Graphics2D g) { |
|||
int |
int x = Config.scoreX; |
||
int y = Config.scoreY; |
|||
g.translate(previewOffets[ord][0], previewOffets[ord][1]); |
|||
g.setColor(Config.textColor); |
|||
for (int[] p : preSelectedShape.shapes[ord]) { |
|||
g.setFont(Config.smallFont); |
|||
drawSquare(g, colors[ord], 2 + p[1], 15 + p[0]); |
|||
g.drawString(format("hiscore %6d", scoreboard.getTopscore()), x, y); |
|||
} |
|||
g.drawString(format("level %6d", scoreboard.getLevel()), x, y + 30); |
|||
g.translate(-previewOffets[ord][0], -previewOffets[ord][1]); |
|||
g.drawString(format("lines %6d", scoreboard.getLines()), x, y + 60); |
|||
g.drawString(format("score %6d", scoreboard.getScore()), x, y + 90); |
|||
// preview |
|||
int idx = preSelectedShape.ordinal(); |
|||
int offsetX = Config.previewOffets[idx][0] + 15 * blockSize; |
|||
int offsetY = Config.previewOffets[idx][1] + 2 * blockSize; |
|||
g.translate(offsetX, offsetY); |
|||
for (int[] p : preSelectedShape.shapes[idx]) |
|||
drawSquare(g, idx, p[1], p[0]); |
|||
g.translate(-offsetX, -offsetY); |
|||
} |
} |
||
void drawFallingShape(Graphics2D g) { |
void drawFallingShape(Graphics2D g) { |
||
int idx = fallingShape.ordinal(); |
|||
for (int[] p : |
for (int[] p : fallingShape.pos) |
||
drawSquare(g, |
drawSquare(g, idx, fallingShapeRow + p[1], fallingShapeCol + p[0]); |
||
} |
} |
||
Line 245: | Line 240: | ||
drawFallingShape(g); |
drawFallingShape(g); |
||
} |
} |
||
drawPreview(g); |
|||
} |
} |
||
Line 265: | Line 258: | ||
for (int[] p : pos) { |
for (int[] p : pos) { |
||
int newCol = |
int newCol = fallingShapeCol + p[0]; |
||
int newRow = |
int newRow = fallingShapeRow + p[1]; |
||
if (grid[newRow][newCol] != EMPTY) { |
if (grid[newRow][newCol] != EMPTY) { |
||
return false; |
return false; |
||
Line 286: | Line 279: | ||
void move(Shape s, int xIncr, int yIncr) { |
void move(Shape s, int xIncr, int yIncr) { |
||
fallingShapeRow += yIncr; |
|||
fallingShapeCol += xIncr; |
|||
} |
} |
||
boolean canMove(Shape s, int xIncr, int yIncr) { |
boolean canMove(Shape s, int xIncr, int yIncr) { |
||
for (int[] p : s.pos) { |
for (int[] p : s.pos) { |
||
int newCol = |
int newCol = fallingShapeCol + xIncr + p[0]; |
||
int newRow = |
int newRow = fallingShapeRow + yIncr + p[1]; |
||
if (grid[newRow][newCol] != EMPTY) |
if (grid[newRow][newCol] != EMPTY) |
||
return false; |
return false; |
||
Line 301: | Line 294: | ||
void shapeHasLanded() { |
void shapeHasLanded() { |
||
addShape( |
addShape(fallingShape); |
||
if ( |
if (fallingShapeRow < 2) { |
||
scoreboard.setGameOver(); |
scoreboard.setGameOver(); |
||
scoreboard.setTopscore(); |
scoreboard.setTopscore(); |
||
Line 339: | Line 332: | ||
void addShape(Shape s) { |
void addShape(Shape s) { |
||
for (int[] p : s.pos) |
for (int[] p : s.pos) |
||
grid[ |
grid[fallingShapeRow + p[1]][fallingShapeCol + p[0]] = s.ordinal(); |
||
} |
} |
||
Line 487: | Line 480: | ||
{{-1, -1}, {0, -1}, {0, 0}, {0, 1}}, |
{{-1, -1}, {0, -1}, {0, 0}, {0, 1}}, |
||
{{1, -1}, {0, -1}, {0, 0}, {0, 1}}}; |
{{1, -1}, {0, -1}, {0, 0}, {0, 1}}}; |
||
} |
|||
final class Config { |
|||
final static Color[] colors = {Color.green, Color.red, Color.blue, |
|||
Color.pink, Color.orange, Color.cyan, Color.magenta}; |
|||
// used for centering shapes in the preview pane |
|||
final static int[][] previewOffets = {{16, 15}, {-15, 15}, {0, 0}, |
|||
{0, 0}, {-15, 5}, {16, 15}, {-15, 15}}; |
|||
final static Font mainFont = new Font("Monospaced", Font.BOLD, 48); |
|||
final static Font smallFont = mainFont.deriveFont(Font.BOLD, 18); |
|||
final static Dimension dim = new Dimension(640, 640); |
|||
final static int blockSize = 30; |
|||
final static int nRows = 18; |
|||
final static int nCols = 12; |
|||
final static int topMargin = 50; |
|||
final static int leftMargin = 20; |
|||
final static int scoreX = 400; |
|||
final static int scoreY = 330; |
|||
final static int titleX = 130; |
|||
final static int titleY = 150; |
|||
final static int clickX = 120; |
|||
final static int clickY = 400; |
|||
final static Rectangle gridRect = new Rectangle(46, 47, 308, 517); |
|||
final static Rectangle previewRect = new Rectangle(387, 47, 200, 200); |
|||
final static Rectangle titleRect = new Rectangle(100, 85, 252, 100); |
|||
final static Rectangle clickRect = new Rectangle(50, 375, 252, 40); |
|||
final static Stroke largeStroke = new BasicStroke(5); |
|||
final static Stroke smallStroke = new BasicStroke(2); |
|||
final static Color squareBorder = Color.white; |
|||
final static Color titlebgColor = Color.white; |
|||
final static Color textColor = Color.black; |
|||
final static Color bgColor = new Color(0xDDEEFF); |
|||
final static Color gridColor = new Color(0xBECFEA); |
|||
final static Color gridBorderColor = new Color(0x7788AA); |
|||
}</lang> |
}</lang> |