前情概要:
使用SpringBoot及Construct2的WebSocket制作联机游戏(一)
一、介绍:
1、SpringBoot服务端添加登录及注册接口,并进行Postman测试
2、SpringBoot服务端WebSocket对接收数据和返回数据进行数据封装,添加Json工具类
3、Construct2客户端实现Get/Post请求并且显示返回数据
4、Construct2客户端使用JSON插件实现对Json字符串的解析和构造
二、所需资源下载地址
1、Postman https://pan.baidu.com/s/1iKt5HY0CZ3VAg400zkvzHQ t1pg
postman需要chrome(谷歌浏览器)支持,它是一款免费的接口测试工具
2、JSON插件 https://pan.baidu.com/s/1PU1wn249ZeNmrjtRENSuiw hycb
将压缩包解压到当前文件夹后,将整个json文件夹放置在Construct2安装目录下,
即D:\Construct 2\exporters\html5\plugins
三、服务端实现
1、登录功能:
登录功能的逻辑是最简单的也是最难的,我曾经栽在这个简单的面试提问上,它简单在只需要两个参数,账号密码,难的在于它要返回什么,用户对象?提示信息?返回码?Cookie?
在这里我演示的是最简单的一种实现方式,连session都没有的实现方式(使用session或者cookie可以实现是否重复登录,权限控制,记住登录状态等功能)
登录功能在这里使用Http的Post请求。
1、Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class PlayerController {
@Autowired
private PlayerService playerService;
/**
* 登录
* @param username 账号
* @param password 密码
* @return
*/
@RequestMapping(value = "/login",method = RequestMethod.POST)
public Player login(String username,String password){
Player player = playerService.login(username,password);
return player;
}
}
RestController = ResponseBody + Controller 即整个类的返回值都是以Json格式返回的
2、Service
public interface PlayerService {
/**
* 登录
* @param username
* @param password
* @return
*/
Player login(String username,String password);
}
@Service
public class PlayerServiceImpl implements PlayerService {
@Override
public Player login(String username,String password) {
return playerDao.login(username,password);
}
}
3、Dao
@Mapper
public interface PlayerDao {
@Select("select playerId,playerName,playerPwd,victory,defeated,roomId from player where
" +"playerName = #{username} and playerPwd = #{password}")
Player login(String username,String password);
}
需要注意的是,我这里的mybatis使用的是注解式的写法,想要这种写法需要写mybatis的配置类,即:
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
}
2、注册功能
简单的注册逻辑判断,只需要判断当前是否有重名用户,如果没有,添加用户,如果有,不予注册
/**
* 注册
* @param username 账号
* @param password 密码
* @return
*/
@RequestMapping(value = "/register",method = RequestMethod.POST)
public int register(String username,String password){
Player player = playerService.findByName(username);
if(player != null) return 0;
player = new Player();
player.setPlayerName(username);
player.setPlayerPwd(password);
return playerService.add(player);
}
3、使用Postman进行接口测试
1、双击安装包,直接安装,然后会在桌面上出现一个快捷方式,进行登录,账号直接使用谷歌账号即可。
2、Post请求示例:
- 名字(保存记录后会显示备注名在此)
- 请求方式,可选择下拉框
- 请求的url
- 请求头部信息
- 请求的数据类型(form-data是表单数据,raw是json格式的数据)
- key和value
- 返回的数据类型及数据
- 发送请求的按钮
3、Get请求示例:
Get请求只需要把Post改成Get,把Body改成Params就可以了
4、注册接口测试
登录接口上面例子已经显示了就不贴了。
接口测试完毕。
5、JSON工具类及数据封装
1、引入依赖
<!-- json -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
</dependency>
2、封装数据类型
/**
* 接收数据封装(客户端-->服务端)
*/
public class RequestData {
//发送玩家id
private int playerId;
//给谁 0代表全部
private int toPlayerId;
//数据
private Map<String,Object> data;
}
/**
* 返回数据封装(服务端-->客户端)
*/
public class ResponseData {
//发送人
private Player fromPlayer;
//接收人
private Player toPlayer;
//数据
private Map<String,Object> data;
}
3、Json工具类
import net.sf.json.JSONObject;
/**
* Json工具类
*/
public class JsonUtil {
/**
* 解析客户端数据转成类
* @param data
* @return
*/
public static RequestData JsonToData(String data){
JSONObject jsonObject = JSONObject.fromObject(data);
RequestData requestData = (RequestData)JSONObject.toBean(jsonObject,RequestData.class);
return requestData;
}
/**
* 将返回数据转成Json
* @param data
*/
public static String DataToJson(ResponseData data){
JSONObject jsonObject = JSONObject.fromObject(data);
String resData = jsonObject.toString();
return resData;
}
}
工具类是为WebSocket准备的,因为Http请求下SpringMVC已经帮我们封装好了。
四、客户端实现
1、Get/Post请求的实现方式
解释:
- 首先使用的是官方的插件AJAX
- 主要用的三个函数:Event的Request Url(发送Get请求)和Post Url(发送Post请求),Action的On Completed(接收返回结果);使用变量:AJAX.LastData(返回结果)
- 如果返回值为空时,Log没有显示,因为返回的空值其实被视为空字符串,即"",所以需要使用System插件中的Compare Two Values对返回结果进行做判空操作
显示结果:
业务实现完毕。
提供工程资源: https://pan.baidu.com/s/1kF3nnINnWHN0yvRhadCZzA 6vqa
由于Json解析和构造方面比较复杂,我分成两方面,尽量让大家了解知道和使用这个插件~~(PS.我也知道Rex有更好用的,但是这插件还是挺傻瓜的2333,等等那我研究了一天不就是大傻瓜了)
这里贴上插件作者的github地址 FrenchYann/JSON_for_construct2 (唯一的文档)
2、解析Json字符串
Json字符串和json最大的区别在于,json字符串多了前后两个双引号~而JSON插件也提供了相关的一些函数,我给演示的主要是解析两种字符串,一种是JSONObject的,另一种是JSONArray的。
1、将字符串转化为Json数据
解释:
1、第2条逻辑中,使用了JSON中的一个函数Load JSON这个函数在文档里面是这样的:
Loads any kind of JSON string. It will internally build a JSON object from it.
然后这个插件对JSON的构造是按节点来构造的,将一个字符串加载到JSON的根节点上,即“root”
2、第3条逻辑,做一个判空操作。来看下返回的结果:
一个JSON数组,它在Java后端的返回数据类型是: List<Player>
当我们只返回一个时,它便是一个这样的结果。我们使用的是插件里面提供的一个函数JSON.Value()来获取各个key的值,在这里需要说明一下,虽然插件里面提供了 For each property 函数,但是因为该函数不出循环,所以建议大家还是用getKey来取值。
3、JSON.Value()用法:Returns the value at the given path.
具体用法是,填上节点的路径即可。0是根节点,因为它是一个List,所以第0个,下面的“playerName”节点的值。可以认为说,除了最后一个参数,前面都是Key,有点像Jquery的选择器一样,一层一层。
4、结果:
2、将数组转化为JSON数据
解释:
- 使用一个“for“循环来遍历数组中的值,这其中用到一个JSON插件的函数JSON.Size(),参数也是和上面一样的表示节点,返回的是节点的长度,如果不是数组则会返回-1,用法:Return the size of the array/object at the given path (-1 if not an array/object)
- 为什么要将for循环放在completed下面做为一个子条件。这是因为我们的游戏是实时刷新的,可以认为它是按帧刷新的,每一帧都会运行一次Event sheet,而我们的for的前置条件是root是否为空,这样每一次循环执行完进入下一帧,它又会执行一遍循环,所以C2里面所有循环都是”无限循环“。当我们将整个事件的前置条件设置为completed,下一帧后便不会继续执行for了。
- 结果:
项目链接:https://pan.baidu.com/s/17kkiBqj2xdV3vqAIo4lj-A 65w3
3、构造JSON数据
啦啦啦,重头戏来了。这是整篇博客最精华的一部分,如何在C2里面构造JSON数据。当然,我们也可以用Get/Post请求,那为什么还要用JSON呢,那是因为——Spring框架既然都帮我们封装好了,肯定用JSON啊(PS.因为用json就不用就修改后端的接口了,嘿嘿,Unity又可以发一篇~~)
使用JSON发送数据有众多好处,这里就不说了,有兴趣请百度。
1、构造JSONObject数据
读过文档的大家一定自己试了一遍吧~~可能有点疏漏。
打印出来的东西正是:
{
"username": "hzyyy",
"password": "1234"
}
这样一个JSONObject。
解释:
- 先new一个JSONObject节点到root,root起始是为空的,请不要给它赋值,不然它会因为找不到根节点而无法构造,你可以把第一句话理解成先生成 {} 一对括号。
- 然后使用set value 函数将我们的key和value添加进去,添加到我们的root节点上。
- 将该根节点转化成字符串打印出来,即JSON.AsJson这个函数。可以理解成toString()
2、构造JSONArray数据
打印出来的结果是:
["第一个", "2", "three"]
解释:
先new一个JSONArray节点,然后用set value把key和value添加进去,和map格式一样,数组的key-value对应关系其实是数组下标-值,所以在key位置上填上对应的数组下标即可
3、复合型JSON数据
将我们在java后端中封装的数据类型用json来构造
打印出来的结果是:
{
"fromId": "发送人",
"toId": "接收人",
"map": {
"消息1": "你好",
"消息2": "你好2",
"list": ["A", "B", "C"]
}
}
解释:
注意到的是,和单构建一个节点不同的是,多了一个Set Current Path 的函数,用法:
它的作用就是修改当前的节点,当前节点指的是当前正在构造的节点,需要把构造节点进行切换,才可以继续构造。
工程链接:https://pan.baidu.com/s/1Q3Y5o0xryQwRjT8OeJx8aQ zkns
五、总结
本期的博客就到此结束了~~
这篇博客算作是目前最长的了,希望大家多多指点。