自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

白小飞

如果你的才华配不上你的野心,那就静下心来看看博客

  • 博客(798)
  • 收藏
  • 关注

原创 《大话设计模式》笔记

《大话设计模式笔记》

2023-03-04 16:47:05 455 1

原创 GameFramework——引用池&对象池

前言之前做游戏的时候用过对象池,适用于频繁使用回收的对象,可以防止对象反复生成和销毁,减少gc,之前用于人物移动的残影上。GF中有两个池子,之前一直不知道有什么区别,直到看了传送门,没错又是群主大佬的文章,才知道引用池和对象池原理一样,但是适用的对象不一样,一般引用池用于存储C#类型的对象,对象池用于Unity相关的GameObj对象。引用池打开GF源码,可以看到关于ReferencePool有这四个文件。先分别介绍这四个类和他们的功能,最后拿StarForce中的一个例子来看看~IRefere

2022-01-24 23:47:35 1552

原创 GameFramework——UI

前言刚开始做游戏时,大家就说入行了都是UI仔,证明了UI的重要性,导致我对UI框架一直有一种畏惧的心理。这次就从GF的UI加载来简单看看GF的UI框架以及它的使用在这里给大家推荐我们群主写的GF解析,写的非常好传送门打开UI界面第一视角分析,找到ProcedureMenu.cs首先订阅一个UI成功打开的事件,接下来就是一个OpenUIForm函数我们继续往上,还需要往上。此处int?代表可空类型,如果没有赋值会返回null而不是0此处我们通过读取配置表,并且加上前置路径,继续往上看

2022-01-23 00:37:51 1588

原创 GameFramework——事件系统

委托和事件要搞懂GF的事件系统,我们要先搞清楚什么是委托和事件传送门委托delegate我认为就是一种函数类型,从而可以绑定多个同种返回值,参数的函数用于同时触发,而事件event就是委托的一种特殊形式,调用后可以用于来通知(调用)处理该事件的相应方法而GF的事件系统则在触发事件的时候,传入了发送通知的本体(this)和EventArgs若要创建自定义事件数据类,请创建一个派生自类的类, EventArgs 并提供用于存储所需数据的属性。 自定义事件数据类的名称应以结束 EventArgs 。

2022-01-21 16:54:57 2023

原创 GameFramework——资源加载

前言此处的资源加载,只是简单涉及到了资源模块,并没有很详细的介绍(当然我自己也没有很详细的学习)三种模式下的资源加载可更新模式就是我们前两篇文章资源热更新的流程

2022-01-19 21:08:48 1649

原创 GameFramework——资源热更新实操

Gameframework资源热更新实际操作

2022-01-18 16:30:15 2543

原创 GameFramework——资源热更新

前言时隔俩月,继续学习GF资源更新流程目前的我学习的版本好像和这个有点出入,比如checkversion后会更新是否需要更新进入updateVersion和checkResource两个流程ProcedureCheckVersionOnEnter订阅webrequest成功或者失败的事件向服务器请求版本信息其中GameEntry.BuiltinData.BuildInfo.CheckVersionUrl在Config文件夹下的同名文件中可以进行配置OnWebRequestSuccess

2022-01-15 15:49:54 915

原创 Unity3D网络游戏实战——通用服务器框架

前言网络游戏涉及客户端和服务端。服务端程序记录玩家数据,处理客户端发来的协议。本文就介绍一套通用客户端的实现。该框架基于Select多路复用处理网络消息,具有粘包半包处理、心跳机制等功能,还是用MySQL数据库存储玩家数据,是一套功能较完备的C#服务端程序。一般单个服务端进程可以承载数百名玩家,如果更多就需要改为分布式架构。7.1服务端架构服务端两大核心是处理客户端的消息和存储玩家数据。客户端与服务端通过TCP连接,使两者可以传递数据,服务端还连接着MySQL数据库,可将玩家数据保存到数据库中。

2021-11-09 11:59:33 11232

