前言
之前我们已经完成了一个有房间的五指棋游戏,现在我们将进一步来完善这个东西。这一次我们打算新增的功能有:
- 之前我们增加了房间,但并没有限制房间只能进入2个人
- 增加一个守护线程,统计当前房间的数量,后面我们将继续完善这个守护线程的功能。
- 展示上一个棋子落在何处
- 离开房间后会减少房间的人数,并回收房间
思考
第一个功能应该是发生在建立连接的时候,如果房间里超过2人,则返回前端一个错误。
第二个我们需要创建一个新的线程。
第三个是一个纯粹的前端开发工作,我们可以新增两个图片,并每次标记上一次的位置,当下一个子的时候,画一个特殊的子,并用一张normal的子覆盖上一个子。
第四个是发生在断开连接的时候。
实现
第一个功能。
Room room = roomMap.get(roomId);
if (room.enterRoom(session)){
session.getUserProperties().put("roomId", roomId);
}else{
Result result = new Result();
result.setSuccess(false);
result.setErrMsg("进入房间失败");
session.getBasicRemote().sendText(new Gson().toJson(result));
}
只要在进入房间失败的时候返回一个错误信息给前端即可。当然前端也要处理这个错误信息咯。
第二个功能,创建一个简单的Deamon,我们用一个context来传入运行时的一些参数。
static {
RunContext context = new RunContext(roomMap);
DeamonThread deamonThread = new DeamonThread(context);
Thread dThread = new Thread(deamonThread);
System.out.println("Create Thread");
dThread.start();
}
我们可以在DeamonThread类中实现各种功能,例如每隔30s统计房间的总数。
public void run() {
while (true){
try{
System.out.println("RoomSize is[" + runContext.getRooms().size() + "]");
Thread.sleep(30000);
}catch (Exception e){
}
}
}
第三个是一个前端功能,我们新增了两张新的图片,用last_x, last_y来表示上一个棋子落在何处。一开始我们初始化为-1。
if (x >= 0 && x < 15 && y >= 0 && y < 15) {
if (chess == 1) {
if (last_x > 0 && last_y > 0){
context.drawImage(img_b, last_x * 40 + 20, last_y * 40 + 20);
}
context.drawImage(img_w_now, x * 40 + 20, y * 40 + 20);//绘制白棋
chessData[x][y] = 1;
}
else {
if (last_x > 0 && last_y > 0){
context.drawImage(img_w, last_x * 40 + 20, last_y * 40 + 20);
}
context.drawImage(img_b_now, x * 40 + 20, y * 40 + 20);
chessData[x][y] = 2;
}
judge(x, y, chess);
last_x = x;
last_y = y;
}
第四个,前面我们提到在onClose方法中,有可选的参数Session,我们可以通过这个Session来获取到房间号。
String roomId = (String)session.getUserProperties().get("roomId");
Room room = roomMap.get(roomId);
if (room != null){
room.leaveRoom(session);
if (room.getNowNumber() <= 0){
roomMap.remove(roomId);
}
}
System.out.println("Connection closed");
PO一张图,现在的变成这样了。。。
总结
我们又往前走了一步。这一次主要都是一些功能的完善吧。后面我们对一些功能继续完善。
源代码下载地址