Java实现五子棋游戏(2.0)

网友投稿 286 2022-08-02


本文实例为大家分享了java实现五子棋游戏的具体代码,供大家参考,具体内容如下

简介

相比之前,做出了以下修改:

1.新增菜单栏,将重新开始和退出的按钮移到了菜单栏;2.可以实时显示时间(多线程);3.下棋时可以显示当前是哪一方在下棋;4.可以更改背景颜色;5.可以更改先行方(默认黑子)。

结果

完整代码

1.Frame.java(主界面)

package Gobang;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

//import java.applet.*;

//import java.net.*;

//import java.io.*;

//import javax.imageio.*;

public class Frame extends JFrame implements MouseListener,ActionListener{//JFrame的扩展类

//ImageIcon image;

//JLayeredPane layeredPane;

//JPanel jp;

/*本来想用于播放背景音乐,但是没有成功,,,先暂时放弃

File f;

URI uri;

URL url;

@SuppressWarnings("deprecation")

*/

private static final long serialVersionUID = 1L;

public JButton AdmitDefeatButton,RegretButton;//两个按钮,各有其功能。

JLabel TimeLabel;//用来显示时间

JLabel jl1,jl2,jl3;//游戏信息

Graphics g;//画笔

BufferedImage buf;

int x;//鼠标的坐标

int y;

int[][] Chess = new int[20][20]; // 保存棋子,1表示黑子,2表示白子

boolean IsBlack = true; //表示当前要下的是黑子还是白子,true表示黑子,false表示白子

boolean IsFinish = false; //表示当前游戏是否结束

int xRange;

int yRange;

int[] chessX = new int[400];//用来保存从开始到当前的所有棋子,用于悔棋;

int[] chessY = new int[400];

int countX = 0;

int countY = 0;

//菜单栏

JMenuBar menubar;

JMenu menu;

JMenu setmenu;

JMenuItem RestartItem,ExitItem,IntroItem,BackgroundItem,FirstItem;

//获取屏幕的宽度和高度

Toolkit kit = Toolkit.getDefaultToolkit();

Dimension screenSize = kit.getScreenSize();

int screenWidth = screenSize.width;

int screenHeight = screenSize.height;

public Frame() {

/*插入背景图片

//layeredPane=new JLayeredPane();

//image=new ImageIcon("F:\\JAVA\\eclipse-workspace\\Gobang\\src\\1.jpg");//随便找一张图就可以看到效果。

//jp=new JPanel();

//jp.setBounds(0,0,600,600);

//jl=new JLabel(image);

//jl.setBounds(0,0,image.getIconWidth(),image.getIconHeight());

//jp.add(jl);

//layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);

//this.setLayeredPane(layeredPane);

*/

/*音频播放部分

try {

f = new File("");

uri = f.toURI();

url = uri.toURL();

AudioClip aau;

aau = Applet.newAudioClip(url);

aau.loop(); //循环播放

} catch (Exception e)

{

e.printStackTrace();

}

*/

//设置标题、大小、排列方式等

this.setTitle("五子棋");

this.setSize(600,600);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setVisible(true);

this.setLayout(null);

int height = this.getHeight();

int width = this.getWidth();

this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);

//实时显示时间,用到多线程来实时显示。

jl1 = new JLabel("北京时间");

jl1.setLocation(430, 120);

jl1.setSize(80,20);

this.add(jl1);

TimeLabel = new JLabel();

new Thread(new Time(TimeLabel)).start();//新建一个线程

TimeLabel.setLocation(510, 120);

TimeLabel.setSize(80,20);

this.add(TimeLabel);

//显示游戏信息,当前是谁执子;

jl2 = new JLabel("游戏信息");

jl2.setLocation(430, 150);

jl2.setSize(80,20);

jl3 = new JLabel("黑方先行");

jl3.setLocation(510, 150);

jl3.setSize(80,20);

this.add(jl2);

this.add(jl3);

//设置背景颜色

this.getContentPane().setBackground(new Color(255, 239 ,213));

this.getContentPane().setVisible(true);

//设置菜单栏

menubar = new JMenuBar();//菜单栏

menu = new JMenu("游戏操作");

RestartItem = new JMenuItem("重新开始");

ExitItem = new JMenuItem("退出");

menu.add(RestartItem);

menu.add(ExitItem);

menubar.add(menu);

setmenu = new JMenu("设置");

IntroItem = new JMenuItem("游戏说明");

BackgroundItem = new JMenuItem("背景颜色");

FirstItem = new JMenuItem("先行方");

setmenu.add(IntroItem);

setmenu.add(BackgroundItem);

setmenu.add(FirstItem);

menubar.add(setmenu);

menubar.setBackground(new Color(249,205,173));

menubar.setVisible(true);

this.setJMenuBar(menubar);

//两个按钮,认输和悔棋;

AdmitDefeatButton = new JButton("认输");

AdmitDefeatButton.setSize(80,40);

AdmitDefeatButton.setLocation(120, 480);

RegretButton = new JButton("悔棋" );

RegretButton.setSize(80,40);

RegretButton.setLocation(240, 480);

this.add(AdmitDefeatButton);

this.add(RegretButton);

/*

五个按钮添加到中间容器;

panel1 = new JPanel();

panel1.setBorder(BorderFactory.createLoweredBevelBorder()); //设置边框

panel1.setLayout(new GridLayout(1,5));

panel1.add(RestartButton);

panel1.add(SetButton);

panel1.add(AdmitDefeatButton);

panel1.add(RegretButton);

panel1.add(ExitButton);

this.add(panel1);

panel1.setSize(460,30);

panel1.setLocation(0, 460);

*/

this.repaint();//表示重新绘制画布,可以自动调用paint函数;

//本类作为监听类,包括鼠标监听和按钮动作监听;

this.addMouseListener(this);

IntroItem.addActionListener(this);

BackgroundItem.addActionListener(this);

FirstItem.addActionListener(this);

RestartItem.addActionListener(this);

AdmitDefeatButton.addActionListener(this);

RegretButton.addActionListener(this);

ExitItem.addActionListener(this);

}

