Java学习笔记(九)——开发个小项目(LazyGoBang)

没搞过项目,大概就是敲很多很多代码来实现某个完全的功能。

这里记录开发一下过程、学到的技术和一些遇到的难题、解决方法。

画个大纲(跟随慢慢开发过程不断完善)

用户

两个用户对战  一黑一白

用户可以是人,也可以是AI。对战模式支持人人,人机,机机。

属性

执棋颜色

用户名

游戏得分

方法

下棋

输赢

比赛规则

一黑一白交替轮流下棋

可以决定哪个玩家先手

不可以重复下棋到同一个位置

不可以将棋子下到边界外

可以撤回刚刚下的棋,不可以撤回上一步的棋

哪一方横竖斜到达5个棋子赢一局

游戏界面

设置棋盘

刷新窗体,背景图、棋盘、棋子不消失

设置计分板(记录目前双方赢得局数)

设置当前局数计时器

设置菜单栏(包含开始游戏、暂停游戏、继续游戏)

乱七八糟的功能

第一天 —— 实现棋盘界面

实现:背景图、棋子位置校正、轮流下棋、不下到棋盘之外,开始游戏菜单界面

实现方式

  1. 背景图:UI声明对象,在paint方法先于棋盘绘制。
  2. 棋子位置校正:在监听器放置棋子时,得到鼠标点击的坐标——>最终放置棋子圆心坐标转化过程。将棋盘的一个格子分成4块,在某片区域就归属于这个点,在边线上的点归左、归上。
  3. 轮流下棋:设置棋子计数器,奇数下白子,偶数下黑子。(为使个数不会加到很大做%2操作。也有很多其他方式可用)

遇到的问题

在实现约束棋子不下到棋盘外面时:想要通过单独为棋盘设置一个JPanel面板,但是画笔分配出现问题,现在确定三个位置:

在开始为面板设置位置时,位置坐标基于:什么地方设置。

鼠标监听器鼠标点击等操作获得的坐标基于:谁加入监听器就是谁

画笔绘图坐标基于:谁产生画笔就基于谁

但是paint方法重写的时候是继承的窗体JFrame,因此paint传进来的画笔是窗体产生的画笔,是从最左上的开始的。那么棋盘、背景图都是基于窗体最左上绘制的。

只有面板也是基于窗体最左上的点开始,和棋盘、背景图设置成同一个位置才能重合,但是面板的位置设置并不是这样。有错位。

一个简单的解决方法

将约束设置在监听器中实现,当获得的坐标必须在棋盘范围之内才能点棋子,否则不做任何操作。

代码

//BiangGoBangInterface.java
/**
 * 五子棋接口 设置固定参数
 * 属性
 * 1.SIZE:棋盘间距 & 棋子直径
 * 2.棋盘左上角坐标 X
 * 3.棋盘左上角坐标 Y
 * 4.棋盘行列数 ROW LINE
 * 5.右拉栏宽度
 * 6.按钮的宽度 btnWidth
 * 7.按钮的高度 btnHeight
 */
public interface BiangGoBangInterface {
    int SIZE = 30;
    int X = 100;
    int Y = 100;
    int ROW = 16;
    int LINE = 16;
    int rightWidth = 200;
    int btnWidth = 100;
    int btnHeight = 50;
}



//BiangGoBang.java

/**
 * GoBang界面
 * 继承JFRame ,重写paint方法
 *
 * 属性:
 * 1.bgimg 背景图
 * 2.mylis GoBang棋盘操作监听器 ———— BiangGoBangListener mylis
 *
 * 方法:
 * 1.initBiangGoBangUI() 初始化界面方法
 *
 * 重写方法:
 * 1.paint() 实现窗体刷新之后重画 背景图 棋盘
 */
public class BiangGoBangUI extends JFrame implements BiangGoBangInterface {
    public static final Image bgimg = new ImageIcon("img/bg50.jpg").getImage();
    public BiangGoBangListener mylis = new BiangGoBangListener();

