(二)使用javaFX画一个中国象棋棋盘
在https://blog.****.net/qq_36270700/article/details/107205985
的基础上,添加一些简单的背景图,行棋
将代码剥离,为后续做准备,画棋盘单独一类,可走路径单独一类,常量都放在Main类
棋盘棋子可以正常使用了,行棋规则还没限制
Main 类
package sample; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundImage; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import sample.utils.Chess; import sample.utils.CanvasUtils; public class Main extends Application { static public int girdW = 40; static public int canvasW = 9*girdW; static public int girdH = 40; static public int canvasH = 10*girdH; static public String colorR = "R"; static public String colorB = "B"; static public Boolean init = true; static public double chessW = 18.0; static public String fontName = "STSong"; static public Chess[][] chesses = new Chess[10][9]; static public String[][] names = { {"車","馬","象","士","將","士","象","馬","車"}, {"","","","","","","","",""}, {"","炮","","","","","","炮",""}, {"卒","","卒","","卒","","卒","","卒"}, {"","","","","","","","",""}, {"","","","","","","","",""}, {"兵","","兵","","兵","","兵","","兵"}, {"","炮","","","","","","炮",""}, {"","","","","","","","",""}, {"車","馬","相","仕","帥","仕","相","馬","車"}, }; static public Chess selectChess = null; static public Double fontSize = 18.0; @Override public void start(Stage primaryStage){ Group root = new Group(); Canvas canvas = new Canvas(canvasW * 1.0, canvasH * 1.0 ); StackPane stackPane = new StackPane(); Image img = new Image(Main.class.getResourceAsStream("c.jpg")); stackPane.setBackground(new Background(new BackgroundImage(img,null,null,null,null))); stackPane.setMinWidth(canvasW*2); stackPane.setMinHeight(canvasH *1.5); GraphicsContext gc = canvas.getGraphicsContext2D(); //选棋子 canvas.setOnMouseClicked(event -> { int i = (int)(event.getX()/girdW); int j = (int)(event.getY()/girdH); Chess chess = CanvasUtils.clickChess(event.getX(),event.getY()); if(chess != null){ if(selectChess == null ){ CanvasUtils.selectChess(chess,gc); }else{ CanvasUtils.moveChess(i,j,gc); } }else{ CanvasUtils.moveChess(i,j,gc); } }); CanvasUtils.drawShapes(gc); stackPane.getChildren().add(CanvasUtils.placeCanvas()); stackPane.getChildren().add(CanvasUtils.rotateCanvas()); stackPane.getChildren().add(canvas); root.getChildren().add(stackPane); primaryStage.setTitle("棋盘"); primaryStage.setScene(new Scene(root, canvasW *2, canvasH *1.5)); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
CanvasUtils类
package sample.utils; import java.util.List; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.TextAlignment; import javafx.scene.transform.Rotate; import sample.Main; import static sample.Main.*; public class CanvasUtils { //移动棋子到指定位置 public static void moveChess(int i , int j ,GraphicsContext gc){ if(selectChess == null ){ return ; } if(chesses[j][i] != null && chesses[j][i].getColor().equals(selectChess.getColor())){ selectChess = chesses[j][i]; selectChess(selectChess,gc); return ; } chesses[selectChess.getJ()][selectChess.getI()] = null; selectChess.setI(i); selectChess.setJ(j); chesses[j][i] = selectChess; gc.clearRect(0, 0, canvasW, canvasH); drawShapes(gc); } //圈棋盘背景 public static Canvas placeCanvas(){ Canvas canvas = new Canvas(canvasW * 1.1, canvasH * 1.1); GraphicsContext gc = canvas.getGraphicsContext2D(); Image img = new Image(Main.class.getResourceAsStream("a.jpg")); gc.drawImage(img,0,0,canvasW * 1.09,canvasH * 1.09); gc.setFill(Color.valueOf("7A6B37")); gc.fillRoundRect(canvasW * 1.09,0,canvasW * 1.1, canvasH * 1.1,canvasW * 0.01,canvasH*0.01); gc.fillRoundRect(0,canvasH * 1.09,canvasH * 1.1, canvasH * 1.1,canvasW * 0.01,canvasH*0.01); return canvas; } //写一个翻转的汉界 public static Canvas rotateCanvas(){ Canvas canvas2 = new Canvas(canvasW * 1.0, canvasH * 1.0); GraphicsContext gc2 = canvas2.getGraphicsContext2D(); gc2.setFill(Color.GREEN); gc2.setStroke(Color.BLUE); gc2.setLineWidth(1); gc2.setTextAlign(TextAlignment.CENTER); gc2.setFont(new Font(fontName, fontSize)); Rotate r = new Rotate(180,girdW/2 + girdW * 6,canvasH - girdH *5 - fontSize/3); gc2.setTransform(r.getMxx(), r.getMyx(), r.getMxy(), r.getMyy(), r.getTx(), r.getTy()); gc2.fillText("汉界" ,girdW/2 + girdW * 6,canvasH - girdH *5 - fontSize/3 + 5); gc2.restore(); return canvas2; } //画棋子 public static void drawChess(GraphicsContext gc){ if(init){ defaultPlace(gc); }else{ for(int i = 0 ; i < 9 ; i++){ System.out.println("\n"); for(int j = 0 ; j < 10 ; j++){ Chess chess = chesses[j][i]; if(chess != null){ System.out.print(chess.getChessName()); drawOneChess(gc,chess); }else{ System.out.print(" "); } } } if(selectChess != null){ gc.setLineWidth(2); gc.setStroke(Color.valueOf("EAEED9")); selectChess.setSelect(true); gc.strokeOval(selectChess.getX(), selectChess.getY(), selectChess.getW(),selectChess.getW()); selectChess = null; } } } //默认棋盘 public static void defaultPlace(GraphicsContext gc){ init = false; for(int i = 0 ; i < 9 ; i++){ for(int j = 0 ; j < 10 ; j++){ if(!"".equals(names[j][i])){ gc.setFill(Color.WHEAT); Chess chess = null; if(j > 4){ chess = new Chess(i,j,names[j][i],colorR); drawOneChess(gc,chess); }else{ chess = new Chess(i,j,names[j][i],colorB); drawOneChess(gc,chess); } chesses[j][i] = chess; } } } } public static void drawOneChess(GraphicsContext gc , Chess chess ){ Color color = Color.RED; if(colorB.equals(chess.getColor())) { color = Color.BLACK; } gc.setFont(new Font(fontName, fontSize)); gc.setFill(Color.WHEAT); gc.fillOval(chess.getX(), chess.getY(), chess.getW(), chess.getW()); gc.setLineWidth(2); gc.setStroke(Color.rgb(1,1,1)); gc.setStroke(Color.valueOf("A4802C")); gc.strokeOval(chess.getX(), chess.getY(), chess.getW(), chess.getW()); gc.setLineWidth(1); gc.strokeOval(chess.getX(), chess.getY(), chess.getW()-1, chess.getW()-1); gc.strokeOval(chess.getX()+5, chess.getY()+5, chess.getW()-10, chess.getW()-10); gc.setFill(color); gc.fillText(chess.getChessName(),chess.getX()+chess.getW()/2, chess.getY()+chess.getW()/2+fontSize/3); } //取消选中 public static void unSelectChess(GraphicsContext gc){ //if(selectChess != null ){ gc.clearRect(0, 0, canvasW, canvasH); drawShapes(gc); //} } //选中棋子 public static void selectChess(Chess chess,GraphicsContext gc){ unSelectChess(gc); selectChess = chess; gc.setLineWidth(2); gc.setStroke(Color.rgb(1,1,1)); gc.setStroke(Color.valueOf("EAEED9")); chess.setSelect(true); gc.strokeOval(chess.getX(), chess.getY(), chess.getW(),chess.getW()); List<Integer[]> list = canMove(chess); if(list != null){ for(Integer[] integers : list){ gc.setStroke(Color.rgb(1,1,1)); gc.setLineWidth(3); gc.setStroke(Color.valueOf("4A951F")); gc.strokeOval(chess.getX(integers[0]), chess.getY(integers[1]), chess.getW(),chess.getW()); } } } private static List<Integer[]> canMove(Chess chess){ int code = chess.getCode(); switch (code){ case 1: return CanMoveUtils.bingMove(chess); } return null; } //获取点击的坐标对应的棋子 public static Chess clickChess(double x,double y){ int i = (int)(x/girdW); int j = (int)(y/girdH); System.out.println(i + " __ " + j ); return chesses[j][i]; } //画棋盘。画线 public static void drawPlace(GraphicsContext gc){ gc.setLineWidth(3); gc.strokeLine(girdW/3 ,girdH/3,girdW/3,canvasH - girdH/3); gc.strokeLine(girdW/3*2 + girdW * 8,girdH/3,girdW/3*2 + girdW * 8,canvasH - girdH/3); gc.strokeLine(girdW/3 ,girdH/3 + girdH * 0,canvasW - girdW/3,girdH/3 + girdH * 0); gc.strokeLine(girdW/3 ,girdH/3*2 + girdH * 9,canvasW - girdW/3,girdH/3*2 + girdH * 9); gc.setLineWidth(1); //竖线 for(int i = 0 ; i < 9 ; i++){ //河界要断开 if(i== 0 || i == 8){ gc.strokeLine(girdW/2 + girdW * i ,girdH/2,girdW/2 + girdW * i,canvasH - girdH/2); }else{ gc.strokeLine(girdW/2 + girdW * i ,girdH/2,girdW/2 + girdW * i,canvasH - girdH/2 - girdH *5); gc.strokeLine(girdW/2 + girdW * i ,canvasH - girdH/2 - girdH *4,girdW/2 + girdW * i,canvasH - girdH/2); } } //横线 for(int i = 0 ; i < 10 ; i++){ gc.strokeLine(girdW/2 ,girdH/2 + girdH * i,canvasW - girdW/2,girdH/2 + girdH * i); } gc.setTextAlign(TextAlignment.CENTER); gc.setFont(new Font(fontName, fontSize)); gc.fillText("楚河 ",girdW/2 + girdW * 3,canvasH - girdH *5 + fontSize/3); //画帅的x gc.strokeLine(girdW/2 + girdW * 3,girdH/2,girdW/2 + girdW * 5,girdH/2 + girdH*2); gc.strokeLine(girdW/2 + girdW * 3,girdH/2 + girdH*2,girdW/2 + girdW * 5,girdH/2 ); //画将x gc.strokeLine(girdW/2 + girdW * 3,canvasH - girdH/2,girdW/2 + girdW * 5,canvasH - girdH/2 - girdH*2); gc.strokeLine(girdW/2 + girdW * 3,canvasH - girdH/2 - girdH*2,girdW/2 + girdW * 5,canvasH - girdH/2 ); //画炮的标 gc.strokeLine(girdW/2 + girdW/3*2,girdH/2 + girdH*2 - girdH/10,girdW/2 + girdW - girdW/10,girdH/2 + girdH*2 - girdH/10); gc.strokeLine(girdW/2 + girdW/3*2,girdH/2 + girdH*2 + girdH/10,girdW/2 + girdW - girdW/10,girdH/2 + girdH*2 + girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10,girdH/2 + girdH*2 - girdH/10,girdW/2 + girdW*1 + girdW/3,girdH/2 + girdH*2 - girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10,girdH/2 + girdH*2 + girdH/10,girdW/2 + girdW*1 + girdW/3,girdH/2 + girdH*2 + girdH/10); gc.strokeLine(girdW/2 + girdW/3*2,girdH/2 + girdH*7 - girdH/10,girdW/2 + girdW - girdW/10,girdH/2 + girdH*7 - girdH/10); gc.strokeLine(girdW/2 + girdW/3*2,girdH/2 + girdH*7 + girdH/10,girdW/2 + girdW - girdW/10,girdH/2 + girdH*7 + girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10,girdH/2 + girdH*7 - girdH/10,girdW/2 + girdW*1 + girdW/3,girdH/2 + girdH*7 - girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10,girdH/2 + girdH*7 + girdH/10,girdW/2 + girdW*1 + girdW/3,girdH/2 + girdH*7 + girdH/10); gc.strokeLine(girdW/2 + girdW/3*2 + girdW*6,girdH/2 + girdH*2 - girdH/10,girdW/2 + girdW - girdW/10 + girdW*6,girdH/2 + girdH*2 - girdH/10); gc.strokeLine(girdW/2 + girdW/3*2 + girdW*6,girdH/2 + girdH*2 + girdH/10,girdW/2 + girdW - girdW/10 + girdW*6,girdH/2 + girdH*2 + girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10 + girdW*6,girdH/2 + girdH*2 - girdH/10,girdW/2 + girdW*1 + girdW/3 + girdW*6,girdH/2 + girdH*2 - girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10 + girdW*6,girdH/2 + girdH*2 + girdH/10,girdW/2 + girdW*1 + girdW/3 + girdW*6,girdH/2 + girdH*2 + girdH/10); gc.strokeLine(girdW/2 + girdW/3*2 + girdW*6,girdH/2 + girdH*7 - girdH/10,girdW/2 + girdW - girdW/10 + girdW*6,girdH/2 + girdH*7 - girdH/10); gc.strokeLine(girdW/2 + girdW/3*2 + girdW*6,girdH/2 + girdH*7 + girdH/10,girdW/2 + girdW - girdW/10 + girdW*6,girdH/2 + girdH*7 + girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10 + girdW*6,girdH/2 + girdH*7 - girdH/10,girdW/2 + girdW*1 + girdW/3 + girdW*6,girdH/2 + girdH*7 - girdH/10); gc.strokeLine(girdW/2 + girdW + girdW/10 + girdW*6,girdH/2 + girdH*7 + girdH/10,girdW/2 + girdW*1 + girdW/3 + girdW*6,girdH/2 + girdH*7 + girdH/10); gc.strokeLine(girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*1 +girdH/3*2,girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*2 -girdH/10); gc.strokeLine(girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*2 +girdH/10,girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*2 +girdH/3); gc.strokeLine(girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*1 +girdH/3*2,girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*2 -girdH/10); gc.strokeLine(girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*2 +girdH/10,girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*2 +girdH/3); gc.strokeLine(girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*6 +girdH/3*2,girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*7 -girdH/10); gc.strokeLine(girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*7 +girdH/10,girdW/2 + girdW*1 - girdW/10,girdH/2 + girdH*7 +girdH/3); gc.strokeLine(girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*6 +girdH/3*2,girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*7 -girdH/10); gc.strokeLine(girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*7 +girdH/10,girdW/2 + girdW*1 + girdW/10,girdH/2 + girdH*7 +girdH/3); gc.strokeLine(girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*1 +girdH/3*2,girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*2 -girdH/10); gc.strokeLine(girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*2 +girdH/10,girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*2 +girdH/3); gc.strokeLine(girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*1 +girdH/3*2,girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*2 -girdH/10); gc.strokeLine(girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*2 +girdH/10,girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*2 +girdH/3); gc.strokeLine(girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*6 +girdH/3*2,girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*7 -girdH/10); gc.strokeLine(girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*7 +girdH/10,girdW/2 + girdW*7 - girdW/10,girdH/2 + girdH*7 +girdH/3); gc.strokeLine(girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*6 +girdH/3*2,girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*7 -girdH/10); gc.strokeLine(girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*7 +girdH/10,girdW/2 + girdW*7 + girdW/10,girdH/2 + girdH*7 +girdH/3); } public static void drawShapes(GraphicsContext gc) { gc.setFill(Color.GREEN); gc.setStroke(Color.BLACK); gc.setLineWidth(1); gc.setTextAlign(TextAlignment.CENTER); gc.setFont(new Font("", fontSize)); drawPlace(gc); drawChess(gc); } }
Chess类
package sample.utils; import sample.Main; import static sample.Main.chessW; import static sample.Main.girdH; import static sample.Main.girdW; public class Chess { int i,j; //半径 double w = (chessW + 1) * 2; String chessName; String color; boolean select; public Chess( int i ,int j , String chessName ,String color){ this.i = i; this.j = j; this.chessName = chessName; this.color = color; } public int getCode(){ //兵1 炮2 車3 马4 相5 士6 将7 红 //卒-1 炮-2 車-3 马-4 相-5 士-6 帅-7 黑 if(Main.colorR.equals(color)){ return "兵".equals(chessName)?1: "炮".equals(chessName)?2: "車".equals(chessName)?3: "馬".equals(chessName)?4: "相".equals(chessName)?5: "仕".equals(chessName)?6: "帥".equals(chessName)?7: 0; }else{ switch (chessName){ case "卒": return -1; case "炮": return -2; case "車": return -3; case "馬": return -4; case "象": return -5; case "士": return -6; case "將": return -7; } } return 0; } public Double getX(){ return girdW/2 - chessW + girdW*i; } public Double getY(){ return girdH/2 - chessW + girdH*j; } public Double getX( int x){ return girdW/2 - chessW + girdW*x; } public Double getY(int y){ return girdH/2 - chessW + girdH*y; } public int getI() { return i; } public void setI(int i) { this.i = i; } public int getJ() { return j; } public void setJ(int j) { this.j = j; } public double getW() { return w; } public void setW(double w) { this.w = w; } public String getChessName() { return chessName; } public void setChessName(String chessName) { this.chessName = chessName; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public boolean isSelect() { return select; } public void setSelect(boolean select) { this.select = select; } }
Can Move Utils 这个类还在写,主要计算可走的位置
package sample.utils; import java.util.ArrayList; import java.util.List; import sample.Main; import static sample.Main.chesses; public class CanMoveUtils { public static List<Integer[]> bingMove(Chess chess ){ int i = chess.getI(); int j = chess.getJ(); if(chesses[j][i] != chess){ System.out.println("exp"); } List<Integer[]> list = new ArrayList<>(); if(Main.colorR.equals(chess.getColor())){ if(j<5){ if(j>0){ if(chesses[j-1][i] ==null){ Integer[] integers = {i,j-1}; list.add(integers); }else{ if(!chesses[j-1][i].color.equals(chess.getColor())){ Integer[] integers = {i,j-1}; list.add(integers); } } } if(i>0){ if(chesses[j][i-1] ==null){ Integer[] integers = {i-1,j}; list.add(integers); }else{ if(!chesses[j][i-1].color.equals(chess.getColor())){ Integer[] integers = {i-1,j}; list.add(integers); } } } if(i<9){ if(chesses[j][i+1] ==null){ Integer[] integers = {i+1,j}; list.add(integers); }else{ if(!chesses[j][i+1].color.equals(chess.getColor())){ Integer[] integers = {i+1,j}; list.add(integers); } } } } } return list; } }
背景图