Java FX小项目国际象棋

Java FX小项目----国际象棋

今天为大家介绍一个简单的Java FX练手项目,使用Java FX开发国际象棋。首先我们要知道国际象棋的基本规则和玩法,类似于我们的中国象棋,最重要的就是保护王,如果王被对方吃掉了,那就输了。https://lichess.org/
在上面这个网站可以学习相关规则和进行试玩。
这个项目使用到的主要有面向对象编程、接口、事件驱动编程、集合框架、Java FX的画布。主要分为:

  1. 实体层:储存数据例如棋子状态。
  2. 视图层:使用面板来显示图像。
  3. 逻辑层:按规则对单击事件进行处理。

1、运行结果

2、项目包

3、代码

  1. 主程序:Main
package sample;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import sample.controller.Controller;
import sample.view.broadPane;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        primaryStage.setTitle("InternationalChess!");
        broadPane pane = new broadPane(60);
        pane.setOnMouseClicked(new Controller(pane));
        primaryStage.setScene(new Scene(pane, 600, 600));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}
  1. 实体层:

chesspiece

package sample.entity;

import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import sample.entity.strategy.MoveStrategy;

public class chessPiece {
    //棋子坐标
    private int x;
    private int y;

    private double cellLen = 60;

    //棋子类型,记录了对应图标的绝对路径
    private chessType chessType;

    //该棋子是否被选中
    private boolean selected;

    //棋子移动的策略
    private MoveStrategy moveStrategy;

    private ImageView imageView;

    public chessPiece(int x, int y, sample.entity.chessType chessType, MoveStrategy moveStrategy) {
        this.x = x;
        this.y = y;
        this.chessType = chessType;
        this.moveStrategy = moveStrategy;
        Image image = new Image(chessType.getPath());
        imageView = new ImageView(image);
    }

