学习程序开发,编一个俄罗斯方块游戏很不错的选择,既可以练一下算法,又可以学习界面开发。

------------------------------------------------------------

源代码:

import javax.swing.*;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;

public class ARusia extends JFrame implements Runnable {
	PicPanel rl = new PicPanel();
	MsgPanel ml = new MsgPanel();
	String realMsg = new String();
	int myLevel;
	int myLines;
	int myPoints;

	boolean bStop;
	Tetris myTetris;
	Blocks myBlocks;

	public ARusia() {
		super("Rusia");
		setSize(600, 600);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new GridLayout(1, 2));
		add(rl);
		add(ml);
		KeyMonitor monitor = new KeyMonitor(this);
		setFocusable(true);
		addKeyListener(monitor);
		setVisible(true);
		bStop = true;
		myLevel = 1;
		myLines = 0;
		myPoints = 0;

		myBlocks = new Blocks();
		myTetris = new Tetris(20, 10, myBlocks);

		ml.setRealMsg("Press SPACE key to play!");
		ml.setLevelMsg(1);
		ml.setLinesMsg(0);
		ml.setPointsMsg(0);
	}

	public void StopPlay() {
		bStop = true;
		ml.setRealMsg("Press SPACE key to play!");
	}

	public boolean isStop() {
		return bStop;
	}

	public int getPoints(int l) {
		if (l == 0) {
			return 0;
		}
		int pt = 0;
		switch (l) {
		case 1:
			pt = 100;
			break;
		case 2:
			pt = 300;
			break;
		case 3:
			pt = 500;
			break;
		default:
			pt = 700;
		}
		return pt;
	}

	public Tetris getTetris() {
		return myTetris;
	}

	public void run() {
		myTetris.clearValues();
		myBlocks.setCurrentBlock();
		myBlocks.creatNextBlock();
		ml.updateBlockPic(myBlocks.getNextBlock());
		myTetris.newBlockEnter();
		bStop = false;
		ml.setRealMsg("Press ESC key to play!");
		while (!bStop) {
			try {
				if (!myTetris.moveDown()) {
					myTetris.stopDown();
					int tl = 0;
					rl.updateBlockPic(myTetris.tr, myTetris.getDet());
					int l = myTetris.getFullRow();
					while (l > 0) {
						myTetris.delOneRow(l);
						tl++;
						rl.updateBlockPic(myTetris.tr, myTetris.getDet());
						Thread.sleep(1000 / myLevel);
						while (myTetris.downOneRow()) {
							rl.updateBlockPic(myTetris.tr, myTetris.getDet());
						}
						l = myTetris.getFullRow();
					}
					myTetris.stopDown();
					myLines += tl;
					myPoints += getPoints(tl);
					myLevel = (int) (myLines / 15) + 1;
					ml.setLinesMsg(myLines);
					ml.setPointsMsg(myPoints);
					ml.setLevelMsg(myLevel);
					myBlocks.setCurrentBlock();
					myBlocks.creatNextBlock();
					ml.updateBlockPic(myBlocks.getNextBlock());
					myTetris.newBlockEnter();
				}
				rl.updateBlockPic(myTetris.tr, myTetris.getDet());
				Thread.sleep(1000 / myLevel);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ARusia ar = new ARusia();

	}

}

class PicPanel extends JPanel {
	JButton[][] rt = new JButton[20][10];

	public PicPanel() {
		GridLayout pl = new GridLayout(20, 10);
		setLayout(pl);
		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 10; j++) {
				rt[i][j] = new JButton("");
				add(rt[i][j]);
				rt[i][j].setEnabled(false);
			}
		}
	}

	public void updateBlockPic(int[][] r, int rowdet) {
		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 10; j++) {
				if (r[i + rowdet][j] == 0) {
					rt[i][j].setEnabled(false);
					rt[i][j].setBackground(Color.GRAY);
				} else {
					rt[i][j].setEnabled(true);
					rt[i][j].setBackground(Color.BLUE);
				}
			}
		}
	}
}

class MsgPanel extends JPanel {
	JButton[][] rt = new JButton[4][4];
	String realMsg = new String();
	int myLevel;
	int myLines;
	int myPoints;

