1. 程式人生 > >Java-俄羅斯方塊最新完善版

Java-俄羅斯方塊最新完善版

趨於完善版

步驟1:

package game;

import java.awt.image.BufferedImage;

public class Cell {
	private int row;
	private int col;
	private BufferedImage image;
	public Cell(){}
	public Cell(int row, int col ,BufferedImage image) {
		super();
		this.row = row;
		this.col = col;
		this.image = image;
	}
	public int getRow() {
		return row;
	}
	public void setRow(int row) {
		this.row = row;
	}
	public int getCol() {
		return col;
	}
	public void setCol(int col) {
		this.col = col;
	}
	public void left(){
		col--;
	}
	public void down(){
		row++;
	}
	public void right(){
		col++;
	}
	@Override
	public String toString() {
		return "Cell [row=" + row + ", col=" + col + "]";
	}
	public BufferedImage getImage() {
		return image;
	}
	public void setImage(BufferedImage image) {
		this.image = image;
	}
}

步驟2:

package game;

public class Tetromino {
	Cell[] cells = new Cell[4];
	/**向左移動*/
	public void moveLeft(){
		for(int i=0;i<cells.length;i++){
			cells[i].left();
		}
	}
	/**向下移動*/
	public void moveDown(){
		for(int i=0;i<cells.length;i++){
			cells[i].down();
		}
	}
	/**向右移動*/
	public void moveRight(){
		for(int i=0;i<cells.length;i++){
			cells[i].right();
		}
	}
	/**新增一個方法,隨機產生一種子類物件*/
	public static Tetromino randomOne(){
		Tetromino one = null;
		int num = (int)(Math.random()*7);
		switch(num){
		case 0:one = new T();break;
		case 1:one = new I();break;
		case 2:one = new O();break;
		case 3:one = new S();break;
		case 4:one = new Z();break;
		case 5:one = new J();break;
		default:one = new L();
		}
		return one;
	}
	/**使用內部類定義7個子型別*/
	static class T extends Tetromino{
		public T(){
			cells[0] = new Cell(0,4,TestTetromino.T);
			cells[1] = new Cell(0,3,TestTetromino.T);
			cells[2] = new Cell(0,5,TestTetromino.T);
			cells[3] = new Cell(1,4,TestTetromino.T);
		}
	}
	static class I extends Tetromino{
		public I(){
			cells[0] = new Cell(0,4,TestTetromino.I);
			cells[1] = new Cell(0,3,TestTetromino.I);
			cells[2] = new Cell(0,5,TestTetromino.I);
			cells[3] = new Cell(0,6,TestTetromino.I);
		}
	}
	static class O extends Tetromino{
		public O(){
			cells[0] = new Cell(0,4,TestTetromino.O);
			cells[1] = new Cell(0,3,TestTetromino.O);
			cells[2] = new Cell(1,3,TestTetromino.O);
			cells[3] = new Cell(1,4,TestTetromino.O);
		}
	}
	static class S extends Tetromino{
		public S(){
			cells[0] = new Cell(0,4,TestTetromino.S);
			cells[1] = new Cell(0,5,TestTetromino.S);
			cells[2] = new Cell(1,3,TestTetromino.S);
			cells[3] = new Cell(1,4,TestTetromino.S);
		}
	}
	static class Z extends Tetromino{
		public Z(){
			cells[0] = new Cell(0,4,TestTetromino.Z);
			cells[1] = new Cell(0,3,TestTetromino.Z);
			cells[2] = new Cell(1,4,TestTetromino.Z);
			cells[3] = new Cell(1,5,TestTetromino.Z);
		}
	}
	static class J extends Tetromino{
		public J(){
			cells[0] = new Cell(0,4,TestTetromino.J);
			cells[1] = new Cell(0,3,TestTetromino.J);
			cells[2] = new Cell(0,5,TestTetromino.J);
			cells[3] = new Cell(1,5,TestTetromino.J);
		}
	}
	static class L extends Tetromino{
		public L(){
			cells[0] = new Cell(0,4,TestTetromino.L);
			cells[1] = new Cell(0,3,TestTetromino.L);
			cells[2] = new Cell(0,5,TestTetromino.L);
			cells[3] = new Cell(1,3,TestTetromino.L);
		}
	}
	/**
	 * 變形:旋轉
	 */
	public void rotate() {
		int num = cells[1].getRow();
		cells[1].setRow(cells[0].getRow()+cells[1].getCol()-cells[0].getCol());
		cells[1].setCol(cells[0].getCol()+cells[0].getRow()-num);
		num = cells[2].getRow();
		cells[2].setRow(cells[0].getRow()+cells[2].getCol()-cells[0].getCol());
		cells[2].setCol(cells[0].getCol()+cells[0].getRow()-num);
		num = cells[3].getRow();
		cells[3].setRow(cells[0].getRow()+cells[3].getCol()-cells[0].getCol());
		cells[3].setCol(cells[0].getCol()+cells[0].getRow()-num);
	}
	/**
	 * 碰撞
	 * @param cell 已堆積的方塊
	 * @return true / false
	 */
	public boolean hit(Cell cell) {
		for(int i=0;i<cells.length;i++){
			if((cells[i].getCol()==cell.getCol()&&
					cells[i].getRow()==cell.getRow()-1)){
				return true;
			}
		}
		return false;
	}
	/**
	 * 底邊的碰撞
	 * @param cell 
	 * @return
	 */
	public boolean hitBound() {
		for(int i=0;i<cells.length;i++){
			if(cells[i].getRow()>=19){
				return true;
			}
		}
		return false;
	}
	public boolean hitLeft(Cell[] cs) {
		for(int i=0;i<cs.length;i++){
			for(int j=0;j<cells.length;j++){
				if(cells[j].getRow()==cs[i].getRow()&&
						cells[j].getCol()==cs[i].getCol()+1){
					return true;
				}
			}
		}
		return false;
	}
	public boolean hitRight(Cell[] cs) {
		for(int i=0;i<cs.length;i++){
			for(int j=0;j<cells.length;j++){
				if(cells[j].getRow()==cs[i].getRow()&&
						cells[j].getCol()==cs[i].getCol()-1){
					return true;
				}
			}
		}
		return false;
	}
}

