javafx 制作五子棋游戏——简单MVC框架

本文介绍了一个使用JavaFX实现的五子棋游戏项目,包括实体层、视图层和控制器的具体实现细节。游戏支持两人对战,并能在一方获胜时给出提示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

游戏描述

一个五子棋游戏,能实现双方黑白对决,当一方获胜时给出提示信息,利用Javafx实现GUI界面实现

上手须知

jdk11以上由于官方已经讲javafx组件分离,需要自己下载相应的组件,需要点击configuration然后在vm options中添加下面参数,注意将你的javafx插件路径替换成你自己的(jdk1.8的盆友请忽略)

--module-path "E:\jdk11\javafx-sdk-11.0.2\lib" --add-modules=javafx.controls,javafx.fxml

源码地址

https://github.com/441712875al/five-chess

项目结构

在这里插入图片描述

一、实体层

FiveChess类

  • 提供五子棋实体包含的所有信息
  • 判断游戏是否结束
  • play方法改变chess[][]棋盘中的数据
package entity;


import enums.Side;


public class FiveChess{

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getCellLen() {
        return cellLen;
    }

    public void setCellLen(double cellLen) {
        this.cellLen = cellLen;
    }

    /**

     * 维度

     */

    private int n;

    private double width;

    private double height;

    /**
     * 小方格的大小
     */
    private double cellLen;

    /**
     * 当前棋手
     */
    private Side currentSide=Side.BLACK;

    public char getFlag() {
        return flag;
    }

    private char flag=' ';

    private int[][] chess;

    public int[][] getChess() {
        return chess;
    }

    public void setChess(int[][] chess) {
        this.chess = chess;
    }

    public Side getCurrentSide() {
        return currentSide;
    }

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



    public FiveChess(double width,double height,double cellLen){
        this.width=width;
        this.height=height;
        this.cellLen=cellLen;
        chess=new int[(int)height][(int)width];
        for(int i=0;i<height;i++)
            for(int j=0;j<width;j++)
                chess[i][j]=' ';
    }



    public void play(int x,int y){

        //将当前的棋子放置到(x,y)
        if(chess[x][y]==' '){
            chess[x][y]=currentSide.getCode();
            changeSide();
        }

    }



    public void  changeSide(){

        //更换下棋方

        setCurrentSide(currentSide==Side.BLACK?Side.WHITE:Side.BLACK);

    }



    public boolean judgeGame(int row, int col, Side chessColor){

        //判断游戏是否结束
        if(rowJudge(row,col,chessColor)&&colJudge(row,col,chessColor)&&mainDiagonalJudge(row,col,chessColor)&&DeputyDiagonalJudge(row,col,chessColor))
            return true;
        return false;


    }

    /**
     * 横向判断五子连线
     * @param row
     * @param col
     * @param chessColor
     * @return
     */
    public boolean rowJudge(int row,int col,Side chessColor){

        int count = 0;
        for(int j = col;j<width;j++){
            if(chess[row][j]!=chessColor.getCode())
                break;
            count++;
        }
        for(int j=col-1;j>=0;j--){
            if(chess[row][j]!=chessColor.getCode())
                    break;
            count++;
        }
        if(count>=5)
                return false;
        return true;
    }

    /**
     * 纵向判断
     * @param row
     * @param col
     * @param chessColor
     * @return
     */
    public boolean colJudge(int row,int col,Side chessColor){

        int count=0;
        for(int i=row;i<height;i++){
            if(chess[i][col]!=chessColor.getCode())
                    break;
            count++;
        }
        for(int i=row-1;i>=0;i--){
            if(chess[i][col]!=chessColor.getCode())
                break;
            count++;
        }
        if(count>=5)
                return false;

        return true;
    }


    /**
     * 主对角线方向
     * @param row
     * @param col
     * @param chessColor
     * @return
     */
    public boolean mainDiagonalJudge(int row,int col,Side chessColor){

        int count=0;

        for(int i=row,j=col;i<height&&j<width;i++,j++){
            if(chess[i][j]!=chessColor.getCode())
                    break;
            count++;
        }


        for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
            if(chess[i][j]!=chessColor.getCode())
                break;
            count++;
        }

        if(count>=5)
            return false;

        return true;
    }


    /**
     * 副对角线方向
     * @param row
     * @param col
     * @param chessColor
     * @return
     */
    public boolean DeputyDiagonalJudge(int row,int col,Side chessColor){

        int count=0;
        for(int i=row,j=col;i>=0&&j<width;i--,j++){
            if(chess[i][j]!=chessColor.getCode())
                break;

            count++;
        }


        for(int i=row+1,j=col-1;i<height&&j>=0;i++,j--){
            if(chess[i][j]!=chessColor.getCode())
                break;

            count++;
        }


        if(count>=5)
            return false;

        return true;
    }
}

二、视图层

ChessPane类继承Pane类实现棋盘和五子棋的绘制

package view;


import entity.FiveChess;
import enums.Side;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;

import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;


public class ChessPane extends Pane {


    public Canvas canvas;

    public GraphicsContext gc;

    public FiveChess fiveChess;

    public Canvas getCanvas() {
        return canvas;
    }

    public GraphicsContext getGc() {
        return gc;
    }

