Javafx实现国际象棋游戏

时间:2021-05-20

本文实例为大家分享了Javafx实现国际象棋游戏的具体代码,供大家参考,具体内容如下

基本规则

  • 棋子马设计“日”的移动方式
  • 兵设计只能向前直走,每次只能走一格。但走第一步时,可以走一格或两格的移动方式
  • 请为后设计横、直、斜都可以走,步数不受限制,但不能越子的移动方式。
  • 车只能横向或者竖向行走
  • 国王是在以自己为中心的九宫格内行走
  • 骑士只能走对角线

项目目录结构

UML类图关系

以骑士为例

实现基本功能

  • 吃子
  • 不能越子
  • 游戏结束提示
  • 基本移动策略
  • 背景音乐

效果

控制器

PressedAction

package com.Exercise3;import com.Exercise3.Controller.PressedAction;import com.Exercise3.Controller.ReleaseAction;import com.Exercise3.Controller.ResetAction;import com.Exercise3.view.ChessBoard;import com.Exercise3.view.ChessPane;import javafx.application.Application;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.BorderPane;import javafx.scene.layout.HBox;import javafx.scene.media.Media;import javafx.scene.media.MediaPlayer;import javafx.stage.Stage;public class Test extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { String MEDIA_URL = "file:/E:/IdeaProjects/Experiment/src/com/Exercise3/music/BackgroundMusic.mp3"; ChessBoard chessBoard = ChessBoard.getInstance(100,40,40); //添加媒体资源 Media media = new Media(MEDIA_URL); MediaPlayer mediaPlayer = new MediaPlayer(media); mediaPlayer.setAutoPlay(true); mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE); mediaPlayer.play(); ChessPane pane = new ChessPane(chessBoard); pane.setOnMousePressed(new PressedAction(pane,mediaPlayer)); pane.setOnMouseReleased(new ReleaseAction(pane)); BorderPane borderPane = new BorderPane(); borderPane.setCenter(pane); HBox hBox = new HBox(); hBox.setAlignment(Pos.TOP_CENTER); Button button = new Button("悔棋"); button.setOnAction(new ResetAction(pane)); hBox.getChildren().add(button); borderPane.setBottom(hBox); Scene scene = new Scene(borderPane,900,900); primaryStage.setScene(scene); primaryStage.setTitle("国际象棋"); primaryStage.show(); }}

ReleasedAction

package com.Exercise3.Controller;import com.Exercise3.entity.Piece.ChessPiece;import com.Exercise3.entity.PieceType;import com.Exercise3.view.ChessBoard;import com.Exercise3.view.ChessPane;import javafx.event.EventHandler;import javafx.scene.control.Alert;import javafx.scene.input.MouseEvent;import java.util.Stack;public class ReleaseAction implements EventHandler<MouseEvent> { private ChessPane chessPane; static Stack<ChessPiece> stack = new Stack<>(); public ReleaseAction(ChessPane chessPane) { this.chessPane = chessPane; } @Override public void handle(MouseEvent e) { chessPane.drawBoard(); ChessBoard chessBoard = chessPane.getChessBoard(); int x = (int) ((e.getX() - chessBoard.getStartX()) / (chessBoard.getCellLength())); int y = (int) ((e.getY() - chessBoard.getStartY()) / (chessBoard.getCellLength())); for (ChessPiece o : chessPane.getChessPieces()) { if (o.isSelected()) { System.out.println(o.isSelected()+" "+o.getRow()+" "+o.getCol()); if (chessBoard.getCurrSide()==o.getSide()){ if(o.getMoveStrategy().move(x, y,chessPane.getChessPieces())){ o.setSelected(false); if(judgeGame(x,y)){ printTip(o.getSide()); } eatPiece(x,y); stack.push((ChessPiece) o.clone()); o.setCol(x); o.setRow(y); chessBoard.changeSide(); } } break; } } chessPane.drawPiece(); } public void eatPiece(int x,int y){ chessPane.getChessPieces().removeIf(e->{ if(e.getCol()==x&&e.getRow()==y){ stack.push(e); return true; } return false; }); } public boolean judgeGame(int x,int y){ for(ChessPiece e:chessPane.getChessPieces()){ if(e.getCol()==x&&e.getRow()==y&&( e.getType()== PieceType.KINGBLACK||e.getType()==PieceType.KINGWHITE)) return true; } return false; } public void printTip(char side){ Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setContentText((side=='B'?"黑":"白")+"方取得胜利"); alert.setTitle("游戏结束"); alert.showAndWait(); }}

ResetAction

package com.Exercise3.Controller;import com.Exercise3.entity.Piece.ChessPiece;import com.Exercise3.view.ChessPane;import javafx.event.ActionEvent;import javafx.event.EventHandler;import java.util.Stack;public class ResetAction implements EventHandler<ActionEvent>{ private ChessPane chessPane; public ResetAction(ChessPane chessPane) { this.chessPane = chessPane; } @Override public void handle(ActionEvent e) { Stack<ChessPiece> stack = ReleaseAction.stack; if(!stack.empty()){ chessPane.getChessPieces().removeIf(o->o.equals(stack.peek()));//去除原来的棋子 chessPane.getChessPieces().add(stack.pop());//将以前压入堆栈的棋子重新加入 chessPane.drawBoard(); chessPane.drawPiece(); } }}

实体

棋子

ChessPiece

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.CarStrategy;public class Car extends ChessPiece { public Car(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new CarStrategy(getCol(),getRow())); }}

Car

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.CarStrategy;public class Car extends ChessPiece { public Car(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new CarStrategy(getCol(),getRow())); }}

Horse

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.HorseStategy;public class Horse extends ChessPiece{ public Horse(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new HorseStategy(getCol(),getRow())); }}

King

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.KingStrategy;public class King extends ChessPiece { public King(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new KingStrategy(getCol(),getRow())); }}