	public MsgPanel() {
		GridLayout pl = new GridLayout(5, 1);
		setLayout(pl);
		JPanel cp = new JPanel();
		cp.setLayout(new GridLayout(1, 3));
		JPanel p1 = new JPanel();
		cp.add(p1);
		JPanel p2 = new JPanel();
		p2.setLayout(new GridLayout(4, 4));
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				rt[i][j] = new JButton("");
				p2.add(rt[i][j]);
				rt[i][j].setEnabled(false);
			}
		}
		cp.add(p2);
		JPanel p3 = new JPanel();
		cp.add(p3);
		add(cp);

	}

	public void updateBlockPic(int[][] r) {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (r[i][j] == 0) {
					rt[i][j].setEnabled(false);
					rt[i][j].setBackground(Color.GRAY);
				} else {
					rt[i][j].setEnabled(true);
					rt[i][j].setBackground(Color.CYAN);
				}
			}
		}
	}

	public void setRealMsg(String s) {
		realMsg = s;
		repaint();
	}

	public void setLinesMsg(int l) {
		myLines = l;
		repaint();
	}

	public void setLevelMsg(int l) {
		myLevel = l;
		repaint();
	}

	public void setPointsMsg(int p) {
		myPoints = p;
		repaint();
	}

	public void paintComponent(Graphics comp) {
		Graphics2D comp2D = (Graphics2D) comp;
		comp2D.setColor(Color.white);
		comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		Rectangle2D.Float background = new Rectangle2D.Float(0F, 0F,
				(float) getSize().width, (float) getSize().height);
		comp2D.fill(background);
		comp2D.setColor(Color.red);
		Rectangle2D.Float boundrt = new Rectangle2D.Float(0F,
				(float) getSize().height / 5, (float) getSize().width - 2,
				(float) getSize().height - 15);
		comp2D.draw(boundrt);
		Font font = new Font("Times New Roman", Font.ITALIC, 22);
		comp2D.setFont(font);
		comp2D.setColor(Color.black);
		comp2D.drawString("Level     " + myLevel, 50F,
				(float) getSize().height / 8 * 3);
		comp2D.drawString("Lines     " + myLines, 50F,
				(float) getSize().height / 8 * 4);
		comp2D.drawString("Points    " + myPoints, 50F,
				(float) getSize().height / 8 * 5);
		font = new Font("Times New Roman", Font.ITALIC, 16);
		comp2D.setFont(font);
		comp2D.setColor(Color.blue);
		comp2D.drawString(realMsg, 50F, (float) getSize().height / 8 * 6);
	}
}

class Tetris {
	int[][] tr;
	int rows, columns;
	int det = 4;
	int curRow, curColumn;
	Blocks mBlocks;

	public Tetris(int r, int c, Blocks blks) {
		rows = r + det;
		columns = c;
		tr = new int[rows][columns];
		mBlocks = blks;
	}

	public int getDet() {
		return det;
	}

	public boolean isInBound(int r, int c) {
		if (r >= 0 && r < rows && c >= 0 && c < columns) {
			return true;
		}
		return false;
	}