    public FiveChess getFiveChess() {
        return fiveChess;
    }

    public void setFiveChess(FiveChess fiveChess) {
        this.fiveChess = fiveChess;
    }


    public ChessPane(FiveChess fiveChess){
        this.fiveChess=fiveChess;
        double cell=fiveChess.getCellLen();
        drawPane(cell);
        drawChess(cell);
        getChildren().add(canvas);
    }

    /*渲染棋盘*/
    public void drawPane(double cell){

        canvas = new Canvas(800,700);
        gc = canvas.getGraphicsContext2D();

        gc.clearRect(0,0,canvas.getWidth(),canvas.getHeight());

        //绘制棋盘
        gc.setStroke(Color.BLACK);

        for(int i=0;i<fiveChess.getWidth();i++)
            for(int j=0;j<fiveChess.getHeight();j++){
                gc.strokeRect(100+i*cell,100+cell*j,cell,cell); //画出小方格
            }

    }

    /*渲染棋子*/
    public void drawChess(double cell){

        /*获取棋子的位置*/
        int[][] chess=fiveChess.getChess();

        for(int i=0;i<fiveChess.getHeight();i++)
            for(int j=0;j<fiveChess.getWidth();j++){

                if(chess[i][j]== Side.BLACK.getCode()){
                    gc.setFill(Color.BLACK);
                    gc.fillOval(100+i*cell-cell/2,100+j*cell-cell/2,cell,cell);//画棋子
                }
                else if(chess[i][j]==Side.WHITE.getCode()){
                    gc.setFill(Color.WHITE);

                    gc.fillOval(100+i*cell-cell/2,100+j*cell-cell/2,cell,cell);
                    gc.strokeOval(100+i*cell-cell/2,100+j*cell-cell/2,cell,cell);
                }
            }

    }

}

三、控制器

PlayAction类继承自事件处理器EventHandler并传递的参数是鼠标事件,表示接受鼠标点击面板事件,该类可以使用lamda表达式替换。

package controller;

import entity.FiveChess;
import enums.Side;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.input.MouseEvent;
import view.ChessPane;

import java.io.*;

/**
 * 时间处理类,可以使用lamda表达式替代
 */
public class PlayAction implements EventHandler<MouseEvent> {

    /*fiveChess表示五子棋游戏模型*/

    private FiveChess fiveChess;

    /*chessPane表示五子棋显示面板*/

    private ChessPane chessPane;



    public PlayAction(FiveChess fiveChess,ChessPane chessPane){
        this.chessPane=chessPane;

        this.fiveChess = fiveChess;

    }

    @Override
    public void handle(MouseEvent event){

        //获取棋盘的小方格的大小
        double cell = fiveChess.getCellLen();


        //获取鼠标点击坐标
        double x = event.getX();
        double y = event.getY();

        /*映射到数组中的坐标*/
        int i = (int)((x-100+cell/2)/cell);
        int j = (int)((y-100+cell/2)/cell);


        /*记录下落子位置*/
        try (FileOutputStream out = new FileOutputStream(new File(System.getProperty("user.dir") + "/src/记录.txt"),true)) {
            out.write(new String(fiveChess.getCurrentSide().getDesc()+"("+j+","+i+")\n").getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*改变棋盘状态*/
        fiveChess.play(i,j);

        /*重新渲染棋子*/
        chessPane.drawChess(cell);

        /*判断是否结束*/
        if(!fiveChess.judgeGame(i,j,fiveChess.getCurrentSide()== Side.BLACK?Side.WHITE:Side.BLACK)){

            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("五子棋游戏");
            alert.setHeaderText("提示信息");

            String msg = (fiveChess.getCurrentSide()==Side.BLACK?Side.WHITE:Side.BLACK).getDesc()+"取得胜利!";
            alert.setContentText(msg);

            try (FileOutputStream out = new FileOutputStream(new File(System.getProperty("user.dir") + "/src/记录.txt"),true)) {
                out.write(msg.getBytes());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            alert.showAndWait();
        }

    }

}

四、测试

import controller.PlayAction;
import entity.FiveChess;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.stage.Stage;
import view.ChessPane;

import javax.print.attribute.standard.Fidelity;
import java.io.*;

public class Test extends Application {

    public static void main(String[] args) {
        launch(args);
    }


    @Override
    public void start(Stage primaryStage) {
        FiveChess fiveChess = new FiveChess(20,20,28.0);
        ChessPane chessPane=new ChessPane(fiveChess);

        /*记录下棋盘信息*/
        try(FileOutputStream out = new FileOutputStream(new File(System.getProperty("user.dir")+"/src/记录.txt"),true)){
            out.write(new String("棋局开始,黑子先行\n").getBytes());
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


        /*注册时间处理器*/
        chessPane.setOnMouseClicked(new PlayAction(fiveChess,chessPane));

        /*显示舞台*/
        Scene scene=new Scene(chessPane,800,700);
        primaryStage.setScene(scene);
        primaryStage.setTitle("五子棋游戏");
        primaryStage.show();

    }
}

效果图

在这里插入图片描述
查看src目录下的记录.txt文件保存的本次对局的记录
在这里插入图片描述

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值