本文實(shí)例講述了java實(shí)現(xiàn)的五子棋游戲代碼,分享給大家供大家參考,具體代碼如下
一、實(shí)踐目標(biāo)
1.掌握J(rèn)avaGUI界面設(shè)計(jì)
2.掌握鼠標(biāo)事件的監(jiān)聽(MouseListener,MouseMotionListener)
二、實(shí)踐內(nèi)容
設(shè)計(jì)一個(gè)簡(jiǎn)單的五子棋程序,能夠?qū)崿F(xiàn)五子棋下棋過程。如下圖所示
1.五子棋棋盤類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
package cn.edu.ouc.fiveChess; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Ellipse2D; import javax.swing.*; /** * 五子棋--棋盤類 */ public class ChessBoard extends JPanel implements MouseListener { public static final int MARGIN= 30 ; //邊距 public static final int GRID_SPAN= 35 ; //網(wǎng)格間距 public static final int ROWS= 15 ; //棋盤行數(shù) public static final int COLS= 15 ; //棋盤列數(shù) Point[] chessList= new Point[(ROWS+ 1 )*(COLS+ 1 )]; //初始每個(gè)數(shù)組元素為null boolean isBlack= true ; //默認(rèn)開始是黑棋先 boolean gameOver= false ; //游戲是否結(jié)束 int chessCount; //當(dāng)前棋盤棋子的個(gè)數(shù) int xIndex,yIndex; //當(dāng)前剛下棋子的索引 Image img; Image shadows; Color colortemp; public ChessBoard(){ // setBackground(Color.blue);//設(shè)置背景色為橘黃色 img=Toolkit.getDefaultToolkit().getImage( "board.jpg" ); shadows=Toolkit.getDefaultToolkit().getImage( "shadows.jpg" ); addMouseListener( this ); addMouseMotionListener( new MouseMotionListener(){ public void mouseDragged(MouseEvent e){ } public void mouseMoved(MouseEvent e){ int x1=(e.getX()-MARGIN+GRID_SPAN/ 2 )/GRID_SPAN; //將鼠標(biāo)點(diǎn)擊的坐標(biāo)位置轉(zhuǎn)成網(wǎng)格索引 int y1=(e.getY()-MARGIN+GRID_SPAN/ 2 )/GRID_SPAN; //游戲已經(jīng)結(jié)束不能下 //落在棋盤外不能下 //x,y位置已經(jīng)有棋子存在,不能下 if (x1< 0 ||x1>ROWS||y1< 0 ||y1>COLS||gameOver||findChess(x1,y1)) setCursor( new Cursor(Cursor.DEFAULT_CURSOR)); //設(shè)置成默認(rèn)狀態(tài) else setCursor( new Cursor(Cursor.HAND_CURSOR)); } }); } //繪制 public void paintComponent(Graphics g){ super .paintComponent(g); //畫棋盤 int imgWidth= img.getWidth( this ); int FWidth=getWidth(); int FHeight=getHeight(); //獲得窗口的寬度與高度 int x=(FWidth-imgWidth)/ 2 ; int y=(FHeight-imgHeight)/ 2 ; g.drawImage(img, x, y, null ); for ( int i= 0 ;i<=ROWS;i++){ //畫橫線 g.drawLine(MARGIN, MARGIN+i*GRID_SPAN, MARGIN+COLS*GRID_SPAN, MARGIN+i*GRID_SPAN); } for ( int i= 0 ;i<=COLS;i++){ //畫豎線 g.drawLine(MARGIN+i*GRID_SPAN, MARGIN, MARGIN+i*GRID_SPAN, MARGIN+ROWS*GRID_SPAN); } //畫棋子 for ( int i= 0 ;i<chessCount;i++){ //網(wǎng)格交叉點(diǎn)x,y坐標(biāo) int xPos=chessList[i].getX()*GRID_SPAN+MARGIN; int yPos=chessList[i].getY()*GRID_SPAN+MARGIN; g.setColor(chessList[i].getColor()); //設(shè)置顏色 // g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, //Point.DIAMETER, Point.DIAMETER); //g.drawImage(shadows, xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER, null); colortemp=chessList[i].getColor(); if (colortemp==Color.black){ RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/ 2 + 25 , yPos-Point.DIAMETER/ 2 + 10 , 20 , new float []{0f, 1f} , new Color[]{Color.WHITE, Color.BLACK}); ((Graphics2D) g).setPaint(paint); ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT); } else if (colortemp==Color.white){ RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/ 2 + 25 , yPos-Point.DIAMETER/ 2 + 10 , 70 , new float []{0f, 1f} , new Color[]{Color.WHITE, Color.BLACK}); ((Graphics2D) g).setPaint(paint); ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT); } Ellipse2D e = new Ellipse2D.Float(xPos-Point.DIAMETER/ 2 , yPos-Point.DIAMETER/ 2 , 34 , 35 ); ((Graphics2D) g).fill(e); //標(biāo)記最后一個(gè)棋子的紅矩形框 if (i==chessCount- 1 ){ //如果是最后一個(gè)棋子 g.setColor(Color.red); g.drawRect(xPos-Point.DIAMETER/ 2 , yPos-Point.DIAMETER/ 2 , 34 , 35 ); } } } public void mousePressed(MouseEvent e){ //鼠標(biāo)在組件上按下時(shí)調(diào)用 //游戲結(jié)束時(shí),不再能下 if (gameOver) return ; String colorName=isBlack? "黑棋" : "白棋" ; //將鼠標(biāo)點(diǎn)擊的坐標(biāo)位置轉(zhuǎn)換成網(wǎng)格索引 xIndex=(e.getX()-MARGIN+GRID_SPAN/ 2 )/GRID_SPAN; yIndex=(e.getY()-MARGIN+GRID_SPAN/ 2 )/GRID_SPAN; //落在棋盤外不能下 if (xIndex< 0 ||xIndex>ROWS||yIndex< 0 ||yIndex>COLS) return ; //如果x,y位置已經(jīng)有棋子存在,不能下 if (findChess(xIndex,yIndex)) return ; //可以進(jìn)行時(shí)的處理 Point ch= new Point(xIndex,yIndex,isBlack?Color.black:Color.white); chessList[chessCount++]=ch; repaint(); //通知系統(tǒng)重新繪制 //如果勝出則給出提示信息,不能繼續(xù)下棋 if (isWin()){ String msg=String.format( "恭喜,%s贏了!" , colorName); JOptionPane.showMessageDialog( this , msg); gameOver= true ; } isBlack=!isBlack; } //覆蓋mouseListener的方法 public void mouseClicked(MouseEvent e){ //鼠標(biāo)按鍵在組件上單擊時(shí)調(diào)用 } public void mouseEntered(MouseEvent e){ //鼠標(biāo)進(jìn)入到組件上時(shí)調(diào)用 } public void mouseExited(MouseEvent e){ //鼠標(biāo)離開組件時(shí)調(diào)用 } public void mouseReleased(MouseEvent e){ //鼠標(biāo)按鈕在組件上釋放時(shí)調(diào)用 } //在棋子數(shù)組中查找是否有索引為x,y的棋子存在 private boolean findChess( int x, int y){ for (Point c:chessList){ if (c!= null &&c.getX()==x&&c.getY()==y) return true ; } return false ; } private boolean isWin(){ int continueCount= 1 ; //連續(xù)棋子的個(gè)數(shù) //橫向向西尋找 for ( int x=xIndex- 1 ;x>= 0 ;x--){ Color c=isBlack?Color.black:Color.white; if (getChess(x,yIndex,c)!= null ){ continueCount++; } else break ; } //橫向向東尋找 for ( int x=xIndex+ 1 ;x<=COLS;x++){ Color c=isBlack?Color.black:Color.white; if (getChess(x,yIndex,c)!= null ){ continueCount++; } else break ; } if (continueCount>= 5 ){ return true ; } else continueCount= 1 ; //繼續(xù)另一種搜索縱向 //向上搜索 for ( int y=yIndex- 1 ;y>= 0 ;y--){ Color c=isBlack?Color.black:Color.white; if (getChess(xIndex,y,c)!= null ){ continueCount++; } else break ; } //縱向向下尋找 for ( int y=yIndex+ 1 ;y<=ROWS;y++){ Color c=isBlack?Color.black:Color.white; if (getChess(xIndex,y,c)!= null ) continueCount++; else break ; } if (continueCount>= 5 ) return true ; else continueCount= 1 ; //繼續(xù)另一種情況的搜索:斜向 //東北尋找 for ( int x=xIndex+ 1 ,y=yIndex- 1 ;y>= 0 &&x<=COLS;x++,y--){ Color c=isBlack?Color.black:Color.white; if (getChess(x,y,c)!= null ){ continueCount++; } else break ; } //西南尋找 for ( int x=xIndex- 1 ,y=yIndex+ 1 ;x>= 0 &&y<=ROWS;x--,y++){ Color c=isBlack?Color.black:Color.white; if (getChess(x,y,c)!= null ){ continueCount++; } else break ; } if (continueCount>= 5 ) return true ; else continueCount= 1 ; //繼續(xù)另一種情況的搜索:斜向 //西北尋找 for ( int x=xIndex- 1 ,y=yIndex- 1 ;x>= 0 &&y>= 0 ;x--,y--){ Color c=isBlack?Color.black:Color.white; if (getChess(x,y,c)!= null ) continueCount++; else break ; } //東南尋找 for ( int x=xIndex+ 1 ,y=yIndex+ 1 ;x<=COLS&&y<=ROWS;x++,y++){ Color c=isBlack?Color.black:Color.white; if (getChess(x,y,c)!= null ) continueCount++; else break ; } if (continueCount>= 5 ) return true ; else continueCount= 1 ; return false ; } private Point getChess( int xIndex, int yIndex,Color color){ for (Point p:chessList){ if (p!= null &&p.getX()==xIndex&&p.getY()==yIndex &&p.getColor()==color) return p; } return null ; } public void restartGame(){ //清除棋子 for ( int i= 0 ;i<chessList.length;i++){ chessList[i]= null ; } //恢復(fù)游戲相關(guān)的變量值 isBlack= true ; gameOver= false ; //游戲是否結(jié)束 chessCount = 0 ; //當(dāng)前棋盤棋子個(gè)數(shù) repaint(); } //悔棋 public void goback(){ if (chessCount== 0 ) return ; chessList[chessCount- 1 ]= null ; chessCount--; if (chessCount> 0 ){ xIndex=chessList[chessCount- 1 ].getX(); yIndex=chessList[chessCount- 1 ].getY(); } isBlack=!isBlack; repaint(); } //矩形Dimension public Dimension getPreferredSize(){ return new Dimension(MARGIN* 2 +GRID_SPAN*COLS,MARGIN* 2 +GRID_SPAN*ROWS); } } |
2.棋子類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package cn.edu.ouc.fiveChess; import java.awt.Color; /** * 棋子類 */ public class Point { private int x; //棋盤中的x索引 private int y; //棋盤中的y索引 private Color color; //顏色 public static final int DIAMETER= 30 ; //直徑 public Point( int x, int y,Color color){ this .x=x; this .y=y; this .color=color; } public int getX(){ //拿到棋盤中x的索引 return x; } public int getY(){ return y; } public Color getColor(){ //獲得棋子的顏色 return color; } } |
3.五子棋主框架類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package cn.edu.ouc.fiveChess; import java.awt.event.*; import java.awt.*; import javax.swing.*; /* 五子棋主框架類,程序啟動(dòng)類 */ public class StartChessJFrame extends JFrame { private ChessBoard chessBoard; private JPanel toolbar; private JButton startButton,backButton,exitButton; private JMenuBar menuBar; private JMenu sysMenu; private JMenuItem startMenuItem,exitMenuItem,backMenuItem; //重新開始,退出,和悔棋菜單項(xiàng) public StartChessJFrame(){ setTitle( "單機(jī)版五子棋" ); //設(shè)置標(biāo)題 chessBoard= new ChessBoard(); Container contentPane=getContentPane(); contentPane.add(chessBoard); chessBoard.setOpaque( true ); //創(chuàng)建和添加菜單 menuBar = new JMenuBar(); //初始化菜單欄 sysMenu= new JMenu( "系統(tǒng)" ); //初始化菜單 //初始化菜單項(xiàng) startMenuItem= new JMenuItem( "重新開始" ); exitMenuItem = new JMenuItem( "退出" ); backMenuItem = new JMenuItem( "悔棋" ); //將三個(gè)菜單項(xiàng)添加到菜單上 sysMenu.add(startMenuItem); sysMenu.add(exitMenuItem); sysMenu.add(backMenuItem); //初始化按鈕事件監(jiān)聽器內(nèi)部類 MyItemListener lis= new MyItemListener(); //將三個(gè)菜單注冊(cè)到事件監(jiān)聽器上 this .startMenuItem.addActionListener(lis); backMenuItem.addActionListener(lis); exitMenuItem.addActionListener(lis); menuBar.add(sysMenu); //將系統(tǒng)菜單添加到菜單欄上 setJMenuBar(menuBar); //將menuBar設(shè)置為菜單欄 toolbar= new JPanel(); //工具面板實(shí)例化 //三個(gè)按鈕初始化 startButton= new JButton( "重新開始" ); exitButton= new JButton( "退出" ); backButton= new JButton( "悔棋" ); //將工具面板按鈕用FlowLayout布局 toolbar.setLayout( new FlowLayout(FlowLayout.LEFT)); //將三個(gè)按鈕添加到工具面板 toolbar.add(startButton); toolbar.add(exitButton); toolbar.add(backButton); //將三個(gè)按鈕注冊(cè)監(jiān)聽事件 startButton.addActionListener(lis); exitButton.addActionListener(lis); backButton.addActionListener(lis); //將工具面板布局到界面”南方“也就是下方 add(toolbar,BorderLayout.SOUTH); add(chessBoard); //將面板對(duì)象添加到窗體上 //設(shè)置界面關(guān)閉事件 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //setSize(800,800); pack(); //自適應(yīng)大小 } private class MyItemListener implements ActionListener{ public void actionPerformed(ActionEvent e){ Object obj=e.getSource(); //獲得事件源 if (obj==StartChessJFrame. this .startMenuItem||obj==startButton){ //重新開始 //JFiveFrame.this內(nèi)部類引用外部類 System.out.println( "重新開始" ); chessBoard.restartGame(); } else if (obj==exitMenuItem||obj==exitButton) System.exit( 0 ); else if (obj==backMenuItem||obj==backButton){ System.out.println( "悔棋..." ); chessBoard.goback(); } } } public static void main(String[] args){ StartChessJFrame f= new StartChessJFrame(); //創(chuàng)建主框架 f.setVisible( true ); //顯示主框架 } } |
三、總結(jié)
1.菜單的設(shè)計(jì)與實(shí)現(xiàn)?
2.鼠標(biāo)點(diǎn)擊棋盤后,如何繪制棋子?如何為剛下的棋子繪制一個(gè)紅色框?
3.棋譜是如何一個(gè)數(shù)據(jù)結(jié)構(gòu)?
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)java程序設(shè)計(jì)有所幫助。