想跟大家分享一下自己做的一个基于局域网的网络版的五子棋(可以留言留下邮箱我会发过去),主要是通过TCP Socket做服务端,通过服务端分发每个客户端的消息以及作出相应;客户端之间对战的时候通过UDP Socket实现,通过DatagramSocket去发送接收消息。话不多说,先上效果图(界面很丑,请多见谅):
登录界面:
登陆后玩家列表:
选中任一空闲中玩家发送对战请求:
对方接收界面:
游戏界面:
界面真的很丑,我没开玩笑。。。
好了,讲正事,整个项目过程中,主要遇到了两个问题:
1、手机模拟器能够发送却无法接收UDP包;
2、由于手机分辨率问题,导致发送的棋子位置错乱。
问题一解决方案:
一开始测试代码的时候只要需要模拟器(我用的我的手机和AS自带模拟器)接收UDP包整个项目就会崩溃,随之我也崩溃,没有任何错误提示。无奈之下只能需求博客帮助,终于苍天不负有心猿,原因是我们的android模拟器接收不到UDP数据包。知道原因就好解决了。
这里贴上一位大神的博客:android模拟器接收不到UDP数据包解决方法。
当然,由于我这里是有多个客户端,这个做法仅仅当做测试用,我的解决方法可能有效直接,就是直接用两台真机测试!简单方便!
问题二解决方案:
由于两台手机分辨率不同,而棋子落下的点的 x,y 又是以像素为单位,在这里我们看onMeasure()方法就懂了:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
width = Math.min(widthSize, heightSize);//可以看出棋盘的绘制是通过获得的最大高度(单位像素)和最大宽度两者中的较小值绘制正方形棋盘
if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
setMeasuredDimension(width, width);
}
所以会导致下棋时棋子的错乱;那既然这样的话,我们也可以通过公式:
我手机横向的像素数 / 你手机横向的像素数 = 我下棋子的 X(或Y) / 你下棋子的 X(或Y)
这样子得到的是一个转换比例,就可以将你的棋子正确的下在我的手机的棋盘上了。
剩下的遇到的问题都是一些常见的错误,这里就不贴了。但是项目还需完善,首先是平局的检测,我们只要在每一次onTouchEvent()最后判断两个存储棋子信息的List是否满了(也就是棋子占满整个棋盘的个数的一半),再去触发回调接口的方法:
/**
* 定义接口,两个方法:
* 1、onPieceDown(int x, int y):棋子落下回调方法
* 2、onGameOver():游戏结束回调方法
*/
public interface OnPieceDownListener {
void onPieceDown(int x, int y);
void onGameOver();
// 平局回调方法
// void onDeadHeat();
}
我们也可以编写一个再来一局的方法,主要就是询问对方是否再来一局,是则清空所有内容,包括棋盘清空、存储棋子信息的List清空等等。。。
项目的源代码我也上传到了CSDN了:Android网络版五子棋
不嫌麻烦的朋友也可以留言留下自己的邮箱,我会将整个项目的压缩包发送给你。欢迎有问题随时赐教。