原创 Unity3D网络游戏实战——通用客户端模块

前言书中说的是搭建一套商业级的客户端网络模块,一次搭建长期使用。本章主要是完善大乱斗游戏中的网络模块,解决粘包分包、完整发送数据、心跳机制、事件分发等功能6.1网络模块设计核心是静态类NetManager,它对外提供了一系列方法NetManager.Connect(ip,port)连接服务端NetManager.Close()NetManager.Send(msgMove)发送消息,参数为协议对象,NetManager会自动把它转换成二进制数据NetManager.Update()需外部调

2021-11-07 02:05:56 816

原创 Unity3D网络游戏实战——深入了解TCP,解决暗藏问题

前言这一章基本属于科普章节,相信看到这篇文章的人也学习过计算机网络,所以很多基础知识,比如三握四挥这些就不多说了。5.3常用TCP参数5.3.1ReceiveBufferSize指定了操作系统读缓冲区的大小,默认值8192。缓冲区满了,发送端会暂停发送数据,较大的缓冲区可以减少发送短暂停的概率,提高效率。5.3.2SendBufferSize指定操作系统写缓冲区的大小,默认值也是8192,设定的大一点也比较好~5.3.3NoDelay默认情况TCP会使用Nagle算法发送数据,因为TCP/I

2021-11-04 22:49:58 1937

原创 Unity3D网络游戏实战——正确收发数据流

前言本章主要介绍和实现怎样正确和高效地处理TCP数据(数据流)。也解决了上一章我们遇到的一些问题4.1TCP数据流4.1.1系统缓冲区收到对端数据时,操作系统会将数据存入到Socket的接收缓冲区中,而且操作系统层面上的缓冲区完全由操作系统操作,程序并不能直接操作,只能通过socket.Receive、socket.Send方法来间接操作。注意:之后出现的readBuff不是发送缓冲区也不是接收缓冲区,而是用户自定义的缓冲区,用于存放两个操作系统缓冲区读取出的字节数据。4.1.2粘包半包现象粘

2021-11-04 15:28:26 2972

原创 Unity3D网络游戏实战——实践出真知:大乱斗游戏

前言这一章是教我们做一个大乱斗游戏。但是书中的代码有些前后不一致导致运行错误,如果你也碰到了这样的情况,可以参考我的代码我们要完成的主要有以下这些事左键操控角色行走右键操控角色攻击受到攻击掉血,队手hp为0时消失,自己hp为0时失败,掉线同理角色类的编写介绍协议、消息队列等客户端以及服务端代码角色类BaseHumanunity相关操作基本都省略了BaseHuman为角色基类CtrlHuman代表操控角色,在BaseHuman基础上多了处理鼠标操控功能SyncHuman代表同步

2021-11-03 00:37:17 1994

原创 Unity3D网络游戏实战——分身有术:异步和多路复用

前言前面一篇文章全部用的是阻塞API,也就是同步Socket程序,客户端一卡一顿、服务端只能一次处理一个客户端的消息,不具有实用性。所有有了异步和多路复用两种技术解决了阻塞问题。2.1什么是异步代码不需要进程一直等待下去,而是继续往下执行,直到满足条件才调用回调函数,这样可以提高执行的效率。异步的实现依赖于多线程技术。在Unity中,执行Start、Update方法的线程是主线程,会另外开一条线程执行异步代码,然后满足条件后另一条线程调用回调函数,主线程继续往下执行代码,不受影响。2.2异步客户

2021-10-31 17:01:31 809

原创 Unity3D网络游戏实战——网络游戏的开端:Echo

前言虽然最爱单机游戏,但是和朋友一起玩联网游戏可以获得双倍快乐!所以开始学习网络游戏相关的知识啦1.1藏在幕后的服务端客户端和客户端之间通过服务端的消息转发进行通信。为了支撑很多玩家,游戏服务端通常采取分布式架构,也就是分区服务端,每个服务端负责不同区的玩家。服务端和服务端之间通常使用TCP通信。1.2网络连接的端点:Socket网络上的两个程序通过一个双向的通信连接实现数据交换,这个连接的一端称为一个Socked。每个Socket包含五种必备信息:连接使用的协议:TCP本地IP:19

