基于Node.js和Cocos Creator的开发 【三,实现用户注册】

一,前端界面设计

在注册界面设计一个比较简单的界面:一个输入用户名的输入框、一个输入密码和一个确认密码的输入框,最后是输入用户名/密码的提示语和一个确定按钮。输入框使用CocosCreator很简单的就可以实现,可参考相关教程:
http://docs.cocos.com/creator/manual/zh/components/editbox.html?h=editbox
整体界面效果图如下:

01.png

操作步骤:

  • 在Scene文件下新建register场景;
  • 在Script文件下的Scene文件夹下新建JavaScript文件:register.js;
  • 在register场景中添加用户脚本组件:register.js
  • 在register场景中创建输入框、提示标签
  • 代码编写

二,代码编写

1,常量的封装

首先将我们的服务器地址做为常量封装起来,在Script文件夹下创建util文件夹,在util中创建Constant.js文件,开发代码如下:

var Constant = {};

var baseURL = 'http://127.0.0.1:8181/';  //将此变量修改为自己服务器地址
Constant.REGISTER_URL = baseURL + 'register/';

module.exports = Constant;
2,register.js的开发
  • 引入文件
var http = require('http');
var Constant = require('Constant');
  • 定义引用变量
    在properties中定义如下变量:
passWordErrorHintLabel: {
        default: null,
        type: cc.Label
    },
    userNameErrorHintLabel: {
        default: null,
        type: cc.Label
    },
    userName: '',
    passWd: '',
    rePassWd : ''
  • 实现用户名输入的处理
inputUserNameEnded: function(editbox, customEventData) {
    this.userName = editbox.string;
},
  • 实现密码输入的处理
inputPassWordEnded: function(editbox, customEventData) {
     this.passWd = editbox.string;
},
  • 实现确认密码的输入处理
reInputPWEnded: function(editbox, customEventData) {
    this.rePassWd = editbox.string;
    if (this.passWd == this.rePassWd) {
        return;
    }

    this._showErrorHint(this.passWordErrorHintLabel);
},
  • 错误提示函数的实现
_showErrorHint: function(label) {
    this.passWordErrorHintLabel.node.active = false;
    this.userNameErrorHintLabel.node.active = false;

    // 显示提示
    label.node.active = true;

    // 设置计时器
    this.scheduleOnce(function(){
        label.node.active = false;
    }.bind(this), 2);
},
  • 注册按钮响应函数
onRegister: function() {
    if (!this.userName || this.userName.length<1) {
        this._showErrorHint(this.userNameErrorHintLabel);
        return;
    }

    if (!this.passWd || this.passWd.length<1) {
        this._showErrorHint(this.passWordErrorHintLabel);
        return;
    }

    if (this.passWd != this.rePassWd) {
        this._showErrorHint();
    }

    this._startRegister();
},
  • 发起请求函数
_startRegister: function() {
        var obj = {
            // node.js收到的url : /register/?userName=&passWord=123
            'url' : Constant.REGISTER_URL,
            'data' : {
                'userName' : this.userName,
                'passWord' : this.passWd
            },
            'success' : function(jsonData) {

            }.bind(this),

            'fail' : function() {

            }.bind(this)

        }
        
        http.request(obj);
    },

代码编写完成后,在CocosCreator编辑器中将register场景中的输入框输入完毕后的处理回调函数设置为相应的函数。

三,后端的实现

1,实现用户ID的管理

在数据库中设置一个标识当前可用用户ID的变量,每次新建用户时获取到此变量标识的值,让后将其增加1。

  • 在后端代码中的Server创建util文件夹,新建constData.js文件:
var constData = {
    'GLOBAL_USER_ID' : 'userId.global'
};

module.exports = constData;
  • 用户ID的初始化处理
    在redis.js文件中,引入常量文件:
    const constData = require('../util/constData');
    修改数据库连接后的处理如下:
client.on('ready', function(error){
    if (error) {
        console.error('start redis error, ' + error);
        return;
    }

    if (redisDB.get(constData.GLOBAL_USER_ID, function(err, result){
        if(err) {
            console.error('get global_user_id err', err);
            return;
        }
        if (result) {
            // 已经设置过了,退出
            return;
        }

        // 设置起始用户ID
        const startUserId = 100001;
        redisDB.set(constData.GLOBAL_USER_ID, startUserId, null);
    }));
})
  • redis.js文件中编写增量指定变量的函数
redisDB.incrby = function(key, incrNum, callBack) {
    client.incrby(key, incrNum, function(number) {
        callBack && callBack(num);
    })
}
2,路由

在开发前端代码时,访问地址已经由
http://127.0.0.1:8181/
修改为
http://127.0.0.1:8181/register/
访问路径上加上了register,在后端需要根据前端的访问地址进行不同的处理,这就涉及到了路由。

  • 在Server目录下新建文件夹router,在router中新建router.js,开发以下代码:
/*
    File : route.js
    Function : 路由处理
*/
const url = require('url');
var router = {};

var getParams = function(req) {
    // 获取请求参数
    var params = url.parse(req.url).query;
    var paramList = params.split('&');
    var res = {};

    for(var i=0, l=paramList.length; i<l; i++) {
        var elements = paramList[i].split('=');
        res[elements[0]] = elements[1];
    }

    return res;
}

router.register = function(req, res, callBack) {
    var params = getParams(req);
    // 参数校验 生成新的用户 todo...
}

module.exports = router;
  • 路由的使用
    在httpServer.js中引入需要的文件:
const router = require('./router/router');
const url = require('url');

修改createServer函数为如下形式:

http.createServer(function(req, res) {
    var pathname = url.parse(req.url).pathname;
    // 去掉/
    pathname = pathname.replace(/\//g, '');

    var response = {
        'error' : 1,
        'note' : 'Not found path'
    };
    if(router[pathname]) {
        router[pathname](req, res, function(resData) {
            res.write(JSON.stringify(resData));
            res.end();            
        });
    }else{
        res.write(JSON.stringify(response));
        res.end();
    }
}).listen(8181);

至此,我们的后端实现了路由访问,在有新的访问路径需要时只需要在router.js文件添加相应的和路径同名的函数即可。

3,创建新用户

创建新用户,即为在数据库中生成一天新的用户记录,我们暂且只设定用户的name、passWord、coin、diamond、head、friends属性。

  • 在constData.js中定义新的键值:
    'USER_BASEK_KEY' : 'user:'
  • 新建文件夹business,在其下新建user.js文件,开发代码
/*
    File : user.js
    Function : 用户相关的逻辑t
*/
const redisDB = require('../db/redis');
const constData = require('../util/constData');

var user = {};

user.createUser = function(userName, passWord, callBack) {
    var createUser = function(userId) {
         // 获取到用户ID后创建用户
         var userKey = constData.USER_BASEK_KEY + userId;
         var userData = {
             'name' : userName,
             'passWord' : passWord,
             'coin' : 0,
             'diamond' : 0,
             'head' : '',
             'friends':[]
         }

        //  数据库创建用户
         redisDB.hmset(userKey, userData, function(err, result) {
            //返回给用户的数据
             var data = {
                 'userId' : userId,
                 'name' : userName,
                 'token' : '' //暂且为空,后续实现
             }
             if(err) {
                data = {
                    'error' : err,
                    'note' : 'create user error!!'
                }
                callBack(data);
                return;
             }
             callBack(data);
         })
    }

    redisDB.incrby(constData.GLOBAL_USER_ID, 1, function(err, userId) {
        if(err) {
            var data = {
                'error' : err,
                'note' : 'create user error!!'
            }
            callBack(data);
            return;
        }

        createUser(userId);
    });
}

module.exports = user;
  • 调用创建用户的接口
    在router.js中添加对user文件的调用:
    const user = require('../business/user');
    修改router.register函数如下:
router.register = function(req, res, callBack) {
    var params = getParams(req);
    // 参数校验 todo...
    user.createUser(params['userName'], params['passWord'], function(data) {
        callBack && callBack(data);
    })
}

四,前端展示注册结果

这一步我们把从后端接收到的注册结果信息展示到一个页面上:

  • UI
    新建一个节点,将其设置为不可见。在这个节点下包含一个透明度为230的单色精灵和一个用于展示注册结果信息的label:


    03.png
  • 代码开发
    相关变量定义:

registerSuccessLabel: {
    default: null,
    type: cc.Label
},
registerInfoNode: {
    default: null,
    type: cc.Node
},
  • 完善_startRegister函数,加入访问成功失败的回调处理
_startRegister: function() {
    var obj = {
        'url' : Constant.REGISTER_URL,
        'data' : {
            'userName' : this.userName,
            'passWord' : this.passWd
        },
        'success' : function(jsonData) {
            this._onRegisterSuccess(jsonData);
        }.bind(this),

        'fail' : function() {
            this._onRegisterFail(jsonData);
        }.bind(this)

    }
    
    http.request(obj);
},
  • 实现回调函数
_onRegisterSuccess: function(jsonData) {
    this.registerInfoNode.active = true;
    console.log('_onRegisterSuccess come in jsonData = ' + JSON.stringify(jsonData));
    var info = '注册成功\n用户名:' + jsonData['name'] + '\n用户ID:'+ jsonData['userId'] + '\n牢记自己的信息\n';
    console.log('info = ' + info);
    this.registerSuccessLabel.string = info;
},

_onRegisterFail: function(jsonData) {
    console.log('_onRegisterFail come in jsonData = ' + JSON.stringify(jsonData));
},

至此,启动服务器,运行CocosCreator,填写注册信息后即可看到注册成功页面。


代码在这儿


上一篇 node.js操作redis
下一篇 实现用户登录

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容