Organizations

  • AntD的前端设计(三) 在这之前已经完成网络请求推送用于前端和服务端进行交互, Login 接口已经完备只差授权机制验证了. 官方提供了 认证机制文档 现在需要对之前的静态配置 config/config.ts 配置来处理: export default defineConfig({ // access 插件依赖 initial State 所以需要同时开启 // 传入空对象则默认开启 access: {}, initialState: {}, // 其他略 }) 之后就是定义过滤器, 编写需要修改权限过滤文件 ( src/access.ts ): // 在这里按照初始化数据定义项目中的权限,统一管理 // 参考文档 https://umijs.org/docs/max/access import {useModel} from "@@/exports"; export default () => { const {isLogin} = useModel('global'); const isCheckAuth = isLogin(); // 直接返回权限类型, 确认是否可以通过 return { isCheckAuth: isCheckAuth }; };
    前端 后台设计 Created Tue, 16 Apr 2024 21:31:01 +0800
  • AntD的前端设计(二) 之前只讲如何配置 RequestConfig 和 ResponseStructure, 这里面内部其实就是为了保持和服务端消息同步, 日常消息协议格式我都采取以下方式: // 常规消息结构体 { "error": 0, "message": "success", "data": {}, } // 这里提供登录授权完成和数据分页完成格式的返回示例 // 1. 授权完成 { "error": 0, "message": "success", "data": { "uid": 1, "username": "meteorcat", "nickname": "MeteorCat", "token": "97ba4dd71592c7b26bc90308806d42f3" }, } // 2. 分页返回, 分页返回有两种: // 2.1 前端推送页数(page)和数据量(total), 服务端返回当前页和总页数(list,page,total) // 2.2 前端推送偏移两(offset)和数据量(total), 服务端返回当前页和总页数(list,page,total) { "error": 0, "message": "success", "data": { "list": [ { "id": 1, "name": "MeteorCat" }, // 其他数据 ], "page": 1, // 数据分页页码 "total": 10, // 总共数据页数 } } 大部分业务都是围绕数据流展示( 像是支付订单|人员流失的查询 )和图表分析( 后台返回数据JSON格式 ), 基本上面那些方式够用了.
    前端 后台设计 Created Tue, 16 Apr 2024 14:27:54 +0800
  • AntD的前端设计(一) 之前搭建完了脚手架环境, 现在优先了解配置文件优先在哪配置: // 这里可以查看到定义配置, 这里就是以项目做根目录 // 文件路径: .umirc.ts import {defineConfig} from '@umijs/max'; export default defineConfig({ antd: {}, access: {}, model: {}, initialState: {}, // 网络请求配置 request: { // 获取消费服务端数据默认初始数据对象 key 为 data // { error:0, message:"success", data:{} }, 这样直接提取 data 而非初始 error/message/data dataField: 'data', }, // layout 配置, title 就是标题名称 // 具体配置说明查看: https://pro.ant.design/zh-CN/docs/title-landing layout: { // logo 标志 logo: 'https://img.alicdn.com/tfs/TB1YHEpwUT1gK0jSZFhXXaAtVXa-28-27.svg', // 页面标题 title: 'Mix管理后台', // 是否采用国际化, 如果不需要国际化直接关闭还能节省开发时间 menu: false, }, // 定义静态路由 // 具体配置说明查看: https://pro.
    前端 后台设计 Created Sat, 13 Apr 2024 01:04:47 +0800
  • AntD的前端设计(零) 因为多年至今都是侧重点偏服务端对于美术设计方面可能接触这么深入, 这时候就要公司项目需要抓紧上马服务后台设计, 虽然日常用 boostrap+jquery 就能搭建好常用后台, 但是时代也是在进步所以需要学习更新易用的后台前端框架来适应. 在终端选型之中找到几个备选方案: Vue+ElementUI React+AntDesign Vue+AntDesign 在最后考虑之后最终定型 React+Ant, 注意采用 AntDesignPro 集成大量的脚手架组件. Umi官网: umi(ant.design) 这里先搭建好最新脚手架服务: # 首先创建新目录并且进入等待初始化 mkdir myapp && cd myapp # 使用 npx 下载 umi 脚手架, 内部支持选择 ant-d 框架 npx create-umi@latest # 生成构建 Ant-D 模板 > Pick Umi App Template › - Use arrow-keys. Return to submit. # Simple App # > Ant Design Pro # Vue Simple App # 之后配置 npm 执行器和镜像地址等待下载完成没问题 # 现在的项目根目录就是 `myapp` 搭建完成的时候直接启动服务测试即可:
    前端 后台设计 Created Fri, 12 Apr 2024 20:38:26 +0800
  • 网络游戏的场景同步 回归到游戏本质就是对于游戏客户端角色的操控, 单机游戏客户端通过操作指令来操作让其位移; 如果架构在网络游戏该怎么规划? 怎么把这方面的指令操作移交到服务端执行? 对于网络游戏来说, 客户端传上来的有可能是伪造数据, 最常见开启 变速齿轮 让游戏环境速度加速的情况, 这时候客户端肆无忌惮手动数据封包推送大量数据打乱游戏内部所有平衡. 但还有种情况是不需要在服务端频繁维护玩家实体状态, 场景中位移频繁都要提交到服务端对于CPU消耗比较庞大, 而有的场景实际上不具有太大的意义. 最常见的某些场景约等于材料本( 游戏中负责材料产出的副本 ), 这种玩家支付体力实际上只需最后结算奖励发放, 所以没必要同步太多细节. 需要明确几种游戏环境情况, 根据这些游戏环境才需要判断是否是否需要同步客户端场景同步: 多人同步: 这种是最常见需要同步操作场景, 因为场景内状态并不是单个玩家拥有的, 需要实时推送给同场景的不同玩家客户端 对战同步: 双人对战竞技场这种也是比较广泛场景, 常见用于双方竞技排名的情况, 最后决出的就是竞技分数和输赢情况 大逃杀模式: 最近兴起的多玩家在大地图互相猎杀的游戏, 这里面设计区域分块设计和多玩家状态同步设计, 这种中小厂目前没有驾驭的能力 塔防游戏: 塔防需要有具体的出怪逻辑和建筑攻击不断算血, 所以需要定时模拟计算攻击范围和血量变动. 上面就是比较常见的情况, 其实能够看出具体大部分都是强交互的情况, 这些情况也十分消耗CPU资源; 因为本身作为单机调用 Update 的情况就十分频繁, 而现在需要上万同时在线请求来维持游戏运转, 可以想象你上万人同时在线游玩来执行服务器的 Update 的 CPU 消耗也是非常惊人的. 偏轻度弱交互的移动端游戏, 则尽可能避免这种频繁需要消耗服务端 CPU 情况, 所以对于明确平台是移动端大部分采用相对简单的状态同步方式而非频繁帧同步. 建议如果对游戏服务端没有概念的, 可以先学习 skynet 试着学习 agent 概念设计和实现; 其中最主要概念就是对于单人在场景和玩法之中其实在服务端看来就是对自己所在数据的 自娱自乐, 轻度弱交互其实就是游玩游戏策划提供的玩法并且写入到服务端数据库. 这里按照最常见游戏帧( 60帧=Update每1/60s执行,30帧=Update每1/30s执行 ), 这种情况下需要在服务端动态创建 Update 定时器来处理. 高频率定时器 1/60s=16.7ms, 所以需要构建出 16.
    Godot 游戏开发 Created Sun, 07 Apr 2024 13:27:59 +0800
  • 建筑系统构建 网络游戏当中比较常见建筑功能经过大量版本迭代, 移动端为了节约性能消耗从地图区块拖动放置演变到固定建筑解锁; 这里先从客户端说明怎么去设计两种系统, 基本上只需要掌握这两种方式就能应对: PixelBuild: 允许玩家拖动建筑在平面上建成单位, 只要在平面不冲突就允许灵活构建单位 UnlockBuild: 平面上已经预设好建筑单位, 只需要按照条件激活该建筑进行工作 两者首先是必须要生成平面, 这里采用 Godot 来编写样例( Unity|UE 实际上思路也差不多 ); 现在构建最简单的生成 矿场(Gold) 和 农场(Farm), 具体自定义策划作用: Gold: 建成矿场之后 每5s 会提取游戏的金币资源到个人资源 Farm: 建成农场之后 每5s 会提取游戏的体力资源到个人资源 注意: 初始的资源收获周期是允许策划自定义的, 这里可以先考虑写死做成初版. 首先是像素点构建出建筑, 具体最后完成结果类似如下( PixelBuild ): 之后第二种建筑解锁方式就类似如下, 直接满足条件解锁激活建筑即可( UnlockBuild ): 注意: 之后内容要求具有一定服务端设计经验才能理解, 主体还是做状态同步到服务器共享. 如果想要达到满足玩家自由交互性, 最好采用 像素构建 让玩家在指定区域内选择构建建筑; 而如果只是简单想做个建筑解锁出资源点让玩家定时上线 收菜 获取收益的话, 直接采用 解锁激活 来激活建筑. 解锁建筑 这种建筑解锁方式目前大部分另外简称为 家园系统, 主要就是提供给玩家升级解锁产出游戏资源来维持游戏内部的经济系统; 以比较知名的二次元品类 “明日方舟” 为例, 初版内部就是家园解锁建筑从而生产出游戏内部货币 “龙门币” 等, 这种简单家园系统不需要太多客户端逻辑, 可能只需要 玩家等级提升|游戏货币解锁|游戏任务解锁 然后服务端协议统治下就能处理. 这方式只需要服务端去自行检查是否满足条件通知客户端解锁即可, 客户端所需要做的就是接收到协议获取多少秒之后可以领取的道具就行了
    Godot 游戏开发 Created Wed, 03 Apr 2024 20:40:56 +0800
  • Nginx多机缓存 Nginx 常用来负载均衡, 用来多个服务端反向代理内部服务器组从而获取到内部网络资源对外提供服务, 后续还有些静态资源就需要考虑多地缓存而不走直接后端流量. 常见比如网状反向服务架构, 多个对外服务Nginx同时转发到内网单机情况; 需要缓存内网资源到外部访问服务器本地, 后续资源不走内部服务器. 假设目前内网机已经部署好对外静态资源服务端, 这时候则需要在可以被对外访问得服务器上安装配置 Nginx: # 安装好 NGINX 服务 sudo apt install -y nginx 之后这里就是假设需求: 目前需要 .mp4|.mkv|.avi|.wmv 这些视频文件十分庞大且占用流量十分多, 所以在对外服务器上需要将内网服务器的资源缓存, 并且后续超时时间设定为 6 个月才重新更新缓存. 这里编写配置来处理这方面设置即可: http { # 设定 video_cache 的缓存, 路径是 /var/nginx/cache # keys_zone 设定 key 名称和名称占用, 1m 可以存放 8000 个KEY # max_size 设定目录最大空间 # use_temp_path 表示是否为临时文件缓存 # inactive 则是设定多久没有访问则清理缓存 proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=video_cache:1024m max_size=200g inactive=256d use_temp_path=off; # 这里就是具体的服务编写 server { # 其他访问设定, 略 # 拦截 .
    部署 Created Fri, 22 Mar 2024 19:45:10 +0800
  • 游戏授权登录服务端 游戏登录授权最好和游戏端脱离开来, 有时候需要接入
    Godot 游戏开发 Created Sun, 17 Mar 2024 00:34:44 +0800
  • 网络游戏在线奖励设计 在线奖励是网络游戏比较常见的, 客户端表现常见: 客户端加载在线时长奖励表 确定目前最后一次领取完时间戳 确认最后领取时间与当前时间戳差距 显示差距时间秒数确定可以被领取 点击推送指定时间戳满足条件奖励id 服务端判断是否满足,满足更新玩家资源信息 这种设计最常见早期二次元游戏品类的体力槽设计, 相当于每分钟回复1点体力然后玩家依靠体力解锁游玩副本. 这里先以最基础的在线体力增值做样例, 配置数据库字段和业务Actor来设计对应功能. 首先必须要在玩家信息实体当中挂载对应的体力相关字段, 主要用于记录玩家体力值相关数据: /** * 玩家实体对象 * 异步保存数据到数据库之中, 同时挂载在进程内存中用于读写 */ @Entity @Table(name = "tbl_player_info") public class PlayerInfoModel { /** * 玩家第三方登录uid, 这里采用主键自递增记录 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false, columnDefinition = "BIGINT COMMENT '主键ID,同时也是标识玩家UID'") private Long uid; /// 以下体力值系统是必须的 ------------------------------------------------------ /** * 体力值 */ @Column(nullable = false, columnDefinition = "INT COMMENT '体力值'") private Integer health = 10; /** * 体力值最后更新时间 */ @Column(nullable = false, columnDefinition = "BIGINT COMMENT '体力值最后更新时间'") private Long healthUpdateTime = 0L; /// 其他略.
    Godot 游戏开发 Created Thu, 14 Mar 2024 13:15:00 +0800
  • 策划CSV转JSON共享 这里可以 参考样例 日常的游戏开发中, 策划编辑配置表一般都是通过 Excel 在 Windows 环境进行配置, 如果是传统的 APP 开发, 一般都是在 WEB 网页端进行配置(在生成 JSON 下载), 所以对于 APP 开发和游戏开发这就存在里比较大的差异, 导致目前我们做很多游戏类应用玩法我们都是采用后者或者采用让产品去编辑 Json|XML 的方式, 更复杂的情况甚至去代码中编写配置表. 这里有 客户端代码库 做CSV据转JSON样例 具体表格格式如下: ##这是一个测试 ID 名字 描述 速度 int string string float 1 谢大脚 我是谢大脚 3.3 2 赵四 我不是找死 3.4 具体每一行数据的作用: 第一行: 策划的关注的表注视信息, 采用 ## 开头标识格式表( 实际上我感觉这行可有可无 ) 第二行: 需要表达的字段属性名, 可以是中文但最好是采用英语防止某些环境字符集导致的问题 第三行: 指定描述第二行对应属性的数据类型, 需要简单向策划或者产品做取值讲解让他们配置 实际上可以第一行就是字段中文含义, 第二行就是字段在代码的 key 取值, 注意策划也是必须要看懂的字段意义 优化之后我常规是这样处理: 标识 名字 描述 速度 key name desc speed int string string float 1 谢大脚 我是谢大脚 3.
    Godot 游戏开发 Created Tue, 12 Mar 2024 23:12:46 +0800