Created
May 21, 2023 10:03
-
-
Save R3DHULK/c3cd8d4b73afbaaae055906937952371 to your computer and use it in GitHub Desktop.
Tetris Game Written In Java Swing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.swing.*; | |
import java.awt.*; | |
import java.awt.event.*; | |
public class TetrisGame extends JFrame { | |
private static final int BOARD_WIDTH = 10; | |
private static final int BOARD_HEIGHT = 20; | |
private static final int BLOCK_SIZE = 30; | |
private Tetromino currentTetromino; | |
private int[][] board; | |
public TetrisGame() { | |
setTitle("Tetris"); | |
setSize(BOARD_WIDTH * BLOCK_SIZE, BOARD_HEIGHT * BLOCK_SIZE); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
setResizable(false); | |
setLocationRelativeTo(null); | |
board = new int[BOARD_HEIGHT][BOARD_WIDTH]; | |
addKeyListener(new TetrisKeyListener()); | |
setFocusable(true); | |
startGame(); | |
} | |
private void startGame() { | |
currentTetromino = new Tetromino(); | |
currentTetromino.setInitialPosition(BOARD_WIDTH / 2, 0); | |
Timer timer = new Timer(500, new GameLoop()); | |
timer.start(); | |
} | |
private void updateGame() { | |
if (canMoveDown()) { | |
currentTetromino.moveDown(); | |
} else { | |
placeCurrentTetromino(); | |
checkLines(); | |
currentTetromino = new Tetromino(); | |
currentTetromino.setInitialPosition(BOARD_WIDTH / 2, 0); | |
} | |
} | |
private boolean canMoveDown() { | |
int[][] shape = currentTetromino.getShape(); | |
int row = currentTetromino.getRow(); | |
int col = currentTetromino.getCol(); | |
for (int i = 0; i < shape.length; i++) { | |
for (int j = 0; j < shape[i].length; j++) { | |
if (shape[i][j] == 1) { | |
int nextRow = row + i + 1; | |
if (nextRow >= BOARD_HEIGHT || board[nextRow][col + j] == 1) { | |
return false; | |
} | |
} | |
} | |
} | |
return true; | |
} | |
private void placeCurrentTetromino() { | |
int[][] shape = currentTetromino.getShape(); | |
int row = currentTetromino.getRow(); | |
int col = currentTetromino.getCol(); | |
for (int i = 0; i < shape.length; i++) { | |
for (int j = 0; j < shape[i].length; j++) { | |
if (shape[i][j] == 1) { | |
board[row + i][col + j] = 1; | |
} | |
} | |
} | |
} | |
private void checkLines() { | |
int linesCleared = 0; | |
for (int i = BOARD_HEIGHT - 1; i >= 0; i--) { | |
boolean lineFilled = true; | |
for (int j = 0; j < BOARD_WIDTH; j++) { | |
if (board[i][j] == 0) { | |
lineFilled = false; | |
break; | |
} | |
} | |
if (lineFilled) { | |
linesCleared++; | |
clearLine(i); | |
moveLinesDown(i); | |
i++; | |
} | |
} | |
if (linesCleared > 0) { | |
// TODO: Update score or perform other actions | |
} | |
} | |
private void clearLine(int row) { | |
for (int j = 0; j < BOARD_WIDTH; j++) { | |
board[row][j] = 0; | |
} | |
} | |
private void moveLinesDown(int startRow) { | |
for (int i = startRow - 1; i >= 0; i--) { | |
System.arraycopy(board[i], 0, board[i + 1], 0, BOARD_WIDTH); | |
} | |
} | |
@Override | |
public void paint(Graphics g) { | |
super.paint(g); | |
for (int i = 0; i < BOARD_HEIGHT; i++) { | |
for (int j = 0; j < BOARD_WIDTH; j++) { | |
if (board[i][j] == 1) { | |
g.setColor(Color.RED); | |
g.fillRect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); | |
} | |
} | |
} | |
int[][] shape = currentTetromino.getShape(); | |
int row = currentTetromino.getRow(); | |
int col = currentTetromino.getCol(); | |
for (int i = 0; i < shape.length; i++) { | |
for (int j = 0; j < shape[i].length; j++) { | |
if (shape[i][j] == 1) { | |
g.setColor(Color.BLUE); | |
g.fillRect((col + j) * BLOCK_SIZE, (row + i) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); | |
} | |
} | |
} | |
} | |
private class GameLoop implements ActionListener { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
updateGame(); | |
repaint(); | |
} | |
} | |
private class TetrisKeyListener extends KeyAdapter { | |
@Override | |
public void keyPressed(KeyEvent e) { | |
if (e.getKeyCode() == KeyEvent.VK_LEFT) { | |
if (canMoveLeft()) { | |
currentTetromino.moveLeft(); | |
} | |
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { | |
if (canMoveRight()) { | |
currentTetromino.moveRight(); | |
} | |
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) { | |
if (canMoveDown()) { | |
currentTetromino.moveDown(); | |
} | |
} else if (e.getKeyCode() == KeyEvent.VK_SPACE) { | |
while (canMoveDown()) { | |
currentTetromino.moveDown(); | |
} | |
} | |
repaint(); | |
} | |
private boolean canMoveLeft() { | |
int[][] shape = currentTetromino.getShape(); | |
int row = currentTetromino.getRow(); | |
int col = currentTetromino.getCol(); | |
for (int i = 0; i < shape.length; i++) { | |
for (int j = 0; j < shape[i].length; j++) { | |
if (shape[i][j] == 1) { | |
int nextCol = col + j - 1; | |
if (nextCol < 0 || board[row + i][nextCol] == 1) { | |
return false; | |
} | |
} | |
} | |
} | |
return true; | |
} | |
private boolean canMoveRight() { | |
int[][] shape = currentTetromino.getShape(); | |
int row = currentTetromino.getRow(); | |
int col = currentTetromino.getCol(); | |
for (int i = 0; i < shape.length; i++) { | |
for (int j = 0; j < shape[i].length; j++) { | |
if (shape[i][j] == 1) { | |
int nextCol = col + j + 1; | |
if (nextCol >= BOARD_WIDTH || board[row + i][nextCol] == 1) { | |
return false; | |
} | |
} | |
} | |
} | |
return true; | |
} | |
} | |
private class Tetromino { | |
private static final int[][][] SHAPES = { | |
// I shape | |
{ | |
{1, 1, 1, 1} | |
}, | |
// J shape | |
{ | |
{1, 0, 0}, | |
{1, 1, 1} | |
}, | |
// L shape | |
{ | |
{0, 0, 1}, | |
{1, 1, 1} | |
}, | |
// O shape | |
{ | |
{1, 1}, | |
{1, 1} | |
}, | |
// S shape | |
{ | |
{0, 1, 1}, | |
{1, 1, 0} | |
}, | |
// T shape | |
{ | |
{0, 1, 0}, | |
{1, 1, 1} | |
}, | |
// Z shape | |
{ | |
{1, 1, 0}, | |
{0, 1, 1} | |
} | |
}; | |
private int[][] shape; | |
private int row; | |
private int col; | |
public Tetromino() { | |
int index = (int) (Math.random() * SHAPES.length); | |
shape = SHAPES[index]; | |
row = 0; | |
col = 0; | |
} | |
public int[][] getShape() { | |
return shape; | |
} | |
public int getRow() { | |
return row; | |
} | |
public int getCol() { | |
return col; | |
} | |
public void setInitialPosition(int initialCol, int initialRow) { | |
col = initialCol; | |
row = initialRow; | |
} | |
public void moveLeft() { | |
col--; | |
} | |
public void moveRight() { | |
col++; | |
} | |
public void moveDown() { | |
row++; | |
} | |
} | |
public static void main(String[] args) { | |
SwingUtilities.invokeLater(() -> { | |
TetrisGame game = new TetrisGame(); | |
game.setVisible(true); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment