Java图形化界面编程——五子棋游戏 笔记

news2024/11/24 12:43:33

2.8.5 五子棋

接下来,我们使用之前学习的绘图技术,做一个五子棋的游戏。
在这里插入图片描述
注意,这个代码只实现了五子棋的落子、删除棋子和动画等逻辑实现,并没有把五子棋的游戏逻辑编写完整,比较简单易上手。

图片素材
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述


package Draw;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;

public class Gobang {
    //定义五子棋游戏窗口
    private JFrame jframe = new JFrame("五子棋游戏"); //改动一,使用swing中的JFrame解决画面闪烁

    //声明四个BufferedImage对象,分别记录四张图片

    BufferedImage table;
    BufferedImage black;
    BufferedImage white;
    BufferedImage selected;

    //声明棋盘的宽和高(与棋盘图片的宽和高一致)
    private final int TABLE_WIDTH = 535;
    private final int TABLE_HEIGHT = 536;

    //声明棋盘横向和纵向分别可以下多少子,它们的值都为十五(多少行多少列)
    final int BOARD_SIZE =15;

    //声明每个棋子占用棋盘的比率
    final int RATE = TABLE_WIDTH/BOARD_SIZE;

    //声明变量记录棋子对于x方向和y方向的偏移量,在像素中量出来的
    final int X_OFFSET = 5;
    final int Y_OFFSET = 6;

    //声明一个二维数组,记录当前位置棋子的状态,如果索引[i][j]的值为 0-没有棋子, 1-白棋, 2-黑棋
    int[][] board = new int[BOARD_SIZE][BOARD_SIZE];

    //声明红色选择框的坐标,也是二维数组中的索引
    int selected_X = -1;
    int selected_Y = -1;

    //自定义类继承Canvas,充当画布
    private class ChessBoard extends JPanel{   //改动二,继承swing中JPanel而不是Canvas,解决画面闪烁
        @Override
        public void paint(Graphics g) {
            //绘图
            //绘制棋盘
            g.drawImage(table,0,0,null);

            //绘制选择框
            if(selected_X>0 && selected_Y>0) //判断有移动时再开始绘制
                //注意索引与真实位置的转换
                g.drawImage(selected,selected_X*RATE+X_OFFSET,selected_Y*RATE+Y_OFFSET,null);

            //绘制棋子
            for (int i = 0; i < BOARD_SIZE; i++) {
                for (int j = 0; j < BOARD_SIZE; j++) {
                    //绘制黑棋
                    if(board[i][j] == 2) g.drawImage(black,i*RATE+X_OFFSET,j*RATE+Y_OFFSET,null);
                    //绘制白棋
                    if(board[i][j] == 1) g.drawImage(white,i*RATE+X_OFFSET,j*RATE+Y_OFFSET,null);
                }
            }
        }
    }
    ChessBoard chessBoard = new ChessBoard();

    //声明变量,记录当前下棋的颜色,1-白棋, 2-黑棋
    int board_type = 2;

    //声明底部需要用的组件
    Panel p = new Panel();
    Button whiteBtn = new Button("白棋");
    Button blackBtn = new Button("黑棋");
    Button deleteBtn = new Button("删除");

    public void refreshBtnColor(Color whitBtnColor, Color blackBtnColor, Color deleteBtnColor) {         //用来刷新按钮的颜色
        whiteBtn.setBackground(whitBtnColor); //setBackground来设置按钮(背景)颜色
        blackBtn.setBackground(blackBtnColor);
        deleteBtn.setBackground(deleteBtnColor);
    }