    /**
     * 依靠MoveStrategy 进行移动
     * @param x
     * @param y
     */
    public void move(int x,int y){
        this.x = x;
        this.y = y;
        this.imageView.setX(x*cellLen);
        this.imageView.setY(y*cellLen);
        this.setSelected(false);
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public sample.entity.chessType getChessType() {
        return chessType;
    }

    public boolean isSelected() {
        return selected;
    }

    public MoveStrategy getMoveStrategy() {
        return moveStrategy;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public ImageView getImageView() {
        return imageView;
    }

    @Override
    public String toString() {
        return "chessPiece{" +
                "chessType=" + chessType +
                '}';
    }
}

chessType

package sample.entity;

public enum chessType{

    //黑方棋子及其图片路径
    blackBishop("file:D:\\Java\\作业\\国际象棋\\images\\blackBishop.png"),
    blackKing("file:D:\\Java\\作业\\国际象棋\\images\\blackKing.png"),
    blackKnight("file:D:\\Java\\作业\\国际象棋\\images\\blackKnight.png"),
    blackPawn("file:D:\\Java\\作业\\国际象棋\\images\\blackPawn.png"),
    blackQueue("file:D:\\Java\\作业\\国际象棋\\images\\blackQueen.png"),
    blackRook("file:D:\\Java\\作业\\国际象棋\\images\\blackRook.png"),

    //白方棋子及其图片路径
    whiteBishop("file:D:\\Java\\作业\\国际象棋\\images\\whiteBishop.png"),
    whiteKing("file:D:\\Java\\作业\\国际象棋\\images\\whiteKing.png"),
    whiteKnight("file:D:\\Java\\作业\\国际象棋\\images\\whiteKnight.png"),
    whitePawn("file:D:\\Java\\作业\\国际象棋\\images\\whitePawn.png"),
    whiteQueen("file:D:\\Java\\作业\\国际象棋\\images\\whiteQueen.png"),
    whiteRook("file:D:\\Java\\作业\\国际象棋\\images\\whiteRook.png");

    //
    private String path;

    private chessType(String s){
        this.path = s;
    }

    public String getPath() {
        return path;
    }

}

MoveStrategy接口:让棋子按规则移动

package sample.entity.strategy;

import sample.entity.chessPiece;

public interface MoveStrategy {
 public boolean move(chessPiece currentChessPiece,int[][] chess,int x,int y);
}

具体实现如:皇后的移动策略

package sample.entity.strategy;

import sample.entity.chessPiece;

public class QueenStrategy implements MoveStrategy {
 @Override
 public boolean move(chessPiece currentChessPiece,int[][] chess,int x,int y){
     //进行移动
     int x1 = currentChessPiece.getX();
     int y1 = currentChessPiece.getY();
     if(x==x1 || y==y1 || Math.abs(x-x1)==(Math.abs(y-y1))){
         if(isEmpty(x1,y1,x,y,chess)){
             currentChessPiece.move(x,y);
             return true;
         }
     }
     return false;
 }

 //判断两个点的连线上是否有棋子
 public boolean isEmpty(int x,int y,int x1,int y1,int[][] chess){
     if(x<x1&&y<y1){
         for(int i=1;i<(x1-x);i++)
             if(chess[y+i][x+i]!=0)
                 return false;
     }
     else if(x==x1&&y<y1){
         for(int i=1;i<(x1-x);i++)
             if(chess[y+i][x]!=0)
                 return false;
     }
     else if(x<x1&&y>y1){
         for(int i=1;i<(x1-x);i++)
             if(chess[y-i][x+i]!=0)
                 return false;
     }
     else if(x==x1&&y>y1){
         for(int i=1;i<(x1-x);i++)
             if(chess[y-i][x]!=0)
                 return false;
     }
     else if(x>x1&&y<y1){
         for(int i=1;i<(x-x1);i++)
             if(chess[y+i][x-i]!=0)
                 return false;
     }
     else if(x>x1&&y==y1){
         for(int i=1;i<(x-x1);i++)
             if(chess[y][x-i]!=0)
                 return false;
     }
     else if  (x>x1&&y>y1){
         for(int i=1;i<(x-x1);i++)
             if(chess[y-i][x-i]!=0)
                 return false;
     }
     else if  (x>x1&&y==y1){
         for(int i=1;i<(x-x1);i++)
             if(chess[y][x-i]!=0)
                 return false;
     }
     return true;
 }
}


  1. 视图层
package sample.view;

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import sample.entity.chessPiece;
import sample.entity.chessType;
import sample.entity.strategy.*;


import java.util.ArrayList;

public class broadPane extends Pane {
   //棋子列表
   private ArrayList whiteChessList = new ArrayList<chessPiece>();
   private ArrayList blackChessList = new ArrayList<chessPiece>();

   //目前持方,对棋子进行操作,初始为白方先走
   private String currentSide = "W";

   private Canvas canvas;
   private GraphicsContext gc;
   private double cellLen;

   //生成国际象棋对象
   public broadPane(double cellLen) {
       //初始化画布,背景
       this.canvas = new Canvas(10*cellLen,10*cellLen);
       this.gc = canvas.getGraphicsContext2D();
       this.cellLen = cellLen;
       getChildren().add(canvas);

       //初始化国际象棋
       initChess();
   }

   /**
    * 初始化国际象棋:
    * 1、绘制棋盘背景
    * 2、创建棋子列表
    */
   public void initChess(){
       drawBackground();
       initChessPiece();

   }

   /**
    * 初始化棋子
    */
   public void initChessPiece(){
       //初始化黑色棋子
       blackPawn();
       blackKing();
       blackQueue();
       blackBishop();
       blackKnight();
       blackRook();

       //初始化白色棋子
       whitePawn();
       whiteKing();
       whiteQueue();
       whiteBishop();
       whiteKnight();
       whiteRook();


   }

   //对图标的位置和形状进行裁剪放置
   public void reshapeImageView(int x,int y,chessPiece piece){
       piece.getImageView().setX(x*cellLen);
       piece.getImageView().setY(y*cellLen);
       piece.getImageView().setFitHeight(cellLen);
       piece.getImageView().setFitWidth(cellLen);
   }

   //初始化8个黑色士兵
   public void blackPawn(){
       for(int i=0;i<8;i++){
           chessPiece piece = new chessPiece(i,1, chessType.blackPawn,new blackPawnStrategy());
           blackChessList.add(piece);
           reshapeImageView(i,1,piece);
           getChildren().add(piece.getImageView());
       }
   }

   //初始化黑国王
   public void blackKing(){
       chessPiece piece = new chessPiece(4,0,chessType.blackKing,new KingStrategy());
       blackChessList.add(piece);
       reshapeImageView(4,0,piece);
       blackChessList.add(piece);
       getChildren().add(piece.getImageView());
   }

   //初始化黑色皇后
   public void blackQueue(){
       chessPiece piece = new chessPiece(3,0,chessType.blackQueue,new QueenStrategy());
       blackChessList.add(piece);
       reshapeImageView(3,0,piece);
       getChildren().add(piece.getImageView());
   }

   //初始化黑色的马
   public void blackKnight(){
       chessPiece piece = new chessPiece(1,0,chessType.blackKnight,new KnightStrategy());
       blackChessList.add(piece);
       reshapeImageView(1,0,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(6,0,chessType.blackKnight,new KnightStrategy());
       blackChessList.add(piece1);
       reshapeImageView(6,0,piece1);
       getChildren().add(piece1.getImageView());
   }

   //初始化黑色的象
   public void blackBishop(){
       chessPiece piece = new chessPiece(2,0,chessType.blackBishop,new BishopStrategy());
       blackChessList.add(piece);
       reshapeImageView(2,0,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(5,0,chessType.blackBishop,new BishopStrategy());
       blackChessList.add(piece1);
       reshapeImageView(5,0,piece1);
       getChildren().add(piece1.getImageView());
   }

   //初始化黑色的车
   public void blackRook(){
       chessPiece piece = new chessPiece(0,0,chessType.blackRook,new RookStrategy());
       blackChessList.add(piece);
       reshapeImageView(0,0,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(7,0,chessType.blackRook,new RookStrategy());
       blackChessList.add(piece1);
       reshapeImageView(7,0,piece1);
       getChildren().add(piece1.getImageView());
   }

   //初始化8个白色士兵
   public void whitePawn(){
       for(int i=0;i<8;i++){
           chessPiece piece = new chessPiece(i,6, chessType.whitePawn,new whitePawnStrategy());
           whiteChessList.add(piece);
           reshapeImageView(i,6,piece);
           getChildren().add(piece.getImageView());
       }
   }

   //初始化白国王
   public void whiteKing(){
       chessPiece piece = new chessPiece(4,7,chessType.whiteKing,new KingStrategy());
       whiteChessList.add(piece);
       reshapeImageView(4,7,piece);
       getChildren().add(piece.getImageView());
   }

   //初始化白色皇后
   public void whiteQueue(){
       chessPiece piece = new chessPiece(3,7,chessType.whiteQueen,new QueenStrategy());
       whiteChessList.add(piece);
       reshapeImageView(3,7,piece);
       getChildren().add(piece.getImageView());
   }

   //初始化白色的马
   public void whiteKnight(){
       chessPiece piece = new chessPiece(1,7,chessType.whiteKnight,new KnightStrategy());
       whiteChessList.add(piece);
       reshapeImageView(1,7,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(6,7,chessType.whiteKnight,new KnightStrategy());
       whiteChessList.add(piece1);
       reshapeImageView(6,7,piece1);
       getChildren().add(piece1.getImageView());
   }

   //初始化白色的象
   public void whiteBishop(){
       chessPiece piece = new chessPiece(2,7,chessType.whiteBishop,new BishopStrategy());
       whiteChessList.add(piece);
       reshapeImageView(2,7,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(5,7,chessType.whiteBishop,new BishopStrategy());
       whiteChessList.add(piece1);
       reshapeImageView(5,7,piece1);
       getChildren().add(piece1.getImageView());
   }

   //初始化白色的车
   public void whiteRook(){
       chessPiece piece = new chessPiece(0,7,chessType.whiteRook,new RookStrategy());
       whiteChessList.add(piece);
       reshapeImageView(0,7,piece);
       getChildren().add(piece.getImageView());
       chessPiece piece1 = new chessPiece(7,7,chessType.whiteRook,new RookStrategy());
       whiteChessList.add(piece1);
       reshapeImageView(7,7,piece1);
       getChildren().add(piece1.getImageView());
   }



   /**
    * 绘制国际象棋背景
    */
   public void drawBackground(){
       //棋盘颜色设置
       Color a = new Color(181/255.0,136/255.0,99/255.0,1);
       Color b = new Color(240/255.0,217/255.0,181/255.0,1);
       for (int i=0;i<8;i++)
           for(int j=0;j<8;j++) {
               if((i+j)%2==0)
                   gc.setFill(b);
               else
                   gc.setFill(a);
               gc.fillRect(i*cellLen,j*cellLen,cellLen,cellLen);
           }
   }

   public ArrayList getWhiteChessList() {
       return whiteChessList;
   }

   public ArrayList getBlackChessList() {
       return blackChessList;
   }

   public double getCellLen() {
       return cellLen;
   }

   public String getCurrentSide() {
       return currentSide;
   }

   public void setCurrentSide(String currentSide) {
       this.currentSide = currentSide;
   }


}

  1. 控制层
package sample.controller;

import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.input.MouseEvent;
import sample.entity.chessPiece;
import sample.entity.chessType;
import sample.entity.strategy.MoveStrategy;
import sample.view.broadPane;

public class Controller implements EventHandler<MouseEvent>{
   private broadPane broadPane;
   private int[][] chess = new int[8][8];

   public Controller(sample.view.broadPane broadPane) {
       this.broadPane = broadPane;
   }

   @Override
   public void handle(MouseEvent event) {

       refresh();

       //获取鼠标单击坐标,转化为格子的坐标
       int x = (int)(event.getX()/broadPane.getCellLen());
       int y = (int)(event.getY()/broadPane.getCellLen());

       //点击位置超出了棋盘的范围,不进行响应
       if(x>7||y>7)
           return ;

       //如果没有选中棋子,进行棋子选择
       if(isSelected()==null){
           chessPiece piece = isEmpty(x,y);
           //该座标无棋子
           if(piece==null)
               return;
           //将该棋子设为选中
           piece.setSelected(true);
       }
       //否则进行移动,或重选需要的移动棋子
       else{
           chessPiece currentPiece = isSelected();
           chessPiece newPiece = isEmpty(x,y);
           //持方没有重选棋子,进行移动判断
           if(newPiece==null){
               //点击坐标的棋子
               chessPiece nextPiece = getPiece(x,y);
               //使用移动策略进行移动或吃子
               MoveStrategy moveStrategy = currentPiece.getMoveStrategy();
               if(moveStrategy.move(currentPiece,chess,x,y)){
                   //如果成功吃子或者移动,则更换持方
                   if(broadPane.getCurrentSide().equals("W"))
                       broadPane.setCurrentSide("B");
                   else
                       broadPane.setCurrentSide("W");
                   //如果是吃子,则nextPiece存在,需要将其移出棋子列表,并去除其图像
                   if(nextPiece!=null){
                       isGameOver(nextPiece);
                       remove(nextPiece);
                   }
               }
           }
           //重选了棋子
           else{
               currentPiece.setSelected(false);
               newPiece.setSelected(true);
           }
       }
   }

   /**
    * 持放是否已经选择了一个棋子
    * 如果当前持放是白方,返回白方是否选中了一个需要进行移动的棋子
    * @return 返回被选中的棋子,如果没有则返回null
    */
   public chessPiece isSelected(){
       if(broadPane.getCurrentSide().equals("W")){
           for(int i=0;i<broadPane.getWhiteChessList().size();i++){
               chessPiece piece = (chessPiece) broadPane.getWhiteChessList().get(i);
               if(piece.isSelected())
                   return piece;
           }
       }
       else{
           for(int i=0;i<broadPane.getBlackChessList().size();i++){
               chessPiece piece = (chessPiece) broadPane.getBlackChessList().get(i);
               if(piece.isSelected())
                   return piece;
           }
       }
       return null;
   }

   /**
    * 返回当前持放在x,y的棋子
    * @param x
    * @param y
    * @return
    */
   public chessPiece isEmpty(int x, int y){
       //如果当前持放是白方,返回该座标是否有白方棋子
      if(broadPane.getCurrentSide().equals("W")){
          for(int i=0;i<broadPane.getWhiteChessList().size();i++){
              chessPiece piece = (chessPiece) broadPane.getWhiteChessList().get(i);
              if(piece.getX()==x && piece.getY()==y)
                  return piece;
          }
      }
      //如果当前持放是黑方,返回该座标是否有黑方棋子
      else{
          for(int i=0;i<broadPane.getBlackChessList().size();i++){
              chessPiece piece = (chessPiece) broadPane.getBlackChessList().get(i);
              if(piece.getX()==x && piece.getY()==y)
                  return piece;
          }
      }
      return null;
   }

   /**
    * 获得棋盘上坐标x,y上的棋子,如果不存在棋子,则返回null
    * @param x
    * @param y
    * @return
    */
   public chessPiece getPiece(int x, int y){
       for(int i=0;i<broadPane.getWhiteChessList().size();i++){
           chessPiece piece = (chessPiece) broadPane.getWhiteChessList().get(i);
           if(piece.getX()==x && piece.getY()==y)
               return piece;
       }
       for(int i=0;i<broadPane.getBlackChessList().size();i++){
           chessPiece piece = (chessPiece) broadPane.getBlackChessList().get(i);
           if(piece.getX()==x && piece.getY()==y)
               return piece;
       }
       return null;
   }

   public void remove(chessPiece piece){
       piece.getImageView().setImage(null);
       if(broadPane.getCurrentSide().equals("B")){
           for(int i=0;i<broadPane.getBlackChessList().size();i++){
               chessPiece piece1 = (chessPiece) broadPane.getBlackChessList().get(i);
               if(piece.equals(piece1)){
                   broadPane.getBlackChessList().remove(i);
                   break;
               }
           }
       }
       else{
           for(int i=0;i<broadPane.getWhiteChessList().size();i++){
               chessPiece piece1 = (chessPiece) broadPane.getWhiteChessList().get(i);
               if(piece.equals(piece1)){
                   broadPane.getWhiteChessList().remove(i);
                   break;
               }
           }
       }
   }

   //更新棋盘数组
   public void refresh(){
       //初始化棋盘数组
       for(int i=0;i<8;i++)
           for(int j=0;j<8;j++){
               chess[i][j] = 0;
           }
       for(int i=0;i<broadPane.getWhiteChessList().size();i++){
           chessPiece piece = (chessPiece) broadPane.getWhiteChessList().get(i);
           chess[piece.getY()][piece.getX()] = 1;
       }
       for(int i=0;i<broadPane.getBlackChessList().size();i++){
           chessPiece piece = (chessPiece) broadPane.getBlackChessList().get(i);
           chess[piece.getY()][piece.getX()] = 2;
       }
   }

   //判断游戏是否结束
   public void isGameOver(chessPiece piece){
       if(piece.getChessType().equals(chessType.blackKing) || piece.getChessType().equals(chessType.whiteKing )){
           Alert alert = new Alert(Alert.AlertType.INFORMATION);
           alert.setTitle("游戏结束!!");
           String content = broadPane.getCurrentSide().equals("W")? "获胜者为黑方!!!":"获胜者为白方!!!";
           alert.setContentText(content);
           alert.show();
       }
   }


}

能看到这里的小伙伴估计对JavaFX也是真爱了!!
感谢阅读!
https://github.com/zouqg/InternationalChess.git

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值