使用SpringBoot及Construct2的WebSocket制作联机游戏(二)

前情概要:

使用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请求示例:

  1. 名字(保存记录后会显示备注名在此)
  2. 请求方式,可选择下拉框
  3. 请求的url
  4. 请求头部信息
  5. 请求的数据类型(form-data是表单数据,raw是json格式的数据)
  6. key和value
  7. 返回的数据类型及数据
  8. 发送请求的按钮

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请求的实现方式

解释:

  1. 首先使用的是官方的插件AJAX
  2. 主要用的三个函数:Event的Request Url(发送Get请求)和Post Url(发送Post请求),Action的On Completed(接收返回结果);使用变量:AJAX.LastData(返回结果)
  3. 如果返回值为空时,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数据

解释:

  1. 使用一个“for“循环来遍历数组中的值,这其中用到一个JSON插件的函数JSON.Size(),参数也是和上面一样的表示节点,返回的是节点的长度,如果不是数组则会返回-1,用法:Return the size of the array/object at the given path (-1 if not an array/object) 
  2. 为什么要将for循环放在completed下面做为一个子条件。这是因为我们的游戏是实时刷新的,可以认为它是按帧刷新的,每一帧都会运行一次Event sheet,而我们的for的前置条件是root是否为空,这样每一次循环执行完进入下一帧,它又会执行一遍循环,所以C2里面所有循环都是”无限循环“。当我们将整个事件的前置条件设置为completed,下一帧后便不会继续执行for了。
  3. 结果:

项目链接: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。

解释:

  1. 先new一个JSONObject节点到root,root起始是为空的,请不要给它赋值,不然它会因为找不到根节点而无法构造,你可以把第一句话理解成先生成  {} 一对括号。
  2. 然后使用set value 函数将我们的key和value添加进去,添加到我们的root节点上。
  3. 将该根节点转化成字符串打印出来,即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

五、总结

本期的博客就到此结束了~~

这篇博客算作是目前最长的了,希望大家多多指点。

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页