    public void initBiangGoBangUI() {

        //JFrame bgb = new JFrame("Biang's五子棋v 1.0");
        this.setTitle("Biang's 五子棋 v1.0");
        this.setSize(SIZE * LINE, SIZE * ROW);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel rightBar = new JPanel();
        rightBar.setBackground(Color.GRAY);
        Dimension dim = new Dimension(rightWidth,rightWidth);
        rightBar.setPreferredSize(dim);

        JButton BeginBtn = new JButton("Begin");
        BeginBtn.setBackground(Color.WHITE);
        BeginBtn.setSize(btnWidth,btnHeight);
        rightBar.add(BeginBtn);

        JButton StopBtn = new JButton("Stop");
        StopBtn.setBackground(Color.WHITE);
        StopBtn.setSize(btnWidth,btnHeight);
        rightBar.add(StopBtn);

        this.add(rightBar,BorderLayout.EAST);

        //BeginBtn.addActionListener(mylis);

//  实现下棋子下在面板之内:特别为棋盘设置面板画笔不一致,需要重新写继承JPanel的paint方法,所以换在监听器里实现
//        this.setLayout(null);
//        JPanel chessBoard = new JPanel();
//        chessBoard.setLocation(X,Y);
//        Dimension dim = new Dimension(SIZE*ROW,SIZE*LINE);
//        //chessBoard.setPreferredSize(dim);
//        chessBoard.setSize(SIZE*ROW,SIZE*LINE);
//        chessBoard.setBackground(Color.BLUE);
//        this.add(chessBoard);

        this.setVisible(true);
        this.addMouseListener(mylis);
        Graphics pen = this.getGraphics();
        mylis.setGraphics(pen);
    }
    @Override
    public void paint(Graphics g){
        super.paint(g);
        g.drawImage(bgimg,X-SIZE,Y-SIZE,(ROW+2)*SIZE,(LINE+2)*SIZE,null);
        for(int i=0;i<=ROW;i++){
            g.drawLine(X,Y+i*SIZE,X+SIZE*LINE,Y+i*SIZE);  //y不变,画横线
            g.drawLine(X+i*SIZE,Y,X+i*SIZE,Y+SIZE*ROW);   //x不变,画竖线
        }
    }
}


//BiangGoBangListener.java

/**
 * 棋盘操作下棋监听器 (实现鼠标 鼠标拖动接口)
 * 属性:
 * 1.chessX chessY当前下棋的坐标
 * 2.pen 绘制棋子的画笔组件
 *
 * 方法:
 * 1.void setGraphics(Graphics pen)  向监听器传入界面的画笔对象
 *
 * 重写的方法:
 * 1.mousePressed 实现点击下棋 棋子校正 控制下棋范围
 * 2.
 *
 */

public class BiangGoBangListener implements MouseListener , MouseMotionListener ,BiangGoBangInterface{
    int chessX,chessY;
    Graphics pen;
    int controlColor=0;
    public void setGraphics(Graphics pen){
        this.pen = pen;
    }
    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        if(x>X-SIZE && x<X+SIZE*ROW+SIZE && y>Y-SIZE && y<Y+SIZE*LINE+SIZE){
            //棋子校正:点中间线归上左
            int baseX = X + ((x - X) / SIZE) * SIZE;
            int baseY = Y + ((y - Y) / SIZE) * SIZE;
            if ((x - baseX) > (SIZE / 2))
                chessX = baseX + SIZE;
            else
                chessX = baseX;
            if ((y - baseY) > (SIZE / 2))
                chessY = baseY + SIZE;
            else
                chessY = baseY;
            if((controlColor%2)==0)
                pen.setColor(Color.BLACK);
            else
                pen.setColor(Color.WHITE);
            System.out.println(controlColor);
            controlColor=(controlColor+1)%2;

            pen.fillOval(chessX - SIZE / 2, chessY - SIZE / 2, SIZE, SIZE);
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }
}



//StartGameUI.java
public class StartGameUI {
    public static void main(String[] args){
        BiangGoBangUI goBangUI = new BiangGoBangUI();
        goBangUI.initBiangGoBangUI();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值