使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网)

一,前期准备

1,Java IDE(Eclipse)与JDK的安装与配置
jdk-15.0.1-免配置路径版
提取码:earu
免安装版Eclipse 解压即可使用
提取码:5iyy

网络上很多配置jdk的方法,我不再重复
这里提供一种便捷操作的方法(针对新手)
由于高版本jdk不需要手动配置路径,将我上传的jdk资源下载后一键安装,路径即可自动配置

2,一台云主机

阿里云,腾讯云,华为云的云主机均可,我用的是windows系统
(window是自带的远程连接很方便),如果想用其他的也可,最好选择一个有桌面的,这样调试起来容易些
在云主机上同样需要安装Eclipse与配置jdk,步骤同上
如果内存较大的可以安装数据库,这样编写的程序上可以加账号登录注册功能

我的云主机

3,另一台可供测试可以联网的电脑或虚拟机

建议方便的同学用另一台电脑,一台电脑用手机热点,另一台用WiFi
这样可以测试外网的连接情况
  • 1
  • 2

4,转换Java Jar为exe文件的软件(如exe4j)

网上很多关于转换的教程(非必须,如果不需要可以忽略这一步)
  • 1

二,功能分析与效果展示
1,这个程序主要分为三部分,UI界面,单机落子部分,联网落子部分,而UI界面又分为登录界面和棋盘界面。在这篇文章中UI界面与联网落子部分为讲述重点。
2,登录界面实现的功能有以下几点,首先当启动程序时,应自动检测与服务器的连接,如果连接失败,则不出现网络登录入口,如果连接成功,则出现网络对战登录入口。

连接失败效果展示


连接成功效果展示


3,棋盘界面应满足的功能,黑白棋的落子,判断胜利,重新开始
棋盘效果展示

4,网络对战应满足的功能,由于很多电脑使用路由器与外网访问(有的通信服务提供商会隐藏真实ip,故两台由不同路由器连接的电脑很难建立连接),同时增加编写难度,采用下棋双方与服务器连接的方式,A->服务器<-B,A<-服务器->B,程序应做到迅速响应服务器信息,减少延迟,双方棋盘信息应一致。

三,具体实现方法
1,棋盘UI的实现

 JPanel jpan1 = new JPanel() {                     //根据新棋盘信息作图,覆盖原有Panel
private static final long serialVersionUID = 1L;
public void paint(Graphics graphics){ //重构paint函数
int xst=20,yst=20,add=32;
for(int t=0;t<15;t++) //画竖线
{
graphics.drawLine(xst,yst,xst,468);
xst=xst+add;
}
xst=20;yst=20;add=32;
for(int t=0;t<15;t++) //画横线
{
graphics.drawLine(xst,yst,468,yst);
yst=yst+add;
} graphics.setColor(Color.BLACK); //画棋盘上五个黑点
graphics.fillOval(113, 113, 6, 6);
graphics.fillOval(369, 113, 6, 6);
graphics.fillOval(113, 369, 6, 6);
graphics.fillOval(369, 369, 6, 6);
graphics.fillOval(241, 241, 6, 6); for(int t=0;t<15;t++) //根据棋盘数组里存储的棋子信息画黑白子
{
for(int t1=0;t1<15;t1++)
{
if(node[t][t1]==1)
{
graphics.setColor(Color.BLACK);
graphics.fillOval(t1*32+20-13,t*32+20-13,26,26);
}
if(node[t][t1]==-1)
{
graphics.setColor(Color.WHITE);
graphics.fillOval(t1*32+20-13,t*32+20-13,26,26);
}
}
}
}
}

由于每次落子棋盘都会发生变化,所以设置一个鼠标触发事件,当每次触发都将窗口重绘,根据棋盘信息数组里的内容更新到当前局面。
2,网络对战(服务器端编程)
网络对战的实质是socket编程,即客户端A将落子信息传给服务器,服务器将信息传给客户端B,接着客户端B将落子信息传给服务器,服务器传给客户端A,故在服务器端编程中应监听两个端口(我设置的是1075和1056)客户端A将信息通过1075端口传给服务器,服务器将A传过来的信息通过1056传给服务器B,默认先连接的是黑子,当黑子连接成功后,监听白子连接。

