rpgmakermv吧 关注:22,122贴子:68,978
  • 12回复贴,共1页

一个显示图片的窗口插件

只看楼主收藏回复

效果如何,二楼贴上我翔一样的代码




IP属地:重庆1楼2016-04-22 22:26回复
    过段时间我会优化可读性并附上一份写这样一个插件的教程
    /*:
    * @author Created by 邪恶道具 on 2016/3/5.
    *
    * @param 图片数量
    * @default 15
    *
    * @param 选项名
    * @default 日记
    *
    * @param 初始化标签
    * @default 0
    *
    * @param 功能选择
    * @default 0
    *
    * @plugindesc
    * 初始化标签为1时,初始化时显示所有图片,为0时隐藏所有图片
    * 功能选择:1是默认,2和3非别是全部设置隐藏或显示
    *
    * @help
    *
    *
    * 将需要使用的图片放入img文件夹中的diary文件夹内
    * 文件名按照这种格式编辑 "diary (x).png",其中x为一个数字,此数字对应相应标签
    * 因此该数字最好是连续的,如:diary (1).png ,diary (2).png...
    * Book.png,这种名称的图片为背景图片
    * 日记选项中显示的标签,需要自己新建一个diary_name.rpgsave文件
    * diary_name.rpgsave文件中的内容使用UTF-8字符,用英文逗号分割
    * 该文件需要放入save文件夹中
    *
    *
    */
    var params = PluginManager.parameters("diary_new");
    (function(){
    var tabName = String(params['选项名'] || "请输入" );
    //console.log("tagNum:"+tabName);
    //通过needsCommand指令添加Menu菜单中的Diary选项
    var _Window_MenuCommand_addMainCommands = Window_MenuCommand.prototype.addMainCommands;
    Window_MenuCommand.prototype.addMainCommands = function(){
    _Window_MenuCommand_addMainCommands.call(this);
    if (this.needsCommand('diary')) {
    //第一个参数是选项的名称,第二个则是对应createCommandWindow里的字符
    this.addCommand(tabName, 'diary', 1);//TextManager.diary的值为'日记'
    }
    };
    //将选项添加进去
    var _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
    Scene_Menu.prototype.createCommandWindow = function(){
    _Scene_Menu_createCommandWindow.call(this);
    this._commandWindow.setHandler('diary', diary_command.bind(this));
    };
    })();
    var diary_command = function(){
    this._commandWindow.deselect();
    run();
    };
    var diary_command_activate = function(){
    SceneManager.goto(Scene_Menu);
    };
    /**
    * Created by 邪恶道具 on 2016/3/5.
    * 日记系统绘制窗口及其功能代码
    * 图片读取是在状态机执行的间隔中进行的
    */
    var functionSelection = Number(params['功能选择'] || "2" );
    var photoNum = Number(params['图片数量'] || 15);//需要载入的图片数量,从1开始,而不是0(也就是表示1-11(11个),而不是往常的0-11(12个))
    var run = function(){
    if(!document.getElementById("theCanvas")){
    create_canvas();
    }else{
    var theCanvas = document.getElementById("theCanvas");
    theCanvas.style.zIndex = 20;
    }
    fileWriteAndRead( functionSelection,photoNum,null, null);
    diary(photoNum);
    };
    var diary = function(photoNum) {
    var theCanvas = document.getElementById("theCanvas");
    var context = theCanvas.getContext("2d");
    //状态机参数
    var state_photoLoad = 1;
    var state_initList = 2;
    var state_windowDraw = 3;
    var state_drawFont = 4;
    var state_nextPage = 5;
    var state_backPage = 6;
    var state_end = 7;
    var currentState = state_photoLoad;
    //参数
    var displayText = new Object();
    displayText.flag = new Array();//为0显示"???",为1显示text属性的内容
    displayText.text = new Array();//日记名称
    displayText.maxLine = 12;//最大行数
    displayText.textCount = 0;
    var photoLoadedCount = 0;//负责已载入图片的计数
    var offset = 2;//边框偏移量
    var line_x = 200;//分割线x坐标
    var currentPage = 1;//记录当前的页数,从1开始
    var rememberNameCount = 0;
    var coordinate = new Object();//该对象负责存储定位选项与显示的必要数据
    coordinate.backGround = null;
    coordinate.photoCache = new Array();//存储日记图片的数组
    coordinate.font_x = new Array();
    coordinate.font_y = new Array();
    coordinate.font_height = new Array();
    coordinate.font_width = new Array();
    //临时参数
    var global_Count = 0;
    var global_Flag = 0;
    var tempFlag = 0;
    //coordinate.photoCache,从第0个元素开始是日记图片
    var photoLoad = function () {
    var backGround = new Image();
    backGround.src = "img/diary/book.png";
    backGround.addEventListener("load", load_done, false);
    coordinate.backGround = backGround;
    window.console.log("loading");
    for (var i = 0; i < photoNum; i++) {
    var number = i + 1;
    var temp = new Image();
    temp.src = "img/diary/diary (" + number + ").png";
    temp.addEventListener("load", load_done, false);
    coordinate.photoCache.push(temp);
    }
    //window.console.log("coordinate.photoCache.length:"+coordinate.photoCache.length);
    currentState = state_end;
    };
    var initList = function () {
    var temp = loadFile();
    var tempName = string_Change_strArray();
    for (var i = 0; i < coordinate.photoCache.length; i++) {
    displayText.text.push(tempName[i]);
    }
    for(var i = 0;i < temp.length;i++){
    if(temp[i]==0||temp[i]==1){
    displayText.flag.push(temp[i]);
    }
    }
    currentState = state_windowDraw;
    };
    //将中文字符串转换成数组
    var string_Change_strArray = function () {
    var fs = require('fs');
    var fileName = "diary_name.rpgsave";
    var savePath = StorageManager.localFileDirectoryPath() + fileName;
    var data = fs.readFileSync(savePath,"utf-8");
    var temp = data.split(",");
    var tempArray = new Array();
    for(var i=0;i<temp.length;i++) {
    if (temp[i] != ",") {
    tempArray.push(temp[i]);
    }
    }
    return tempArray;
    };
    var loadFile = function () {
    var fs = require('fs');
    var fileName = "diary.rpgsave";
    var savePath = StorageManager.localFileDirectoryPath() + fileName;
    var readData = null;
    readData = fs.readFileSync(savePath);
    readData = ""+readData;
    return readData;
    };
    var load_done = function () {
    photoLoadedCount++;
    //coordinate.photoCache.length + 1,背景图加上日记图片的数量
    if (photoLoadedCount == (coordinate.photoCache.length + 1)) {
    coordinate.backGround.removeEventListener("load", load_done, false);
    for (var i = 0; i < coordinate.photoCache.length; i++) {
    coordinate.photoCache[i].removeEventListener("load", load_done, false);
    }
    currentState = state_initList;
    coordinate.time = setInterval(stateMachine, 33);
    console.log("loaded");
    photoLoadedCount--;//这下才是日记图片数(-1是为了去掉背景的计数)
    }
    };


    IP属地:重庆2楼2016-04-22 22:28
    回复
      2026-10-04 17:08:43
      广告
      不感兴趣
      开通SVIP免广告
      var windowDraw = function () {
      var width = theCanvas.width - offset;
      var height = theCanvas.height - offset;
      context.drawImage(coordinate.backGround, 0, 0);
      //给背景增加透明度
      context.beginPath();
      context.globalAlpha = 0.8;
      context.fillStyle = "#000000";
      context.fillRect(0, 0, theCanvas.width, theCanvas.height);
      //绘制边框
      context.beginPath();
      context.lineWidth = 4;
      context.lineJoin = "round";
      context.strokeStyle = "#FFFFFF";
      context.moveTo(offset, offset);
      context.lineTo(width, offset);
      context.lineTo(width, height);
      context.lineTo(offset, height);
      context.closePath();
      context.stroke();
      //获取显示日记内容区域的信息
      coordinate.diaryDisplayArea_minX = line_x;
      coordinate.diaryDisplayArea_maxX = width;
      coordinate.diaryDisplayArea_minY = offset;
      coordinate.diaryDisplayArea_maxY = height;
      context.beginPath();
      context.moveTo(line_x, offset);
      context.lineTo(line_x, height);
      context.stroke();
      currentState = state_drawFont;
      };
      var drawFont = function () {
      var offset = 20;
      var tempStr = null;
      //var temp = displayText.maxLine + rememberNameCount;
      if(photoNum==(displayText.maxLine + rememberNameCount - 2)){
      rememberNameCount--;
      currentPage--;
      }
      var length = displayText.maxLine + rememberNameCount;
      for (var i = rememberNameCount; i < length; i++) {
      if (displayText.flag[i] == 1) {
      tempStr = 0;
      }
      if(displayText.flag[i] == 0){
      tempStr = 1;
      }
      if ((i + 1) == length) {
      if(global_Count == coordinate.photoCache.length-1 || (global_Count
      == coordinate.photoCache.length && tempFlag == 0)){
      tempStr = 4;
      }else{
      tempStr = 2;
      }
      }
      if(currentPage>1&&i==rememberNameCount){
      tempStr = 3;
      }
      switch(tempStr){
      case 0:
      tempStr = displayText.text[i];
      if(global_Flag==0){
      global_Count++;
      }
      break;
      case 1:
      tempStr = "???";
      if(global_Flag==0){
      global_Count++;
      }
      break;
      case 2:
      tempStr = "下一个";
      break;
      case 3:
      tempStr = "上一个";
      break;
      case 4:
      if(displayText.flag[i] == 1){
      tempStr = displayText.text[i];
      global_Count++;
      break;
      }else{
      tempStr = "???";
      global_Count++;
      break;
      }
      case null:
      tempStr = "";
      window.console.log("无剩余图片");
      break;
      }
      if(global_Count > coordinate.photoCache.length && tempFlag == 0){
      global_Count = coordinate.photoCache.length;
      }
      var fontMaxWidth = line_x - offset;
      var fontSize = 30;
      var y = offset + fontSize;
      context.beginPath();
      context.font = "normal " + fontSize + "px Arial";
      context.fillStyle = "#FFFFFF";
      var str_width = Math.round(context.measureText(tempStr).width);
      var x = ((line_x - offset) / 2) - Math.floor(str_width / 2) + 10;//使字
      体居中
      context.fillText(tempStr, x, y * (i - rememberNameCount + 1),
      fontMaxWidth);
      coordinate.font_x.push(x);
      coordinate.font_y.push((y * (i- rememberNameCount + 1)) - fontSize);//
      不减去fontSize,那么y会位于字体下方
      coordinate.font_width.push(str_width);//压入字符串宽度
      //绘制字体下划线
      context.beginPath();
      context.strokeStyle = "#FFFFFF";
      var fontOffset = 10;
      context.moveTo(x, y * (i- rememberNameCount + 1) + fontOffset);
      context.lineTo(x + str_width, y * (i- rememberNameCount + 1) +
      fontOffset);
      coordinate.font_height.push(fontSize + fontOffset);//压入字符串高度
      context.stroke();
      coordinate.fontOffset = fontOffset;
      }
      currentState = state_end;
      };
      var game_end = function () {
      clearInterval(coordinate.time);
      };
      var checkClick = function (event) {
      if(event.button == 2 || exitKey(event)){
      exitDiary(theCanvas);
      }else{
      var x = Math.round(event.pageX);
      var y = Math.round(event.pageY);
      //console.log("x:" + x);
      //console.log("y:" + y);
      for (var i = 0; i < coordinate.photoCache.length; i++) {
      if (displayText.flag[i] == 1 || displayText.flag[i] == 0) {
      //minBoundary和maxBoundary分别为选项的左右边界
      var minX = coordinate.font_x[i];
      var minY = coordinate.font_y[i];
      var maxX = minX + Math.round(coordinate.font_width[i]);
      var maxY = minY + Math.round(coordinate.font_height[i]);
      var minBoundary = (x > minX && y > minY);
      var maxBoundary = (x < maxX && y < maxY);
      if (minBoundary && maxBoundary) {
      theCanvas.width = theCanvas.width;
      theCanvas.height = theCanvas.height;
      global_Flag = 1;
      windowDraw();
      drawFont();
      currentState = null;
      //获取设置图片位置的必要信息
      if(displayText.flag[i+rememberNameCount] == 1){
      var centext_width =
      coordinate.diaryDisplayArea_maxX - coordinate.diaryDisplayArea_minX;
      var centext_height =
      coordinate.diaryDisplayArea_maxY - coordinate.diaryDisplayArea_minY;
      var centerPoint_x = (centext_width / 2 +
      coordinate.diaryDisplayArea_minX);
      var centerPoint_y = (centext_height / 2 +
      coordinate.diaryDisplayArea_minY);
      var photo_width = coordinate.photoCache[i
      +rememberNameCount].width / 2;
      var photo_height = coordinate.photoCache[i
      +rememberNameCount].height / 2;
      var place_x = centerPoint_x - photo_width;
      var place_y = centerPoint_y - photo_height;
      }
      if ((i + 1) == displayText.maxLine && global_Count <
      coordinate.photoCache.length) {
      nextPage();
      break;
      }
      if(i==0&&currentPage>1){
      backPage();
      break;
      }
      //日记内容显示部分
      if(!(((i + 1) == displayText.maxLine)&&
      (i==0&&currentPage>1))) {
      if(displayText.flag[i+rememberNameCount] == 1){


      IP属地:重庆3楼2016-04-22 22:31
      回复
        context.drawImage(coordinate.photoCache[i
        +rememberNameCount], place_x, place_y);
        break;
        }
        }
        }
        }
        }
        }
        };
        //diary窗口的退出函数
        var exitDiary = function(theCanvas){
        theCanvas.removeEventListener("mouseup", checkClick,false);
        document.removeEventListener("keyup", checkClick,false);
        theCanvas.style.zIndex = -20;
        diary_command_activate();
        theCanvas.width = theCanvas.width;
        theCanvas.height = theCanvas.height;
        window.console.log("退出完成");
        };
        var exitKey = function(event){
        switch (event.keyCode){
        case 27:
        return true;
        break;
        /* case 93:
        return true;
        break;*/
        }
        };
        var nextPage = function () {
        if(global_Count < photoNum){
        tempFlag = 0;
        }
        global_Count++;
        currentPage++;
        rememberNameCount++;
        theCanvas.width = theCanvas.width;
        theCanvas.height = theCanvas.height;
        windowDraw();
        drawFont();
        currentState = null;
        };
        var backPage = function () {
        if(global_Count == photoNum && tempFlag == 0){
        global_Count--;
        }
        tempFlag = 1;
        global_Count--;
        currentPage--;
        rememberNameCount--;
        theCanvas.width = theCanvas.width;
        theCanvas.height = theCanvas.height;
        windowDraw();
        drawFont();
        currentState = null;
        };
        var stateMachine = function () {
        switch (currentState) {
        case state_photoLoad:
        photoLoad();
        break;
        case state_initList:
        initList();
        break;
        case state_windowDraw:
        windowDraw();
        break;
        case state_drawFont:
        drawFont();
        break;
        case state_nextPage:
        nextPage();
        break;
        case state_backPage:
        backPage();
        break;
        case state_end:
        game_end();
        break;
        case null:
        //window.console.log("错误的状态值");
        break;
        }
        };
        document.addEventListener('keyup', checkClick,false);
        theCanvas.addEventListener("mouseup", checkClick, false);
        coordinate.time = setInterval(stateMachine, 33);
        };
        var create_canvas = function(){
        var theCanvas = document.createElement("canvas");
        if(!theCanvas){
        document.write("no support canvas");
        return ;
        }
        //mv的是816*624
        theCanvas.width = 816;
        theCanvas.height = 624;
        theCanvas.style.position = "absolute";
        theCanvas.style.margin = "auto";
        theCanvas.style.top = 0 + "px";
        theCanvas.style.left = 0 + "px";
        theCanvas.style.right = 0 + "px";
        theCanvas.style.bottom = 0 + "px";
        theCanvas.style.zIndex = 20;
        theCanvas.id = "theCanvas";
        document.body.appendChild(theCanvas);
        return theCanvas;
        };
        /**
        * Created by 邪恶道具 on 16-4-19.
        * 负责文件的读取与存储,使用node.js
        */
        var fileDisplay = Number(params['初始化标签'] || "0" );
        var _Game_Interpreter_pluginCommand =
        Game_Interpreter.prototype.pluginCommand;
        Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);
        console.log("functionSelection:"+functionSelection);
        fileWriteAndRead( functionSelection,photoNum,command, args);
        };
        //第1个和3个参数决定运行那个函数,第2个参数表示有多少图片,第4个参数是插件变量
        //第1个参数是手动指定
        fileWriteAndRead = function(select,photoNum,command, args) {
        var fs = require('fs');
        var fileName = "diary.rpgsave";
        var savePath = StorageManager.localFileDirectoryPath() + fileName;
        var length = photoNum;//为图片数量
        //intiData只在初始化时使用
        var initData = null;
        var readData = null;
        console.log("select2:"+select);
        var initFile = function () {
        initData = new Array(length);
        for (var i = 0; i < length; i++) {
        initData[i] = fileDisplay;
        }
        saveFile(initData);
        };
        var saveFile = function (data) {
        fs.writeFileSync(savePath, data,"utf-8");
        };
        var loadFile = function () {
        readData = fs.readFileSync(savePath,"utf-8");
        readData = string_Change_array(readData);
        return readData;
        };
        //index为要修改的位置,flag的值为0和1
        var changeFlag = function () {
        readData = loadFile();
        var count = 0;
        for(var i=0;i<readData.length;i++){
        if (count == args[0]) {
        readData[count] = args[1];
        break;
        }
        if((i % 2) == 0){
        count++;
        }
        }
        saveFile(readData);
        };
        //将数字字符串转换成数组
        var string_Change_array = function (data) {
        var temp = data.split("");
        var tempArray = new Array();
        for(var i=0;i<temp.length;i++){
        if(temp[i]==1||temp[i]==0){
        tempArray.push(temp[i]);
        }
        }
        return tempArray;
        };
        //将中文字符串转换成数组
        var string_Change_strArray = function () {
        var fs = require('fs');
        var fileName = "diary_name.rpgsave";
        var savePath = StorageManager.localFileDirectoryPath() + fileName;
        var data = fs.readFileSync(savePath,"utf-8");
        var temp = data.split(",");
        var tempArray = new Array();
        for(var i=0;i<temp.length;i++) {
        if (temp[i] != ",") {
        tempArray.push(temp[i]);
        }
        }
        return tempArray;
        };
        var exist = function () {
        //为真表示文件已存在
        if (!fs.existsSync(savePath)) {
        initFile();
        } else {
        loadFile();
        }
        switch (command) {
        case "changeFlag":
        changeFlag();
        break;
        case "string_Change_strArray":
        string_Change_strArray();
        break;
        case null:
        //console.log("指令为空");
        break;
        }
        };
        var reInitFile = function(flag){
        console.log("进入reInitFile");
        var temp = null;
        if(flag == 2){
        temp = 0;
        }else{
        temp = 1;
        }
        readData = loadFile();
        for(var i=0;i<readData.length;i++){
        if (readData[i] != ",") {
        readData[i] = temp;
        }
        }
        console.log("reInitFile_readData:"+readData);
        saveFile(readData);
        };
        var run = function(select) {
        var temp = 2;
        switch (select) {
        case 1:
        exist();
        break;
        case 2:
        reInitFile(temp);
        break;
        case 3:
        reInitFile(temp+1);
        break;
        }
        };
        run(select);
        };


        IP属地:重庆4楼2016-04-22 22:35
        回复
          虽然看不懂,但还是支持


          IP属地:广东来自iPhone客户端5楼2016-04-23 01:10
          回复
            优化语义后的UML图,基本上就是把上面的部分代码封装到函数里,需要源代码的可以加群 515860452


            IP属地:重庆6楼2016-04-25 16:43
            收起回复
              我一直在想为什么楼主写的代码和我认识的JS完全不一样......泪奔ing.........


              IP属地:四川7楼2016-04-30 20:42
              收起回复
                ps:这教程很久前就写好了,有人建议应该写的更通熟易懂,但水平有限修改过后也只有这样了
                该教程的特点是对mv源码的依赖小,适合有js编程能力但对mv源码研究不深的人
                理解这些技术后,就可以不受到mv本身的约束来写窗口和它所要展示的内容
                1.首先,将选项添加进主菜单
                var _Window_MenuCommand_addMainCommands = Window_MenuCommand.prototype.addMainCommands;
                Window_MenuCommand.prototype.addMainCommands = function(){
                _Window_MenuCommand_addMainCommands.call(this);
                if (this.needsCommand('diary')) {
                this.addCommand(tagName, 'diary', 1);
                }
                };
                上面这几段代码,用于将你窗口的选项添加进主菜单中,其中tagName为该选项所显示的字符串
                'diary'则是一个指令名,该指令名可以自行设置,但一定要是字符串
                第三个选项用途不明,但填1并没有问题,所以写你自己的窗口时填1即可
                2.然后给你的选项添加功能
                var _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
                Scene_Menu.prototype.createCommandWindow = function(){
                _Scene_Menu_createCommandWindow.call(this);
                this._commandWindow.setHandler('diary', diary_command.bind(this));
                };
                this._commandWindow.setHandler('diary', diary_command.bind(this));
                这段代码中的第一个参数是变量名,第二个参数用于给你添加的选项附加上逻辑功能
                bind关键字与call类似,都是改变函数或变量的this指向,但不同的是,call是改变后立即执行,bind则是改变this的指向,但不立即执行
                setHandler源码如下:
                Window_Selectable.prototype.setHandler = function(symbol, method) {
                this._handlers[symbol] = method;
                };
                关于上面代码使用call的意义可以参见我以前的帖子
                http://tieba.baidu.com/p/4185225772?pid=79770073662&cid=0#79770073662
                3.其他函数介绍
                3.1 窗口跳转函数
                var diary_command_activate = function(){
                SceneManager.goto(Scene_Menu);
                };
                该函数在退出日记窗口时执行,用于切换回主菜单,根据给goto输入不同的参数,可以跳转到其他菜单
                3,2 窗口逻辑函数
                var diary_command = function(){
                this._commandWindow.deselect();
                diary_run();
                };
                this._commandWindow.deselect();用于冻结主菜单,使其不接受鼠标与键盘操作
                diary_run();则包含了你编写的窗口的所有代码
                现在关键的几个函数都介绍完毕了,实际上通过这几个函数已经可以开始编写窗口了
                现在来介绍我写的插件中的几项关键技术:状态机,资源预载和本地文件读写
                先来说说状态机
                //状态机参数
                var state_photoLoad = 1;
                var state_initList = 2;
                var state_windowDraw = 3;
                var state_drawFont = 4;
                var state_nextPage = 5;
                var state_backPage = 6;
                var state_end = 7;
                var currentState = state_photoLoad;
                首先设置一组状态变量,然后设置一个记录状态变量的变量,该变量记录下一个应该执行的函数的代码
                设置一个状态机,然后设置一个计时器,我设置的是每33毫秒查询一次状态
                在下述每个函数执行完时,状态变量currentState都会发生相应变化
                这就是状态机了,简单而且能更有效的控制代码的执行,相当简单的技术
                //计时器
                coordinate.time = setInterval(stateMachine, 33);
                //状态机
                var stateMachine = function () {
                switch (currentState) {
                case state_photoLoad:
                photoLoad();
                break;
                case state_initList:
                initList();
                break;
                case state_windowDraw:
                windowDraw();
                break;
                case state_drawFont:
                drawFont();
                break;
                case state_nextPage:
                nextPage();
                break;
                case state_backPage:
                backPage();
                break;
                case state_end:
                game_end();
                break;
                case null:
                //window.console.log("错误的状态值");
                break;
                }
                };
                资源预载:
                在我的源码是photoLoad和load_done这两个函数在负责这一功能
                原理非常简单
                var backGround = new Image();
                backGround.src = "img/diary/book.png";
                backGround.addEventListener("load", load_done, false);
                coordinate.backGround = backGround;
                window.console.log("loading");
                在这段代码中,设置好正确的资源路径,然后加上一个监听函数来监听资源是否被载入
                如果确认载入,则执行load_done函数来移除监听并计数,资源载入是在代码执行的空隙时进行的,所以photoLoad的末尾有这么一句代码currentState = state_end
                用于停止轮询,等待载入
                当load_done中的计数等于需要被载入的资源数量时,就表示资源被全部载入,此时再次启动轮询并指定新的状态
                载入的资源此时位于内存中,所以会增加内存负担
                此技术也是相当简单的
                本地文件读写可以去看node.js的file system那一部分,说的比我好,具体实现可以参考我的代码
                node存储的文件是一个字符串文件,所以要转换为数组时,需要自己写个转换函数,也可以参考我的源码


                IP属地:重庆8楼2016-05-10 15:46
                回复
                  2026-10-04 17:02:43
                  广告
                  不感兴趣
                  开通SVIP免广告
                  留名~


                  IP属地:宁夏来自Android客户端9楼2017-11-23 17:04
                  回复
                    谢谢大大分享


                    10楼2017-11-23 20:08
                    回复
                      大佬,怎样才能联系上你啊


                      11楼2022-06-17 22:28
                      回复