• 学Cocos Creator 3.8.0链接GoWorld自带示例ChatRoom


    下载Cocos Dashboard

    创建按一个3D项目

    场景里添加2个UI对象,按钮,编辑框

    左下添加一个TS脚本NewComponent添加到Canvas上作为按钮的组件

    TS里写

    1. onBtnClick(event, customEventData){
    2. var editBox = this.node.getChildByName("EditBox").getComponent(EditBox);
    3. console.log('按钮按下'+editBox.textLabel.string);
    4. }

    然后按钮事件挂自己的按钮节点,选择这个脚本的这个方法。

    点上面三角形运行后会直接打开Edge浏览器,F12打开浏览器调试分割窗口,点击按钮看到右边出现“按钮按下”文字

    场景名字改为login

    把官方例子的Js代码改为Ts代码调用注册:

    1. import { _decorator, Component, EditBox, EventMouse,PhysicsSystem,Node,resources,Prefab,instantiate, Vec3 ,geometry, Camera,Input,input, CameraComponent} from 'cc';
    2. import { encode,decode } from "./msgpack-ts-master/src"
    3. const { ccclass, property } = _decorator;
    4. const _RECV_PAYLOAD_LENGTH = 1
    5. const _RECV_PAYLOAD = 2
    6. const CLIENTID_LENGTH = 16
    7. const ENTITYID_LENGTH = 16
    8. const SIZE_FIELD_SIZE = 4
    9. const MT_INVALID = 0
    10. // Server Messages
    11. const MT_SET_GAME_ID = 1
    12. const MT_SET_GATE_ID = 2
    13. const MT_NOTIFY_CREATE_ENTITY = 3
    14. const MT_NOTIFY_DESTROY_ENTITY = 4
    15. const MT_DECLARE_SERVICE = 5
    16. const MT_UNDECLARE_SERVICE = 6
    17. const MT_CALL_ENTITY_METHOD = 7
    18. const MT_CREATE_ENTITY_ANYWHERE = 8
    19. const MT_LOAD_ENTITY_ANYWHERE = 9
    20. const MT_NOTIFY_CLIENT_CONNECTED = 10
    21. const MT_NOTIFY_CLIENT_DISCONNECTED = 11
    22. const MT_CALL_ENTITY_METHOD_FROM_CLIENT = 12
    23. const MT_SYNC_POSITION_YAW_FROM_CLIENT = 13
    24. const MT_NOTIFY_ALL_GAMES_CONNECTED = 14
    25. const MT_NOTIFY_GATE_DISCONNECTED = 15
    26. const MT_START_FREEZE_GAME = 16
    27. const MT_START_FREEZE_GAME_ACK = 17
    28. // Message types for migrating
    29. const MT_MIGRATE_REQUEST = 18
    30. const MT_REAL_MIGRATE = 19
    31. const MT_GATE_SERVICE_MSG_TYPE_START = 1000
    32. const MT_REDIRECT_TO_GATEPROXY_MSG_TYPE_START = 1001 // messages that should be redirected to client proxy
    33. const MT_CREATE_ENTITY_ON_CLIENT = 1002
    34. const MT_DESTROY_ENTITY_ON_CLIENT = 1003
    35. const MT_NOTIFY_MAP_ATTR_CHANGE_ON_CLIENT = 1004
    36. const MT_NOTIFY_MAP_ATTR_DEL_ON_CLIENT = 1005
    37. const MT_NOTIFY_LIST_ATTR_CHANGE_ON_CLIENT = 1006
    38. const MT_NOTIFY_LIST_ATTR_POP_ON_CLIENT = 1007
    39. const MT_NOTIFY_LIST_ATTR_APPEND_ON_CLIENT = 1008
    40. const MT_CALL_ENTITY_METHOD_ON_CLIENT = 1009
    41. const MT_UPDATE_POSITION_ON_CLIENT = 1010
    42. const MT_UPDATE_YAW_ON_CLIENT = 1011
    43. const MT_SET_CLIENTPROXY_FILTER_PROP = 1012
    44. const MT_CLEAR_CLIENTPROXY_FILTER_PROPS = 1013
    45. // add more ...
    46. const MT_REDIRECT_TO_GATEPROXY_MSG_TYPE_STOP = 1500
    47. const MT_CALL_FILTERED_CLIENTS = 1501
    48. const MT_SYNC_POSITION_YAW_ON_CLIENTS = 1502
    49. // add more ...
    50. const MT_GATE_SERVICE_MSG_TYPE_STOP = 2000
    51. export class ClientEntity{
    52. ID:string;
    53. isPlayer=false;
    54. owner:NewComponent=null;
    55. typeName:string=null;
    56. attrs:{ [key: string]: any; } ={};
    57. main:NewComponent;
    58. create(owner:NewComponent, typeName:string, entityID:string, attrs:Uint8Array) {
    59. this.owner = owner
    60. this.typeName = typeName
    61. this.ID = entityID
    62. this.attrs = attrs
    63. this.isPlayer = false
    64. }
    65. onCreated() {
    66. if (this.typeName == "Account") {
    67. console.log("Account created, start logining...")
    68. }
    69. }
    70. onBecomePlayer() {
    71. let scene = cc.director.getScene()
    72. console.log("获得玩家对象:", this, scene.name)
    73. if (this.typeName == "Avatar") {
    74. // 玩家登录成功!
    75. this.getGoWorld().onAvatarLoginSuccess( this )
    76. } else if (this.typeName == "Account") {
    77. // 账号创建成功,可以开始登陆
    78. if (scene.name != "login") {
    79. cc.director.loadScene("login");
    80. }
    81. }
    82. }
    83. onCall(method, ...args:Uint8Array[]) {
    84. console.log(this+",onCall,"+method+"("+args+")")
    85. // this[method](...args)
    86. this[method](args)//20230929
    87. }
    88. ShowInfo(msg){
    89. console.info(msg)
    90. }
    91. // Put Client Methods Here
    92. ShowError(msg:string) {
    93. // this.getGoWorld().showErrorTip(msg)
    94. console.error('ShowError'+msg);
    95. }
    96. DisplayAttack(playerID:string):void {
    97. // ClientEntity player = GoWorld.GetEntity (playerID);
    98. let player = this.main.entities[playerID];
    99. console.warn (this + " attack " + playerID + " " + player);
    100. // Vector3 startPos = this.gameObject.transform.position;
    101. // Vector3 endPos = player.gameObject.transform.position;
    102. // startPos.y = 0.5f;
    103. // endPos.y = 0.5f;
    104. // lineRenderer.SetPosition(0, startPos);
    105. // lineRenderer.SetPosition (1, endPos);
    106. // lineRenderer.enabled = true;
    107. // attackTime = Time.time;
    108. }
    109. applyMapAttrChange(path:{[key:string]:any}, key:string, val:any) {
    110. let attr = this.getAttrByPath(path)
    111. var rootkey = path!=null&&path.length > 0 ? path[0] : key
    112. attr[key] = val
    113. var methodName = 'onAttrChange_'+rootkey;
    114. console.log('methodName=',methodName);
    115. this[methodName]();
    116. }
    117. getAttrByPath(path:any): any {
    118. var attr = this.attrs
    119. if(path==null)
    120. return attr;
    121. for (var i=0; i< path.length;i++) {
    122. let key = path[i]
    123. attr = attr[key]
    124. }
    125. return attr
    126. }
    127. onAttrChange_action(){
    128. console.log('onAttrChange_action,'+this.attrs['action']);
    129. }
    130. onAttrChange_hp(){
    131. console.log('onAttrChange_hp,'+this.attrs['hp']);
    132. }
    133. onAttrChange_name(){
    134. console.log('onAttrChange_name,'+this.attrs['name']);
    135. }
    136. onAttrChange_lv(){
    137. console.log('onAttrChange_lv,'+this.attrs['lv']);
    138. }
    139. onAttrChange_hpmax(){
    140. console.log('onAttrChange_hpmax,'+this.attrs['hpmax']);
    141. }
    142. }
    143. @ccclass('NewComponent')
    144. export class NewComponent extends Component {
    145. ID="ID_TEST";
    146. // entities:Record;
    147. recvBuf = new ArrayBuffer(0);
    148. recvStatus = _RECV_PAYLOAD_LENGTH;
    149. recvPayloadLen = 0;
    150. entities : { [key: string]: ClientEntity; } ={};
    151. sendBuf = new ArrayBuffer(1024*1024);
    152. _sendPacket = new DataView(this.sendBuf);
    153. _sendPacketWritePos = SIZE_FIELD_SIZE;
    154. player:ClientEntity=null;
    155. editBox:EditBox=null;
    156. plane:Node;
    157. camera:CameraComponent
    158. start() {
    159. let main = this;
    160. this.plane=this.node.parent.getChildByName("Plane");
    161. this.camera=this.node.parent.getChildByName("Main Camera").getComponent(CameraComponent);
    162. input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
    163. resources.load("Cube", Prefab, (err, prefab) => {
    164. console.log('resources.load callback',err,prefab);
    165. const newNode = instantiate(prefab);
    166. this.plane.addChild(newNode);
    167. newNode.position =new Vec3(-3,0,0);
    168. console.log('resources.load newNode',newNode);
    169. });
    170. // this.recvBuf = new ArrayBuffer()
    171. // this.recvStatus = _RECV_PAYLOAD_LENGTH
    172. // this.recvPayloadLen = 0
    173. // this.entities = {}
    174. // this.sendBuf = new ArrayBuffer(1024*1024);
    175. // this._sendPacket = new DataView(this.sendBuf);
    176. // this._sendPacketWritePos = SIZE_FIELD_SIZE
    177. this.editBox = this.node.getChildByName("EditBox").getComponent(EditBox);
    178. // this.editBox.string = 'asdf';
    179. this.connect();
    180. }
    181. update(deltaTime: number) {
    182. }
    183. onMouseUp(eventMouse: EventMouse) {
    184. // if (event.getButton() === 0) {
    185. // this.jumpByStep(1);
    186. // } else if (event.getButton() === 2) {
    187. // this.jumpByStep(2);
    188. // }
    189. // }
    190. let ray = new geometry.Ray();
    191. this.camera.screenPointToRay(eventMouse.getLocationX(), eventMouse.getLocationY(), ray);
    192. // 以下参数可选
    193. const mask = 0xffffffff;
    194. const maxDistance = 10000000;
    195. const queryTrigger = true;
    196. console.log( eventMouse );
    197. console.log( ray );
    198. if (PhysicsSystem.instance.raycastClosest(ray)){//}, mask, maxDistance, queryTrigger)) {
    199. const raycastClosestResult = PhysicsSystem.instance.raycastClosestResult;
    200. const hitPoint = raycastClosestResult.hitPoint
    201. const hitNormal = raycastClosestResult.hitNormal;
    202. const collider = raycastClosestResult.collider;
    203. const distance = raycastClosestResult.distance;
    204. console.log( collider.node.name , hitPoint );
    205. }
    206. }
    207. onBtnClick(event, customEventData){
    208. // var editBox = this.node.getChildByName("EditBox").getComponent(EditBox);
    209. console.log('按钮按下,edit='+this.editBox.string);
    210. let account = this.getEntityByType("Account")
    211. this.callServer(account,"Register",this.editBox.string,"asdf");
    212. }
    213. onLogin() {
    214. // let loginUser = cc.find("loginUser").getComponent("cc.EditBox").string
    215. // let loginPwd = cc.find("loginPwd").getComponent("cc.EditBox").string
    216. console.log("登录...", this.editBox.string, "asdf" )
    217. let account = this.getEntityByType("Account")
    218. console.log("account", account !== null ? account.toString():null)
    219. if (account === null) {
    220. console.error("正在连接服务器,请耐心等待")
    221. return
    222. }
    223. // if (loginUser == "" || loginPwd == "") {
    224. // console.error("请输入用户名和密码!")
    225. // return
    226. // }
    227. this.callServer(account,"Login", this.editBox.string, "asdf")
    228. }
    229. getEntityByType(typeName) {
    230. for (var eid in this.entities) {
    231. let e = this.entities[eid]
    232. if (e.typeName == typeName) {
    233. return e
    234. }
    235. }
    236. return null
    237. }
    238. callServer(entity:ClientEntity, method , ...args2) {
    239. var args = Array.prototype.slice.call(arguments);
    240. args = args.slice(2)
    241. this.callServerMethod( entity, method, args )
    242. }
    243. callServerMethod(entity:ClientEntity, method:string, args) {
    244. console.log(">>> "+entity+"."+method+"("+args+")")
    245. // packet.AppendUint16(MT_CALL_ENTITY_METHOD_FROM_CLIENT)
    246. // packet.AppendEntityID(id)
    247. // packet.AppendVarStr(method)
    248. // packet.AppendArgs(args)
    249. this.appendUint16(MT_CALL_ENTITY_METHOD_FROM_CLIENT)
    250. this.appendEntityID(entity.ID)
    251. this.appendVarStr(method)
    252. this.appendArgs(args)
    253. this.sendPacket()
    254. }
    255. appendUint16(v) {
    256. this._sendPacket.setUint16(this._sendPacketWritePos, v, true)
    257. this._sendPacketWritePos += 2
    258. }
    259. appendEntityID(eid) {
    260. console.log(eid);
    261. let b = this.string2Uint8Array(eid)
    262. console.log("convert", eid, "to", b, b.length)
    263. this.appendBytes(b)
    264. }
    265. string2Uint8Array(str) {
    266. console.log(str);
    267. let bufView = new Uint8Array(str.length);
    268. for (var i=0, strLen=str.length; i
    269. bufView[i] = str.charCodeAt(i);
    270. }
    271. return bufView;
    272. }
    273. appendBytes(b) {
    274. new Uint8Array(this._sendPacket.buffer, this._sendPacketWritePos, b.length).set(b, 0);
    275. this._sendPacketWritePos += b.length
    276. }
    277. appendVarStr(s) {
    278. let b = this.string2Uint8Array(s)
    279. this.appendVarBytes(b)
    280. }
    281. appendVarBytes(b) {
    282. this.appendUint32(b.length)
    283. this.appendBytes(b)
    284. }
    285. appendUint32(v) {
    286. this._sendPacket.setUint32(this._sendPacketWritePos, v, true)
    287. this._sendPacketWritePos += 4
    288. }
    289. appendArgs(args) {
    290. console.log("appendArgs", args.length, args)
    291. this.appendUint16(args.length)
    292. for (var i=0; ilength;i++) {
    293. this.appendData(args[i])
    294. }
    295. }
    296. appendData(data) {
    297. data = encode(data)
    298. console.log("msgpack encode:", typeof(data), data.length)
    299. this.appendVarBytes(data)
    300. }
    301. sendPacket() {
    302. let payloadLen = this._sendPacketWritePos - SIZE_FIELD_SIZE
    303. this._sendPacket.setUint32(0, payloadLen, true)
    304. let packetLen = this._sendPacketWritePos
    305. this._sendPacketWritePos = SIZE_FIELD_SIZE
    306. console.log("sendPacket:", packetLen)
    307. this.websocket.send(this.sendBuf.slice(0, packetLen))
    308. }
    309. websocket : WebSocket = null;
    310. connect() {
    311. var serverAddr='localhost';
    312. var serverPort=15101;
    313. var serverAddr = 'ws://'+serverAddr+':'+serverPort+'/ws'
    314. console.log("正在连接 " + serverAddr + ' ...')
    315. var websocket = new WebSocket(serverAddr)
    316. this.websocket = websocket
    317. websocket.binaryType = 'arraybuffer'
    318. console.log(websocket)
    319. var gameclient = this
    320. //连接发生错误的回调方法
    321. websocket.onerror = function () {
    322. console.log("WebSocket连接发生错误");
    323. };
    324. //连接成功建立的回调方法
    325. websocket.onopen = function () {
    326. console.log("WebSocket连接成功");
    327. }
    328. //接收到消息的回调方法
    329. websocket.onmessage = function (event) {
    330. var data = event.data
    331. console.log("收到数据:", typeof(data), data.length);
    332. gameclient.onRecvData(data)
    333. }
    334. //连接关闭的回调方法
    335. websocket.onclose = function () {
    336. console.log("WebSocket连接关闭");
    337. }
    338. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    339. window.onbeforeunload = function () {
    340. console.log("onbeforeunload");
    341. }
    342. }
    343. onRecvData(data) {
    344. if (this.recvBuf.byteLength == 0) {
    345. this.recvBuf = data
    346. } else {
    347. var tmp = new Uint8Array( this.recvBuf.byteLength + data.byteLength );
    348. tmp.set( new Uint8Array( this.recvBuf ), 0 );
    349. tmp.set( new Uint8Array( data ), this.recvBuf.byteLength );
    350. this.recvBuf = tmp.buffer
    351. }
    352. console.log("未处理数据:", this.recvBuf.byteLength)
    353. while (true) {
    354. let payload = this.tryReceivePacket()
    355. if (payload !== null) {
    356. this.onReceivePacket(payload)
    357. } else {
    358. break
    359. }
    360. }
    361. }
    362. // 从已经收到的数据(recvBuf)里解析出数据包(Packet)
    363. tryReceivePacket() {
    364. let recvBufView = new DataView(this.recvBuf)
    365. if (this.recvStatus == _RECV_PAYLOAD_LENGTH) {
    366. if (this.recvBuf.byteLength < SIZE_FIELD_SIZE) {
    367. return null
    368. }
    369. this.recvPayloadLen = recvBufView.getUint32(0, true)
    370. console.log("数据包大小: ", this.recvPayloadLen)
    371. this.recvStatus = _RECV_PAYLOAD
    372. }
    373. // recv status == _RECV_PAYLOAD
    374. console.log("包大小:", this.recvPayloadLen, "现有数据:", this.recvBuf.byteLength - SIZE_FIELD_SIZE)
    375. if (this.recvBuf.byteLength - SIZE_FIELD_SIZE < this.recvPayloadLen) {
    376. // payload not enough
    377. return null
    378. }
    379. // 足够了,返回包数据
    380. var payload = this.recvBuf.slice(SIZE_FIELD_SIZE, SIZE_FIELD_SIZE+this.recvPayloadLen)
    381. this.recvBuf = this.recvBuf.slice(SIZE_FIELD_SIZE+this.recvPayloadLen)
    382. // 恢复到接收长度状态
    383. this.recvStatus = _RECV_PAYLOAD_LENGTH
    384. this.recvPayloadLen = 0
    385. return payload
    386. }
    387. onReceivePacket (payload2) {
    388. // payload is ArrayBuffer
    389. payload = new DataView(payload2) // 转换为DataView便于操作
    390. var [msgtype, payload] = this.readUint16(payload)
    391. console.log("收到包:", payload, payload.byteLength, ",消息类型:", msgtype)
    392. if (msgtype != MT_CALL_FILTERED_CLIENTS && msgtype != MT_SYNC_POSITION_YAW_ON_CLIENTS) {
    393. var [dummy, payload] = this.readUint16(payload)
    394. console.log("gateid", dummy)
    395. var [dummy2, payload] = this.readBytes(payload, CLIENTID_LENGTH) // read ClientID
    396. console.log("clientid", dummy2.length)
    397. }
    398. if (msgtype == MT_CREATE_ENTITY_ON_CLIENT) {
    399. this.handleCreateEntityOnClient(payload)
    400. } else if (msgtype == MT_CALL_ENTITY_METHOD_ON_CLIENT) {
    401. this.handleCallEntityMethodOnClient(payload)
    402. } else if (msgtype == MT_DESTROY_ENTITY_ON_CLIENT) {
    403. this.handleDestroyEntityOnClient(payload)
    404. } else if (msgtype == MT_CALL_FILTERED_CLIENTS) {
    405. this.handleCallFilteredClients(payload)
    406. } else if (msgtype == MT_NOTIFY_MAP_ATTR_CHANGE_ON_CLIENT) {
    407. this.handleNotifyMapAttrChangeOnClient(payload)
    408. } else if (msgtype == MT_NOTIFY_MAP_ATTR_DEL_ON_CLIENT) {
    409. } else if (msgtype == MT_NOTIFY_LIST_ATTR_APPEND_ON_CLIENT) {
    410. } else if (msgtype == MT_NOTIFY_LIST_ATTR_CHANGE_ON_CLIENT) {
    411. } else if (msgtype == MT_NOTIFY_LIST_ATTR_POP_ON_CLIENT) {
    412. } else if (msgtype == MT_SYNC_POSITION_YAW_ON_CLIENTS) {
    413. this.handleSyncPositionYawOnClients(payload)
    414. } else {
    415. console.error("无法识别的消息类型:"+msgtype)
    416. }
    417. }
    418. handleSyncPositionYawOnClients(payload:DataView):void
    419. {
    420. while(0 < payload.byteLength)// while (pkt.UnreadPayloadLen > 0)
    421. {
    422. console.log('payload.byteOffset,payload.byteLength',payload.byteOffset,payload.byteLength)
    423. var [entityID, payload] = this.readEntityID(payload)// string entityID = pkt.ReadEntityID();
    424. // float x = pkt.ReadFloat32();
    425. // float y = pkt.ReadFloat32();
    426. // float z = pkt.ReadFloat32();
    427. // float yaw = pkt.ReadFloat32();
    428. var [x, payload] = this.readFloat32(payload)
    429. console.log('payload.byteOffset,payload.byteLength',payload.byteOffset,payload.byteLength)
    430. var [y, payload] = this.readFloat32(payload)
    431. console.log('payload.byteOffset,payload.byteLength',payload.byteOffset,payload.byteLength)
    432. var [z, payload] = this.readFloat32(payload)
    433. console.log('payload.byteOffset,payload.byteLength',payload.byteOffset,payload.byteLength)
    434. var [yaw, payload] = this.readFloat32(payload)
    435. console.log('payload.byteOffset,payload.byteLength',payload.byteOffset,payload.byteLength)
    436. // EntityManager.Instance.OnSyncEntityInfo(entityID, x, y, z, yaw);
    437. console.log('handleSyncPositionYawOnClients',entityID,x,y,z,yaw)
    438. }
    439. }
    440. handleNotifyMapAttrChangeOnClient(payload:DataView) {
    441. var [entityID, payload] = this.readEntityID(payload)
    442. var [path, payload] = this.readData(payload)
    443. var [key, payload] = this.readVarStr(payload)
    444. var [val, payload] = this.readData(payload)
    445. console.log("MT_NOTIFY_MAP_ATTR_CHANGE_ON_CLIENT", entityID, "path", typeof(path), JSON.stringify(path), "key", key, "val", val)
    446. // console.log("MT_NOTIFY_MAP_ATTR_CHANGE_ON_CLIENT", entityID, "path", typeof(path), JSON.stringify(path), path.length, "key", key, "val", val)
    447. let e = this.entities[entityID]
    448. if (!e) {
    449. console.log("找不到对象:"+entityID)
    450. return
    451. }
    452. e.applyMapAttrChange( path, key, val )
    453. }
    454. readUint8(buf:DataView):[any,DataView] {
    455. let v = buf.getUint8(0)
    456. return [v, new DataView(buf.buffer, buf.byteOffset+1)]
    457. }
    458. readUint16(buf:DataView):[any,DataView] {
    459. let v = buf.getUint16(0, true)
    460. return [v, new DataView(buf.buffer, buf.byteOffset+2)]
    461. }
    462. readUint32(buf:DataView) :[any,DataView]{
    463. let v = buf.getUint32(0, true)
    464. return [v, new DataView(buf.buffer, buf.byteOffset+4)]
    465. }
    466. readFloat32(buf:DataView) :[Number,DataView]{
    467. let v = buf.getFloat32(0, true)
    468. return [v, new DataView(buf.buffer, buf.byteOffset+4)]
    469. }
    470. readBytes(buf:DataView, length) :[Uint8Array,DataView]{
    471. let v = new Uint8Array(buf.buffer, buf.byteOffset, length)
    472. return [v, new DataView(buf.buffer, buf.byteOffset+length)]
    473. }
    474. readVarBytes(buf:DataView) :[Uint8Array,DataView]{
    475. var [n, buf] = this.readUint32(buf)
    476. var [b, buf] = this.readBytes(buf, n)
    477. console.log('VarBytes len', n, 'b', b.length)
    478. return [b, buf]
    479. }
    480. readEntityID(buf:DataView) :[string,DataView]{
    481. var [eid, buf] = this.readBytes(buf, ENTITYID_LENGTH)
    482. var eid2 = this.uint8Array2String(eid)
    483. return [eid2, buf]
    484. }
    485. readVarStr(buf:DataView) :[any,DataView]{
    486. var [b, buf] = this.readVarBytes(buf)
    487. let s = this.uint8Array2String(b)
    488. return [s, buf]
    489. }
    490. readBool(buf):[any,DataView] {
    491. var b
    492. [b, buf] = this.readUint8(buf)
    493. b = b == 0 ? false : true
    494. return [b, buf]
    495. }
    496. readData(buf:DataView):[any,DataView] {
    497. var [b, buf] = this.readVarBytes(buf)
    498. let data = decode(b)//二进制转对象(带具体类型),反序列化,功能很强 20230929
    499. return [data, buf]
    500. // return [b, buf]
    501. }
    502. readArgs(buf:DataView) :[any[],DataView]{
    503. var [argcount, buf] = this.readUint16(buf)
    504. console.log("readArgs: argcount", argcount)
    505. var args = new Array<any>(argcount)
    506. for (var i = 0; i
    507. var [data, buf] = this.readData(buf)
    508. args[i] = data
    509. }
    510. return [args, buf]
    511. }
    512. handleCreateEntityOnClient(payload:DataView) {
    513. var [isPlayer, payload] = this.readBool(payload)
    514. var [eid, payload] = this.readEntityID(payload)
    515. var [typeName, payload] = this.readVarStr(payload)
    516. var [x, payload] = this.readFloat32(payload)
    517. var [y, payload] = this.readFloat32(payload)
    518. var [z, payload] = this.readFloat32(payload)
    519. var [yaw, payload] = this.readFloat32(payload)
    520. var [clientData,payload] = this.readVarBytes(payload)
    521. clientData = decode(clientData)
    522. console.log("MT_CREATE_ENTITY_ON_CLIENT", "isPlayer", isPlayer, 'eid', eid,"typeName", typeName, 'position', x, y, z, 'yaw', yaw, 'clientData', JSON.stringify(clientData))
    523. var e = new ClientEntity()
    524. e.main=this;
    525. e.create( this, typeName, eid, clientData )
    526. this.entities[eid] = e
    527. if (isPlayer) {
    528. e.isPlayer = true
    529. if (this.player) {
    530. // dupliate player!!!
    531. console.error("玩家对象重复:老玩家"+this.player.toString() + ",新玩家:", e.toString())
    532. }
    533. this.player = e
    534. }
    535. this.onEntityCreated(e)
    536. e.onCreated()
    537. if (this.player === e) {
    538. e.onBecomePlayer()
    539. }
    540. }
    541. onEntityCreated(e) {
    542. console.log("entity created:", e.toString())
    543. }
    544. uint8Array2String(b) :string{
    545. return String.fromCharCode.apply(null, b)
    546. }
    547. handleDestroyEntityOnClient(payload:DataView) {
    548. // typeName := packet.ReadVarStr()
    549. // entityID := packet.ReadEntityID()
    550. var [typeName, payload] = this.readVarStr(payload)
    551. var [entityID, payload] = this.readEntityID(payload)
    552. let e = this.entities[entityID]
    553. if (e == undefined) {
    554. return
    555. }
    556. delete this.entities[entityID]
    557. if (this.player === e) {
    558. this.player = null
    559. console.log("失去玩家对象:", e.toString())
    560. }
    561. }
    562. handleCallEntityMethodOnClient(payload:DataView) {
    563. // entityID := packet.ReadEntityID()
    564. // method := packet.ReadVarStr()
    565. // args := packet.ReadArgs()
    566. var [entityID, payload] = this.readEntityID(payload)
    567. var [method, payload] = this.readVarStr(payload)
    568. var [args, payload] = this.readArgs(payload)
    569. console.log("MT_CALL_ENTITY_METHOD_ON_CLIENT", "entityID", entityID, "method", method, "args", args.length, args)
    570. let e = this.entities[entityID]
    571. if (e == undefined) {
    572. console.log("找不到entity:", entityID)
    573. return
    574. }
    575. e.onCall( method, ...args )
    576. }
    577. handleCallFilteredClients(payload:DataView) {
    578. var [fkey, payload] = this.readVarStr(payload)
    579. var [fval, payload] = this.readVarStr(payload)
    580. var [method, payload] = this.readVarStr(payload)
    581. var [args, payload] = this.readArgs(payload)
    582. console.log("MT_CALL_FILTERED_CLIENTS", fkey, "=", fval, "method=", method, "args=", args)
    583. this.player.onCall( method, ...args )
    584. }
    585. }

    raycastClosest要加了BoxCollider才能生效

    完整Cocos Creator 3.8项目同步到:

    git@gitee.com:griffon2/go-world-unit-demo-cocos-creator38.git

  • 相关阅读:
    Power BI vs Superset BI 调研报告
    pyarmor 加密许可证的使用
    RFID智能档案柜助力各大银行实现RFID智能档案管理
    Linux内核驱动开发-001字符设备开发-内核中断驱动独立按键
    ArrayBlockingQueue源码分析
    上下文管理器与with关键字为业务增加辅助功能
    如何在ownCloud/NextCloud/丰盘ECM等免费企业网盘集成在线Office?
    关于TCP协议面试中常见的一千个问题
    生产环境TiDB集群缩容TiKV操作步骤
    石油数字孪生可视化管理平台,推动石油行业数字化转型与智能化应用
  • 原文地址:https://blog.csdn.net/brook0344/article/details/133234564