一.此五子棋是基于java的swing开发,是单机版,源码见git:https://github.com/zhangliqingyun/FiveChess.git,先看效果图
二.功能介绍
1.首先建立程序启动类
public class MyFiveChess {
public static void main(String[] args) {
GamePanel gamePanel=new GamePanel();
}
}
2.面板主要界面包含:加载背景图片、操作文件、操作监听、画出棋格、文字提示
public GamePanel(){
this.setTitle("立增版五子棋");
this.setSize(420,420);
this.setResizable(false);
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
this.setLocation((width-300)/2,(height-300)/2);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.addMouseListener(this);
this.setVisible(true);
}
3.棋盘继承JFrame、实现鼠标监听MouseListener
public class GamePanel extends JFrame implements MouseListener {}
4.定义记录棋子的二维坐标、落子标识等信息
//保存鼠标点击的当前坐标
int x=0,y=0;
//保存所有下过的棋子,1表示黑子,2表示白子,0表示没有棋子
int[][] allChess=new int[16][16];
boolean isOver=false;
//定义一个标记用于记录是否是黑方
boolean isBlack=true;
String blackTime="无限制";
String whiteTime="无限制";
//提示信息
String message="黑方时间";
//记录当前保存进二维数组的棋子的x和y
int x1,y1;
5.重写paint画图方法
public void paint(Graphics g) {
BufferedImage image=null;
try {
image= ImageIO.read(getClass().getClassLoader().getResource("./cn/qingyun/img/fivechess-backage.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
g.drawImage(image,0,20,this);
//双缓冲技术防止屏幕闪烁
BufferedImage bi=new BufferedImage(420,420,BufferedImage.TYPE_INT_ARGB);
Graphics g2=bi.createGraphics();
g2.setFont(new Font("黑体",25,25));
g2.setColor(Color.black);
g2.drawString("提示信息:",6,60);
g2.drawString(message, 128, 60);
g2.drawRect(14, 380,130, 30);
g2.drawRect(180,380,130,30);
g2.setFont(new Font("黑体",13,13));
g2.drawString("黑方时间:"+blackTime, 18, 400);
g2.drawString("白方时间:"+whiteTime, 183, 400);
g2.setFont(new Font("宋体",35,35));
g2.setColor(Color.blue);
g2.drawString("悔棋", 330, 380);
g2.drawString("新局", 330, 100);
g2.drawString("关于", 330, 210);
g2.drawString("退出", 330, 325);
g2.drawString("认输", 330, 265);
g2.drawString("让子", 330, 155);
g2.setColor(Color.black);
for(int i=0;i<16;i++){//画出棋盘格子线
g2.drawLine(13,72+20*i,313,72+20*i);
g2.drawLine(13+20*i,72, 13+20*i, 372);
}
g2.fillOval(170, 230, 6, 6);
g2.fillOval(170, 110, 6, 6);
g2.fillOval(170, 350, 6, 6);
g2.fillOval(50, 230, 6, 6);
g2.fillOval(290, 230, 6, 6);
g2.fillOval(290, 350, 6, 6);
g2.fillOval(290, 110, 6, 6);
g2.fillOval(50, 350, 6, 6);
g2.fillOval(50, 110, 6, 6);
//g.fillOval(x,y,10,10);
//循环显示输出所有的棋子
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
if(allChess[i][j]==1){//黑子
int tempX=i*20+13;
int tempY=j*20+72;
g2.fillOval(tempX-7, tempY-7, 14, 14);
}
else if(allChess[i][j]==2){//白子
int tempX2=i*20+13;
int tempY2=j*20+74;
g2.setColor(Color.white);
g2.fillOval(tempX2-7, tempY2-7, 14, 14);
g2.setColor(Color.black);
g2.drawOval(tempX2-7, tempY2-7,14, 14);
}
}
}
g.drawImage(bi,0,0,this);
}
6.实现鼠标监听方法
//鼠标点击的监听
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("鼠标点击事件");
}
//鼠标进入的监听
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("鼠标进入");
}
//鼠标离开的监听
@Override
public void mouseExited(MouseEvent e) {
System.out.println("鼠标离开");
}
//鼠标按下的监听
@Override
public void mousePressed(MouseEvent e) {
if(!isOver){
x=e.getX();
y=e.getY();
//开始一局新游戏
if(x>=332&&x<=395&&y>=72&&y<=107){
int newGame=JOptionPane.showConfirmDialog(this, "开始一局新游戏?");
if(newGame==0){
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
allChess[i][j]=0;
isOver=false;
isBlack=true;
message="黑方时间";
this.repaint();
}
}
}
}
//关于
if(x>=334&&x<=400&&y>=184&&y<=215){
JOptionPane.showMessageDialog(this, "这是一个五子棋,五个连成一起就算赢,立增版五子棋,详询请咨询立增");
}
//退出
if(x>=336&&x<=398&&y>=304&&y<=330){
int exit=JOptionPane.showConfirmDialog(this,"确定退出吗?");
if(exit==0){
System.exit(0);
}
}
//认输
if(x>=337&&x<=398&&y>=240&&y<=269){
int loseWin=JOptionPane.showConfirmDialog(this,"确定认输吗?");
if(loseWin==0){
if(isBlack){
JOptionPane.showMessageDialog(this, "白方胜!黑方认输");
}
else{
JOptionPane.showMessageDialog(this, "黑方胜!白方认输");
}
}
}
//设置
if(x>=334&&x<=402&&y>=131&&y<=160){
if(isBlack){
int rangZi=JOptionPane.showConfirmDialog(this, "白方确定让一个子?");
if(rangZi==0){
rangZi();
this.repaint();
}
}else{
int rangZi=JOptionPane.showConfirmDialog(this, "黑方确定让一个子?");
if(rangZi==0){
rangZi();
this.repaint();
}
}
}
//悔棋
if(x>=335&&x<=400&&y>=350&&y<=384)
{
int huiqi=JOptionPane.showConfirmDialog(this, "要悔棋吗?");
if(huiqi==0){
this.destoryQi();
this.repaint();
}
}
if(x>=13&&x<=313&&y>=72&&y<=372){//棋盘范围内
x=(x-13)/20;//取接近的点
y=(y-72)/20;
if(allChess[x][y]==0){
if(isBlack){//是否是黑方
x1=x;
y1=y;
allChess[x][y]=1;
isBlack=false;
message="白方时间";
}else{
x1=x;
y1=y;
allChess[x][y]=2;//存进去
isBlack=true;
message="黑方时间";
}
}else{
JOptionPane.showMessageDialog(this, "当前位置已有棋子,请重新下棋子");
}
this.repaint();//重新绘制图形
this.lieBlackWin();
this.hangWhiteWin();
this.xiayouBlackWin();
this.shangyouBlackWin();
}
System.out.println("按下的x:"+x+"----Y:"+y);
System.out.println("鼠标按下");
}else{
int a=JOptionPane.showConfirmDialog(this, "游戏已结束,是否重新开始?");
if(a==0){
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
allChess[i][j]=0;
isOver=false;
message="黑方时间";
this.repaint();
}
}
}
}
}
7.让子方法实现逻辑:使用x1、y1记录最近点击的坐标,移除此坐标
//让子
public void rangZi(){
allChess[x1][y1]=0;
}
8.悔棋逻辑:根据当前是白方还是黑方落子移除最近落子的坐标
//悔棋操作
public void destoryQi(){
//当时黑方时间时悔棋,悔的棋是白子,所以下一步还是黑方下子,把提示信息也更改
if(isBlack){
isBlack=false;
message="白方时间";
}else{
message="黑方时间";
isBlack=true;
}
allChess[x1][y1]=0;
}
9.每次落完子都需要判断一下是否有五子已经连成线,判断逻辑:以当前棋子为中心,判断竖的方向是否有五子相连、横向是否有五子相连、左上和右下是否有五子相连、坐下和右上是否有五子相连,有则根据落子标识提示赢得一方
//判断是否列向有5个棋子
private void hangWhiteWin(){
int count=1;
int color=allChess[x][y];
int i=1;
while(color==allChess[x-i][y]){
i++;
count=count+1;
}
i=1;
while(color==allChess[x+i][y]){
i++;
count=count+1;
}
if(count>=5){
if(!isBlack){
JOptionPane.showMessageDialog(this, "黑方胜");
}else{
JOptionPane.showMessageDialog(this, "白方胜");
}
isOver=true;
}
}
//判断是否列向有5个棋子
private void lieBlackWin(){
int count=1;
int color=allChess[x][y];
int i=1;
while(color==allChess[x][y+i]){
i++;
count=count+1;
}
i=1;
while(color==allChess[x][y-i]){
i++;
count=count+1;
}
if(count>=5){
if(!isBlack){
JOptionPane.showMessageDialog(this, "黑方胜");
}else{
JOptionPane.showMessageDialog(this, "白方胜");
}
isOver=true;
}
}
//判断是否左下和右上有5个棋子
private void xiayouBlackWin(){
int count=1;
int color=allChess[x][y];
int i=1;
//左下
while(color==allChess[x-i][y+i]){
i++;
count=count+1;
}
i=1;
while(color==allChess[x+i][y-i]){
i++;
count=count+1;
}
if(count>=5){
if(!isBlack){
JOptionPane.showMessageDialog(this, "黑方胜");
}else{
JOptionPane.showMessageDialog(this, "白方胜");
}
isOver=true;
}
}
//判断是否左上和右下有5个棋子
private void shangyouBlackWin(){
int count=1;
int color=allChess[x][y];
int i=1;
//左上
while(color==allChess[x-i][y-i]){
i++;
count=count+1;
}
i=1;
//右下
while(color==allChess[x+i][y+i]){
i++;
count=count+1;
}
if(count>=5){
if(!isBlack){
JOptionPane.showMessageDialog(this, "黑方胜");
}else{
JOptionPane.showMessageDialog(this, "白方胜");
}
isOver=true;
}
}