Javafx实现国际象棋游戏
本文实例为大家分享了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(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
阿里dubbo出错提示Thread pool is EXHAUSTED问题及解决方法
这篇文章主要介绍了阿里dubbo出错提示Thread pool is EXHAUSTED的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-08-08testNG项目通过idea Terminal命令行执行的配置过程
这篇文章主要介绍了testNG项目通过idea Terminal命令行执行,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-07-07Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
这篇文章主要介绍了Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting),本文直接给出实现代码,代码中包含详细注释,需要的朋友可以参考下2015-06-06
最新评论