步驟3:

package game;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**TestTetromino 是一個畫板*/
public class TestTetromino extends JPanel{
	//常量 矩形的寬度,方格的寬度
	public static final int CELL_SIZE = 26;
	
	//成員變數
	Tetromino currentOne = Tetromino.randomOne();
	Tetromino currentNext = Tetromino.randomOne();
	private Cell[] cs = {};
	private boolean[][] b = new boolean[20][10];
	private int state;
	public static final int RUNNING = 0;
	public static final int GAMEOVER = 1;
	
	
	private int score=0;
	
	public static BufferedImage I;
	public static BufferedImage T;
	public static BufferedImage O;
	public static BufferedImage S;
	public static BufferedImage Z;
	public static BufferedImage J;
	public static BufferedImage L;
	public static BufferedImage tetris;
	public static BufferedImage gameover;
	static{
		try {
			//read讀取硬碟上的圖片
			//getResource(String path):path是圖片的相對當前包的位置
			I = ImageIO.read(TestTetromino.class.getResource("I.png"));
			T = ImageIO.read(TestTetromino.class.getResource("T.png"));
			O = ImageIO.read(TestTetromino.class.getResource("O.png"));
			S = ImageIO.read(TestTetromino.class.getResource("S.png"));
			Z = ImageIO.read(TestTetromino.class.getResource("Z.png"));
			J = ImageIO.read(TestTetromino.class.getResource("J.png"));
			L = ImageIO.read(TestTetromino.class.getResource("L.png"));
			tetris = ImageIO.read(TestTetromino.class.getResource("tetris.png"));
			gameover = ImageIO.read(TestTetromino.class.getResource("gameover.png"));
		} catch (Exception e) {
			//列印棧中的資訊
			e.printStackTrace();
		}
		
	}
	/**重寫繪製功能,此功能畫板預設呼叫*/
	public void paint(Graphics g){
		g.drawImage(tetris,0, 0, null);
		//平移座標軸
		g.translate(15, 15);
		paintScore(g);
		panelWall(g);
		paintCurrentOne(g);
		paintCurrentNext(g);
		paintCs(g);
		paintState(g);
	}
	private void paintState(Graphics g) {
		if(state==GAMEOVER){
			g.drawImage(gameover, 0, 0, null);
		}
	}
	private void paintCurrentNext(Graphics g) {
		Cell[] cells = currentNext.cells;
		for(int i=0;i<cells.length;i++){
			Cell cell = cells[i];
			int col = cell.getCol();
			int row = cell.getRow();
			g.drawImage(cell.getImage(), col*CELL_SIZE+270, row*CELL_SIZE+25, null);
		}
	}
	private void paintScore(Graphics g) {
		Font font = new Font(Font.SANS_SERIF,Font.BOLD,20);
		g.setFont(font);
		g.drawString("SCORE:"+score, 340, 270);
	}
	private void paintCs(Graphics g) {
		Cell[] cells = cs;
		for(int i=0;i<cells.length;i++){
			Cell cell = cells[i];
			int col = cell.getCol();
			int row = cell.getRow();
			g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null);
		}
	}
	/**繪製當前下落的四方塊*/
	private void paintCurrentOne(Graphics g) {
		//獲取正在下落的方塊組合內的陣列物件
		Cell[] cells = currentOne.cells;
		for(int i=0;i<cells.length;i++){
			Cell cell = cells[i];
			int col = cell.getCol();
			int row = cell.getRow();
			g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null);
		}
	}
	/**繪製一個牆,20行,10列的表格*/
	public void panelWall(Graphics g){
		for(int i=0;i<20;i++){
			for(int j=0;j<10;j++){
				//橫座標j,縱座標i
				g.drawRect(j*CELL_SIZE, i*CELL_SIZE, CELL_SIZE, CELL_SIZE);
			}
		}
	}
	private Timer timer;
	public void action(){
		/*
		 * 定義監聽器物件,用於監聽鍵盤事件
		 * */
		KeyListener l = new KeyAdapter(){
			public void keyPressed(KeyEvent e){
				int code = e.getKeyCode();
				System.out.println("code:"+code);
				if(state==RUNNING){
					switch(code){
					case 37:
						if(!currentOne.hitLeft(cs)){
							currentOne.moveLeft();
						}
						break;
					case 39:
						if(!currentOne.hitRight(cs)){
							currentOne.moveRight();
						}
						break;
					case 40:currentOne.moveDown();break;
					case 38:currentOne.rotate();
					}
					outOfBoundAction();//越界
				}
				if(code==83){
					cs = new Cell[]{};
					b = new boolean[20][10];
					score = 0;
					currentOne = Tetromino.randomOne();
					currentNext = Tetromino.randomOne();
					state=RUNNING;
				}
				//重新繪製
				repaint();
			}
		};
		//面板新增鍵盤監聽事件
		this.addKeyListener(l);
		//面板設定成螢幕焦點
		this.requestFocus();
		timer = new Timer();
		timer.schedule(new TimerTask(){
			public void run(){
				if(state==RUNNING){
					hitAction();//碰撞
					
					hitBoundAction();//碰撞底邊
					deleteAction();//消除
					gameoverAction();//檢查遊戲是否結束
				}
				repaint();
				
			}
		},0,1);
		
		while(true){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if(state==RUNNING){
				currentOne.moveDown();
			}
			//重寫繪製整個畫板上的內容
			repaint();
		}
	}
	protected void gameoverAction() {
		if(isGameOver()){
			state = GAMEOVER;
		}
	}
	private boolean isGameOver() {
		for(int i=0;i<cs.length;i++){
			if(cs[i].getRow()==0){
				return true;
			}
		}
		return false;
	}
	protected void deleteAction() {
		for(int i=0;i<b.length;i++){
			boolean bool = false;
			for(int j=0;j<b[0].length;j++){
				if(!b[i][j]){
					bool = true;
					break;
				}
			}
			if(!bool){
				score+=15;
				for(int k=0;k<cs.length;k++){
					if(cs[k].getRow()==i){
						cs[k] = cs[cs.length-1];
						cs = Arrays.copyOf(cs, cs.length-1);
						k--;
					}
				}
				for(int k=0;k<cs.length;k++){
					if(cs[k].getRow()<i){
						cs[k].setRow(cs[k].getRow()+1);
					}
				}
			}		
		}
		b = new boolean[20][10];
		for(int i=0;i<cs.length;i++){
			b[cs[i].getRow()][cs[i].getCol()] = true;
		}
	}
	/**
	 * 到底邊
	 */
	private void hitBoundAction() {
		Cell[] cells = currentOne.cells; 
		for(int i=0;i<cells.length;i++){
			if(currentOne.hitBound()){
				for(int j=0;j<cells.length;j++){
					cs = Arrays.copyOf(cs, cs.length+1);
					cs[cs.length-1] = cells[j];
					b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true;
				}
				currentOne = currentNext;
				currentNext = Tetromino.randomOne();
				break;
			}
		}
	}
	/**
	 * 方塊間的碰撞
	 */
	protected void hitAction() {
		for(int i=0;i<cs.length;i++){
			if(currentOne.hit(cs[i])){
				Cell[] cells = currentOne.cells;
				for(int j=0;j<cells.length;j++){
					cs = Arrays.copyOf(cs, cs.length+1);
					cs[cs.length-1] = cells[j];
					b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true;
				}
				currentOne = currentNext;
				currentNext = Tetromino.randomOne();
				break;
			}
		}
	}
	/**
	 * 左右邊界
	 */
	protected void outOfBoundAction() {
		Cell[] cells = currentOne.cells;
		for(int i=0;i<cells.length;i++){
			if(cells[i].getCol()<0){
				for(int j=0;j<cells.length;j++){
					cells[j].setCol(cells[j].getCol()+1);
				}
				break;
			}else if(cells[i].getCol()>9){
				for(int j=0;j<cells.length;j++){
					cells[j].setCol(cells[j].getCol()-1);
				}
				break;
			}
		}
	}
	public static void main(String[] args) {
		//建立一個遊戲視窗
		JFrame frame = new JFrame("俄羅斯方塊");
		//設計視窗的大小
		frame.setSize(540, 588);
		//建立一個畫板物件
		TestTetromino panel = new TestTetromino();
		//畫板嵌入視窗
		frame.add(panel);
		
		//設定視窗居中
		frame.setLocationRelativeTo(null);
		//設定視窗關閉
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//設定可見性
		frame.setVisible(true);
		panel.action();
	}
}

用到的圖片可以自己在網上尋找*_*