Tetris/Java: Difference between revisions

m
→‎Code: Fixed syntax highlighting.
(→‎{{headerJava}}: added Java)
 
m (→‎Code: Fixed syntax highlighting.)
 
(9 intermediate revisions by 2 users not shown)
Line 1:
{{collection|Tetris}}
=={{header|Java}}==
===Code===
{{works with|java|8}}
<syntaxhighlight lang ="java">importpackage java.awt.*tetris;
 
import java.awt.*;
import java.awt.event.*;
import static java.lang.Math.*;
import static java.lang.String.format;
import java.util.Arrays*;
import javax.swing.*;
import static tetris.Config.*;
 
public class Tetris extends JPanel implements Runnable {
enum Dir {
right(1, 0), down(0, 1), left(-1, 0);
 
Dir(int x, int y) {
this.x = x;
this.y = y;
}
final int x, y;
};
 
public static final int EMPTY = -1;
public static final int BORDER = -2;
 
Shape fallingShape;
final Color[] colors = {Color.green, Color.red, Color.blue, Color.pink,
Shape nextShape;
Color.orange, Color.cyan, Color.magenta};
 
// position of falling shape
// for centering the shapes in the preview window
int fallingShapeRow;
final int[][] previewOffets = {{16, 15}, {-15, 15}, {0, 0}, {0, 0},
int fallingShapeCol;
{-15, 5}, {16, 15}, {-15, 15}};
 
final int[][] grid = new int[nRows][nCols];
 
Shape selectedShape;
Shape preSelectedShape;
 
int blockSize = 30;
int nRows = 18;
int nCols = 12;
int shapeRow;
int shapeCol;
int topMargin = 50;
int leftMargin = 20;
 
Thread fallingThread;
final Scoreboard scoreboard = new Scoreboard();
static final Random rand = new Random();
 
Font smallFont;
Rectangle gridRect, previewRect;
 
public Tetris() {
setPreferredSize(new Dimension(640, 640)dim);
setBackground(new Color(0xDDEEFF)bgColor);
setFont(new Font("Monospaced", Font.BOLD, 48));
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();
grid = new int[nRows][nCols];
initGrid();
selectShape();
Line 75 ⟶ 69:
 
case KeyEvent.VK_UP:
if (canRotate(selectedShapefallingShape))
rotate(selectedShapefallingShape);
break;
 
case KeyEvent.VK_LEFT:
if (canMove(selectedShapefallingShape, -1, 0Dir.left))
move(selectedShape, -1, 0Dir.left);
break;
 
case KeyEvent.VK_RIGHT:
if (canMove(selectedShapefallingShape, 1, 0Dir.right))
move(selectedShape, 1, 0Dir.right);
break;
 
Line 92 ⟶ 86:
if (!fastDown) {
fastDown = true;
while (canMove(selectedShapefallingShape, 0, 1Dir.down)) {
move(selectedShape, 0, 1Dir.down);
repaint();
}
Line 110 ⟶ 104:
 
void selectShape() {
shapeRowfallingShapeRow = 1;
shapeColfallingShapeCol = 5;
selectedShapefallingShape = preSelectedShapenextShape;
preSelectedShapeShape[] shapes = Shape.values()[(int) (Math.random() * colors.length)];
nextShape = shapes[rand.nextInt(shapes.length)];
if (selectedShape != null)
if (fallingShape != selectedShape.reset(null);
fallingShape.reset();
}
 
Line 151 ⟶ 146:
try {
Thread.sleep(scoreboard.getSpeed());
} catch (InterruptedException ignorede) {
return;
}
 
if (!scoreboard.isGameOver()) {
if (canMove(selectedShapefallingShape, 0, 1Dir.down)) {
move(selectedShape, 0, 1Dir.down);
} else {
shapeHasLanded();
Line 166 ⟶ 162:
 
void drawStartScreen(Graphics2D g) {
g.setFont(getFont()mainFont);
 
g.setColor(new Color(0xFFFFFF)titlebgColor);
g.fillRectfill(leftMargin + 80, topMargin + 35, 252, 100titleRect);
g.fillRectfill(leftMargin + 30, topMargin + 325, 252, 40clickRect);
 
g.setColor(Color.blacktextColor);
g.drawString("Tetris", leftMargin + 110titleX, topMargin + 100titleY);
 
g.setFont(smallFont);
g.drawString("click to start", leftMargin + 100clickX, topMargin + 350clickY);
}
 
void drawSquare(Graphics2D g, Colorint colorcolorIndex, int r, int c) {
g.setStrokesetColor(new BasicStroke(2)colors[colorIndex]);
 
g.setColor(color);
g.fillRect(leftMargin + c * blockSize, topMargin + r * blockSize,
blockSize, blockSize);
 
g.setColorsetStroke(Color.whitesmallStroke);
g.setColor(squareBorder);
g.drawRect(leftMargin + c * blockSize, topMargin + r * blockSize,
blockSize, blockSize);
Line 192 ⟶ 187:
 
void drawUI(Graphics2D g) {
g.setStroke(new// BasicStroke(5));grid background
g.setColor(new Color(0xBECFEA)gridColor);
g.fill(gridRect);
 
// the blocks dropped in the grid
g.setColor(new Color(0x7788AA));
g.draw(gridRect);
g.draw(previewRect);
 
for (int r = 0; r < nRows; r++) {
for (int c = 0; c < nCols; c++) {
int ididx = grid[r][c];
if (ididx > EMPTY)
drawSquare(g, colors[id]idx, r, c);
}
}
 
// the borders of grid and preview panel
g.setColor(Color.black);
g.setStroke(largeStroke);
g.setColor(gridBorderColor);
g.draw(gridRect);
g.draw(previewRect);
 
// scoreboard
int x = scoreX;
int y = scoreY;
g.setColor(textColor);
g.setFont(smallFont);
g.drawString(format("hiscore %6d", scoreboard.getTopscore()),400 x, 330y);
g.drawString(format("level %6d", scoreboard.getLevel()), 400x, 360y + 30);
g.drawString(format("lines %6d", scoreboard.getLines()), 400x, 390y + 60);
g.drawString(format("score %6d", scoreboard.getScore()), 400x, 420y + 90);
}
 
// preview
void drawPreview(Graphics2D g) {
int ordminX = preSelectedShape.ordinal()5, minY = 5, maxX = 0, maxY = 0;
for (int[] p : nextShape.pos) {
g.translate(previewOffets[ord][0], previewOffets[ord][1]);
for (int[] p : preSelectedShape.shapesminX = min(minX, p[ord0]) {;
drawSquareminY = min(gminY, colors[ord], 2 + p[1], 15 + p[0]);
maxX = max(maxX, p[0]);
maxY = max(maxY, p[1]);
}
double cx = previewCenterX - ((minX + maxX + 1) / 2.0 * blockSize);
g.translate(-previewOffets[ord][0], -previewOffets[ord][1]);
double cy = previewCenterY - ((minY + maxY + 1) / 2.0 * blockSize);
 
g.translate(cx, cy);
for (int[] p : nextShape.shape)
drawSquare(g, nextShape.ordinal(), p[1], p[0]);
g.translate(-cx, -cy);
}
 
void drawFallingShape(Graphics2D g) {
Colorint cidx = colors[selectedShapefallingShape.ordinal()];
for (int[] p : selectedShapefallingShape.pos)
drawSquare(g, cidx, shapeRowfallingShapeRow + p[1], shapeColfallingShapeCol + p[0]);
}
 
Line 240 ⟶ 248:
drawUI(g);
 
if (fallingThread == nullscoreboard.isGameOver()) {
drawStartScreen(g);
} else {
drawFallingShape(g);
}
 
drawPreview(g);
}
 
Line 265 ⟶ 271:
 
for (int[] p : pos) {
int newCol = shapeColfallingShapeCol + p[0];
int newRow = shapeRowfallingShapeRow + p[1];
if (grid[newRow][newCol] != EMPTY) {
return false;
Line 285 ⟶ 291:
}
 
void move(ShapeDir s, int xIncr, int yIncrdir) {
shapeRowfallingShapeRow += yIncrdir.y;
shapeColfallingShapeCol += xIncrdir.x;
}
 
boolean canMove(Shape s, intDir xIncr, int yIncrdir) {
for (int[] p : s.pos) {
int newCol = shapeColfallingShapeCol + xIncrdir.x + p[0];
int newRow = shapeRowfallingShapeRow + yIncrdir.y + p[1];
if (grid[newRow][newCol] != EMPTY)
return false;
Line 301 ⟶ 307:
 
void shapeHasLanded() {
addShape(selectedShapefallingShape);
if (shapeRowfallingShapeRow < 2) {
scoreboard.setGameOver();
scoreboard.setTopscore();
Line 339 ⟶ 345:
void addShape(Shape s) {
for (int[] p : s.pos)
grid[shapeRowfallingShapeRow + p[1]][shapeColfallingShapeCol + p[0]] = s.ordinal();
}
 
Line 354 ⟶ 360:
});
}
}</syntaxhighlight>
}
 
<syntaxhighlight lang="java">package tetris;
 
class Scoreboard {
Line 461 ⟶ 469:
return score;
}
}</syntaxhighlight>
}
 
<syntaxhighlight lang="java">package tetris;
 
enum Shape {
ZShape(new int[][]{{0, SShape-1}, Straight{0, TShape0}, Square{-1, LShape0}, JShape;{-1, 1}}),
SShape(new int[][]{{0, -1}, {0, 0}, {1, 0}, {1, 1}}),
IShape(new int[][]{{0, -1}, {0, 0}, {0, 1}, {0, 2}}),
TShape(new int[][]{{-1, 0}, {0, 0}, {1, 0}, {0, 1}}),
Square(new int[][]{{0, 0}, {1, 0}, {0, 1}, {1, 1}}),
LShape(new int[][]{{-1, -1}, {0, -1}, {0, 0}, {0, 1}}),
JShape(new int[][]{{1, -1}, {0, -1}, {0, 0}, {0, 1}});
 
private Shape(int[][] shape) {
this.shape = shape;
pos = new int[4][2];
reset();
Line 473 ⟶ 490:
void reset() {
for (int i = 0; i < pos.length; i++) {
pos[i] = shapes[ordinal()]shape[i].clone();
}
}
 
final int[][] pos, shape;
}</syntaxhighlight>
 
<syntaxhighlight lang="java">package tetris;
 
import java.awt.*;
 
final class Config {
final static Color[] colors = {Color.green, Color.red, Color.blue,
Color.pink, Color.orange, Color.cyan, Color.magenta};
 
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 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 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 int previewCenterX = 467;
final static int previewCenterY = 97;
 
final static Stroke largeStroke = new BasicStroke(5);
final static Stroke smallStroke = new BasicStroke(2);
 
final int[][][]static shapesColor squareBorder = {Color.white;
final static Color titlebgColor = Color.white;
{{0, -1}, {0, 0}, {-1, 0}, {-1, 1}},
final static Color textColor = Color.black;
{{0, -1}, {0, 0}, {1, 0}, {1, 1}},
final static Color bgColor = new Color(0xDDEEFF);
{{0, -1}, {0, 0}, {0, 1}, {0, 2}},
final static Color gridColor = new Color(0xBECFEA);
{{-1, 0}, {0, 0}, {1, 0}, {0, 1}},
final static Color gridBorderColor = new Color(0x7788AA);
{{0, 0}, {1, 0}, {0, 1}, {1, 1}},
}</syntaxhighlight>
{{-1, -1}, {0, -1}, {0, 0}, {0, 1}},
{{1, -1}, {0, -1}, {0, 0}, {0, 1}}};
}</lang>
9,485

edits