业务分析:百度
数据模型:
类的设计:
1) Cell 格子
int row 行;
int col 列;
Image image 贴图;
2) Tetromino 四格方块
Cell[] cells 4个格子;
3) Tetris 俄罗斯方块 继承 JPanel
int score 分数;
int lines 行数;
Cell[][] wall = new Cell[20][10] 墙;
Tetromino tetromino 四格方块;
Tetromino nextOne 下一个四格方块;
数据的初始化:
构造器
设计功能:
下落
左移动
右移动
旋转
计分
入墙
界面绘制
java Swing API
背景图片
结束游戏图片
七种方块
ps技术有限,有个样子就行了
package xyz.rhel.els; import java.awt.Image; public class Cell { private int row; private int col; private Image image; public Cell(int row, int col, Image image) { this.row = row; this.col = col; this.image = image; } public int getRow() { return row; } public int getCol() { return col; } public Image getImage() { return image; } public void setRow(int row) { this.row = row; } public void setCol(int col) { this.col = col; } public void setImage(Image image) { this.image = image; } public void up() { row--; } public void drop() { row++; } public void moveLeft() { col--; } public void moveRight() { col++; } public String toString() { return "[" + row + "," + col + "]"; } }
package xyz.rhel.els; import java.util.Random; public abstract class Tetromino { protected Cell[] cells = new Cell[4]; protected State[] states; private int index = 100; private Tetromino() { } protected class State { int row0, col0; int row1, col1; int row2, col2; int row3, col3; public State(int row0, int col0, int row1, int col1, int row2, int col2, int row3, int col3) { this.row0 = row0; this.col0 = col0; this.row1 = row1; this.col1 = col1; this.row2 = row2; this.col2 = col2; this.row3 = row3; this.col3 = col3; } } public static Tetromino randomOne() { Random r = new Random(); int type = r.nextInt(7); switch (type) { case 0: return new T(); case 1: return new I(); case 2: return new S(); case 3: return new Z(); case 4: return new J(); case 5: return new L(); case 6: return new O(); } return null; } public void up() { for (Cell cell : cells) { cell.up(); } } public void softDrop() { for (Cell cell : cells) { cell.drop(); } } public void moveRight() { for (Cell cell : cells) { cell.moveRight(); } } public void moveLeft() { for (Cell cell : cells) { cell.moveLeft(); } } public void rotateRight() { index++; State s = states[index % states.length]; Cell rotatingCenter = cells[0]; int row = rotatingCenter.getRow(); int col = rotatingCenter.getCol(); cells[1].setRow(row + s.row1); cells[1].setCol(col + s.col1); cells[2].setRow(row + s.row2); cells[2].setCol(col + s.col2); cells[3].setRow(row + s.row3); cells[3].setCol(col + s.col3); } public void rotateLeft() { index--; State s = states[index % states.length]; Cell rotatingCenter = cells[0]; int row = rotatingCenter.getRow(); int col = rotatingCenter.getCol(); cells[1].setRow(row + s.row1); cells[1].setCol(col + s.col1); cells[2].setRow(row + s.row2); cells[2].setCol(col + s.col2); cells[3].setRow(row + s.row3); cells[3].setCol(col + s.col3); } private static class T extends Tetromino { public T() { cells[0] = new Cell(0, 4, Tetris.T); cells[1] = new Cell(0, 3, Tetris.T); cells[2] = new Cell(0, 5, Tetris.T); cells[3] = new Cell(1, 4, Tetris.T); states = new State[4]; states[0] = new State(0, 0, 0, -1, 0, 1, 1, 0);// 原始 states[1] = new State(0, 0, -1, 0, 1, 0, 0, -1);// 右90 states[2] = new State(0, 0, 0, 1, 0, -1, -1, 0);// 右90 states[3] = new State(0, 0, 1, 0, -1, 0, 0, 1);// 右90 } } private static class I extends Tetromino { public I() { cells[0] = new Cell(0, 4, Tetris.I); cells[1] = new Cell(0, 3, Tetris.I); cells[2] = new Cell(0, 5, Tetris.I); cells[3] = new Cell(0, 6, Tetris.I); states = new State[2]; states[0] = new State(0, 0, 0, -1, 0, 1, 0, 2); states[1] = new State(0, 0, -1, 0, 1, 0, 2, 0); } } private static class S extends Tetromino { public S() { cells[0] = new Cell(0, 4, Tetris.S); cells[1] = new Cell(0, 5, Tetris.S); cells[2] = new Cell(1, 3, Tetris.S); cells[3] = new Cell(1, 4, Tetris.S); states = new State[2]; states[0] = new State(0, 0, 0, 1, 1, -1, 1, 0); states[1] = new State(0, 0, 1, 0, -1, -1, 0, -1); } } private static class Z extends Tetromino { public Z() { cells[0] = new Cell(0, 4, Tetris.Z); cells[1] = new Cell(0, 3, Tetris.Z); cells[2] = new Cell(1, 4, Tetris.Z); cells[3] = new Cell(1, 5, Tetris.Z); states = new State[2]; states[0] = new State(0, 0, 0, -1, 1, 0, 1, 1); states[1] = new State(0, 0, -1, 0, 0, -1, 1, -1); } } private static class L extends Tetromino { public L() { cells[0] = new Cell(0, 4, Tetris.L); cells[1] = new Cell(0, 3, Tetris.L); cells[2] = new Cell(0, 5, Tetris.L); cells[3] = new Cell(1, 3, Tetris.L); states = new State[4]; states[0] = new State(0, 0, 0, -1, 0, 1, 1, -1); states[1] = new State(0, 0, -1, 0, 1, 0, -1, -1); states[2] = new State(0, 0, 0, -1, 0, 1, -1, 1); states[3] = new State(0, 0, -1, 0, 1, 0, 1, 1); } } private static class J extends Tetromino { public J() { cells[0] = new Cell(0, 4, Tetris.J); cells[1] = new Cell(0, 3, Tetris.J); cells[2] = new Cell(0, 5, Tetris.J); cells[3] = new Cell(1, 5, Tetris.J); states = new State[4]; states[0] = new State(0, 0, 0, -1, 0, 1, 1, 1); states[1] = new State(0, 0, -1, 0, 1, 0, 1, -1); states[2] = new State(0, 0, 0, 1, 0, -1, -1, -1); states[3] = new State(0, 0, 1, 0, -1, 0, -1, 1); } } private static class O extends Tetromino { public O() { cells[0] = new Cell(0, 4, Tetris.O); cells[1] = new Cell(0, 5, Tetris.O); cells[2] = new Cell(1, 4, Tetris.O); cells[3] = new Cell(1, 5, Tetris.O); states = new State[1]; states[0] = new State(0, 0, 0, 1, 1, 0, 1, 1); } } }
package xyz.rhel.els; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Arrays; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.JFrame; public class Tetris extends JPanel { public static final int ROWS = 20;// 墙的行 public static final int COLS = 10;// 墙的列 public static final int CELL_SIZE = 18;// 格子大小 public static final int FONT_COLOR = 0x741852; public static final int FONT_SIZE = 25; public static Image background;// 背景图片 public static Image I; public static Image T; public static Image S; public static Image Z; public static Image L; public static Image J; public static Image O; public static Image gameOverImg; private boolean pause;// 暂停标志 private boolean gameOver;// 游戏结束标志 private Timer timer;// private int inteval = 800;// 时间间隔 private int lines;// 消除的行数 private int[] scoreTable = { 0, 1, 20, 40, 60 };// 得分表 private int score;// 得分 private Cell[][] wall = new Cell[20][10];// 墙 private Tetromino tetromino;// 正在下落 private Tetromino nextOne;// 下一个将下落的 static {// 静态加载图片 try { Class cls = Tetris.class; background = ImageIO.read(cls.getResource("background.png")); I = ImageIO.read(cls.getResource("I.png")); T = ImageIO.read(cls.getResource("T.png")); S = ImageIO.read(cls.getResource("S.png")); Z = ImageIO.read(cls.getResource("Z.png")); L = ImageIO.read(cls.getResource("L.png")); J = ImageIO.read(cls.getResource("J.png")); O = ImageIO.read(cls.getResource("O.png")); gameOverImg = ImageIO.read(cls.getResource("gameOverImg.png")); } catch (Exception e) { e.printStackTrace(); } } private void paintGmaeOver(Graphics g) {// 画结束图片 g.drawImage(gameOverImg, 200, 200, null); } private void paintScore(Graphics g) {// 画得分 String str = "分数:" + score; g.setColor(new Color(FONT_COLOR)); Font font = getFont(); font = new Font(font.getName(), Font.BOLD, FONT_SIZE);// 为了跨平台 g.setFont(font); g.drawString(str, 250, 200); } private void paintLines(Graphics g) {// 画行 String str = "行数:" + lines; g.drawString(str, 250, 250); } private void paintNextOne(Graphics g) {// 画下一个方块的方法 if (nextOne == null) { return; } Cell[] cells = nextOne.cells; for (int i = 0; i < cells.length; i++) { Cell cell = cells[i]; int x = cell.getCol() * CELL_SIZE; int y = cell.getRow() * CELL_SIZE; g.drawImage(cell.getImage(), x + 200, y + 100, null); } } private void paintNextOneBox(Graphics g) {// 画将要下落方块的容器的方法 g.drawRect(250, 80, 80, 80); } private void paintTetromino(Graphics g) {// 画下落的方块 if (tetromino == null) { return; } Cell[] cells = tetromino.cells; for (int i = 0; i < cells.length; i++) { Cell cell = cells[i]; int x = cell.getCol() * CELL_SIZE; int y = cell.getRow() * CELL_SIZE; g.drawImage(cell.getImage(), x, y, null); } } private void paintWall(Graphics g) {// 画墙 for (int row = 0; row < wall.length; row++) { Cell[] line = wall[row]; for (int col = 0; col < line.length; col++) { Cell cell = line[col]; int x = col * CELL_SIZE; int y = row * CELL_SIZE; if (cell == null) { g.setColor(new Color(0xff0000)); g.drawRect(x, y, CELL_SIZE, CELL_SIZE); } else { g.drawImage(cell.getImage(), x, y, null); } } } } public void paint(Graphics g) {// 重写JPanel 中的paint方法 repaint来调用 g.drawImage(background, 0, 0, null);// 在窗口中画背景图片 g.translate(10, 10);// 坐标系平移 paintWall(g);// 画墙 paintTetromino(g);// 画下落的方块 paintNextOneBox(g);// 画将要下落方块的容器 paintNextOne(g);// 画下一个将下落的 paintScore(g);// 画得分 paintLines(g);// 画行 if (pause) { g.drawString("暂停中请按C继续", 400, 100); } if (gameOver) { paintGmaeOver(g); g.drawString("重新开始请按S", 400, 100); } } private boolean canUp() {// 作弊使用,向上 Cell[] cells = tetromino.cells; for (Cell cell : cells) { int row = cell.getRow(); if (row == 0) { return false; } } return true; } private boolean canDrop() {// 判断当前方块是否可以下落 Cell[] cells = tetromino.cells; for (Cell cell : cells) {// 检查当前方块是否到达底部 int row = cell.getRow(); if (row == ROWS - 1) { return false; } } for (Cell cell : cells) {// 检查当前方块的下一行是否有方块 int row = cell.getRow(); int col = cell.getCol(); if (wall[row + 1][col] != null) { return false; } } return true; } private void landToWall() {// 进入墙 Cell[] cells = tetromino.cells; for (Cell cell : cells) { int row = cell.getRow(); int col = cell.getCol(); wall[row][col] = cell; } } private boolean fullCells(int row) {// 查格子是否是满的 Cell[] line = wall[row]; for (Cell cell : line) { if (cell == null) { return false; } } return true; } private void deleteLine(int row) {// 删除满行 for (int i = row; i >= 1; i--) { System.arraycopy(wall[i - 1], 0, wall[i], 0, COLS); } Arrays.fill(wall[0], null); } private void destroyLines() {// 消除行方法 int lines = 0; for (int row = 0; row < ROWS; row++) { if (fullCells(row)) { deleteLine(row); lines++; } } this.lines += lines; this.score += scoreTable[lines]; } private void checkGameOver() {// 检查游戏是否结束 if (wall[0][4] != null) { gameOver = true; timer.cancel(); repaint(); } } private boolean outOfBounds() {// 左右边界检查 Cell[] cells = tetromino.cells; for (Cell cell : cells) { int col = cell.getCol(); if (col < 0 || col >= COLS) { return true; } } return false; } private boolean coincide() {// 格子重合检查 Cell[] cells = tetromino.cells; for (Cell cell : cells) { int row = cell.getRow(); int col = cell.getCol(); if (row >= 0 && row < ROWS && col >= 0 && col < COLS && wall[row][col] != null) { return true; } } return false; } private void upAction() {// 作弊使用,向上 if (canUp()) { tetromino.up(); } } private void softDropAction() {// 下落动作 if (canDrop()) { tetromino.softDrop(); } else { landToWall(); destroyLines(); checkGameOver(); tetromino = nextOne; nextOne = Tetromino.randomOne(); } } private void hardDropAction() {// 硬下落 while (canDrop()) { tetromino.softDrop(); } landToWall(); destroyLines(); checkGameOver(); tetromino = nextOne; nextOne = Tetromino.randomOne(); } private void moveLeftAction() {// 左移动方法 tetromino.moveLeft(); if (outOfBounds() || coincide()) { tetromino.moveRight(); } } private void moveRightAction() {// 右移动方法 tetromino.moveRight(); if (outOfBounds() || coincide()) { tetromino.moveLeft(); } } private void rotateRightAction() {// 右转动 tetromino.rotateRight(); if (outOfBounds() || coincide()) { tetromino.rotateLeft(); } } private void rotateLeftAction() {// 左转动 tetromino.rotateLeft(); if (outOfBounds() || coincide()) { tetromino.rotateRight(); } } private void action() {// 开始方法 startAction(); repaint(); KeyListener l = new KeyAdapter() { public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_Q) { System.exit(0); } if (gameOver) { if (key == KeyEvent.VK_S) { startAction(); } return; } if (pause) { if (key == KeyEvent.VK_C) { continueAction(); } return; } switch (key) { case KeyEvent.VK_UP: upAction(); break; case KeyEvent.VK_DOWN: softDropAction(); break; case KeyEvent.VK_RIGHT: moveRightAction(); break; case KeyEvent.VK_LEFT: moveLeftAction(); break; case KeyEvent.VK_Z: rotateLeftAction(); break; case KeyEvent.VK_X: rotateRightAction(); break; case KeyEvent.VK_SPACE: hardDropAction(); break; case KeyEvent.VK_S: pauseAction(); break; } repaint(); } }; this.addKeyListener(l); this.requestFocus(); } private void startAction() {// 开始 pause = false; gameOver = false; score = 0; lines = 0; for (Cell[] line : wall) { Arrays.fill(line, null); } tetromino = Tetromino.randomOne(); nextOne = Tetromino.randomOne(); TimerTask task = new TimerTask() { public void run() { softDropAction(); repaint(); } }; timer = new Timer(); timer.schedule(task, inteval, inteval); } private void pauseAction() {// 暂停 timer.cancel(); pause = true; } private void continueAction() {// 继续 pause = false; timer = new Timer(); timer.schedule(new TimerTask() { public void run() { softDropAction(); repaint(); } }, inteval, inteval); } public static void main(String[] args) { JFrame frame = new JFrame("<俄罗斯方块>"); Tetris tetris = new Tetris(); // tetris.setBackground(new Color(0xff5511)); frame.add(tetris); frame.setSize(800, 450); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); tetris.action(); } }
本文出自 “浪漫的偷笑” 博客,转载请与作者联系!