//画布绘制

public void paint(Graphics g)

{

if(g == null)//如果第一次绘制,新建一个图片,并且创建画布。

{

buf = new BufferedImage(450, 450, BufferedImage.TYPE_INT_RGB);

g = buf.createGraphics();

}

if(g != null)//

{

super.paint(g);//表示在原来图像的基础上,再画图

g.setColor(new Color(249,205,173));//画笔颜色调成褐色;

g.fill3DRect(20, 130, 400, 400,true);//用画笔画一个边长为400的正方形;边距为20,130

for(int i = 0; i <= 20; i++)//用画笔横竖各画19条线

{

g.setColor(Color.BLACK);//画笔颜色调为黑色;

g.drawLine(20,130+i*20,420,130+i*20);

g.drawLine(20+i*20,130,20+i*20,530);

}

}

for(int i=0; i<20; i++){

for (int j = 0; j < 20; j++) {

//画实心黑子,直径16

if(Chess[i][j] == 1){

int tempX = i*20+12;

int tempY = j*20+122;

g.setColor(Color.BLACK);

g.fillOval(tempX, tempY, 16, 16);

g.setColor(Color.BLACK);

g.drawOval(tempX, tempY, 16, 16);

}

//画实心白子,直径16

if(Chess[i][j] == 2){

int tempX = i*20+12;

int tempY = j*20+122;

g.setColor(Color.WHITE);

g.fillOval(tempX, tempY, 16, 16);

g.setColor(Color.WHITE);

g.drawOval(tempX, tempY, 16, 16);

}

}

}

g.drawImage(buf, 0, 0,this);

}

public void mousePressed(MouseEvent e) {

// TODO Auto-generated method stub

if(!IsFinish) //判断棋局是否结束

{

x = e.getX(); //获取当前鼠标点击位置

y = e.getY();

if(x >= 20 && x < 420 && y >= 130 && y<= 530)//判断鼠标是否在棋局内

{

xRange = (x-20)%20;

if(xRange > 10 && xRange < 20) //如果在交叉点的边长为10的范围内,就把棋子下在这;

{

x = (x - 20) / 20 + 1;

}

else

{

x = (x - 20) / 20;

}

yRange = (y-130)%20;

if(yRange > 10 && yRange < 20)

{

y = (y - 130) / 20 + 1;

}

else

{

y = (y - 130) / 20;

}

if(Chess[x][y] == 0) //如果该交叉点没有被下过;

{

chessX[countX++] = x; //存储当前棋子的位置;

chessY[countY++] = y;

if(jl3.getText().equals("黑方先行")) //如果是黑子

{

Chess[x][y] = 1;

IsBlack = false;

jl3.setText("白方先行");

}

else if(jl3.getText().equals("白方先行"))

{

Chess[x][y] = 2;

IsBlack = true;

jl3.setText("黑方先行");

}

this.repaint();//重新绘制画布

}

if(this.isWin())//如果下棋之后赢了,弹出对话框

{

if(Chess[x][y] == 1)

{

JOptionPane.showMessageDialog(this, "黑方胜利");

}

else

{

JOptionPane.showMessageDialog(this, "白方胜利");

}

this.IsFinish = true; //游戏结束

}

}

}

}