Knight

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.KnightStrategy;public class Knight extends ChessPiece { public Knight(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new KnightStrategy(getCol(),getRow())); }}

Queen

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.QueenStrategy;public class Queen extends ChessPiece { public Queen(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new QueenStrategy(getCol(),getRow())); }}

Soldier

package com.Exercise3.entity.Piece;import com.Exercise3.entity.PieceType;import com.Exercise3.entity.Strategy.SoldierStategy;public class Soldier extends ChessPiece{ public Soldier(PieceType type, int row, int col) { super(type, row, col); setMoveStrategy(new SoldierStategy(getCol(),getRow(),getSide())); }}

移动策略

MoveStategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.Set;public interface MoveStrategy { boolean move(int x, int y, Set<ChessPiece> chessPieces);}

CarStrategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Set;public class CarStrategy implements MoveStrategy { private int curX; private int curY; public CarStrategy() { } public CarStrategy(int curX, int curY) { this.curX = curX; this.curY = curY; } public boolean move(int x, int y, Set<ChessPiece> chessPieces) { if(x!=curX&&y!=curY) return false; if(isOverPiece(Math.min(curX,x),Math.min(curY,y), Math.max(curX,x),Math.max(curY,y),chessPieces)) return false; curX = x; curY = y; return true; } public static boolean isOverPiece(int stX,int stY,int edX,int edY,Set<ChessPiece> chessPieces){ for(ChessPiece e:chessPieces) if((e.getRow()>stY&&e.getRow()<edY)&&e.getCol()==stX|| (e.getCol()>stX&&e.getCol()<edX&&e.getRow()==stY)) return true; return false; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

HorseStrategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Set;public class HorseStategy implements MoveStrategy{ private int curX; private int curY; public HorseStategy(int curX, int curY) { this.curX = curX; this.curY = curY; } @Override public boolean move(int x, int y, Set<ChessPiece> chessPieces) { if((Math.abs(curX-x)==1&&Math.abs(curY-y)==2)|| (Math.abs(curX-x)==2&&Math.abs(curY-y)==1)){ curX = x; curY = y; return true; } return false; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

KingStrategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Set;public class KingStrategy implements MoveStrategy { private int curX; private int curY; public KingStrategy(int curX, int cuY) { this.curX = curX; this.curY = cuY; } @Override public boolean move(int x, int y, Set<ChessPiece> chessPieces) { if(Math.abs(curX-x)<=1&&Math.abs(curY-y)<=1){ curX = x; curY = y; return true; } return false; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

KnightStrage

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Map;import java.util.Set;public class KnightStrategy implements MoveStrategy { private int curX; private int curY; public KnightStrategy(int curX, int curY) { this.curX = curX; this.curY = curY; } @Override public boolean move(int x, int y, Set<ChessPiece> chessPieces) { if(Math.abs(x-curX)==Math.abs(y-curY)){ if(isOverPiece(Math.min(curX,x),Math.min(curY,y), Math.max(curX,x),Math.max(curY,y),chessPieces)) return false; curX=x; curY=y; return true; } return false; } public static boolean isOverPiece(int stX,int stY,int edX,int edY,Set<ChessPiece> chessPieces){ for(ChessPiece e:chessPieces){ if(e.getCol()-stX==edX-e.getCol()&&edY-e.getRow()==e.getRow()-stY){ System.out.println(e.isSelected()+" "+e.getRow()+" "+e.getCol()); return true; } } return false; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

QueeStrategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Set;public class QueenStrategy implements MoveStrategy{ private int curX; private int curY; public QueenStrategy(int curX, int curY) { this.curX = curX; this.curY = curY; } @Override public boolean move (int x, int y, Set<ChessPiece> chessPieces) { if(Math.abs(x-curX)==Math.abs(y-curY)||!(x!=curX&&y!=curY)){ if(isOverPiece(Math.min(curX,x),Math.min(curY,y), Math.max(curX,x),Math.max(curY,y),chessPieces)) return false; curX = x; curY = y; return true; } return false; } public boolean isOverPiece (int stX,int stY,int edX,int edY,Set<ChessPiece> chessPieces) { for(ChessPiece e:chessPieces){ if(e.getRow()!=stY&&e.getCol()!=stX){ return KnightStrategy.isOverPiece(stX,stY,edX,edY,chessPieces); } else{ return CarStrategy.isOverPiece(stX,stY,edX,edY,chessPieces); } } return false; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

SoldierStrategy

package com.Exercise3.entity.Strategy;import com.Exercise3.entity.Piece.ChessPiece;import java.util.List;import java.util.Set;public class SoldierStategy implements MoveStrategy{ private int curX; private int curY; private char side; private boolean firstMove = true; public SoldierStategy(int curX, int curY,char side) { this.curX = curX; this.curY = curY; this.side = side; } @Override public boolean move(int x, int y, Set<ChessPiece> chessPieces) { //直线移动 if(curY==y){ switch (side){ case 'B': { if(isFirstMove()&&(x==curX+1||curX+2==x)){ setFirstMove(false); curY = y; curX = x; return true; } else if(!isFirstMove()&&curX+1==x){ curY = y; curX = x; return true; } break; } case 'W':{ if(isFirstMove()&&(x==curX-1||x==curX-2)){ setFirstMove(false); curY = y; curX = x; return true; } else if(!isFirstMove()&&curX-1==x){ curY = y; curX = x; return true; } break; } } } //吃子移动 for(ChessPiece e:chessPieces){ if(Math.abs(e.getRow()-curY)==1){ if(e.getCol()-curX==1&&e.getSide()=='W'|| curX-e.getCol()==1&&e.getSide()=='B'){ curY = y; curX = x; return true; } } } return false; } public boolean isFirstMove() { return firstMove; } public void setFirstMove(boolean firstMove) { this.firstMove = firstMove; } public int getCurX() { return curX; } public void setCurX(int curX) { this.curX = curX; } public int getCurY() { return curY; } public void setCurY(int curY) { this.curY = curY; }}

棋子类型

package com.Exercise3.entity;public enum PieceType { KINGBLACK("KingBlack","com/Exercise3/img/KingBlack.jpg"), QUEENBLACK("QueenBlack","com/Exercise3/img/QueenBlack.jpg"), CARBLACK("CarBlack","com/Exercise3/img/CarBlack.jpg"), HORSEBLACK("HorseBlack","com/Exercise3/img/HorseBlack.jpg"), SOLDIERBLACK("SoldierBlack","com/Exercise3/img/SoldierBlack.jpg"), KNIGHTBLACK("KnightBlack","com/Exercise3/img/KnightBlack.jpg"), KINGWHITE("KingWhite","com/Exercise3/img/KingWhite.jpg"), QUEENWHITE("QueenWhite","com/Exercise3/img/QueenWhite.jpg"), CARWHITE("CarWhite","com/Exercise3/img/CarWhite.jpg"), HORSEWHITE("HorseWhite","com/Exercise3/img/HorseWhite.jpg"), SOLDIERWHITE("SoldierWhite","com/Exercise3/img/SoldierWhite.jpg"), KNIGHTWHITE("KnightWhite","com/Exercise3/img/KnightWhite.jpg"); private String desc; private PieceType(String desc,String url ){ this.desc = desc; this.url = url; } private String url; public String getDesc(){ return desc; } public String getUrl() { return url; }}

视图

package com.Exercise3.view;public class ChessBoard { static ChessBoard chessBoard = null; private int row; private int col; private double cellLength; private double startX; private double startY; private char currSide; private ChessBoard(double cellLength, double startX, double startY) { this.row = 8; this.col = 8; this.cellLength = cellLength; this.startX = startX; this.startY = startY; this.currSide = 'B'; } public static ChessBoard getInstance(double cellLength, double startX, double startY){ if(chessBoard == null) return new ChessBoard(cellLength,startX,startY); return chessBoard; } public ChessBoard getInstance(){ return chessBoard; } public int getCol() { return col; } public int getRow() { return row; } public double getCellLength() { return cellLength; } public void changeSide(){ currSide=(currSide=='B'?'W':'B'); } public void setCellLength(double cellLength) { this.cellLength = cellLength; } public double getStartX() { return startX; } public void setStartX(double startX) { this.startX = startX; } public double getStartY() { return startY; } public void setStartY(double startY) { this.startY = startY; } public char getCurrSide() { return currSide; }}package com.Exercise3.view;import com.Exercise3.entity.Piece.*;import com.Exercise3.entity.PieceType;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.image.*;import javafx.scene.layout.Pane;import javafx.scene.paint.Color;import java.util.*;public class ChessPane extends Pane { private Set<ChessPiece> chessPieces; private ChessBoard chessBoard; private Canvas canvas; private GraphicsContext gc; public ChessPane(ChessBoard chessBoard) { this.chessBoard = chessBoard; setChessPiece(); canvas = new Canvas(900,900); gc = canvas.getGraphicsContext2D(); draw(); } public void draw(){ drawBoard(); drawPiece(); getChildren().add(canvas); } public void drawBoard(){ gc.clearRect(0,0,900,900); double x = chessBoard.getStartX(); double y = chessBoard.getStartY(); double cell = chessBoard.getCellLength(); boolean flag = false; for(int i=0;i<chessBoard.getRow();i++){ flag = !flag; for(int j=0;j<chessBoard.getCol();j++){ gc.setFill(flag? Color.valueOf("#EDEDED"):Color.valueOf("CDC5BF")); gc.fillRect(x+j*cell,y+i*cell,cell,cell); flag = !flag; } } gc.setStroke(Color.GRAY); gc.strokeRect(x,y,cell*chessBoard.getCol(),cell*chessBoard.getRow()); } public void drawPiece(){ double cell = chessBoard.getCellLength(); chessPieces.forEach( e->{ if(e.isSelected()){ gc.setFill(Color.valueOf("#6495ED")); gc.fillRect(chessBoard.getStartX()+e.getCol()*cell, chessBoard.getStartY()+e.getRow()*cell, cell,cell); } Image image = new Image(e.getType().getUrl()); gc.drawImage(image, chessBoard.getStartX()+10 + e.getCol() * cell, chessBoard.getStartY()+10 + e.getRow() * cell, cell-20, cell-20); }); } //加入棋子 public void setChessPiece() { chessPieces = new HashSet<>(); chessPieces.add(new Car(PieceType.CARBLACK,0,0)); chessPieces.add(new Horse(PieceType.HORSEBLACK,1,0)); chessPieces.add(new Knight(PieceType.KNIGHTBLACK,2,0)); chessPieces.add(new King(PieceType.KINGBLACK,3,0)); chessPieces.add(new Queen(PieceType.QUEENBLACK,4,0)); chessPieces.add(new Knight(PieceType.KNIGHTBLACK,5,0)); chessPieces.add(new Horse(PieceType.HORSEBLACK,6,0)); chessPieces.add(new Car(PieceType.CARBLACK,7,0)); for(int i=0;i<8;i++){ chessPieces.add(new Soldier(PieceType.SOLDIERBLACK,i,1)); } chessPieces.add(new Car(PieceType.CARWHITE,0,7)); chessPieces.add(new Horse(PieceType.HORSEWHITE,1,7)); chessPieces.add(new Knight(PieceType.KNIGHTWHITE,2,7)); chessPieces.add(new King(PieceType.KINGWHITE,3,7)); chessPieces.add(new Queen(PieceType.QUEENWHITE,4,7)); chessPieces.add(new Knight(PieceType.KNIGHTWHITE,5,7)); chessPieces.add(new Horse(PieceType.HORSEWHITE,6,7)); chessPieces.add(new Car(PieceType.CARWHITE,7,7)); for(int i=0;i<8;i++){ chessPieces.add(new Soldier(PieceType.SOLDIERWHITE,i,6)); } } public ChessBoard getChessBoard() { return chessBoard; } public void setChessBoard(ChessBoard chessBoard) { this.chessBoard = chessBoard; } public Set<ChessPiece> getChessPieces() { return chessPieces; } public void setChessPieces(Set<ChessPiece> chessPieces) { this.chessPieces = chessPieces; } public Canvas getCanvas() { return canvas; } public void setCanvas(Canvas canvas) { this.canvas = canvas; } public GraphicsContext getGc() { return gc; } public void setGc(GraphicsContext gc) { this.gc = gc; }}

测试

package com.Exercise3;import com.Exercise3.Controller.PressedAction;import com.Exercise3.Controller.ReleaseAction;import com.Exercise3.Controller.ResetAction;import com.Exercise3.view.ChessBoard;import com.Exercise3.view.ChessPane;import javafx.application.Application;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.BorderPane;import javafx.scene.layout.HBox;import javafx.scene.media.Media;import javafx.scene.media.MediaPlayer;import javafx.stage.Stage;public class Test extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { String MEDIA_URL = "file:/E:/IdeaProjects/Experiment/src/com/Exercise3/music/BackgroundMusic.mp3"; ChessBoard chessBoard = ChessBoard.getInstance(100,40,40); //添加媒体资源 Media media = new Media(MEDIA_URL); MediaPlayer mediaPlayer = new MediaPlayer(media); mediaPlayer.setAutoPlay(true); mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE); mediaPlayer.play(); ChessPane pane = new ChessPane(chessBoard); pane.setOnMousePressed(new PressedAction(pane,mediaPlayer)); pane.setOnMouseReleased(new ReleaseAction(pane)); BorderPane borderPane = new BorderPane(); borderPane.setCenter(pane); HBox hBox = new HBox(); hBox.setAlignment(Pos.TOP_CENTER); Button button = new Button("悔棋"); button.setOnAction(new ResetAction(pane)); hBox.getChildren().add(button); borderPane.setBottom(hBox); Scene scene = new Scene(borderPane,900,900); primaryStage.setScene(scene); primaryStage.setTitle("国际象棋"); primaryStage.show(); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章