Java20: 俄罗斯方块

业务分析:百度


数据模型:


类的设计:

    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


背景图片

wKiom1aLX0XSDAfaAAJXNxFfKnE815.png


结束游戏图片

wKiom1aLX5DyQpaOAAAKm3TscVU622.png


七种方块

wKiom1aLX0XS8hONAAAAMBKNZQo478.png

wKioL1aLX2vR3GFDAAAAMK6vAjo768.png

wKiom1aLX0bD-evFAAAAMEap_xw937.png

wKiom1aLX0aQ3e1gAAAAMGXLR7I228.png

wKiom1aLX0aCqNT0AAAAMM-2pG8415.png

wKiom1aLX0fimgrbAAAAMGmawj4417.png

wKiom1aLX0eyIWZcAAAAMFrlZV4947.png

 

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();
	}
}


本文出自 “浪漫的偷笑” 博客,转载请与作者联系!

你可能感兴趣的:(java,源码,背景图片)