五子棋小游戏(一)

前面在实现完一个JAVA的面板之后,就想着继续实现一个相较于面板更复杂一点的程序——五子棋。但是我在在搜索资料的时候,发现网上很多关于五子棋实现的博文都是一步到位,直接给个源代码,不是很适合新手学习。所以我这里打算记录一下自己实现五子棋的整个过程,大致会分为三四个阶段。今天我们先来实现第一个阶段的五子棋。同样的我们在着手写代码之前我们需要先做一些准备。

完整代码已上传到github上,地址:https://github.com/Alexlingl/GoBang。有需要的可以自取。

JAVA五子棋的实现(二)

一、我们需要实现哪些东西

1.一个15*15的五子棋界面;

2.能够在界面上下黑白棋子;

3.需要把棋子下在交叉点上;

4.实现棋子重绘;——作用:当界面大小被改变时能够保持棋盘和棋盘上面的棋子不会消失;

5.相同位置不能下多个棋子;

6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;

(判断输赢等其他部分我们放到后面实现)

 

二、根据我们要实现的功能确定我们所需要的API类

五子棋的大致界面如下:

实现五子棋界面需要的API类:

JFrame  顶级容器类

BorderLayout  框架布局类——把容器分为上北下南左西右东中间五个部分,每个部分只能添加一个组件。在这里我们需要把整个界面分为左右两部分。选择在框架布局的中间和右边两个部分。

这里我们还需要另一个容器类——JPanel  面板容器类。主要用来实现右边的部分,因为原本框架布局的右边部分只能添加一个组件,但是我们需要添加的组件不只一个,因此就先这个部分加上一个JPanel,然后再在JPanel上加我们需要的组件,包括按钮等等。

JFrame和JPanel的区别:JFrame是最底层的容器,JPanel放在它上面,同一个界面只有一个JFrame,但是一个JFrame上面可以有多个JPanel。相当于JFrame是一个大餐桌,JPanel是盘子,如果我们要对餐桌JFrame上的东西进行管理分类等,我们就需要使用这些JPanel盘子。

FlowLayout   流式布局类。因为我们右边的JPanel部分需要将按钮等组件由上到下进行排列。

JButton  按钮组件类

JComboBox   下拉列表框类——实现那个人人对战和人机对战的选择

Dimension  封装组件宽度和高度的类——组件类不能直接用setSize方法来设置

事件监听机制的类:

ActionListener  状态监听处理类

ActionEvent   状态监听事件,监听某个组件的状态是否有改变

MouseListener  鼠标监听处理类

MouseEvent  鼠标监听事件,里面包含鼠标被点击等事件的处理方法。当界面被点击时就放下一个棋子。

绘画所需要的类:

Graphics|Graphics2D   画笔类

Color  颜色类,需要设置画笔的颜色,实现黑白棋子

 

三、各个功能实现的思路

1.一个15*15的五子棋界面;

需要重写GoBangframe的重绘方法,使其在界面刚生成时就产生一个15*15的棋盘。(重绘方法会在每次页面大小被改变时执行,因此当你改变大小时,棋盘不会消失)。这里我们可以通过两个for循环画出15条行线和15条列线。

2.能够在界面上下黑白棋子;

实现这个功能需要定义一个变量turn表名当前轮到哪方下棋。如果turn=1表明轮到黑方,turn=2表明轮到白方。每次黑方下完棋之后turn+1,白方下完棋之后turn-1。

3.需要把棋子下在交叉点上;

如果鼠标点击在交叉点处的某个范围内,我们都把棋子下在这个交叉点上。在这个由于各自大小是40,我们定义的范围时以交叉点为中心的上下20的正方形。这样我们就能确保每一次点击都会落到某一个交叉点处,不会覆盖也不会出现没有落子的情况。

4.实现棋子重绘;——作用:当界面大小被改变时能够保持棋盘上面的棋子不消失;

前面的棋盘重绘,虽然15*15的棋盘不会消失,但是棋子会消失。因此我们在重绘出棋盘以后还要把棋子也重新画上去。这里用了一个二维数组isAvail[15][15]来保存棋子信息,如果isArray[i][j]=0,表明这个位置没有棋子,等于1表明是一个黑棋子,等于2表明是一个白棋子。我们根据这些信息,遍历isArray数组,把棋子重新绘制上去。

5.相同位置不能下多个棋子;