public boolean isWin(){

boolean flag = false;

int count = 1;

int color = Chess[x][y];

//判断横向是否有5个棋子相连

count = this.checkCount(1,0,color);

if(count >= 5){

flag = true;

}else {

//判断纵向

count = this.checkCount(0,1,color);

if(count >= 5){

flag = true;

}else {

//判断右上,左下

count = this.checkCount(1,-1,color);

if(count >= 5){

flag = true;

}else {

//判断右下,左上

count = this.checkCount(1,1,color);

if(count >= 5){

flag = true;

}

}

}

}

return flag;

}

// 检查棋盘中的五子棋是否连成五子,xChange,yChange为相对于当前棋子位置的变化量

public int checkCount(int xChange , int yChange ,int color){

int count = 1;//统计总共有几个连着的棋子;

int tempX = xChange;

int tempy = yChange;

//判断棋子右边有没有相同颜色的棋子;

while(x + xChange >=0 && x+xChange <20 && y+yChange >=0 &&

y+yChange < 20 && color == Chess[x+xChange][y+yChange])

{

count++; //如果有,棋子数加一

if(xChange != 0)

xChange++; //如果横向方向变化,x相对位置加一

if(yChange != 0 )

{

if(yChange != 0)

{

if(yChange > 0) //如果纵向方向增加,y相对位置加一

{

yChange++;

}

else //如果纵向方向减小,y相对位置减一

{

yChange--;

}

}

}

}

xChange = tempX;

yChange = tempy;

//判断棋子左边有没有相同颜色的棋子;

while(x-xChange >=0 && x-xChange <20 && y-yChange >=0 &&

y-yChange <20 && color == Chess[x-xChange][y-yChange])

{

count++;

if(xChange != 0)

{

xChange++;

}

if(yChange != 0)

{

if (yChange > 0)

{

yChange++;

}

else

{

yChange--;

}

}

}

return count;

}

//监听动作函数

//@SuppressWarnings("deprecation")

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

if(e.getActionCommand()=="重新开始")//如果点击的按钮是RestartButton,清空画板,还原设置

{

if(JOptionPane.showConfirmDialog(this, "是否重新开始游戏?") == 0)

{

for (int i = 0; i < 20; i++)

{

for (int j = 0; j < 20; j++)

{

Chess[i][j] = 0; //清空棋盘的棋子

}

}

//清空下棋棋子坐标的记录

for (int i = 0; i < 400; i++)

{

chessX[i] = 0;

chessY[i] = 0;

}

countX =0;

countY =0;

IsBlack = true;

jl3.setText("黑方先行");

IsFinish = false;

this.repaint();

}

}

if(e.getSource() == AdmitDefeatButton)//如果点击的按钮是AdmitDefeatButton,结束游戏,并提示

{

if(!IsFinish) //判断棋局是否结束

{

if(JOptionPane.showConfirmDialog(this, "是否确定认输?") == 0)

{

if(IsBlack == true)

{

JOptionPane.showMessageDialog(this,"白方获胜");

}

else

{

JOptionPane.showMessageDialog(this,"黑方获胜");

}

IsFinish = true;

}

}

}

if(e.getActionCommand()=="退出")//如果点击的按钮是ExitButton,退出程序

{

if(JOptionPane.showConfirmDialog(this, "是否确定退出?") == 0)

{

System.exit(0);

}

}

if(e.getSource() == RegretButton)///如果点击的按钮是RegretButton,悔棋一步

{

if(!IsFinish) //判断棋局是否结束

{

if(IsBlack == true) //如果现在是黑子要下,表示悔棋的是白子

{

if(JOptionPane.showConfirmDialog(this, "白方想要悔棋,是否同意?") == 0)

{

int tempX = chessX[--countX]; //获取上一步白子下的位置;

int tempY = chessY[--countY];

Chess[tempX][tempY] = 0; //撤回白子

IsBlack = false; //当前要下的变为白方

jl3.setText("白方先行");

}

}

else

{

if(JOptionPane.showConfirmDialog(this, "黑方想要悔棋?") == 0)

{

int tempX = chessX[--countX];

int tempY = chessY[--countY];

Chess[tempX][tempY] = 0;

IsBlack = true;

jl3.setText("黑方先行");

}

}

this.repaint(); //重新绘制画布

}

}

if(e.getActionCommand()=="游戏说明")

{

JDialog frame1 = new JDialog();//新建对话框

frame1.setSize(200,200);

int height = frame1.getHeight();

int width = frame1.getWidth();

frame1.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);