	public boolean newBlockEnter() {
		curRow = det - 1;
		curColumn = 4;
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				if (tr[i][j + curColumn] > 0
						&& mBlocks.getCurrentBlock()[i][j] > 0) {
					return false;
				}
			}
		for (int i = det - 4; i < det; i++)
			for (int j = 0; j < 4; j++) {
				if (tr[i][j + curColumn] == 0) {
					tr[i][j + curColumn] = mBlocks.getCurrentBlock()[i][j];
				}
			}
		return true;
	}

	public void setValues(int ro, int cl, int[][] value) {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (value[i][j] > 0 && isInBound(ro - 3 + i, cl + j)) {
					tr[ro - 3 + i][cl + j] = value[i][j];
				}
			}
		}
	}

	public void clearValues() {
		for (int i = 0; i < rows; i++)
			for (int j = 0; j < columns; j++) {
				tr[i][j] = 0;
			}
	}

	public int getFullRow() {
		boolean bOK;
		for (int i = rows - 1; i >= 0; i--) {
			bOK = true;
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 0) {
					bOK = false;
					j = columns;
				}
			}
			if (bOK) {
				return i - det;
			}
		}
		return -1;
	}

	public void delOneRow(int r) {
		for (int j = 0; j < columns; j++) {
			tr[r + det][j] = 0;
		}
		for (int i = r + det; i >= 0; i--) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] > 0) {
					tr[i][j] = 2;
				}
			}
		}
	}

	public boolean downOneRow() {
		boolean bMove = false;
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 2) {
					bMove = true;
					if (i == rows - 1) {
						return false;
					}
					if (tr[i + 1][j] == 1) {
						return false;
					}
				}
			}
		}
		if (!bMove) {
			return false;
		}
		for (int i = rows - 1; i > 0; i--) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 0 && tr[i - 1][j] == 2) {
					tr[i][j] = 2;
					tr[i - 1][j] = 0;
				}
			}
		}
		return true;
	}

	public boolean rotateClock() {
		for (int i = curRow - 3; i <= curRow; i++) {
			for (int j = curColumn; j < curColumn + 4; j++) {
				if (isInBound(i, j)) {
					if (tr[i][j] == 2) {
						tr[i][j] = 0;
					}
				}
			}
		}
		mBlocks.rotateCurrentBlockClock();
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (!isInBound(curRow - 3 + i, curColumn + j)
						&& mBlocks.getCurrentBlock()[i][j] == 2) {
					mBlocks.rotateCurrentBlockUnClock();
					setValues(curRow, curColumn, mBlocks.getCurrentBlock());
					return false;
				}
				if (isInBound(curRow - 3 + i, curColumn + j)) {
					if (tr[curRow - 3 + i][curColumn + j] == 1
							&& mBlocks.getCurrentBlock()[i][j] == 2) {
						mBlocks.rotateCurrentBlockUnClock();
						setValues(curRow, curColumn, mBlocks.getCurrentBlock());
						return false;
					}
				}
			}
		}
		setValues(curRow, curColumn, mBlocks.getCurrentBlock());
		return true;
	}

	public boolean rotateUnClock() {
		for (int i = curRow - 3; i <= curRow; i++) {
			for (int j = curColumn; j < curColumn + 4; j++) {
				if (isInBound(i, j)) {
					if (tr[i][j] == 2) {
						tr[i][j] = 0;
					}
				}
			}
		}
		mBlocks.rotateCurrentBlockUnClock();
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (!isInBound(curRow - 3 + i, curColumn + j)
						&& mBlocks.getCurrentBlock()[i][j] == 2) {
					mBlocks.rotateCurrentBlockClock();
					setValues(curRow, curColumn, mBlocks.getCurrentBlock());
					return false;
				}
				if (isInBound(curRow - 3 + i, curColumn + j)) {
					if (tr[curRow - 3 + i][curColumn + j] == 1
							&& mBlocks.getCurrentBlock()[i][j] == 2) {
						mBlocks.rotateCurrentBlockClock();
						setValues(curRow, curColumn, mBlocks.getCurrentBlock());
						return false;
					}
				}
			}
		}
		setValues(curRow, curColumn, mBlocks.getCurrentBlock());
		return true;
	}

	public boolean moveDown() {
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 2 && i == rows - 1) {
					return false;
				}
				if (tr[i][j] == 2 && tr[i + 1][j] == 1) {
					return false;
				}
			}
		}
		for (int i = rows - 1; i >= 0; i--) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 2 && tr[i + 1][j] == 0) {
					tr[i + 1][j] = 2;
					tr[i][j] = 0;
				}
			}
		}
		curRow++;
		return true;
	}

	public boolean moveLeft() {
		for (int i = curRow - 3; i <= curRow; i++) {
			for (int j = curColumn; j < curColumn + 4; j++) {
				if (!isInBound(i, j)) {
					continue;
				}
				if (tr[i][j] == 2 && j == 0) {
					return false;
				}
				if (tr[i][j] == 2 && tr[i][j - 1] == 1) {
					return false;
				}
			}
		}
		for (int i = curRow; i > curRow - 4; i--) {
			for (int j = 1; j < columns; j++) {
				if (tr[i][j - 1] == 0 && tr[i][j] == 2) {
					tr[i][j - 1] = 2;
					tr[i][j] = 0;
				}
			}
		}
		curColumn--;
		return true;
	}

	public boolean moveRight() {
		for (int i = curRow - 3; i <= curRow; i++) {
			for (int j = curColumn; j < curColumn + 4; j++) {
				if (!isInBound(i, j)) {
					continue;
				}
				if (tr[i][j] == 2 && j == columns - 1) {
					return false;
				}
				if (tr[i][j] == 2 && tr[i][j + 1] == 1) {
					return false;
				}
			}
		}
		for (int i = curRow; i > curRow - 4; i--) {
			for (int j = columns - 2; j >= 0; j--) {
				if (tr[i][j + 1] == 0 && tr[i][j] == 2) {
					tr[i][j + 1] = 2;
					tr[i][j] = 0;
				}
			}
		}
		curColumn++;
		return true;
	}

	public void stopDown() {
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				if (tr[i][j] == 2) {
					tr[i][j] = 1;
				}
			}
		}
	}
}