判断isArray[i][j]是不是等于0,如果是0就可以下,如果不是则提示玩家下在其它地方。

6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;

下棋是通过监听棋盘界面来实现的,因此我们只需要监听“开始新游戏”这个按钮,如果这个按钮被点击了,我们在给棋盘界面添加监听方法,否则不添加。

四、代码部分


 
 
  1. //构建五子棋界面GoBangframe类
  2. import javax.swing.JFrame;
  3. import javax.swing.JPanel;
  4. import javax.swing.JButton;
  5. import javax.swing.JComboBox;
  6. import java.awt.Dimension;
  7. import java.awt.BorderLayout;
  8. import java.awt.Color;
  9. import java.awt.FlowLayout;
  10. import java.awt.Graphics;
  11. import java.awt.event.ActionListener;
  12. import java.awt.event.MouseListener;
  13. public class GoBangframe extends JPanel implements GoBangconfig{
  14. public Graphics g; //定义一支画笔
  15. public int[][] isAvail= new int [ 15][ 15]; //定义一个二维数组来储存棋盘的落子情况
  16. //主函数入口
  17. public static void main(String args[]) {
  18. GoBangframe gf= new GoBangframe(); //初始化一个五子棋界面的对象
  19. gf.initUI(); //调用方法进行界面的初始化
  20. }
  21. public void initUI() {
  22. //初始化一个界面,并设置标题大小等属性
  23. JFrame jf= new JFrame();
  24. jf.setTitle( "五子棋");
  25. jf.setSize( 800, 650);
  26. jf.setLocationRelativeTo( null);
  27. jf.setDefaultCloseOperation( 3);
  28. jf.setLayout( new BorderLayout()); //设置顶级容器JFrame为框架布局
  29. Dimension dim1= new Dimension( 150, 0); //设置右半部分的大小
  30. Dimension dim3= new Dimension( 550, 0); //设置左半部分的大小
  31. Dimension dim2= new Dimension( 140, 40); //设置右边按钮组件的大小
  32. //实现左边的界面,把GoBangframe的对象添加到框架布局的中间部分
  33. this.setPreferredSize(dim3); //设置下棋界面的大小
  34. this.setBackground(Color.LIGHT_GRAY); //设置下棋界面的颜色
  35. //这里的话直接把左边的画板添加上去,指明是在框架布局的中间版块
  36. //若放在其他版块会有一些小问题
  37. jf.add( this,BorderLayout.CENTER); //添加到框架布局的中间部分
  38. //实现右边的JPanel容器界面
  39. JPanel jp= new JPanel();
  40. jp.setPreferredSize(dim1); //设置JPanel的大小
  41. jp.setBackground(Color.white); //设置右边的界面颜色为白色
  42. jf.add(jp,BorderLayout.EAST); //添加到框架布局的东边部分
  43. jp.setLayout( new FlowLayout()); //设置JPanel为流式布局
  44. //接下来我们需要把按钮等组件依次加到那个JPanel上面
  45. //设置按钮数组
  46. String[] butname= { "开始新游戏", "悔棋", "认输"};
  47. JButton[] button= new JButton[ 3];
  48. //依次把三个按钮组件加上去
  49. for( int i= 0;i<butname.length;i++) {
  50. button[i]= new JButton(butname[i]);
  51. button[i].setPreferredSize(dim2);
  52. jp.add(button[i]);
  53. }
  54. //按钮监控类
  55. ButtonListener butListen= new ButtonListener( this);
  56. //对每一个按钮都添加状态事件的监听处理机制
  57. for( int i= 0;i<butname.length;i++) {
  58. button[i].addActionListener(butListen); //添加发生操作的监听方法
  59. }
  60. //设置选项按钮
  61. String[] boxname= { "人人对战", "人机对战"};
  62. JComboBox box= new JComboBox(boxname);
  63. jp.add(box);
  64. jf.setVisible( true);
  65. }
  66. //重写重绘方法,这里重写的是第一个大的JPanel的方法
  67. public void paint(Graphics g) {
  68. super.paint(g);
  69. //重绘出棋盘
  70. g.setColor(Color.black);
  71. for( int i= 0;i<row;i++) {
  72. g.drawLine(x, y+size*i, x+size*(column- 1), y+size*i);
  73. }
  74. for( int j= 0;j<column;j++) {
  75. g.drawLine(x+size*j, y, x+size*j, y+size*(row- 1));
  76. }
  77. //重绘出棋子
  78. for( int i= 0;i<row;i++) {
  79. for( int j= 0;j<column;j++) {
  80. if(isAvail[i][j]== 1) {
  81. int countx=size*i+ 20;
  82. int county=size*j+ 20;
  83. g.setColor(Color.black);
  84. g.fillOval(countx-size/ 2, county-size/ 2, size, size);
  85. }
  86. else if(isAvail[i][j]== 2) {
  87. int countx=size*i+ 20;
  88. int county=size*j+ 20;
  89. g.setColor(Color.white);
  90. g.fillOval(countx-size/ 2, county-size/ 2, size, size);
  91. }
  92. }
  93. }
  94. }
  95. }

 
 
  1. //设置按钮监听方法ButttonLitener类
  2. import java.awt.event.ActionListener;
  3. import java.awt.event.ActionEvent;
  4. //实现对JPanel的监听接口处理
  5. public class ButtonListener implements GoBangconfig,ActionListener{
  6. public GoBangframe gf;
  7. public ButtonListener(GoBangframe gf) {
  8. this.gf=gf; //获取左半部分的画板
  9. }
  10. //当界面发生操作时进行处理
  11. public void actionPerformed(ActionEvent e) {
  12. //获取当前被点击按钮的内容,判断是不是"开始新游戏"这个按钮
  13. if(e.getActionCommand().equals( "开始新游戏")) {
  14. //如果是开始新游戏的按钮,再为左半部分设置监听方法
  15. frameListener fl= new frameListener();
  16. fl.setGraphics(gf); //获取画笔对象
  17. gf.addMouseListener(fl);
  18. }
  19. }
  20. }

 
 
  1. //定义GoBangconfig接口
  2. //定义与棋盘数据相关的接口,保存棋盘的起点,格子大小,行数列数等信息
  3. public interface GoBangconfig {
  4. int x= 20,y= 20,size= 40,row= 15,column= 15;
  5. }

 
 
  1. import java.awt.event.ActionListener;
  2. import java.awt.event.MouseListener;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.Graphics;
  5. import java.awt.Color;
  6. //实现对GoBangframe下棋界面的监听接口处理
  7. public class frameListener implements GoBangconfig,MouseListener{
  8. public GoBangframe gf;
  9. public int turn= 1; //判断当前轮到谁了,1表示黑方,2表示白方
  10. public void setGraphics(GoBangframe gf) {
  11. this.gf=gf;
  12. }
  13. public void mouseClicked(java.awt.event.MouseEvent e) {
  14. int x=e.getX();
  15. int y=e.getY();
  16. //计算棋子要落在棋盘的哪个交叉点上
  17. int countx=(x/ 40)* 40+ 20;
  18. int county=(y/ 40)* 40+ 20;
  19. Graphics g=gf.getGraphics();
  20. if(gf.isAvail[(countx- 20)/ 40][(county- 20)/ 40]!= 0) {
  21. System.out.println( "此处已经有棋子了,请下在其它地方");
  22. }
  23. else {
  24. //当前位置可以落子,先计算棋盘上棋子在数组中相应的位置
  25. int colu=(countx- 20)/ 40;
  26. int ro=(county- 20)/ 40;
  27. if(turn== 1) {
  28. //先设置颜色
  29. g.setColor(Color.black);
  30. //落子
  31. g.fillOval(countx-size/ 2, county-size/ 2, size, size);
  32. //设置当前位置已经有棋子了,棋子为黑子
  33. gf.isAvail[colu][ro]= 1;
  34. turn++;
  35. }
  36. else {
  37. g.setColor(Color.white);
  38. g.fillOval(countx-size/ 2, county-size/ 2, size, size);
  39. //设置当前位置已经有棋子了,棋子为白子
  40. gf.isAvail[colu][ro]= 2;
  41. turn--;
  42. }
  43. }
  44. }
  45. // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
  46. public void mousePressed(java.awt.event.MouseEvent e) {
  47. }
  48. // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
  49. public void mouseReleased(java.awt.event.MouseEvent e) {
  50. }
  51. // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
  52. public void mouseEntered(java.awt.event.MouseEvent e) {
  53. }
  54. // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
  55. public void mouseExited(java.awt.event.MouseEvent e) {
  56. }
  57. }

五、实现的界面

至此,我们已经初步实现了五子棋的界面和落子,后面我们会继续完善这个五子棋,包括输赢的判断和悔棋等操作。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值