📄 chessboard.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 + -