2021-10-30 00:51:31 720

原创 CSAPP——计算机系统漫游

1.计算机系统漫游1.1信息就是位+上下文大部分计算机系统使用ASCII标准表示文本字符,实际上就是用一个唯一的单字节大小的整数值表示每个字符。只由ASCII字符构成的文件称为文本文件,其余都是二进制文件。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文,不同上下文中同样的字节序列可能表示int、float、string等1.2程序被其他程序翻译成不同格式.c可以被读懂,但是系统要运行必须被转换为低级机器语言指令,再打包为可执行目标程序格式。编译系统:1.预处理阶段:预处理器cpp

2021-10-28 00:27:45 163

原创 GameFramework——打包

AssetBundleAB包的作用AssetBundle的作用是,把资源打包,然后可以在需要的时候动态加载,从而可以实现资源的热更新。之前学习了唐老狮的AB包打包课程,需要进行比较复杂的配置,但是GF已经帮我们安排好了最基础的部分,所以在一般项目中不用过分关心这些配置,只需要把相应的资源打包进相应的包里即可。打包StarForceAB包,从左往右分别是AB列表、AB包内的内容列表、Asset资源列表添加AB包时左边填的是AB包名称,包含路径用/分割。后面是变体名称,比如muscic.bg,mu

2021-10-27 18:08:07 1410 1

原创 GameFramework——Procedure

前言结束了鹅厂三个多月的实习后,回到学校,当然不能忘记学习GF,今天就来盘一盘GF中的精华——流程流程,是贯穿游戏运行时整个生命周期的有限状态机。通过流程,将不同的游戏状态进行解耦将是一个非常好的习惯。对于网络游戏,你可能需要如检查资源流程、更新资源流程、检查服务器列表流程、选择服务器流程、登录服务器流程、创建角色流程等流程,而对于单机游戏,你可能需要在游戏选择菜单流程和游戏实际玩法流程之间做切换。如果想增加流程,只要派生自 ProcedureBase 类并实现自己的流程类即可使用。看到上面的类图我

2021-10-27 17:21:47 335

原创 GameFramework——FSM

前言提到FSM有限状态机,做过游戏的人应该都知道简单的敌人AI很多情况下都是基于这个实现的。其实前不久吉比特面试官也问过我,有没有使用过状态机模式来运行整个游戏,我根本听不懂他在说什么。直到看了GF之后,才懂了些。GameFramework整个游戏流程也是基于状态机来实现的,我们先在这篇笔记看看状态机,下一篇再研究流程~总的来说,我觉得只要是能切换的都可以基于这个模块来实现?比如idle状态切换到move状态标题...

2021-06-09 01:23:20 604

原创 203. 移除链表元素