package cilent;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; public class test {
public static void main(String[] args) {
ServerSocket server,server1;
try {
server = new ServerSocket(1075);
Socket socket=server.accept();
System.out.println("black is ok");
server1 = new ServerSocket(1056);
Socket socket1=server1.accept();
System.out.println("white is ok");
while(true){
System.out.println("----------");
InputStream in,in1;
try {
in = socket.getInputStream();
byte [] b=new byte[1024];
StringBuffer sb=new StringBuffer();
String s;
if(in.read(b) !=-1){
s=new String(b);
sb.append(s);
}
OutputStream out1=socket1.getOutputStream();
System.out.println("黑发给白"+sb);
out1.write(sb.toString().getBytes());
out1.flush();
in1 = socket1.getInputStream();
byte [] b1=new byte[1024];
StringBuffer sb1=new StringBuffer();
String s1;
if(in1.read(b1) !=-1){
s1=new String(b1);
sb1.append(s1);
}
OutputStream out=socket.getOutputStream();
System.out.println("白发给黑"+sb1);
out.write(sb1.toString().getBytes());
out.flush();
} catch (IOException e) {
// e.printStackTrace();
}
} } catch (IOException e) {
e.printStackTrace();
}
} }

3,网络对战(客户端编程)
在客户端这边不仅要考虑数据的发送与接收,还要考虑接收或发送的数据在窗体上如何实时的显示,为此我自己创立了一套编码解码方式,为方便每次发送的信息的格式为XX*YY,前两位为二维数组行数,后两位为二维数组列数,发送部分代码如下

 if(xrec<=9)                        //确认发送数据格式 XX*XX XX指二维数组列,行
sent="0"+xrec;
else
sent=""+xrec;
sent=sent+"*";
if(yrec<=9)
sent=sent+"0"+yrec;
else
sent=sent+""+yrec;
System.out.println("==========");
try {
socket.getOutputStream().write(sent.getBytes());
System.out.println("MY sent:"+sent);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
socket.getOutputStream().flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} //发送完毕

由于socket的接收函数有阻塞性,当执行接收函数时,程序被阻塞,窗体无法及时更新,这样就会出现无法更新落子信息,当接收到对方落子时一次更新两个棋子的情况,为解决这个问题,将本机落子与接收落子分隔开,当鼠标按下时更新本机落子,当鼠标松开时接收服务器信息。

void jieshou(Socket socket, JFrame jFrame)
{ //temp=1;
InputStream in = null;
try {
in = socket.getInputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
JOptionPane.showMessageDialog(null,"对方未就绪!");
}
byte[] b = new byte[1024];
StringBuffer sb = new StringBuffer(); try {
if (in.read(b) != -1) {
s = new String(b);
System.out.println(s);
sb.append(s);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
JOptionPane.showMessageDialog(null,"对方未就绪!");
}
System.out.println("来自服务器的数据:" + sb); //收到对方落子信息
int xnew=(sb.charAt(0)-'0')*10+(sb.charAt(1)-'0');//解码
int ynew=(sb.charAt(3)-'0')*10+(sb.charAt(4)-'0');
if(node[xnew][ynew]==0) { //更改对方落子
node[xnew][ynew]=-1;
// m=1;
} JPanel jpan1 = new JPanel() { //根据新棋盘信息作图,覆盖原有Panel
private static final long serialVersionUID = 1L;
public void paint(Graphics graphics){
super.paint(graphics);
int xst=20,yst=20,add=32;
for(int t=0;t<15;t++)
{
graphics.drawLine(xst,yst,xst,468);
xst=xst+add;
}
xst=20;yst=20;add=32;
for(int t=0;t<15;t++)
{
graphics.drawLine(xst,yst,468,yst);
yst=yst+add;
} graphics.setColor(Color.BLACK);
graphics.fillOval(113, 113, 6, 6);
graphics.fillOval(369, 113, 6, 6);
graphics.fillOval(113, 369, 6, 6);
graphics.fillOval(369, 369, 6, 6);
graphics.fillOval(241, 241, 6, 6); for(int t=0;t<15;t++)
{
for(int t1=0;t1<15;t1++)
{
if(node[t][t1]==1)
{
graphics.setColor(Color.BLACK);
graphics.fillOval(t1*32+20-13,t*32+20-13,26,26);
}
if(node[t][t1]==-1)
{
graphics.setColor(Color.WHITE);
graphics.fillOval(t1*32+20-13,t*32+20-13,26,26);
}
}
}
}
};
jFrame.add(b1);
jFrame.add(jpan1);
jFrame.setVisible(true);
//temp=0;
}

如果有兴趣的同学也可以在服务器端加一个本地服务器(推荐SQL server)搭配jdbc实现一个客户端登录程序(类似QQ),具体如何实现我会在下节详细叙述。
有需要的可以给我留言,分享源码

使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网)的更多相关文章

  1. 用Java语言编写一个简易画板

    讲了三篇概博客的概念,今天,我们来一点实际的东西.我们来探讨一下如何用Java语言,编写一块简易的画图板. 一.需求分析 无论我们使用什么语言,去编写一个什么样的项目,我们的第一步,总是去分析这个项目 ...

  2. 第二次作业利用java语言编写计算器进行四则运算

    随着第一次作业的完成,助教 牛老师又布置了第二次作业:用java语言编写一个程序然后进行四则运算用户用键盘输入一个字符来结束程序显示统计结果.一开始看到这个题目我也着实吓了一跳 因为不知道如何下手而且 ...

  3. Fastjson是一个Java语言编写的高性能功能完善的JSON库。

    简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...

  4. Atiitt 使用java语言编写sql函数或存储过程

    Atiitt 使用java语言编写sql函数或存储过程 1.1. java编写sql函数或存储过程的机制1 1.2. Java编写sp的优点1 1.3. 支持java源码,class文件,blog f ...

  5. 使用java语言编写窗口按钮

    使用java语言编写窗口按钮 代码如下: package Day08; import java.awt.FlowLayout; import javax.swing.JButton;import ja ...

  6. 用C语言编写一个简单的词法分析程序

    问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...

  7. linux c语言编写一个shell壳

    目的:我们要用c语言编写一个shell可以运行在linux机器上的. 介绍:shell所在的层次 我们要做的是操作系统,用于用户与操作系统进行交互的myhsell 思路:用户输入  一行字符串,我们先 ...

  8. java语言写一个建议的五子棋

    经过16天的java学习,也学得了不少关于Java方面的知识,我想分享一下我用java写的一个简单的五子棋. 游戏规则: (1)对局双方各执一色棋子.(2)空棋盘开局.(3)白先.黑后,交替下子,每次 ...

  9. Java中编写一个完美的equals方法

    首先看下Java语言规范对equals方法的要求: 1,自反性,对于任何非控引用x,x.equals(x)都应该返回true. 2,对称性,对于任何引用x和y,如果x.equals(y)返回true, ...