class Blocks {
	int[][][] blk = new int[7][][];
	int[][] currentBlk = new int[4][4];
	int[][] nextBlk = new int[4][4];
	int blkMax;

	public Blocks() {
		blk[0] = new int[][] { { 0, 2, 0, 0 }, { 0, 2, 0, 0 }, { 0, 2, 0, 0 },
				{ 0, 2, 0, 0 } };
		blk[1] = new int[][] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
				{ 2, 2, 2, 2 } };
		blk[2] = new int[][] { { 0, 0, 0, 0 }, { 0, 2, 0, 0 }, { 0, 2, 0, 0 },
				{ 0, 2, 2, 0 } };
		blk[3] = new int[][] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 2, 2, 2, 0 },
				{ 0, 2, 0, 0 } };
		blk[4] = new int[][] { { 0, 0, 0, 0 }, { 0, 0, 2, 0 }, { 0, 2, 2, 0 },
				{ 0, 2, 0, 0 } };
		blk[5] = new int[][] { { 0, 0, 0, 0 }, { 0, 2, 0, 0 }, { 0, 2, 2, 0 },
				{ 0, 0, 2, 0 } };
		blk[6] = new int[][] { { 0, 0, 0, 0 }, { 0, 0, 2, 0 }, { 0, 0, 2, 0 },
				{ 0, 2, 2, 0 } };
		blkMax = 7;
		int c = (int) (Math.random() * blkMax);
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				currentBlk[i][j] = blk[c][i][j];
			}
		c = (int) (Math.random() * blkMax);
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				nextBlk[i][j] = blk[c][i][j];
			}
	}

	public int[][] getNextBlock() {
		return nextBlk;
	}

	public int[][] getCurrentBlock() {
		return currentBlk;
	}

	public void setCurrentBlock() {
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				currentBlk[i][j] = nextBlk[i][j];
			}
	}

	public void creatNextBlock() {
		int c = (int) (Math.random() * blkMax);
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				nextBlk[i][j] = blk[c][i][j];
			}
	}

	public void rotateCurrentBlockClock() {
		int[][] tb = new int[4][4];
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				tb[i][j] = currentBlk[i][j];
			}
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				currentBlk[i][j] = tb[3 - j][i];
			}
	}

	public void rotateCurrentBlockUnClock() {
		int[][] tb = new int[4][4];
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				tb[i][j] = currentBlk[i][j];
			}
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++) {
				currentBlk[3 - j][i] = tb[i][j];
			}
	}
}

class KeyMonitor extends KeyAdapter {
	ARusia display;

	KeyMonitor(ARusia display) {
		this.display = display;
	}

	public void keyPressed(KeyEvent event) {
		switch (event.getKeyCode()) {
		case KeyEvent.VK_UP:
			if (display.getTetris().rotateUnClock()) {
				display.rl.updateBlockPic(display.getTetris().tr, display
						.getTetris().getDet());
			}
			break;
		case KeyEvent.VK_A:
			if (display.getTetris().rotateClock()) {
				display.rl.updateBlockPic(display.getTetris().tr, display
						.getTetris().getDet());
			}
			break;
		case KeyEvent.VK_DOWN:
			if (display.getTetris().moveDown()) {
				display.rl.updateBlockPic(display.getTetris().tr, display
						.getTetris().getDet());
			}
			break;
		case KeyEvent.VK_LEFT:
			if (display.getTetris().moveLeft()) {
				display.rl.updateBlockPic(display.getTetris().tr, display
						.getTetris().getDet());
			}
			break;
		case KeyEvent.VK_RIGHT:
			if (display.getTetris().moveRight()) {
				display.rl.updateBlockPic(display.getTetris().tr, display
						.getTetris().getDet());
			}
			break;
		case KeyEvent.VK_ESCAPE:
			display.StopPlay();
			break;
		case KeyEvent.VK_SPACE:
			if (display.isStop()) {
				Thread th1 = new Thread(display);
				th1.start();
			}
			break;
		default:
			;
		}
		display.repaint();
	}
}

!

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