十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇内容主要讲解“java怎么实现单机版五子棋游戏的教程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java怎么实现单机版五子棋游戏的教程”吧!
成都创新互联公司专注于企业成都全网营销推广、网站重做改版、钟楼网站定制设计、自适应品牌网站建设、H5技术、商城系统网站开发、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为钟楼等各大城市提供网站开发制作服务。
Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序。
这个小游戏是我和我姐们儿的JAVA课程设计,也是我做的第一个JAVA项目,适合初学者,希望能帮到那些被JAVA课设所困扰的孩纸们~~~
一、该游戏需要实现
1、设计主框架,界面。
2、利用ActionListener接口实现按钮事件的监听。
3、重新开始功能的实现。
4、悔棋功能的实现。
5、退出功能的实现。
6、棋盘中棋子点类的定义。
7、利用MouseListener接口实现事件监听,并实现接口里的所有方法。
8、当鼠标移动到棋盘上的交点上,且该点上无棋子时能够变成小手形状。
9、点击棋盘时,利用if语句判断该点是否点在交点上,并利用foreach语句和棋子类中的getX(),getY()方法遍历每一个棋子的位置判断该点是否有棋子。
10、当判断到可以在所点击的点上下子时,画棋子时利用for循环遍历已有的每一个点并利用Graphics类的setColor设置颜色,利用Graphics类的fillOval方法设置形状大小。
11、当画完棋子时要及时判断输赢,用棋子所在索引和for循环遍历最后一个棋子的各个方向,如果有在同一条直线上的棋子个数大于等于五的即当前棋子所代表的那方赢。
12、胜负已定的时候,能够弹出相应的信息。
二、功能代码实现
2.1进入游戏
public static void main(String[] args) { StartChessJFrame f=new StartChessJFrame();//创建主框架 f.setVisible(true);//显示主框架 }
2.2初始化,定义一些要用到的量。
private ChessBoard chessBoard;//对战面板 private Panel toolbar;//工具条面板 private Button startButton;//设置开始按钮 private Button backButton;//设置悔棋按钮 private Button exitButton;//设置退出按钮
2.3界面的构造方法(游戏的框架)
public StartChessJFrame(){ setTitle("单机版五子棋");//设置标题 chessBoard=new ChessBoard();//初始化面板对象,创建和添加菜单 MyItemListener lis=new MyItemListener();//初始化按钮事件监听器内部类 toolbar=new Panel();//工具面板栏实例化 startButton=new Button("重新开始"); backButton=new Button("悔棋"); exitButton=new Button("退出");//三个按钮初始化 toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));//将工具面板按钮用FlowLayout布局 toolbar.add(backButton); toolbar.add(startButton); toolbar.add(exitButton);//将三个按钮添加到工具面板上 startButton.addActionListener(lis); backButton.addActionListener(lis); exitButton.addActionListener(lis);//将三个按钮事件注册监听事件 add(toolbar,BorderLayout.SOUTH);//将工具面板布局到界面南方也就是下面 add(chessBoard);//将面板对象添加到窗体上 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置界面关闭事件 pack();//自适应大小 }
2.4按钮的实现与监听(构造方法内部)
MyItemListener lis=new MyItemListener();//初始化按钮事件监听器内部类 toolbar=new Panel();//工具面板栏实例化 startButton=new Button("重新开始"); backButton=new Button("悔棋"); exitButton=new Button("退出");//三个按钮初始化 toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));//将工具面板按钮用FlowLayout布局 toolbar.add(backButton); toolbar.add(startButton); toolbar.add(exitButton);//将三个按钮添加到工具面板上 startButton.addActionListener(lis); backButton.addActionListener(lis); exitButton.addActionListener(lis);//将三个按钮事件注册监听事件
2.5按钮事件的监听
private class MyItemListener implements ActionListener{ public void actionPerformed(ActionEvent e) { Object obj=e.getSource();//获取事件源 if(obj==startButton){ System.out.println("重新开始...");//重新开始 //JFiveFrame.this内部类引用外部类 chessBoard.restartGame(); }else if(obj==exitButton){ System.exit(0);//结束应用程序 }else if(obj==backButton){ System.out.println("悔棋...");//悔棋 chessBoard.goback(); } } }
2.6重新开始按钮的功能实现
public void restartGame(){//清除棋子 for(int i=0;i2.7悔棋按钮的功能实现
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(); } isBack=!isBack; repaint(); }2.8当棋盘根据需要变大或变小时窗口应随之发生改变
//Dimension:矩形ChessBoard类内部 public Dimension getPreferredSize(){ return new Dimension(MARGIN*2+GRID_SPAN*COLS,MARGIN*2+GRID_SPAN*ROWS); } pack();//自适应大小StartChessBoard类内部2.9定义棋子类
import java.awt.*; public class Point { private int x;//棋子在棋盘中的x索引值 private int y;//棋子在棋盘中的y索引值 private Color color;//颜色 public static int DIAMETER=30;//直径 public Point(int x,int y,Color color){ this.x=x; this.y=y; this.color=color; } //得到棋子在棋盘中的x索引值 public int getX(){ return x; } //得到棋子在棋盘中的y索引值 public int getY(){ return y; } //得到棋子颜色 public Color getColor(){ return color; } }三、功能部分代码实现
3.1初始化,定义一些要用到的量。
public static int MARGIN=30;//边距 public static int GRID_SPAN=35;//网格间距 public static int ROWS=18;//棋盘行数 public static int COLS=18;//棋盘列数 Point[] chessList=new Point[(ROWS+1)*(COLS+1)];//初始化每个数组元素为null boolean isBack=true;//默认开始是黑棋先下 boolean gameOver=false;//游戏是否结束 int chessCount;//当前棋盘的棋子个数 int xIndex,yIndex;//当前刚下棋子的索引3.2棋盘对象的构造方法
public ChessBoard(){ setBackground(Color.LIGHT_GRAY);//设置背景颜色为灰色 addMouseListener(this);//添加事件监听器 addMouseMotionListener(new MouseMotionListener() {//匿名内部类 @Override public void mouseMoved(MouseEvent e) { int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN; int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;//将鼠标单击的坐标位置转化为网格索引 if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1)){//游戏已经结束,不能下;落在棋盘外,不能下;x,y位置已经有棋子存在,不能下 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));//设置成默认形状 }else{ setCursor(new Cursor(Cursor.HAND_CURSOR));//设置成手型 } } @Override public void mouseDragged(MouseEvent e) { } }); }3.3设置鼠标监听器,变小手(在构造方法内部)
addMouseMotionListener(new MouseMotionListener() {//匿名内部类 @Override public void mouseMoved(MouseEvent e) { int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN; int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;//将鼠标单击的坐标位置转化为网格索引 if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1)){//游戏已经结束,不能下;落在棋盘外,不能下;x,y位置已经有棋子存在,不能下 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));//设置成默认形状 }else{ setCursor(new Cursor(Cursor.HAND_CURSOR));//设置成手型 } } @Override public void mouseDragged(MouseEvent e) { } });3.4点击棋盘时的鼠标按压事件
public void mousePressed(MouseEvent e) {//鼠标按键在组件上按下时调用 if(gameOver)//游戏已经结束,不能下 return ; String colorName=isBack ? "黑棋" : "白棋"; 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 ; if(findChess(xIndex,yIndex))//x,y位置已经有棋子存在,不能下 return ; Point ch=new Point(xIndex,yIndex,isBack ? Color.black : Color.white); chessList[chessCount++]=ch; repaint();//通知系统重新绘制 if(isWin()){ String msg=String.format("恭喜,%s赢啦~", colorName); JOptionPane.showMessageDialog(this, msg); gameOver=true; } else if(chessCount==(COLS+1)*(ROWS+1)) { String msg=String.format("棋鼓相当,棒棒哒~"); JOptionPane.showMessageDialog(this,msg); gameOver=true; } isBack=!isBack; }3.5绘制棋盘,棋子还有红框框
public void paintComponent(Graphics g){ super.paintComponent(g);//画棋盘 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;i3.6判断输赢
/*判断哪方赢*/ private boolean isWin(){ int continueCount=1;//连续棋子的个数 for(int x=xIndex-1;x>=0;x--){//横向向左寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,yIndex,c)!=null){ continueCount++; }else break; } for(int x=xIndex+1;x<=ROWS;x++){//横向向右寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,yIndex,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int y=yIndex-1;y>=0;y--){//纵向向上寻找 Color c=isBack ? Color.black : Color.white; if(getChess(xIndex,y,c)!=null){ continueCount++; }else break; } for(int y=yIndex+1;y<=ROWS;y++){//纵向向下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(xIndex,y,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int x=xIndex+1,y=yIndex-1;y>=0&&x<=COLS;x++,y--){//右下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } for(int x=xIndex-1,y=yIndex+1;y<=ROWS&&x>=0;x--,y++){//左上寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int x=xIndex-1,y=yIndex-1;y>=0&&x>=0;x--,y--){//左下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } for(int x=xIndex+1,y=yIndex+1;y<=ROWS&&x<=COLS;x++,y++){//右上寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; return false; }3.7弹出相应消息框(在鼠标按压函数内部)
if(isWin()){ String msg=String.format("恭喜,%s赢啦~", colorName); JOptionPane.showMessageDialog(this, msg); gameOver=true; } else if(chessCount==(COLS+1)*(ROWS+1))//平局 { String msg=String.format("棋鼓相当,棒棒哒~"); JOptionPane.showMessageDialog(this,msg); gameOver=true; }3.8上面用到的一个判断某点是否有棋子的函数
private boolean findChess(int x,int y){ for(Point c:chessList){ if(c!=null&&c.getX()==x&&c.getY()==y) return true; } return false; }3.9因为该棋盘类实现了鼠标监听接口MonseListener,所以要重写该接口内的所有方法,其它方法如下
@Override public void mouseClicked(MouseEvent e) {//鼠标按键在组件上单击(按下并释放)时调用 } @Override public void mouseReleased(MouseEvent e) {////鼠标按键在组件上释放时调用 } @Override public void mouseEntered(MouseEvent e) {//鼠标进入组件时调用 } @Override public void mouseExited(MouseEvent e){//鼠标离开组件时调用 }四、运行结果
五、代码汇总
该游戏总共建了三个类,一个是界面StartChessJFrame,一个是棋盘类ChessBoard,一个是棋子类Point
5.1StartChessJFrame类
package chess.lcc.com; import javax.swing.*; import java.awt.event.*; import java.awt.*; /* * 五子棋的主框架,程序启动类 */ public class StartChessJFrame extends JFrame { private ChessBoard chessBoard;//对战面板 private Panel toolbar;//工具条面板 private Button startButton;//设置开始按钮 private Button backButton;//设置悔棋按钮 private Button exitButton;//设置退出按钮 public StartChessJFrame(){ setTitle("单机版五子棋");//设置标题 chessBoard=new ChessBoard();//初始化面板对象,创建和添加菜单 MyItemListener lis=new MyItemListener();//初始化按钮事件监听器内部类 toolbar=new Panel();//工具面板栏实例化 startButton=new Button("重新开始"); backButton=new Button("悔棋"); exitButton=new Button("退出");//三个按钮初始化 toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));//将工具面板按钮用FlowLayout布局 toolbar.add(backButton); toolbar.add(startButton); toolbar.add(exitButton);//将三个按钮添加到工具面板上 startButton.addActionListener(lis); backButton.addActionListener(lis); exitButton.addActionListener(lis);//将三个按钮事件注册监听事件 add(toolbar,BorderLayout.SOUTH);//将工具面板布局到界面南方也就是下面 add(chessBoard);//将面板对象添加到窗体上 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置界面关闭事件 pack();//自适应大小 } private class MyItemListener implements ActionListener{ public void actionPerformed(ActionEvent e) { Object obj=e.getSource();//获取事件源 if(obj==startButton){ System.out.println("重新开始...");//重新开始 //JFiveFrame.this内部类引用外部类 chessBoard.restartGame(); }else if(obj==exitButton){ System.exit(0);//结束应用程序 }else if(obj==backButton){ System.out.println("悔棋...");//悔棋 chessBoard.goback(); } } } public static void main(String[] args) { StartChessJFrame f=new StartChessJFrame();//创建主框架 f.setVisible(true);//显示主框架 } }5.2ChessBoard类
package chess.lcc.com; import javax.swing.*; import java.awt.*; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseEvent; /*五子棋-棋盘类*/ public class ChessBoard extends JPanel implements MouseListener{ public static int MARGIN=30;//边距 public static int GRID_SPAN=35;//网格间距 public static int ROWS=15;//棋盘行数 public static int COLS=15;//棋盘列数 Point[] chessList=new Point[(ROWS+1)*(COLS+1)];//初始化每个数组元素为null boolean isBack=true;//默认开始是黑棋先下 boolean gameOver=false;//游戏是否结束 int chessCount;//当前棋盘的棋子个数 int xIndex,yIndex;//当前刚下棋子的索引 public ChessBoard(){ setBackground(Color.LIGHT_GRAY);//设置背景颜色为黄色 addMouseListener(this);//添加事件监听器 addMouseMotionListener(new MouseMotionListener() {//匿名内部类 @Override public void mouseMoved(MouseEvent e) { int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN; int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;//将鼠标单击的坐标位置转化为网格索引 if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1)){//游戏已经结束,不能下;落在棋盘外,不能下;x,y位置已经有棋子存在,不能下 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));//设置成默认形状 }else{ setCursor(new Cursor(Cursor.HAND_CURSOR));//设置成手型 } } @Override public void mouseDragged(MouseEvent e) { } }); } /*绘制*/ public void paintComponent(Graphics g){ super.paintComponent(g);//画棋盘 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;iROWS||yIndex<0||yIndex>COLS)//棋子落在棋盘外,不能下 return ; if(findChess(xIndex,yIndex))//x,y位置已经有棋子存在,不能下 return ; Point ch=new Point(xIndex,yIndex,isBack ? Color.black : Color.white); chessList[chessCount++]=ch; repaint();//通知系统重新绘制 if(isWin()){ String msg=String.format("恭喜,%s赢啦~", colorName); JOptionPane.showMessageDialog(this, msg); gameOver=true; } else if(chessCount==(COLS+1)*(ROWS+1)) { String msg=String.format("棋鼓相当,棒棒哒~"); JOptionPane.showMessageDialog(this,msg); gameOver=true; } isBack=!isBack; } @Override public void mouseClicked(MouseEvent e) {//鼠标按键在组件上单击(按下并释放)时调用 } @Override public void mouseReleased(MouseEvent e) {////鼠标按键在组件上释放时调用 } @Override public void mouseEntered(MouseEvent e) {//鼠标进入组件时调用 } @Override public void mouseExited(MouseEvent e){//鼠标离开组件时调用 } 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;//连续棋子的个数 for(int x=xIndex-1;x>=0;x--){//横向向左寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,yIndex,c)!=null){ continueCount++; }else break; } for(int x=xIndex+1;x<=ROWS;x++){//横向向右寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,yIndex,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int y=yIndex-1;y>=0;y--){//纵向向上寻找 Color c=isBack ? Color.black : Color.white; if(getChess(xIndex,y,c)!=null){ continueCount++; }else break; } for(int y=yIndex+1;y<=ROWS;y++){//纵向向下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(xIndex,y,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int x=xIndex+1,y=yIndex-1;y>=0&&x<=COLS;x++,y--){//右下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } for(int x=xIndex-1,y=yIndex+1;y<=ROWS&&x>=0;x--,y++){//左上寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } if(continueCount>=5){//判断记录数大于等于五,即表示此方获胜 return true; }else continueCount=1; // for(int x=xIndex-1,y=yIndex-1;y>=0&&x>=0;x--,y--){//左下寻找 Color c=isBack ? Color.black : Color.white; if(getChess(x,y,c)!=null){ continueCount++; }else break; } for(int x=xIndex+1,y=yIndex+1;y<=ROWS&&x<=COLS;x++,y++){//右上寻找 Color c=isBack ? 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 c:chessList){ if(c!=null&&c.getX()==xIndex&&c.getY()==yIndex&&c.getColor()==color) return c; } return null; } public void restartGame(){//清除棋子 for(int i=0;i 0){ xIndex=chessList[chessCount-1].getX(); yIndex=chessList[chessCount-1].getY(); } isBack=!isBack; repaint(); } //Dimension:矩形 public Dimension getPreferredSize(){ return new Dimension(MARGIN*2+GRID_SPAN*COLS,MARGIN*2+GRID_SPAN*ROWS); } } 5.3Point类
package chess.lcc.com; import java.awt.*; public class Point { private int x;//棋子在棋盘中的x索引值 private int y;//棋子在棋盘中的y索引值 private Color color;//颜色 public static int DIAMETER=30;//直径 public Point(int x,int y,Color color){ this.x=x; this.y=y; this.color=color; } //得到棋子在棋盘中的x索引值 public int getX(){ return x; } //得到棋子在棋盘中的y索引值 public int getY(){ return y; } //得到棋子颜色 public Color getColor(){ return color; } }到此,相信大家对“java怎么实现单机版五子棋游戏的教程”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
文章题目:java怎么实现单机版五子棋游戏的教程
路径分享:http://shouzuofang.com/article/gpiied.html