随机推荐

  1. MacOS上Parallels Desktop安装MacOSHighSierra

    下载dmg文件 http://www.macoshome.com/macos/977.html 配置宿主机时间2015-10-27 23:25 为了防止"macOS未能安装在您的电脑上_安装 ...

  2. [SQL Server]多次为 '派生表' 指定了列 'id'

    问题: 原因: 因为派生表oo中出现了两个同样的'ID'属性,所以会报[多次为 'o' 指定了列 'ID']的错误. 只需要把第二个星号替换成所需要的列名并把重复字段重命名就好了 解决方案:

  3. jQuery无限滚动

    由于demo实在虚拟桌面写的,所以懒得在敲一遍了,直接贴图了

  4. SPFA算法优化

    前言 \(SPFA\) 通常在稀疏图中运行效率高于 \(Dijkstra\) ,但是也容易被卡. 普通的 \(SPFA\) 时间复杂度为 \(O(km)\) ,其中 \(k\) 是一条边松弛其端点点的 ...

  5. 傲视Kubernetes(二):Docker镜像搭建与本地Kubernetes环境搭建

    主要内容: 1.Docker与Kubernetes的关系 2.SpringBoot微服务的Docker镜像创建 3.Kubernetes本地环境搭建 一.Docker与Kubernetes的关系 在说 ...

  6. IOS中使用.xib文件封装一个自定义View

    1.新建一个继承UIView的自定义view,假设类名叫做 MyAppVew #import <UIKit/UIKit.h> @class MyApp; @interface MyAppV ...

  7. MetaException(message:Could not connect to meta store using any of the URIs provided. Most recent failure: org.apache.thrift.transport.TTransportException: java.net.ConnectException: 拒绝连接 (Connection

    hive在hive-site.xml中配置hive.metastore.uris属性,后启动异常 hive异常 [fan@master hive-0.13.1-cdh5.3.6]$ bin/hive ...

  8. 软件测试最常用的 SQL 命令 | 掌握基本查询、条件查询、聚合查询

    1.DML核心CRUD增删改查 缩写全称和对应 SQL: * DML 数据操纵语言:Data Manipulation Language * Create 增加:insert * Retrieve 查 ...

  9. 留心一下VS的这个调试代码的bug

    最近和同事在Debug代码时,遇到一个诡异的问题,开始以为是代码问题,分析了之后发现是VS(v16.8.3)的bug,特此分享一下,如果大家近期遇到类似的问题,不要茫然. 这个bug重现的方式是,在d ...

  10. AddressSanitizer —— ASAN分析内存错误

    简介 AddressSanitizer 是一个性能非常好的C/C++ 内存错误探测工具. 它由编译器的插桩模块和替换了malloc函数的运行时库组成. 这个工具可以探测如下这些类型的错误: 对堆.栈和 ...