JTextArea ta = new JTextArea();//新建文本框

ta.setText("双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜。");

ta.setEditable(false);

jscrollPane jsp = new JScrollPane(ta);

frame1.setTitle("规则");

frame1.getContentPane().add(jsp); //添加文本框

frame1.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // 设置模式类型

frame1.setVisible(true);

}

if(e.getActionCommand()=="背景颜色")

{

JDialog frame2 = new JDialog();//新建对话框

frame2.setSize(150,200);

int height = frame2.getHeight();

int width = frame2.getWidth();

frame2.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);

frame2.setLayout(new GridLayout(3,2,10,10));

//三个文本框;

JLabel label1 = new JLabel("Red");

JLabel label2 = new JLabel("Green");

JLabel label3 = new JLabel("Blue");

JTextField tf1 = new JTextField("255");

//tf1.setSize(80, 20);

JTextField tf2 = new JTextField("239");

//tf2.setBounds(10, 40, 80, 20);

JTextField tf3 = new JTextField("213");

//tf3.setBounds(10, 70, 80, 20);

frame2.setTitle("设置背景颜色");

frame2.getContentPane().add(label1);

frame2.getContentPane().add(tf1); //

frame2.getContentPane().add(label2);

frame2.getContentPane().add(tf2);

frame2.getContentPane().add(label3);

frame2.getContentPane().add(tf3);

frame2.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // 设置模式类型

frame2.setVisible(true);

//改变背景颜色

int Red =Integer.parseInt(tf1.getText());

int Green =Integer.parseInt(tf2.getText());

int Blue =Integer.parseInt(tf3.getText());

this.getContentPane().setBackground(new Color(Red,Green,Blue));

this.repaint();

}

if(e.getActionCommand() == "先行方") {

new FirstDialog(IsBlack,jl3);//新建对话框,改变先行方

}

}

public static void main(String[] args) {

new Frame();

}

@Override

public void mouseClicked(MouseEvent e) {

// TODO Auto-generated method stub

}

@Override

public void mouseReleased(MouseEvent e) {

// TODO Auto-generated method stub

}

@Override

public void mouseEntered(MouseEvent e) {

// TODO Auto-generated method stub

}

@Override

public void mouseExited(MouseEvent e) {

// TODO Auto-generated method stub

}

}

//改变先行方

class FirstDialog extends JDialog implements ItemListener{

/**

*

*/

private static final lohttp://ng serialVersionUID = 1L;

Toolkit kit = Toolkit.getDefaultToolkit();

Dimension screenSize = kit.getScreenSize();

int screenWidth = screenSize.width;

int screenHeight = screenSize.height;

Boolean IsBlack;

JLabel jl = new JLabel();

JRadioButton rbWhite,rbBlack;

FirstDialog(Boolean IsBlack,JLabel jl)

{

this.IsBlack = IsBlack;

this.jl = jl;

this.setSize(150,200);

int height = this.getHeight();

int width = this.getWidth();

this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);

this.setTitle("先行方");

//一个单选组合;

rbWhite = new JRadioButton("白子");

rbBlack = new JRadioButton("黑子");

this.setLayout(new FlowLayout());

this.getContentPane().add(rbWhite);

this.getContentPane().add(rbBlack); //

ButtonGroup bgroup = new ButtonGroup();

bgroup.add(rbWhite);

bgroup.add(rbBlack);

//本类做监听类

rbWhite.addItemListener(this);

rbBlack.addItemListener(this);

this.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // 设置模式类型

this.setVisible(true);

}

public void itemStateChanged(ItemEvent e) {

if(rbWhite.isSelected())//选中白子时,将先行方设为白子;

{

IsBlack = false;

jl.setText("白方先行");

}

else if(rbBlack.isSelected())

{

IsBlack = true;

jl.setText("黑方先行");

}

}

}

2.Time.java(实时显示时间)

package Gobang;

import java.awt.*;

import javax.swing.*;

import java.util.*;

import java.text.*;

public class Time implements Runnable{

private JLabel lab = new JLabel();

public Time(JLabel lab) {

this.lab = lab;

}

public void run() {

while(true) {

SimpleDateFormat simpleFormat = new SimpleDateFormat("HH:mm:ss");

Calendar c = Calendar.getInstance();

lab.setText(simpleFormat.format(c.getTime()));

lab.setForeground(Color.RED);

try {

Thread.sleep(1000);

}catch(Exception e)

{

e.printStackTrace();

}

}

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java文件操作实例详解(java项目设计文档)
下一篇:全面分析Java方法的使用与递归(java递归讲解)
相关文章