⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chessboard.java

📁 SWT实现人人的象棋程序 供学习SWT的同志做个参考
💻 JAVA
字号:
package com.catking.GUI.chessBoard;

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;

import com.catking.Manager.*;
import com.catking.Utility.*;
import com.catking.chess.*;

public class ChessBoard extends Canvas{
	private static final int WIDTH = 600;
	private static final int HEIGHT = 700;
	private static final int SAMLL_BAR_LENGTH = 10;
	private static final int GAP = 5;
	private static final int FIRST_GRID_X = 50;
	private static final int FIRST_GRID_Y = 70;
	private static final int GRID_SIZE = 60;
	private static final int GRIDS_WIDTH = GRID_SIZE * 8;
	private static final int GRIDS_HEIGHT = GRID_SIZE * 9;
	private static final int CHESS_SIZE 	= 							//正方形
		ResourceManager.chessModelImage.getBounds().width;
	private static final Rectangle rect = 
		new Rectangle( FIRST_GRID_X - CHESS_SIZE / 2,
				FIRST_GRID_Y - CHESS_SIZE / 2,
				GRIDS_WIDTH + CHESS_SIZE,
				GRIDS_HEIGHT + CHESS_SIZE
		);
	private static boolean haveSelected = false;
	private static Point selectPoint = null;


	public ChessBoard(Composite parent, int style) {
		//画背景图片时候不抖动
		super(parent, style | SWT.NO_BACKGROUND);

		this.setSize(WIDTH, HEIGHT);
		//绘制背景图片网格并且初始化缓冲图片
		paintBackImage();
		//准备缓冲图片
		prepareBufferedImage();

		this.addPaintListener(new PaintListener(){
			@Override
			public void paintControl(PaintEvent e) {
				e.gc.drawImage(
						ResourceManager.canvasImage, 0, 0);
			}

		});
		this.addKeyListener(new KeyAdapter(){

			@Override
			public void keyReleased(KeyEvent e) {

				showUndo();
			}

		});
		this.addMouseListener(new MouseAdapter(){

			@Override
			public void mouseDoubleClick(MouseEvent e) {

				doubleClick(e.x, e.y);
			}

			@Override
			public void mouseDown(MouseEvent e) {

				clickDown(e.x, e.y);
			}
		});
		this.addMouseMoveListener(new MouseMoveListener(){

			@Override
			public void mouseMove(MouseEvent e) {

				moveMouse(e.x, e.y);
			}

		});

	}

	private void doubleClick(int x, int y){

	}
	private void clickDown(int x, int y){
		Point p = getChessPos(x, y);
		//还没有选中棋子
		if(p != null && !haveSelected){
			//判断是不是合法的选中
			boolean isOK = 
				ChessPane.chesses[p.x][p.y].showSelectedEffect();
			if(isOK){
				haveSelected = !haveSelected; 
				selectPoint = p;
			}
		}
		//选中棋子开始下棋了
		else if(p != null && haveSelected){

			int result ;
			if(!p.equals(selectPoint)){
				result = ChessPane.chesses[selectPoint.x][selectPoint.y].
				setPos(p.x, p.y, true);
				switch(result){
				case BoardStateManager.CANNOT_PUT_CHESS:
					Display.getCurrent().beep();
					break;
				case BoardStateManager.CAN_PUT_CHESS:
					//画目标的棋子
					ChessPane.chesses[p.x][p.y].paint();
					//空棋画背景
					ChessPane.chesses[selectPoint.x][selectPoint.y].paint();
					haveSelected = !haveSelected;
					break;
				}

			}
			else{
				//棋子未动
				ChessPane.chesses[p.x][p.y].paint();
				haveSelected = !haveSelected;
				return;
			}

		}


	}
	private void moveMouse(int x, int y){

		Point p = getChessPos(x, y);
		if(p != null)
			ChessPane.chesses[p.x][p.y].showCursor();
	}
	//在棋盘上任意点,得到是那个棋子在数组中的位置
	private Point getChessPos(int x, int y){

		if(rect.contains(x, y)){

			x = (x - rect.x) / GRID_SIZE;
			y = (y - rect.y) / GRID_SIZE;

			//行列与数组行列刚好相反
			return	new Point(y, x);
		}

		return null;				//非棋子

	}


