Java棋类游戏实践之单机版五子棋
程序员文章站
2024-03-09 10:34:11
本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下
一、实践目标
 ...
本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下
一、实践目标
1.掌握javagui界面设计
2.掌握鼠标事件的监听(mouselistener,mousemotionlistener)
二、实践内容
设计一个简单的五子棋程序,能够实现五子棋下棋过程。如下图所示
1.五子棋棋盘类
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;//网格间距 public static final int rows=15;//棋盘行数 public static final int cols=15;//棋盘列数 point[] chesslist=new point[(rows+1)*(cols+1)];//初始每个数组元素为null boolean isblack=true;//默认开始是黑棋先 boolean gameover=false;//游戏是否结束 int chesscount;//当前棋盘棋子的个数 int xindex,yindex;//当前刚下棋子的索引 image img; image shadows; color colortemp; public chessboard(){ // setbackground(color.blue);//设置背景色为橘黄色 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; //将鼠标点击的坐标位置转成网格索引 int y1=(e.gety()-margin+grid_span/2)/grid_span; //游戏已经结束不能下 //落在棋盘外不能下 //x,y位置已经有棋子存在,不能下 if(x1<0||x1>rows||y1<0||y1>cols||gameover||findchess(x1,y1)) setcursor(new cursor(cursor.default_cursor)); //设置成默认状态 else setcursor(new cursor(cursor.hand_cursor)); } }); } //绘制 public void paintcomponent(graphics g){ super.paintcomponent(g);//画棋盘 int imgwidth= img.getwidth(this); int imgheight=img.getheight(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++){ //网格交叉点x,y坐标 int xpos=chesslist[i].getx()*grid_span+margin; int ypos=chesslist[i].gety()*grid_span+margin; g.setcolor(chesslist[i].getcolor());//设置颜色 // 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); //标记最后一个棋子的红矩形框 if(i==chesscount-1){//如果是最后一个棋子 g.setcolor(color.red); g.drawrect(xpos-point.diameter/2, ypos-point.diameter/2, 34, 35); } } } public void mousepressed(mouseevent e){//鼠标在组件上按下时调用 //游戏结束时,不再能下 if(gameover) return; string colorname=isblack?"黑棋":"白棋"; //将鼠标点击的坐标位置转换成网格索引 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位置已经有棋子存在,不能下 if(findchess(xindex,yindex))return; //可以进行时的处理 point ch=new point(xindex,yindex,isblack?color.black:color.white); chesslist[chesscount++]=ch; repaint();//通知系统重新绘制 //如果胜出则给出提示信息,不能继续下棋 if(iswin()){ string msg=string.format("恭喜,%s赢了!", colorname); joptionpane.showmessagedialog(this, msg); gameover=true; } isblack=!isblack; } //覆盖mouselistener的方法 public void mouseclicked(mouseevent e){ //鼠标按键在组件上单击时调用 } public void mouseentered(mouseevent e){ //鼠标进入到组件上时调用 } public void mouseexited(mouseevent e){ //鼠标离开组件时调用 } public void mousereleased(mouseevent e){ //鼠标按钮在组件上释放时调用 } //在棋子数组中查找是否有索引为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;//连续棋子的个数 //横向向西寻找 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; //继续另一种搜索纵向 //向上搜索 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; //继续另一种情况的搜索:斜向 //东北寻找 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; //继续另一种情况的搜索:斜向 //西北寻找 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; } //恢复游戏相关的变量值 isblack=true; gameover=false; //游戏是否结束 chesscount =0; //当前棋盘棋子个数 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.棋子类
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.五子棋主框架类
package cn.edu.ouc.fivechess; import java.awt.event.*; import java.awt.*; import javax.swing.*; /* 五子棋主框架類,程序啟動類 */ 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; //重新开始,退出,和悔棋菜单项 public startchessjframe(){ settitle("单机版五子棋");//设置标题 chessboard=new chessboard(); container contentpane=getcontentpane(); contentpane.add(chessboard); chessboard.setopaque(true); //创建和添加菜单 menubar =new jmenubar();//初始化菜单栏 sysmenu=new jmenu("系统");//初始化菜单 //初始化菜单项 startmenuitem=new jmenuitem("重新开始"); exitmenuitem =new jmenuitem("退出"); backmenuitem =new jmenuitem("悔棋"); //将三个菜单项添加到菜单上 sysmenu.add(startmenuitem); sysmenu.add(exitmenuitem); sysmenu.add(backmenuitem); //初始化按钮事件监听器内部类 myitemlistener lis=new myitemlistener(); //将三个菜单注册到事件监听器上 this.startmenuitem.addactionlistener(lis); backmenuitem.addactionlistener(lis); exitmenuitem.addactionlistener(lis); menubar.add(sysmenu);//将系统菜单添加到菜单栏上 setjmenubar(menubar);//将menubar设置为菜单栏 toolbar=new jpanel();//工具面板实例化 //三个按钮初始化 startbutton=new jbutton("重新开始"); exitbutton=new jbutton("退出"); backbutton=new jbutton("悔棋"); //将工具面板按钮用flowlayout布局 toolbar.setlayout(new flowlayout(flowlayout.left)); //将三个按钮添加到工具面板 toolbar.add(startbutton); toolbar.add(exitbutton); toolbar.add(backbutton); //将三个按钮注册监听事件 startbutton.addactionlistener(lis); exitbutton.addactionlistener(lis); backbutton.addactionlistener(lis); //将工具面板布局到界面”南方“也就是下方 add(toolbar,borderlayout.south); add(chessboard);//将面板对象添加到窗体上 //设置界面关闭事件 setdefaultcloseoperation(jframe.exit_on_close); //setsize(800,800); pack();//自适应大小 } private class myitemlistener implements actionlistener{ public void actionperformed(actionevent e){ object obj=e.getsource();//获得事件源 if(obj==startchessjframe.this.startmenuitem||obj==startbutton){ //重新开始 //jfiveframe.this内部类引用外部类 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();//创建主框架 f.setvisible(true);//显示主框架 } }
三、总结
1.菜单的设计与实现?
2.鼠标点击棋盘后,如何绘制棋子?如何为刚下的棋子绘制一个红色框?
3.棋谱是如何一个数据结构?
以上就是本文的全部内容,希望对大家学习java程序设计有所帮助。
上一篇: c# static 静态数据成员