    public void init() throws Exception{

        //组装视图,编写逻辑
        //编写白棋按钮的逻辑
        whiteBtn.addActionListener(e->{
            //修改当前要下的棋子的标志为1,对应下白棋。
            board_type = 1;

            //刷新按钮的颜色
            refreshBtnColor(Color.GREEN,Color.GRAY,Color.GRAY);
        });
        //黑棋和清除按钮的逻辑
        blackBtn.addActionListener(e->{
            //修改当前要下的棋子的标志为2,对应下黑棋。
            board_type = 2;

            //刷新按钮的颜色
            refreshBtnColor(Color.GRAY,Color.GREEN,Color.GRAY);
        });
        deleteBtn.addActionListener(e->{
            //修改当前要下的棋子的标志为0,对应着删除
            board_type = 0;

            //刷新按钮的颜色
            refreshBtnColor(Color.GRAY,Color.GRAY,Color.GREEN);
        });
        //将按钮添加到面板中
        p.add(whiteBtn);
        p.add(blackBtn);
        p.add(deleteBtn);
        //将面板添加到frame的南部区域
        jframe.add(p,BorderLayout.SOUTH);

        //组装棋盘
        //初始化图片
        //这里保存图片时需要在项目里建立一个文件夹,来存放图片,不然放在其他地方好像都读不到。。
        table = ImageIO.read(new File("E:\\java_untitled\\calculatoe\\img\\table.jpg"));
        black = ImageIO.read(new File("E:\\java_untitled\\calculatoe\\img\\black.gif"));
        white = ImageIO.read(new File("E:\\java_untitled\\calculatoe\\img\\white.gif"));
        selected = ImageIO.read(new File("E:\\java_untitled\\calculatoe\\img\\selected.gif"));

        //处理棋盘的游戏逻辑,如红色选择框随鼠标移动,鼠标点击便下子
        //处理鼠标移动
        chessBoard.addMouseMotionListener(new MouseMotionAdapter() {
            //当鼠标移动时会调用该方法
            @Override
            public void mouseMoved(MouseEvent e) {
                selected_X = (e.getX()-X_OFFSET)/RATE;//获取此时鼠标的坐标-偏移量/比率,就能得到下棋子的坐标
                selected_Y = (e.getY()-Y_OFFSET)/RATE;
                chessBoard.repaint();
            }
        });

        //处理鼠标点击
        chessBoard.addMouseListener(new MouseAdapter() {
            //当鼠标被点击后会调用该方法
            @Override
            public void mouseClicked(MouseEvent e) {
                int xPos = (e.getX()-X_OFFSET)/RATE;//跟上面一样得到真实坐标
                int yPos = (e.getY()-Y_OFFSET)/RATE;

                board[xPos][yPos] = board_type;//更新坐标中的标记意味已经下子了
                chessBoard.repaint();
            }
            //当鼠标退出区域时,重置界面,使selected_X和selected_Y为-1
            @Override
            public void mouseExited(MouseEvent e) {
                selected_X = -1;
                selected_Y = -1;
                chessBoard.repaint();
            }
        });

        chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));//设置画布
        jframe.add(chessBoard);

        //设置frame最佳大小并可见
        jframe.pack();
        jframe.setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        new Gobang().init();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1451905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

.NET Core MongoDB数据仓储和工作单元模式实操

前言 上一章节我们主要讲解了MongoDB数据仓储和工作单元模式的封装&#xff0c;这一章节主要讲的是MongoDB用户管理相关操作实操。如&#xff1a;获取所有用户信息、获取用户分页数据、通过用户ID获取对应用户信息、添加用户信息、事务添加用户信息、用户信息修改、用户信息删除…

每日OJ题_算法_递归③力扣206. 反转链表

目录 力扣206. 反转链表 解析代码 力扣206. 反转链表 206. 反转链表 LCR 024. 反转链表 难度 简单 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,…

Leetcode3010. 将数组分成最小总代价的子数组 I

Every day a Leetcode 题目来源&#xff1a;3010. 将数组分成最小总代价的子数组 I 题目描述&#xff1a; 给你一个长度为 n 的整数数组 nums 。 一个数组的代价是它的第一个元素。比方说&#xff0c;[1,2,3] 的代价是 1 &#xff0c;[3,4,1] 的代价是 3 。 你需要将 num…

HTML5+CSS3小实例:彩色拨动开关

实例:彩色拨动开关 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><…

双输入宽带混合 Doherty-Outphasing功率放大器设计(2021.02 MTT)-从理论到ADS版图

基于双输入的宽带混合 Doherty-Outphasing功率放大器设计(2021.02 MTT)-从理论到ADS版图 原文: Wideband Two-Way Hybrid Doherty Outphasing Power Amplifier 发表于FEBRUARY 2021&#xff0c;在微波顶刊IEEE T MTT上面&#xff0c;使用的GAN CGH40010F 全部工程下载&#…

Covalent Network(CQT)与卡尔加里大学建立合作,共同推动区块链技术创新

Covalent Network&#xff08;CQT&#xff09;作为领先的 Web3 数据索引器和提供者&#xff0c;宣布已经与卡尔加里大学达成了具备开创性意义的合作&#xff0c;此次合作标志着推动区块链数据研究和可访问性的重要里程碑。卡尔加里大学是首个以验证者的身份加入 Covalent Netwo…

linux-firewalld防火墙端口转发