	//绘制背景方格图片
	private void paintBackImage(){

		//////////表盘
		PaletteData palette = new PaletteData(0xFF , 0xFF00 , 0xFF0000);
		ImageData imageData = new ImageData(WIDTH, HEIGHT, 24, palette);	//能够保存24位位图

		ResourceManager.backImage = new Image(Display.getCurrent(), imageData);
		GC gc = new GC(ResourceManager.backImage);
		gc.setBackground(ResourceManager.canvasBackColor);
		gc.fillRectangle(0, 0, WIDTH, HEIGHT);


		//黑色边框
		int lineWidth = 1;
		gc.setLineWidth(lineWidth);
		gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
		gc.drawLine(0, 0, 0, HEIGHT);
		gc.drawLine(0, HEIGHT - lineWidth, WIDTH, HEIGHT - lineWidth);
		gc.drawLine(WIDTH - lineWidth, 0, WIDTH - lineWidth, HEIGHT);

		/////方格大小60 
		gc.setLineWidth(2);
		int temp;
		//横线
		for(int i = 0; i < 10; ++i){

			gc.drawLine(FIRST_GRID_X, temp = (FIRST_GRID_Y + i * GRID_SIZE), 
					FIRST_GRID_X + GRIDS_WIDTH, temp);
		}
		//竖线
		for(int i = 0; i < 9; ++i){

			gc.drawLine( temp = (FIRST_GRID_X + i * GRID_SIZE), FIRST_GRID_Y, 
					temp, FIRST_GRID_Y + GRIDS_HEIGHT);
		}
		//擦除部分竖线 
		gc.setForeground(ResourceManager.canvasBackColor);
		for(int i = 1; i < 8; ++i){

			gc.drawLine(temp = (FIRST_GRID_X + i * GRID_SIZE), FIRST_GRID_Y + 4 * GRID_SIZE,
					temp, FIRST_GRID_Y + 5 * GRID_SIZE);
		}
		//楚河汉界
		gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));

		gc.setFont(ResourceManager.kaiTiFont);
		gc.drawString("楚河       汉界", 
				FIRST_GRID_X + 2 * GRID_SIZE ,
				FIRST_GRID_Y + 4 * GRID_SIZE + GRID_SIZE / 4);
		//1 2 3 4 5 6 7 8 9 
		//九 八 七 六 五 四 三 二 一 
		gc.setFont(ResourceManager.dialogFont);
		//文字
		final char[] number = {'九','八','七','六','五','四','三','二','一'};
		for(int i = 0; i < 9; ++i){
			//数字
			gc.drawString(	String.valueOf(i+1), 
					temp = (FIRST_GRID_X  - 5 + i * GRID_SIZE),		//调整x坐标,使竖线正对数字
					5);												//上沿
			gc.drawString(	String.valueOf(number[i]), 
					temp - 5, 										//调整x
					HEIGHT - 25);									//下沿
		}
		//画特殊的交叉线条
		//上面交叉线条
		int x1 = FIRST_GRID_X + 3 * GRID_SIZE;
		int y1 = FIRST_GRID_Y;
		int x2 = FIRST_GRID_X + 5 * GRID_SIZE;
		int y2 = FIRST_GRID_Y + GRID_SIZE * 2;
		gc.drawLine(x1, y1, x2, y2);
		gc.drawLine(x1, y2, x2, y1);
		//下面交叉线条
		y1 = FIRST_GRID_Y + 7 * GRID_SIZE;
		y2 = FIRST_GRID_Y + 9 * GRID_SIZE;
		gc.drawLine(x1, y1, x2, y2);
		gc.drawLine(x1, y2, x2, y1);

		//画复杂的兵座和炮座
		int[][] jiaZiPos = {
				{2, 1},{2, 7},{7, 1},{7, 7},
				{3, 2},{3, 4},{3, 6},
				{6, 2},{6, 4},{6, 6}
		};
		for(int j = 0; j < jiaZiPos.length; ++j){
			
			paintPaoJia(jiaZiPos[j][0], jiaZiPos[j][1], gc);
		}
		//右架子
		paintRightPaoJia(3, 0, gc);
		paintRightPaoJia(6, 0, gc);
		//左架子
		paintLeftPaoJia(3, 8, gc);
		paintLeftPaoJia(6, 8, gc);

		gc.dispose();

	}
	
	private void paintLeftPaoJia(int x, int y, GC gc){
		
		int x1, y1, x2, y2;
		
		x1 = x2 = FIRST_GRID_X + GRID_SIZE * y  - GAP;
		y2 = FIRST_GRID_Y + GRID_SIZE * x - GAP;
		y1 = y2 - SAMLL_BAR_LENGTH;
		//上左
		gc.drawLine(x1, y1, x2, y2);
		
		y1 = y2 + 2 * GAP;
		y2 = y1 + SAMLL_BAR_LENGTH;
		//下左
		gc.drawLine(x1, y1, x2, y2);
		
		y2 = y1;
		x1 = x2 - SAMLL_BAR_LENGTH;
		//左下
		gc.drawLine(x1, y1, x2, y2);
		
		y1 -= 2 * GAP;
		y2 = y1;
		//左上
		gc.drawLine(x1, y1, x2, y2);
	}
	private void paintRightPaoJia(int x, int y, GC gc){
		int x1, y1, x2, y2;

		x1 = x2 = FIRST_GRID_X + GRID_SIZE * y  + GAP;
		y2 = FIRST_GRID_Y + GRID_SIZE * x - GAP;
		y1 = y2 - SAMLL_BAR_LENGTH;
		//上右
		gc.drawLine(x1, y1, x2, y2);
		
		y1 = y2 + 2 * GAP;
		y2 = y1 + SAMLL_BAR_LENGTH;
		//下右
		gc.drawLine(x1, y1, x2, y2);
		
		y2 = y1;
		x2 = x1 + SAMLL_BAR_LENGTH;
		//左下
		gc.drawLine(x1, y1, x2, y2);
		
		y1 -= 2 * GAP;
		y2 = y1;
		gc.drawLine(x1, y1, x2, y2);
		//右上
		
	}
	private void paintPaoJia(int x, int y, GC gc){
		int x1, y1, x2, y2;

		x2 = FIRST_GRID_X + GRID_SIZE * y  - GAP;
		x1 = x2 - SAMLL_BAR_LENGTH;
		y1 = y2 = FIRST_GRID_Y + GRID_SIZE * x - GAP;
		//左上
		gc.drawLine(x1, y1, x2, y2);

		y1 += 2 * GAP;
		y2 = y1;
		//左下
		gc.drawLine(x1, y1, x2, y2);

		x1 += 2 * GAP + SAMLL_BAR_LENGTH;
		x2 =  x1 + SAMLL_BAR_LENGTH;
		//右下
		gc.drawLine(x1, y1, x2, y2);

		y1 -= 2 * GAP;
		y2 = y1;
		//右上
		gc.drawLine(x1, y1, x2, y2);

		x2 = x1;
		y2 = y1;
		y1 -= SAMLL_BAR_LENGTH;
		//上右
		gc.drawLine(x1, y1, x2, y2);

		x1 -= 2 * GAP;
		x2 = x1;
		//上左
		gc.drawLine(x1, y1, x2, y2);

		y1 += SAMLL_BAR_LENGTH + 2 * GAP;
		y2 = y1 + SAMLL_BAR_LENGTH;
		//下左
		gc.drawLine(x1, y1, x2, y2);

		x1 += 2 * GAP;
		x2 = x1;
		//下右
		gc.drawLine(x1, y1, x2, y2);

	}


	//绘制单个棋子
	public void paint(int x, int y, char name, boolean isRed){

		GC gc = new GC(ResourceManager.canvasImage);

		int xx = getPos(x, y).x;
		int yy = getPos(x, y).y;

		gc.drawImage(ResourceManager.chessModelImage, xx, yy);
		gc.setFont(ResourceManager.kaiTiFont);
		gc.setBackground(ResourceManager.chessBackColor);
		if(isRed)
			gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
		gc.drawString(String.valueOf(name), xx + 9, yy + 9);

		gc.dispose();
		this.redraw();
	}
	//得到数组中的棋子下标对应的实际坐标
	private Point getPos(int x, int y){

		int xx = FIRST_GRID_X + y * GRID_SIZE;
		int yy = FIRST_GRID_Y + x * GRID_SIZE;

		xx -= CHESS_SIZE / 2;
		yy -= CHESS_SIZE / 2;

		return new Point(xx, yy);
	}
	//初始化整个棋盘的缓冲图片
	private void prepareBufferedImage(){

		if(ResourceManager.canvasImage != null
				&& !ResourceManager.canvasImage.isDisposed())
			ResourceManager.canvasImage.dispose();
		ResourceManager.canvasImage = new Image(
				Display.getCurrent(), 
				ResourceManager.backImage.getImageData());
	}
	public void showGameOver(boolean isAttackUpWin){

		MessageBox messageBox = new MessageBox(this.getShell(),
				SWT.APPLICATION_MODAL |
				SWT.ICON_QUESTION | 
				SWT.NO | SWT.YES);
		messageBox.setMessage((isAttackUpWin?"红方胜!":"黑方胜!")+"\n再来一局?");
		int result = messageBox.open();
		if(result == SWT.YES){
			restartGame();
		}else{

			Display.getCurrent().beep();
		}

	}
	public void showSelectedCursor(){

		this.setCursor(
				Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND));
	}
	public void resetCursor(){

		this.setCursor(
				Display.getCurrent().getSystemCursor(SWT.CURSOR_ARROW));
	}
	public void showSelectedEffect(int x, int y, char name, boolean isRed){

		Point p = getPos(x, y);
		ImageData data = cutAreaData(x, y, CHESS_SIZE, CHESS_SIZE);
		data.alpha = 144;

		Image img = new Image(Display.getCurrent(), data);

		//确保重画时候正确显示
		GC gc = new GC(ResourceManager.canvasImage);
		gc.drawImage(img, p.x, p.y);
		img.dispose();
		gc.dispose();
		this.redraw();

	}
	public void showUndo(){

		Position latestPlayerPos = 
			ChessPane.prePosition[ChessPane.pre_player];
		Position latestRivalPos = 
			ChessPane.prePosition[3 - ChessPane.pre_player];


		if(latestPlayerPos != null && latestRivalPos != null){

			int lastX1 = latestPlayerPos.x;
			int lastY1 = latestPlayerPos.y;
			int lastX2 = latestRivalPos.x;
			int lastY2 = latestRivalPos.y;
			//新的一局,不能再悔棋了
			if(ChessPane.chesses[lastX1][lastY1].undo())
				return;
			if(ChessPane.chesses[lastX2][lastY2].undo())
				return;

			ChessPane.chesses[lastX1][lastY1].paint();
			//重新读取
			latestPlayerPos = ChessPane.prePosition[ChessPane.pre_player];
			ChessPane.chesses[latestPlayerPos.x][latestPlayerPos.y].paint();

			latestRivalPos =  ChessPane.prePosition[3 - ChessPane.pre_player];
			ChessPane.chesses[latestRivalPos.x][latestRivalPos.y].paint();

		}

	}


	public ImageData cutAreaData(int x, int y, int w, int h){
		Point p = getPos(x, y);
		PaletteData palette = new PaletteData(0xFF , 0xFF00 , 0xFF0000);
		ImageData copyData = new ImageData(w, h, 24, palette);

		ImageData data = ResourceManager.canvasImage.getImageData();

		//棋盘的底色
		ImageData paneData = ResourceManager.backImage.getImageData();

		int[] lineDataUp = new int[w];
		int[] lineDataDown = new int[w];
		for(int i = 0; i < h; ++i){
			//得到一行像素
			data.getPixels(p.x, p.y + i, w, lineDataUp, 0);
			paneData.getPixels(p.x, p.y + i, w, lineDataDown, 0);
			//还原原来的底色 
			data.setPixels(p.x, p.y + i, w, lineDataDown, 0);
			//拷贝一行像素
			copyData.setPixels(0, i, w, lineDataUp, 0);

		}
		//保存对CanvasImage的修改
		ResourceManager.canvasImage.dispose();
		ResourceManager.canvasImage = new Image(
				Display.getCurrent(),data);

		return copyData;
	}
	//显现背景色
	public void eraseChess(int x, int y){

		Point p = this.getPos(x, y);
		PaletteData palette = new PaletteData(0xFF , 0xFF00 , 0xFF0000);
		ImageData copyData = new ImageData(CHESS_SIZE, CHESS_SIZE, 24, palette);

		//棋盘的底色
		ImageData paneData = ResourceManager.backImage.getImageData();

		int[] lineDataDown = new int[CHESS_SIZE];
		for(int i = 0; i < CHESS_SIZE; ++i){
			//得到一行像素
			paneData.getPixels(p.x, p.y + i, CHESS_SIZE, lineDataDown, 0);
			//拷贝一行像素
			copyData.setPixels(0, i, CHESS_SIZE, lineDataDown, 0);

		}
		Image blankImg = new Image(Display.getCurrent(), copyData);
		GC gc = new GC(ResourceManager.canvasImage);
		gc.drawImage(blankImg, p.x, p.y);
		gc.dispose();
		blankImg.dispose();
		this.redraw();
	}
	public void restartGame(){
		//restart game
		ChessPane.init(true);
		BoardStateManager.reset();

		//准备好缓冲图片
		prepareBufferedImage();

		ChessPane.paint();

		haveSelected = false;
		selectPoint = null;
		ChessPane.canvas = this;
		BoardStateManager.startGame();
		this.redraw();
		//开始游戏咯
	}
	public void copyArea(int xf, int yf, int xt, int yt){

		Point pf = getPos(xf, yf);
		Point pt = getPos(xt, yt);

		ImageData data = ResourceManager.canvasImage.getImageData();

		int redMask = data.palette.redMask;
		int greenMask = data.palette.greenMask;
		int blueMask = data.palette.blueMask;

		int[] lineData = new int[CHESS_SIZE];
		for(int i = 0; i < CHESS_SIZE; ++i){

			// Analyze each pixel value in the line
			data.getPixels(pf.x, pf.y + i, lineData.length, lineData, 0);

			for(int j = 0; j < CHESS_SIZE; ++j){
				// Extract the red, green and blue component

				int piexlValue = lineData[j];
				int r = piexlValue & redMask;
				int g = (piexlValue & greenMask) >> 8;
			int b = (piexlValue & blueMask) >> 16;

		//只拷贝一圆形的棋子
		if(r != 183 && g != 170 && b != 163)
			data.setPixel(pt.x + j, pt.y + i, piexlValue);
			}
		}
		//确保重画时候正确显示
		ResourceManager.canvasImage.dispose();
		ResourceManager.canvasImage = new Image(Display.getCurrent(), data);
		this.redraw();
	}



}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -