C#服务端的微信小游戏——多人在线角色扮演(十四)

C#服务端的微信小游戏——多人在线角色扮演(十四)

名字不是自己定义的,但人生却可以
——茂叔

为了实现让用户选择角色的姓名和性别,我们需要这样一个界面:
在这里插入图片描述

服务器端

要实现这个功能,我们需要在服务器端还应该添加一条命令CREATECHARACTER。客户端把选择的名字和性别连同这个命令一起发送给服务端后,服务端完成修改,然后把最新的用户Json值返回给客户端。

添加命令很简单,在服务器端的Types.cs里修改我们的命令枚举就可以了。

public enum GameCommand : byte
    {
        ERROR = 0,
        CONNECTED = 1,
        LOGIN,
        MAKENAMES,
        CREATECHARACTER,//添加在这里就可以了,不喜欢这个位置么?好吧,顺序不重要的,随便添在哪儿都一样。
        MOVE,
        ATTACK,
        SEARCH,
        TAKE,
        QUIT
    }

然后再去GameServer.csParseClientCommand方法里面添加解析这条命令的处理代码:

……
                case GameCommand.MAKENAMES:
                    {
                        uint playerID = ((GameConnection)connection).PlayerID;
                        JArray retjson = JArray.FromObject(gGame.MakeName(playerID));
                        ((GameConnection)connection).SendMessage(cmd, retjson.ToString());
                    }                    
                    break;
                case GameCommand.CREATECHARACTER:
                    {
                        uint playerID = ((GameConnection)connection).PlayerID;
                        JObject datajson = JObject.Parse(data);
                        int nameidx = int.Parse(datajson["nameidx"].ToString());
                        byte sexidx = byte.Parse(datajson["sexidx"].ToString());
                        ((GameConnection)connection).SendMessage(cmd, gGame.SetPlayerSexAndName(playerID,nameidx,sexidx));
                    }
                    break;
                case GameCommand.MOVE:
……                

最后,在Game.cs里面去实现设置姓名和性别的方法:

public string SetPlayerSexAndName(uint PlayerID,int nameidx,int sexidx)
        {
            GamePlayer player = GetPlayerByPlayerId(PlayerID);
            if (player.Name == "@")//已经设置过的就不准再设置了,一个名字跟随你一生。
            {
                player.Name = player.NameList[nameidx];
                player.Gender = (byte)sexidx;
            }
            return player.ToJson().ToString();
        }

所以,整个过程就是:

定义命令
添加解析
实现功能
Types.cs
GameServer.cs
Game.cs

是不是很简单?所有的命令都是用这样的模式去实现的。定义归定义,解析归解析,实现归实现。以后修改维护都很方便。

服务器端的活就完成了~

客户端

然后我们再来看客户端。客户端除了界面背景,按钮外,还有一些文字,为此,我们定义一个Label类来处理(别问为什么,这又不是我想出来的……)
UIOBJECT.js里面定义新的界面元素(好吧,如果你习惯叫控件也可以).

……
exports.UILabel = UILabel
function UILabel(father, x = 0, y = 0, w = 100, h = 25) {
  baseUIObj.call(this, father, x, y, w, h)
  this.text = "UILabel"
  this.name = "Label"
  this.color = "transparent"
  this.isTouchable = false
  this.borderWidth=0
}
UILabel.prototype = new baseUIObj()
UILabel.prototype.constructor = UILabel
UILabel.prototype.redraw = function (needrender = true, caller = this) {
  if (caller.isRedrawing) return
  caller.isRedrawing = true
  if (caller.isHidden) {
    if (caller.father)
      caller.father.redraw(caller.father)
  } else {
    baseUIObj.prototype.redraw(caller)
    if (caller.text && caller.text.length > 0)
      drawText(caller.gCtx, caller.text, caller.width / 2 - caller.text.length * 7, (caller.height - 12) / 2)
    caller.children.forEach(function (child, index, array) {
      if (!child.isHidden) {
        child.redraw(false)
        caller.gCtx.drawImage(child.canvas, child.x, child.y, child.width, child.height)
      }
    })
  }
  if (needrender)
    GameWindow.redraw()
  caller.isRedrawing = false
}
……

考虑到要选择,所以我们的按钮应该添加select()unselect()方法……

……
UIButton.prototype.select = function (caller = this) {
  caller.color = "#555"
  caller.borderWidth = 2
  caller.redraw()
}

UIButton.prototype.unselect = function (caller = this) {
  caller.color = "#333"
  caller.borderWidth = 1
  caller.redraw()
}
……

我偷偷地把UIButton的默认borderWidth属性改成1了,2代表当前选中。
我们添加了新的命令,所以,客户端这边要处理这个命令。
net.jsparseMessage(msg)方法里面去添加对命令回传信息的处理:

……
switch (msg.command) //其他命令的处理结果
    {
      case _g.COMMAND.CREATECHARACTER:
        _g.Player = JSON.parse(msg.data)
        console.log(_g.Player)
        if (_g.Player.Name === "@") {
          let nextUI = require('/UI/makename.js')
          nextUI.initialize()
        } else {
          let nextUI = require('/UI/main.js')
          nextUI.initialize()
        }
        break
      case _g.COMMAND.MAKENAMES:
        _g.Player.NameList = JSON.parse(msg.data)
        let nextUI = require('/UI/makename.js')
        nextUI.UpdateName()
        break
      case _g.COMMAND.LOGIN:
        _g.Player = JSON.parse(msg.data)
……

考虑到有了新的界面,将来还会有更多的界面,所以,我们把界面处理程序提取出来,单独存放在\UI目录下,所以,建个\UI目录,下面建立两个文件main.jsmakename.js,用来专门处理角色设置和显现游戏主界面:
main.js

exports.initialize = () => {
  if (GameGlobal.GameMainUI === undefined) {
    GameGlobal.GameMainUI = new UIObj.UIGame()
    let image = wx.createImage();
    image.src = "images/UI.png"
    image.onload = () => {
      GameMainUI.background = image

      var btn = new UIObj.UIButton(GameMainUI)
      btn.x = 44
      btn.y = 150
      btn.text = "退出游戏"
      btn.onClick = () => {
        wx.closeSocket()
      }

      GameWindow = GameMainUI
      GameWindow.show()
    }
  } else {
    GameWindow = GameMainUI
    GameWindow.show()
  }
}

makename.js

var sexSelectItem
var btnSex1
var btnSex2
var nameSelectItem
var btnName0
var btnName1
var btnName2
var btnName3
var btnSubmit
var btnRename
exports.initialize = () => {
  if (GameGlobal.GameMakenameUI === undefined) {
    GameGlobal.GameMakenameUI = new UIObj.UIGame()
    let image = wx.createImage();
    image.src = "images/UI.png"
    image.onload = () => {
      GameMakenameUI.background = image
      createMakenameUI()
    }
  } else {
    showMakenameUI()
  }
}

function createMakenameUI() {
  var label1 = new UIObj.UILabel(GameMakenameUI, 44, 8)
  label1.text = "设定角色"

  var label2 = new UIObj.UILabel(GameMakenameUI, 8, 50, 60)
  label2.text = "性别:"

  var label3 = new UIObj.UILabel(GameMakenameUI, 8, 80, 60)
  label3.text = "姓名:"

  btnSex1 = new UIObj.UIButton(GameMakenameUI, 60, 50, 30)
  btnSex1.text = "男"
  btnSex1.name = 1
  btnSex1.select()
  btnSex1.onClick = () => {
    if (sexSelectItem) sexSelectItem.unselect()
    btnSex1.select()
    sexSelectItem = btnSex1
  }
  sexSelectItem = btnSex1

  btnSex2 = new UIObj.UIButton(GameMakenameUI, 110, 50, 30)
  btnSex2.text = "女"
  btnSex2.name = 0
  btnSex2.onClick = () => {
    if (sexSelectItem) sexSelectItem.unselect()
    btnSex2.select()
    sexSelectItem = btnSex2
  }

  btnName0 = new UIObj.UIButton(GameMakenameUI, 60, 90, 100)
  btnName0.text = _g.Player.NameList[0]
  btnName0.name = 0
  btnName0.select()
  btnName0.onClick = () => {
    if (nameSelectItem) nameSelectItem.unselect()
    btnName0.select()
    nameSelectItem = btnName0
  }
  nameSelectItem = btnName0

  btnName1 = new UIObj.UIButton(GameMakenameUI, 60, 120, 100)
  btnName1.text = _g.Player.NameList[1]
  btnName1.name = 1
  btnName1.onClick = () => {
    if (nameSelectItem) nameSelectItem.unselect()
    btnName1.select()
    nameSelectItem = btnName1
  }

  btnName2 = new UIObj.UIButton(GameMakenameUI, 60, 150, 100)
  btnName2.text = _g.Player.NameList[2]
  btnName2.name = 2
  btnName2.onClick = () => {
    if (nameSelectItem) nameSelectItem.unselect()
    btnName2.select()
    nameSelectItem = btnName2
  }

  btnName3 = new UIObj.UIButton(GameMakenameUI, 60, 180, 100)
  btnName3.text = _g.Player.NameList[3]
  btnName3.name = 3
  btnName3.onClick = () => {
    if (nameSelectItem) nameSelectItem.unselect()
    btnName3.select()
    nameSelectItem = btnName3
  }

  btnRename = new UIObj.UIButton(GameMakenameUI, 44, 235)
  btnRename.text = "换一批名字"
  btnRename.onClick = () => {
    var data = {
      command: _g.COMMAND.MAKENAMES,
      data: _g.Player.PlayerID
    }
    wx.sendSocketMessage({
      data: JSON.stringify(data)
    })
  }

  btnSubmit = new UIObj.UIButton(GameMakenameUI, 44, 265)
  btnSubmit.text = "确定"
  btnSubmit.onClick = () => {
    btnSubmit.hide()
    btnRename.hide()
    var data = {
      command: _g.COMMAND.CREATECHARACTER,
      data: {
        nameidx: nameSelectItem.name,
        sexidx: sexSelectItem.name
      }
    }
    wx.sendSocketMessage({
      data: JSON.stringify(data)
    })
  }
  showMakenameUI()
}

exports.UpdateName = () => {
  btnName0.text = _g.Player.NameList[0]
  btnName1.text = _g.Player.NameList[1]
  btnName2.text = _g.Player.NameList[2]
  btnName3.text = _g.Player.NameList[3]
  btnSubmit.show()
  btnRename.show()
  GameWindow.show()
}

function showMakenameUI() {
  btnName0.onClick()
  btnSex1.onClick()
  btnSubmit.show()
  btnRename.show()
  GameWindow = GameMakenameUI
  GameWindow.show()
}

这样一来,我们在net.js里面需要调用这两个界面的时候,就应该这样写:

……
case _g.COMMAND.LOGIN:
        _g.Player = JSON.parse(msg.data)
        wx.getUserInfo({
          success(res) {
            _g.Player.nickName = res.userInfo.nickName
            _g.Player.avatarUrl = res.userInfo.avatarUrl
            console.log(_g.Player)
            if (_g.Player.Name === "@") {
              let nextUI = require('/UI/makename.js')
              nextUI.initialize()
            } else {
              let nextUI = require('/UI/main.js')
              nextUI.initialize()
            }
          }
        })

        break
……

所有的主界面我都设置为全局变量,方便在任何地方调用。
客户端和服务器端都修改好了……
是的,就这样就修改好了……方便得不要不要的。

不信你自己调试一下看看,是不是回传的新用户资料已经有了性别和名字了:
在这里插入图片描述
点击退出后再进来,就直接进入主界面了。服务器端也同时显示了每次命令的情况:
在这里插入图片描述
通过修改姓名和性别的功能实现,我们对代码不断的调整优化,对于后续的开发奠定了良好的基础。下一步,我们需要将玩家的角色加入到小猫小狗(不认识?你没从第一篇开始看么?)的世界,然后把世界的资料回传给客户端,从而实现玩家角色对游戏世界的第一次感知……

截止这一篇的全部代码,请大家去我的GitHub下载:
>>第十四篇代码连接<<

上一篇:C#服务端的微信小游戏——多人在线角色扮演(十三)
下一篇:C#服务端的微信小游戏——多人在线角色扮演(十五)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值