目的:通过统一地址实现对外同一地址暴露 1.系统配置文件开启 ipv4 端口转发 echo "net.ipv4.ip_forward 1" >> /etc/sysctl.confsysctl -p 2.查看防火墙配置端口转发之前的状态 firewall-cmd --statefirewall-cmd --list-all 3.开启 IP 伪装 firewall-cm…

TIM(Timer)定时中断 P1

难点&#xff1a;定时器级联、主从模式 一、简介&#xff1a; 1.TIM&#xff08;Timer&#xff09;定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 补充&#xff1a; { 定时器本质上是一个计数器&#xff0c;可以工作在定时或计数模式&…

视频生成模型作为世界模拟器

我们探索了在视频数据上大规模训练生成模型。具体来说&#xff0c;我们联合训练文本条件扩散模型&#xff0c;处理不同持续时间、分辨率和宽高比的视频和图像。我们利用一种在时空补丁上操作视频和图像潜码的transformer架构。我们最大的模型&#xff0c;Sora&#xff0c;能够生…

SQL中的各种连接的区别总结

前言 今天主要的内容是要讲解SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别和用法&#xff0c;不用我说其实前面的这些基本SQL语法各位攻城狮基本上都用过。但是往往我们可能用的比较多的也就是左右连接和内连接了&#xff0c;而且对于许多初学…

C++中的volatile:穿越编译器的屏障

C中的volatile&#xff1a;穿越编译器的屏障 在C编程中&#xff0c;我们经常会遇到需要与硬件交互或多线程环境下访问共享数据的情况。为了确保程序的正确性和可预测性&#xff0c;C提供了关键字volatile来修饰变量。本文将深入解析C中的volatile关键字&#xff0c;介绍其作用、…

luigi,一个好用的 Python 数据管道库!

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️付费专栏:Python专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前言 大家好,今天为大家分享一个超级厉害的 Python 库 - luigi。 Github地址:https://github.com/spotify/luigi 在大数据时代,处理海量数据已经成…

Java on VS Code 2024年1月更新|JDK 21支持!测试覆盖率功能最新体验!

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division At Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 2024年的第一期更新&#xff01;提前祝愿大家春节快乐&#xff01;在本博客中&#xff0c;我们将有…

ChatGPT高效提问—prompt实践(智能辅导-心理咨询-职业规划)

ChatGPT高效提问—prompt实践&#xff08;智能辅导-心理咨询-职业规划&#xff09; ​ 智能辅导是指利用人工智能技术&#xff0c;为学习者提供个性化、高效的学习辅助服务。它基于大数据分析和机器学习算法&#xff0c;可以针对学习者的学习行为、状态和能力进行评估和预测&a…

idea里微服务依赖在maven能install但不能启动

场景&#xff1a;多个微服务相互依赖&#xff0c;install都没问题&#xff0c;jar包都是正常的&#xff0c;就连jar都能启动&#xff0c;为什么在idea里面项目就是不能启动呢&#xff0c;我是懵逼的 所以解决办法就是&#xff1a; 在设置的编译器里面虚拟机选项添加 -Djps.tr…

三、Maven项目搭建及Destination(队列、主题)

Maven项目搭建及Destination&#xff08;队列、主题&#xff09; 一、Idea中Maven项目准备1.创建Module2.创建java包3.配置pom.xml 二、队列&#xff08;Queue&#xff09;1.JMS编程架构2.代码实现生产者3.代码实现消费者4.队列消费者三大情况 三、消费者类型1.同步式消费者1.1…

相机图像质量研究(30)常见问题总结:图像处理对成像的影响--重影

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

前端工程化面试题 | 11.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

高性能MySQL 阅读笔记

mysql由服务器端与存储引擎两部分组成&#xff0c;存储引擎部分的锁机制对服务器端是透明的。服务器端内置缓存机制&#xff0c;有解析器和优化器机制。不同的存储引擎对事务、并发等都用不同的处理。 ACID代表的特性&#xff1a;原子性、一致性、隔离性、持久性 共享锁与排他…

【FPGA开发】HDMI通信协议解析及FPGA实现

本篇文章包含的内容 一、HDMI简介1.1 HDMI引脚解析1.2 HDMI工作原理1.3 DVI编码1.4 TMDS编码 二、并串转换、单端差分转换原语2.1 原语简介2.2 IO端口组件 笔者在这里使用的开发板是正点原子的达芬奇开发板&#xff0c;FPGA型号为XC7A35TFGG484-2。参考的课程是正点原子的课程手…