看似不难其实麻烦,设置一个虚拟头结点是关键。记得将虚拟节点和然后就是双指针,一个前一个后,分情况讨论。法一:设置虚拟节点后将其和head相连,因为我们不会每一次都将pre->next指向cur。如果是val,就让pre->next=cur->next,cur往后,pre别往后,因为不保证下一个cur就是正常的,可能下一个还是val,所以pre不能这么快更新。如果不是val,就把pre更新为cur,cur继续更新。/** * Definition for singly-linked.

2021-06-05 23:56:30 145 1

原创 GAMES101图形学P13笔记(Ray Tracing1)

为什么有光线追踪?因为光栅化不能将全局效果处理的很好,比如不过光栅化很快,但是质量很低光线追踪效果好,但是很慢。光栅化一般用于实时应用,光追一般用于离线应用(电影之类的)光线光线沿直线传播光线和光线之间不会发生碰撞,各传播各的光线从光源中被发出来经过多次反射折射等,最后传入到eye中。也可以认为光路是可逆的,从eye发出感知光线可以原路返回到光源光线追踪就是在模拟光线不断弹射的过程将光线折射和反射出去所有地方用light进行计算一遍(算是否在shadow中),将所有点的着色的值加上

2021-06-05 01:14:41 227

原创 525. 连续数组

前缀和周不用说了!还以为是dp嘞,看来连续子数组不仅要考虑dp还要考虑prefixsum我们把0看成-1,那么就变成了求一段和为0的最长解,所以我们用前缀和+哈希来做。前缀和是防止重复求和,哈希是为了快速查找相同是否有相同前缀和的情况,如果有,中间差的那一段一定是0!每一轮循环先更新前两位的,不能更新前一位的哦,不然要是和sum[i]相同,那么这一段连续子数组和可能是只有1个的,虽然不可能发生,但是还是要注意。直接判断前两位是否已存在,如果不存在就更新一下前两位的前缀和,因为要保证连续子数组长度&g.

2021-06-03 23:53:36 117

原创 C#泛型与约束

前言最近在看一些项目和框架,用了好多泛型,虽然C++模板比较熟,但是泛型却接触的比较少,所以看了CLR的泛型后打算写个文章记录下方便以后自己看。(其实和模板差不多!)泛型介绍泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,也就是算法重用,比如泛型List类的List< T >表名它操作的是一个未指定的数据类型,到时候使用泛型类型或者方法时指定的具体数据类型称为类型实参,也就是用具体的类型实参来代替T优点源代码保护,开发人员不需要访问算法的源代码,而模板编程需要

2021-06-03 16:58:21 618

原创 523. 连续的子数组和

sum 是前 i+1 项和,每次加入集合的是前 i 项和的模。 当两个前缀和关于模 k 同余时,它们的差值就是满足条件的子数组和因为这两个前缀和%k的值一样,所以它们之间的差值一定是k的整数倍!为什么我们在每一轮加入的是sum-nums[i]对k的余数呢?因为这样在下一轮对sum+nums[i]进行判断的时候,差的就是两个,满足最小数量>=2的标准class Solution {public: bool checkSubarraySum(vector<int>& n.

2021-06-03 00:17:12 95

原创 GameFramework——Entry

前言看了两三天GF,发现群主大佬的无境和GF竟有几分相似,希望我毕设也是能做出差不多级别的项目~一开始是从流程Procedure模块开始看的,但是又涉及到状态机,里面的层层封装看的我有点麻。看了网上的一些教程和说明,我就先从Entry(入口模块)入手了。(我在博客里写自己的心得体会以及一些大佬的讲解,主要是为了记录下自己的学习过程,不是为了大家能学到啥东西,当然如果大家能有一丝收获当然是最好的!有错误也希望大家能指出,因为我也只是个只做过一些小游戏的人罢了)Entry这个场景就是StarForce

2021-06-02 22:31:11 309 1

原创 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

题解都在注释里,总的来说这是一道前缀和的题,在一个数组从i-j被重复计算的时候就要考虑用空间换时间,也就是前缀和。class Solution {public: vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>& queries) { //queries里每一个一维都是从第0天开始判断的,但是要把queries[i][0]前的糖果..

2021-06-02 00:25:08 81

原创 GAMES101图形学P12笔记(geometry3)

Loop Subdivision(loop 细分),只能用于三角形面分出更多的三角形以及让三角形的位置发生变化,使整个模型更加光滑。方法:先引入更多的三角形再将老顶点根据新生成顶点的位置得到新位置。Catmull-Clark Subdivision,可以用于不同面的细分Shadow mapping着色解决不了阴影,所以用shadow mapping来解决,但是只能做硬阴影,就是0或者1,右或者无。key:点不在阴影里就是你可以看到这个点,但是光源看不到这个点shadowmapping的两

2021-06-01 14:31:34 136

转载 C#中Internal关键字的总结

转载自:https://www.cnblogs.com/wowoblog/p/6970502.html前言在学习GF的时候看到了internal,但是又想不起来,遂看了一些博客,也学习到了一些东西就打算转发一下,方便以后自己翻阅。进入主题之前先来了解一下,项目、解决方案、程序集、命名空间四个容易混淆的概念。项目就是我们开发的一个软件。.NET下,项目有多种类型,如控制台、Windows应用程序、类库、Web应用程序等等。经过编译后,会生成.exe文件和.dll文件。.exe文件有统一的主程序入口

2021-05-31 23:29:15 453

原创 GameFramework——前言

前言大二的时候就看群友推荐学习这个框架,也看了烟雨的一些博客,但是那个时候的我是根本没有这个能力学习这个框架的。直到现在我也找到了一份满意的实习,基础知识方面背的也算比较完整了。所以希望能通过学习gf框架提升一些游戏开发的思想以及掌握一些功能的实现。Game Framework 简介Game Framework 是一个基于 Unity 引擎的游戏框架,主要对游戏开发过程中常用模块进行了封装,很大程度地规范开发过程、加快开发速度并保证产品质量。适用于 Unity 5.3、Unity 5.4、Unity

2021-05-31 22:26:31 340 1

原创 477. 汉明距离总和

一开始暴力了,想想就不行,立方级别的时间复杂度肯定不行的。不用两两异或,通过统计这个数组中每一位的1的个数和0的个数即可。因为是有范围不大于10^9也就是2 ^30,所以我们只要遍历0到30位就行,用每一位上的1的个数和0的个数相乘,就是这一位上能提供的所有汉明距离的和。1就是(val>>i)&1,0的个数就是n-c。为什么是0和1的相乘,就相当于做一个组合运算,用这一位是1的数字和另一个这一位是0的数字异或才能提供11的汉明距离,所以只要0的个数1的个数就是这一位所能提供的汉明距.

2021-05-29 00:02:50 93

原创 GAMES101图形学P11笔记(geometry2)

显示几何的表示方法:point cloud(点云),用无数精确和密集的点表示一整个面or模型polygon mesh(多边形面),用三角形or多边形表示一个面,最广泛Curve(曲线):贝塞尔曲线:用一系列的控制点去定义曲线,满足曲线的某些性质,只要经过起止点如何画出贝塞尔曲线?递归找点,假设每次找两个点中间,然后将其相连,这样就每次减少一个点,最后只剩一个点,这个点就是经过的点。然后再重新找两个点的三分之一,最后只剩一个的时候也是必定经过的。枚举两个点之间的所有情况,就可以将其所有会经过

2021-05-27 01:45:02 102

原创 1190. 反转每对括号间的子串

一开始看到这题就感觉用递归or栈做,递归版本可能太久没写了,是不对的,还是向栈妥协了。栈中记录的是左括号的下标,当你碰到右括号的时候,将栈顶的左括号和其匹配并出栈,将这两个下标之间的字符串全部翻转,不包括(),包括也没事。最后再遍历tmp之后将其取出()就行了class Solution {public: string reverseParentheses(string s) { //递归翻转,写个函数,碰到(就进入,碰到)就退出 //将前面翻转好的,加上后..

2021-05-26 23:41:55 179

原创 GAMES101图形学P10笔记(geometry1)

纹理的应用:环境贴图:描述环境光怎么样,将环境光存储在贴图上,可以用这个贴图来渲染别的东西圆形贴图展开可能会有扭曲问题,解决方法就是映射到立方体凹凸(法线)贴图:不一定只描述颜色,可以定义高度(相对高度),也就是纹理的高度相对于物体本身这个点的高度差可以定义复杂纹理但是不改变几何信息,我们用凹凸贴图伪造它的高度模拟凹凸效果3d噪声记录已经计算好的信息几何几何分为隐式几何和显式几何隐式几何:表示一定的关系,并不给实际的点,比如x2+y2+z^2=1,就代表一个球缺点:很难看出形

2021-05-26 00:53:48 134

原创 692. 前K个高频单词

两种方法,先用哈希表记录词频,法一:来一个pair数组,先根据次数排序,再根据字母顺序排序。法二:维护一个大小为k的小顶堆,用优先队列即可class Solution {public: static bool cmp(pair<string,int> p1, pair<string,int> p2){ //true就不交换 //先根据次数,再根据字母顺序 if(p1.second != p2.second) return .

2021-05-21 00:38:43 96

原创 1723. 完成所有工作的最短时间

一眼就感觉是dfs爆搜,肯定超时,正解应该是递归回溯+二分+剪枝(做不来hhh)超时版本:class Solution {public: //第一个参数是当前处理到的工作数量,第二个参数是当前所有人中的最大工作时间 void dfs(int u,int maxn,vector<int>& jobs,int k){ //剪枝 if(maxn >= res) return;//当前已经不可能成为最优解了 //递归边.

2021-05-08 23:28:00 198

原创 1486. 数组异或操作

0到n-1就这样class Solution {public: int xorOperation(int n, int start) { //先求出每一位,然后依次异或,异或^相同为0,不同为1,所以一开始和0异或 int res = 0; //下标从0开始,到n-1很重要 for(int i = 0; i < n; ++i){ res ^= (start + 2*i); } .

2021-05-08 00:17:47 94

原创 1720. 解码异或后的数组

先将first加入数组,然后遍历encoded,每一轮将res[i]和encoded[i]做异或的结果加入res。class Solution {public: vector<int> decode(vector<int>& encoded, int first) { //xor就是异或 //异或^,相同为0,不同为1,与运算&,全1为1,其余未0,|或运算,全0为0,其余为1 //根据first慢慢推,a.

2021-05-08 00:16:04 87

原创 740. 删除并获得点数

评论说是打家劫舍4,很形象。这道题的题意是删除某个数字获得点数,然后强制删除i+1和i-1并且不能获得点数,我们要得到最大的点数。我们先遍历nums,记录每个数字出现的次数,并且记录下最大的数字。主要是看是否取当前数字,如果取了前面就不能取,如果没取前面就可以取,0就是没取,1就是取了状态定义:dp[i][1]就是删除当前数字,dp[i][0]就是不删除当前数字状态转移:如果取了前面就不能取(前面的被强制删除),如果没取前面就可取可不取,取了的话就=dp[i-1][0] + ima[i],用当前.

2021-05-08 00:13:59 119

原创 554. 砖墙

这道题要求的是穿过的最少砖块数量,用哈希表来记录间隙。unordered_map可以直接用key来移除。记录每行出现间隙的次数,比如1,2这样的,那么间隙就是1的地方出现1次,3的地方出现1次然后遍历哈希表,我们让行-出现间隙最多的次数就是穿过最少的砖块。class Solution {public: int leastBricks(vector<vector<int>>& wall) { //记录每行出现间隙的次数,比如1,2这样的,那...

2021-05-07 23:56:48 90

原创 403. 青蛙过河

dp的hard题,写出状态定义和状态转移都不是最难的。basecase很难,而且最好从dfs->记忆化->dp的顺序循序渐进class Solution {public: bool canCross(vector<int>& stones) { //dfs超时就考虑dp //状态定义:dp[i][k]的含义是当前在第 i 个位置,并且是以步长 k 跳到位置 i 时,是否到达最后一块石子。 //状态转移方程:根据上..

2021-04-29 17:40:07 105

原创 938. 二叉搜索树的范围和

利用bst的特性做,如果当前结点符合,就让sum加上当前的,并递归左右。如果当前小于low,就去右边就行了,否则就去左边。最后返回sum。一开始考虑中序遍历,很明显这样很快,O(logn),中序就是O(n)了class Solution {public: void dfs(TreeNode* root, int low ,int high){ if(root == nullptr) return; //根据low和high和val递归左边or右边 ..

2021-04-28 00:24:28 96

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除