自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(231)
  • 资源 (27)
  • 收藏
  • 关注

原创 刷存在感,Excel转Protobuf/Json通用配置文件

Excel已定义的关键词,以下的所有的配置都可以放在任何sheet里面关键词描述#message同protobuf message#enum同protobuf enum#package同protobuf package#config标识当前message导出为config#desc描述/注释#type数据类型, 基本同Protobuf类型,有自定义#var变量名称#value枚举的变量。

2024-01-31 13:59:19 1123

原创 【Unity】 HTFramework框架(四十七)编辑器日志中使用超链接的技巧

更新日期:2024年1月3日。

2024-01-03 18:20:33 1294

原创 记录使用注入的方式为Unity编辑器实现扩展能力

【代码】记录使用注入的方式为Unity编辑器实现扩展能力。

2023-07-10 19:05:36 1542

原创 【Unity】 HTFramework框架(四十六)【进阶篇】运行时调试器+指令系统

更新日期:2023年7月10日。

2023-07-10 14:10:05 655

原创 【Unity】 HTFramework框架(四十五)【进阶篇】指令系统-自定义指令

指令系统当前支持十几种指令关键字(也即是指令类型),实际上用他们只能进行一些简单的程序修补工作,虽然指令系统的定位便是如此,咱比不上强大的Lua(人家虚拟机、解释器自成一体),高大上的ILRuntime(随时随地C#写代码,高端优雅上档次),但咱也有优点:简单、小巧、门槛低,人家是大型解决方案,咱的定位就是小型解决方案!So!为了提升扩展性和灵活性,自定义指令应运而生,接下来,按程序界不成文的老规矩,先写一个来证明它的存在吧。此时,我们便可以编写#Debug# Debug "null" "你好世界"

2023-06-19 22:58:26 1766 2

原创 【Unity Shader】Special Effects(八)Wireframe 线框化(UI)

边缘检测算法采用了卷积计算方式(上述的Sobel算子也即是其卷积核),将目标像素所在位置的8连通(九宫格)范围内的9个像素进行分权求和(不同权重值)计算,所以此处需要在片元处理方法(fragWF)的输入数据结构FragDataWF中定义九宫格uv坐标,才能更方便我们后续读取目标像素//九宫格数组像素坐标中,索引4为目标像素 float2 texcoord [ 9 ] : TEXCOORD0;

2023-06-17 20:05:43 1993

原创 【Unity】 HTFramework框架(四十四)【进阶篇】指令系统

首先,定义一个对象,字面理解为可执行指令的代理者,他是指令系统开放出来的最简单的使用接口,将源码读取代码编译代码执行融合在了一起,使用者什么都不需要关心,写入源码直接调用执行即可。[ Label("动态指令代码") ] public InstructionAgent Agent;"动态指令代码"[ Label("动态指令代码") ] public InstructionAgent Agent;

2023-05-29 10:52:25 1156

原创 【Unity】 HTFramework框架(四十三)标准化命名

更新日期:2022年4月28日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引标准化命名使用标准化命名配置一键重命名标准化命名当团队成员各自的命名习惯(或者说不是习惯,只是随心)凑在了一起,产生了下图这样的情况,作为强迫症患者的你,是否已经崩溃…事实上,对于脑力大部分都运转在编写功能上的程序员来说,对于命名这件事,确实腾不出更多的时间了,所以,UI组件、游戏物体、乃至于脚本变量的命名长时间以来没有一种固定的规则可言,但是,殊不知良好的命名习惯不仅可以带来可读性的显著.

2022-04-28 14:38:14 5036 9

原创 在Web中实现ImGui界面

在Web中实现ImGui界面前言技术方案成果扩展前言想为自己的服务端增加一个性能/数据监控系统,使用web是一个最合理的选择。写过几天vue.js,做过一个简单的app,咋说呢,可能是我学习能力太差了吧,不是特别想写第二次了。我还是喜欢自己熟悉的语言,比如C/C++、Lua/Python,是C#就最好了。简而言之,我在就在找寻其他的解决方案,我的目光又回到了Dear ImGui上,Dear ImGui拥有最小的依赖,可以自由选择渲染底层。如果Dear ImGui+WebAssembly+GLES3.0

2022-01-21 14:54:04 4529 4

原创 【Unity】 HTFramework框架(四十二)【进阶篇】使用依赖注入(控制反转模式)

更新日期:2022年1月4日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引依赖注入使用InjectPathInjectUI作用域依赖注入控制反转模式是一种经典设计模式,关于其概念我就不再过多描述,直接进入正题,目前这里仅支持两种依赖注入方式:1.InjectPath:通过路径注入依赖;2.InjectUI:注入UI逻辑类对象;使用InjectPathInjectPath只能注入GameObject或组件,通过路径注入:public class Test :.

2022-01-04 14:30:33 2647

原创 【Unity Shader】Special Effects(七)Correct 色彩修正(UI)

更新日期:2021年10月20日。Github源码:[点我获取源码]索引Correct 色彩修正思路分析属性定义筛选目标颜色修正目标颜色色彩变化动画Correct 色彩修正色彩修正效果用于将一张图像的指定色彩修正为任意色彩,比如我想将一张图像中的红色区域修正为黄色,便可以使用色彩修正效果,效果如下:或者将红色修正为绿色:或者将红色修正为紫色:思路分析这里的色彩修正效果可以看做是将目标颜色的色相整体扭转为我们指定的修正颜色的色相!(涉及到色相的相关知识可以查阅资料或参考RGB、YUV.

2021-10-20 18:03:14 410

原创 【Unity】 HTFramework框架(四十一)在编辑器内绘制美观且实用的表格窗口(TableView)

更新日期:2021年10月16日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引TableView表格视图使用定义表格行定义表格列表格视图通用表格检视器TableView表格视图使用TableView可以很方便的绘制表格视图,当然,实际上它就是使用了TreeView进行绘制而已,所以关于TreeView的一些信息我便不再讲解了,如有什么不明白的地方可以参考官方脚本手册。使用定义表格行TableView的使用非常简单,首先,表格的数据对应了一个List集合,其中每一.

2021-10-16 17:50:05 2901

原创 【Unity Shader】Special Effects(六)Pixel 像素化(UI)

更新日期:2021年9月30日。Github源码:[点我获取源码]索引Pixel 像素化思路分析放大uv细节像素大小缩放系数最终输出像素波动动画Pixel 像素化像素化效果就是所谓的降采样导致的结果,这在一些低端设备上很常见,比如90年代的小霸王红白机,那是因为硬件性能不足而导致的表现效果上的折中体现,如今,我们同样可以通过降采样的方式来实现将一张高像素的图像低像素化:思路分析低像素化的本质也即是降低了图片的分辨率,比如一张图的像素大小为100*100,我们将它缩小到20*20,那么剩下的.

2021-09-30 15:03:17 748

原创 【Unity Shader】Special Effects(五)Scan 扫描(UI)

更新日期:2021年9月22日。Github源码:[点我获取源码]索引Scan 扫描思路分析扫描光线扫描光线区域平滑闪烁的方格放大uv细节,生成方格方格闪烁最终的扫描光线扫描动画Scan 扫描扫描特效是类似一种扫描光线从屏幕上一扫而过的效果,并非3D游戏中那种以主角为中心发射的扫描脉冲波,我们的效果比较简单,直接看最终效果图:思路分析其实,如同流光效果一样,整个扫描光线就是一个从左往右移动的过程,所以,我们先实现扫描光线一扫而过的效果,再来研究那些不停闪烁的方格该怎么实现。扫描光线通过.

2021-09-22 19:26:32 1191

原创 【Unity Shader】Special Effects(四)Dissolve 溶解(UI)

更新日期:2021年9月11日。Github源码:[点我获取源码]索引Dissolve 溶解思路分析溶解区域溶解因子溶解颜色因子溶解透明度因子溶解区域柔和度溶解动画Dissolve 溶解溶解特效是一种延迟消散型效果,当我们要让一张图片消失时,直接隐藏显得很呆板,所以使用溶解效果看起来就更有特色,我们看看最终的效果图:思路分析首先,所谓溶解,也就是根据时间流逝(或者一个度作为控制开关),将纹理中的指定部分的透明度值逐渐变为0,直到整张纹理的每个地方的透明度值都变为0了,则溶解过程结束。主要.

2021-09-11 16:59:54 936

原创 【Unity Shader】Special Effects(三)Shiny 闪亮(UI)

更新日期:2021年9月2日。Github源码:[点我获取源码]索引Shiny 闪亮思路分析闪亮区域Shiny 闪亮Shiny以另一种方式实现了LOGO流光,在表现效果上与其相差无几,不同的地方是Shiny不需要指定流光遮罩以及流动的图片纹理等,他是直接通过UV计算出一块区域,然后叠加颜色,以达到亮闪闪的效果,最终的效果图:思路分析首先,按照LOGO流光的思路,我们只需要选出一片uv区域,为区域叠加颜色,并使得区域的中心越亮,越往区域的两边扩散越暗,在不考虑动画的情况下,这便是我们想要的区.

2021-09-03 13:58:02 1346 1

原创 【Unity Shader】Special Effects(二)BorderFlow 边框流动(UI)

更新日期:2021年8月23日。Github源码:[点我获取源码]索引BorderFlow 边框流动思路分析流光区域流光区域的中心点流光区域的宽度、高度定义流光区域流光效果如何求一个二维点在一个矩形内流光效果的平滑流光动画BorderFlow 边框流动UI边框流动的效果非常常见,实现思路也五花八门,在此我就不贴网上的那些示例了,直接看我们最终的效果图:思路分析流光区域我们首先将上下左右四个方向在流动的区域(青色)定义为流光区域,其他的定义为非流光区域,本质上也即是流光区域叠加了一个流光颜.

2021-08-23 18:45:37 3210 4

原创 【Unity Shader】Special Effects(一)UI特效的动画播放器

更新日期:2021年8月16日。Github源码:[点我获取源码]索引【系列简介】【SpecialEffects 模块简介】【UI特效的动画播放器】【系列简介】本专栏作为SpecialEffects的Shader学习教程,会逐步讲解各种特效的设计思路和实现算法,力求将晦涩难懂的着色器语句通俗化。【SpecialEffects 模块简介】SpecialEffects模块是一个基于Unity的Shader库,里面包含多个UI特效和模型网格特效,主要是自己学习和平时积累而来,虽然每个特效的效果表现.

2021-08-18 11:45:16 1806

原创 Unity实现动作游戏的技能系统(Ability System)设计原型

前言尝试写一个技能系统,希望其尽量完善。目前能想到的元素包括控制、模型、动画、音效、特效、碰撞检测、事件响应、伤害判断、Buff控制。集所有元素为一个编辑器,方便策划和美术进行操作。输入控制使用Input System作为跨平台接收输入响应,然后整合到Character脚本中,然后由Character的节点,监听对应的操作。public void AddActionStarted(string actionName,Action<InputAction.CallbackContext>

2021-06-07 15:53:38 10080 14

原创 【Unity】 HTFramework框架(四十)Debug的性能监控

更新日期:2021年4月22日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引UI的数据驱动模式UI的数据驱动模式MVVM的基础特性是数据绑定,也可以在某种程度上称之为数据驱动,在最新版本中,框架的UI模块支持数据驱动模式,所谓的数据驱动模式也即是UGUI控件与数据的双向绑定(这里不考虑单向绑定)。...

2021-04-23 15:22:14 1298

原创 【Unity】OnePieceFTG(九)角色AI(终章)

更新日期:2021年3月7日。项目源码:在本章末尾发布索引简介正式开始AI驱动器基类AI_PlayerAI_Normal(普通AI)AI_Advanced(高级AI)AI_Violent(狂暴AI)终章源码简介FTG2D系统提供了一个简易的AI模板,只需要将任意类继承至AI驱动器基类,便可作为角色的AI控制类。在此基础上我们可以根据不同的等级编写不同强度的AI控制类,用以代表不同实力的对手。正式开始AI驱动器基类AI驱动器基类源码如下,只有几个生命周期回调函数: /// <.

2021-03-08 11:36:57 1204 2

原创 【Unity】OnePieceFTG(八)输入键位

更新日期:2021年3月5日。项目源码:在终章发布索引简介正式开始游戏键位自定义输入设备使用输入设备简介目前FTG2D游戏需要8个键位,我们使用框架的Input跨平台输入模块重新定义输入设备(InputDevice)。正式开始游戏键位我们为FTG2D游戏定义了8个键位,分别是上下左右四个方向键,和ABCD四个功能键,InputDataSet(输入配置数据集)源码如下: /// <summary> /// 玩家输入数据 /// </summary&g.

2021-03-05 22:42:40 383

原创 【Unity】OnePieceFTG(七)行动助手

更新日期:2021年3月4日。项目源码:在终章发布索引简介正式开始新建行动助手编辑行动助手行动助手使用示例简介行动助手用于为任意行动编写自定义逻辑,由于行动编辑器是在一种统一的结构下构建行动,所有的行动都是一个模子刻出来的,不同的只是内容,如果要在行动中插入一些自己的逻辑控制,那就不得不使用到行动助手了。正式开始新建行动助手在行动编辑器界面左下角便有行动助手的相关配置,比如这里为Skill5行动配置了行动助手Skill5Helper_LuFei:行动助手可以通过点击面板的下拉菜单按钮,.

2021-03-04 22:29:34 324 1

原创 【Unity】OnePieceFTG(六)角色武器

更新日期:2021年2月27日。项目源码:在终章发布索引简介正式开始近身武器远程武器远程武器的生命周期回调简介FTG2D的角色武器分为近身武器和远程武器:近身武器:附在角色身上的武器,比如角色的拳头,拿在手中的刀剑等。远程武器:可以发射出去且有自己的控制逻辑的武器,比如发射出去的火球。正式开始近身武器在行动编辑器中有一个编辑攻击碰撞盒区域的功能,此攻击碰撞盒便是角色的近身武器的碰撞盒范围,启用此碰撞盒后,便是在此帧中启用近身武器,如下,红色框包围的角色手中长剑的区域,便是近身武器的.

2021-02-27 14:41:55 731

原创 Spring Boot Hello World

在我使用熟悉的工具链中,好像vscode也能开发Spring Boot, 但是我还是选择了专业的IDEA,因为穷,选择了社区版。之前在https://spring.io/根据QuickStart的模板创建了一个工程,羡慕IDEA正常版,可以直接创建Spring Boot的工程,找到一个插件Spring Assistant,在社区版可以安装,然后创建Spring Boot的工程,不错,应该够用了。打开IDEA创建项目,选择Spring Assistant然后就是跟https://star..

2021-02-26 15:51:47 218

原创 【Unity】OnePieceFTG(五)游戏流程

更新日期:2021年2月19日。项目源码:在终章发布索引简介正式开始OnePieceFTG全局数据类准备流程选择模式流程选择角色流程选择地图流程战斗流程简介FTG2D的游戏流程我们初步划分为如下五个流程:准备流程:用于完成游戏的一些初始化或其他准备工作。选择模式流程:用于玩家选择将要进行的游戏模式,比如是玩家对战玩家,还是玩家对战电脑AI。选择角色流程:用于玩家选择将要为自己出战的角色。选择地图流程:用于玩家选择将要进入的地图。战斗流程:进入战斗流程后,玩家可以控制自己的角色进行对战.

2021-02-19 16:02:10 524

原创 【Unity】OnePieceFTG(四)战斗环境

更新日期:2021年2月5日。项目源码:在终章发布索引简介正式开始战斗场景创建战斗场景战斗场景属性战斗配置创建战斗配置战斗配置属性战斗地图创建战斗地图战斗地图属性动态创建玩家、地图简介FTG2D的战斗环境主要由GameScene(战斗场景)、GameConfig(战斗配置)和GameGround(战斗地图)组成,说白了其实也即是确保场景中存在这三个模块的对象即可,战斗场景的作用是统一协调游戏的逻辑,战斗配置的作用是提供整个游戏场景的全局参数配置,战斗地图的作用是用于容纳双方角色进行游戏对战(到目.

2021-02-06 20:27:12 625

原创 【Unity】OnePieceFTG(三)角色

更新日期:2021年1月25日。项目源码:在终章发布索引简介正式开始创建行动简介Actor(行动者)作为承载一切行动的基类对象,简言之它即是行动的播放器,而Player(角色)便是继承至它,在本章,我们将了解Player是如何应用行动的,以及它将如何被驱动!正式开始创建行动在Project视图点击右键,选择创建菜单:Create->HTFramework GC->FTG2D->Motion Asset,可以在选定位置创建一个行动资源,比如下图的Move:...

2021-01-27 23:52:41 816

原创 【Unity】OnePieceFTG(二)行动编辑器

更新日期:2021年1月20日。项目源码:在终章发布索引简介正式开始创建行动打开行动编辑器简介本章我们将引入行动编辑器,行动编辑器作为FTG2D的核心功能,游戏核心玩法的70%都将在其中完成!不过,到目前为止我们先不关心它是如何使角色动起来的,我们先了解如何从零开始创建一个行动,以及在行动中我们能够做些什么。正式开始创建行动在Project视图点击右键,选择创建菜单:Create->HTFramework GC->FTG2D->Motion Asset,可以在选定位置创建.

2021-01-22 22:07:27 1238 1

原创 【Unity】OnePieceFTG(一)搭建项目、导入框架、前期开发准备

更新日期:2021年1月14日。项目源码:在终章发布免责声明:OnePieceFTG使用的图片、音频等所有素材均有可能来自互联网,本专栏所有文章仅做学习和教程目的,不会将任何素材用于任何商业用途。索引【系列简介】【GameComponent 模块简介】【FTG2D 系统简介】【最终效果预览】正式开始导入GameComponent模块导入FTG2D模块使用项目创建向导开始开发【系列简介】本系列会基于HTFramework框架和FTG2D系统开发一个名为OnePieceFTG的小游戏,他同时也.

2021-01-14 23:47:51 1799 1

原创 Unity 纹理优化及TextureProcessor工具

更新日期:2020年11月18日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引纹理优化模块管理器使用打开模块管理器界面纹理优化作为Unity所有优化方案中最重要、最简单的优化手段,纹理优化一直被我们放在了项目优化的第一步,而对于纹理优化,主要可以分为以下两个点:纹理的压缩格式纹理的尺寸大小对于纹理的压缩格式,只要纹理资源满足条件(宽、高满足一定条件),Unity默认会使用当前平台的最佳压缩方案,除非你懂得每种压缩格式间的利弊,否则一般不用去强制设置。然后就.

2020-11-18 18:07:09 1582

原创 Unity Module Manager 模块管理器

更新日期:2020年11月4日。Github源码:[点我获取源码]Gitee源码:[点我获取源码]索引模块管理器使用打开模块管理器界面模块管理器界面简介下载模块(也即是Git Clone)更新模块(也即是Git Pull)新建模块打开模块用户凭证冲突解决模块管理器ModuleManager模块管理器是类似于Unity包管理器的针对项目中可选模块的一种统一管理方案,他使得管理你自己的所有扩展包更加方便,你可以将你的任何扩展包设置为原生模块(前提是该包为git存储库),原生模块会自动包含在Modu.

2020-11-04 13:44:35 4592 1

原创 【Unity】 HTFramework框架(三十九)UI的数据驱动模式,MVVM

更新日期:2020年10月24日。Github源码:[点我获取源码]索引UI的数据驱动模式使用MoveHandler移动手柄处理器UI的数据驱动模式框架的UI模块支持数据驱动模式,所谓的数据驱动模式也即是UGUI控件与数据的双向绑定(这里不考虑单向绑定),双向绑定后,在代码中任意位置修改数据的值,与其绑定的UGUI控件会自动更新显示,同时如果修改了UGUI控件的值,与其绑定的数据的值也会跟着改变。使用MoveHandler移动手柄处理器目前可以为Vector3,Vector2两种类型的序列.

2020-10-24 11:01:49 4117 5

原创 Unity UGUI无限列表(Infinite List)

更新日期:2020年10月16日。Github源码:[点我获取源码]索引InfiniteList使用创建InfiniteListScrollRectInfiniteListScrollRect参数详解重写数据类重写元素类编辑元素模板添加数据移除数据清空数据InfiniteListInfiniteList为基于UGUI的ScrollRect无限滚动列表的一种实现,很多时候当我们的ScrollRect的视图中包含的数据无限多时,而同时可见的数据往往只有几条,大量不可见数据被Mask组件排除在肉眼可见.

2020-10-16 17:03:21 8259 7

原创 【Unity】 HTFramework框架(三十八)SceneHandler场景控制柄特性

更新日期:2020年8月28日。Github源码:[点我获取源码]索引SceneHandler场景控制柄特性使用Dropdown下拉框检视器SceneHandler场景控制柄特性SceneHandler场景控制柄特性支持通过简单的在序列化字段上添加特性标记从而实现在Scene界面自定义多种实用的控制柄。使用Dropdown下拉框检视器目前可以为int,string,float三种类型的序列化字段定义下拉框检视器,下拉框检视器使得目标字段在Inspector面板只能设置为下拉框中的几种值之一.

2020-08-31 11:45:25 3037 2

原创 【Unity】 HTFramework框架(三十七)Inspector自定义序列化检视器

更新日期:2020年8月20日。Github源码:[点我获取源码]索引Inspector自定义序列化检视器使用Dropdown下拉框检视器string下拉框int下拉框float下拉框ReorderableList可排序列表检视器数组集合Enable激活状态检视器Display显示状态检视器Label标签检视器Color颜色检视器ReadOnly只读检视器Button按钮检视器Inspector自定义序列化检视器Inspector自定义序列化检视器支持通过简单的在序列化字段上添加特性标记从而实现.

2020-08-20 10:49:32 2176 1

原创 【Unity】 HTFramework框架(三十六)AssetsMaster资源管理器,做资产的主人

更新日期:2020年8月13日。Github源码:[点我获取源码]索引AssetsMaster使用AssetsMaster打开AssetsMaster检视窗口AssetsMaster窗口简介Material材质检索Texture贴图检索Mesh网格检索MonoScript脚本检索Missing警告排序Texture警戒值AssetsMasterAssetsMaster(资产的主人)允许你在编辑模式或是运行模式非常直观的查看和管理当前打开场景中的你感兴趣的资产,目前可以管理如下四种资产:材质,贴图.

2020-08-13 13:55:51 2122 2

原创 【Unity】超级坦克大战(十六)闯关流程:超级武器Buff(终章)

更新日期:2020年7月29日。项目源码:在本章末尾发布索引本章最佳实践正式开始Hit受击逻辑Buff基类BuffDeceleration减速BuffImprison禁锢BuffShock震慑BuffInverse逆反终章源码本章最佳实践获得源码。正式开始在超级坦克大战的设定中,超级武器除了带有群体攻击的强大特性外,同时还会携带一个针对敌方的Buff,只要被超级武器击中,那么超级武器携带的Buff就会附加到目标身上,同时会对目标造成一定程度上的影响。Hit受击逻辑我们再次回顾一下之前.

2020-07-29 23:17:39 1544 2

原创 【Unity】超级坦克大战(十五)闯关流程:输入模块

更新日期:2020年7月28日。项目源码:在终章发布索引本章最佳实践正式开始输入设备OnStartUp设备启动OnRun设备运行OnShutdown设备停止使用自定义输入设备移动端输入设备本章最佳实践Input跨平台输入模块。正式开始超级坦克大战需要重定义自己的输入设备,当然目前也只是针对PC平台的,如果针对移动端的话,最好的方式是再重定义一个移动端的输入设备。输入设备我们新建一个脚本TankWarInput,并继承至基类InputDeviceBase:public class T.

2020-07-28 17:45:00 936

原创 【Unity】超级坦克大战(十四)闯关流程:坦克控制单元

更新日期:2020年7月27日。项目源码:在终章发布索引本章最佳实践正式开始玩家坦克控制单元敌人控制单元(普通敌人)敌人控制单元(BOSS)物理层划分显示层划分本章最佳实践Input跨平台输入模块。ReferencePool引用池。正式开始坦克的控制单元分为玩家的输入控制,和敌人的AI控制。玩家坦克控制单元我们先回顾之前的坦克状态机数据类,里面存有控制单元的属性(也叫行为控制器): /*TankData.cs*/ /// <summary> /// 坦.

2020-07-27 15:39:41 577

MeshMaker 5.5.0.unitypackage

MeshMaker 5.5.0.unitypackage 博客地址:https://blog.csdn.net/qq992817263/article/details/75213659

2019-05-30

MorphAnimation 5.5.0.unitypackage

MorphAnimation 5.5.0.unitypackage 博客地址:https://wanderer.blog.csdn.net/article/details/78288356

2019-05-30

ImportSTL 5.5.0.unitypackage

ImportSTL 5.5.0.unitypackage 博客地址:https://blog.csdn.net/qq992817263/article/details/72738344

2019-05-30

MeshMelt 5.3.5.unitypackage

MeshMelt 5.3.5.unitypackage 博客地址:https://blog.csdn.net/qq992817263/article/details/51832884#comments

2019-05-30

CommandMode

CommandMode 5.5.0.unitypackage 博客地址:https://blog.csdn.net/qq992817263/article/details/72780521#commentBox

2019-05-30

LinkageAnimation 2017.3.unitypackage

LinkageAnimation 2017.3.unitypackage 博客地址:https://wanderer.blog.csdn.net/article/details/78487996

2019-05-30

内嵌python3.7的工具 tool-python

使用C++内嵌python3.7的工具,支持windows平台,支持python第三方库的扩展

2019-04-25

Unity LOGO流光效果

Unity UGUI的LOGO流光效果,编写时的Unity版本是2018.1

2018-08-10

Unity AB包编辑器工具

Unity的一个轻量级AB包编辑器工具,博客链接 https://blog.csdn.net/qq992817263/article/details/79654398

2018-04-25

PipeFlow 2017.3.unitypackage

Unity使用拖尾效果(TrailRenderer)模拟管道流体,Unity版本2017.3.0

2018-01-15

ParticlePath

Unity粒子系统路径移动

2017-08-24

AssetsBundleExtractor_2.1_64bit

unity资源提取工具

2017-04-09

UGUI TreeView

UGUI的树形菜单

2017-02-08

UGUI TreeView

UGUI的树形菜单

2017-02-08

TreeView.unitypackage

2017-02-08

BloodSlider

BloodSlider

2016-10-21

MeshAnimation.unitypackage

MeshAnimation.unitypackage

2016-10-20

unity优化 降低 drawcalls 合并 材质 Mesh Baker 2

unity优化 降低 drawcalls 合并 材质 Mesh Baker 2

2015-08-14

unity 体积云 CloudsToy v1.2

unity体积云插件CloudsToy v1.2, CloudsToy是packpage创建和修改容积云,所有参数都为手动设置,改变大小,范围,类型,渲染模式等等

2015-08-14

unity3d 特效插件 Tasharen Water 水效果 插件

unity3d 特效插件 Tasharen Water 水效果 插件

2015-04-12

mysql数据库集成工具UPUPW

upupw_nginx_32_64 mysql数据库集成工具UPUPW

2015-02-06

unity PUN插件

Photon Unity Networking Free v1 50 2.unitypackage

2015-02-06

photon服务端SDK

ExitGames-Photon-Server-SDK_v3-4-13-5874

2015-02-06

unity3d 游戏插件 Hard Surface Shaders Pro 硬表面着色器专业版

unity3d 游戏插件 Hard Surface Shaders Pro 硬表面着色器专业版

2015-01-25

unity3d 游戏插件 溶解特效插件 - Dissolve Shader

unity3d 游戏插件 溶解特效插件 - Dissolve Shader

2015-01-25

HGE_系列教材(1-9)

HGE 系列教材(1) --- 简介 HGE 是一个硬件加速(Hardware accelerated)的2D 游戏引擎(Game Engine), HGE 是一个富有特性的中间件,可以用于开发任何类型的2D 游戏。HGE 封装性良好, 以至于你仅仅需要关系游戏逻辑(Game Logic),而不需要在意DirectX,Windows 消 息循环等。 HGE 架构在DirectX 8.0 之上,能够跑在大多数的Windows 系统上。 1. 选用HGE 的理由: 1)专业化--- 专注于2D 领域 2)简单化--- 非常容易使用 3)技术优势--- 基于Direct3D API 有较好的性能和特性 4)免费--- 对于个人或者商业用户都免费,遵循zlib/libpng license 5)代码高度的一致性--- 代码是否具有一致性,是衡量代码质量的标准之一(《Co de Reading: The Open Source Perspective》) 2. 体系结构: HGE 有3 个抽象层(layers of abstraction): 1)核心函数(Core Functions) 处于核心的函数和例程(routines),被整个系统所依赖。 2)辅助类(Helper Classes) 游戏对象相关的类,架构于HGE Core Functions 层之上,辅助用户进行游戏开发。 3)创作工具(Authoring Tools) 用于游戏开发的一组工具。 从上图可以看见: 1)用于代码只需要架构在HGE Helper Classes 之上 2)通常游戏资源(Game Resources)需要使用HGE 创作工具来产生 3. 体系结构概述: 1)Core Functions 层 <1> 图形格式支持:支持BMP, JPG, PNG, TGA, DDS, DIB 文件格式 <2> 支持窗口模式和全屏模式 <3> 音频支持和音乐回放(music playback):支持WAV, MP3, MP2, MP1 an d OGG 音频文件格式(audio file formats),支持MO3, IT, XM, S3M, MTM, MO D and UMX 音乐文件格式(music file formats),支持压缩流的回放。声音大小和声 道的控制 <4> 输入设备支持:鼠标和键盘 <5> 资源:读取硬盘上的资源,支持ZIP 打包的文件格式 <6> 日志支持 2)Helper Classes 层 <1> 精灵(Sprites)和动画(Animations) 对于所有硬件设备特性的直接支持:锚点(anchor)支持,伸展、缩放、旋转的支持, 不同的回放模式的支持 <2> 字体 读取和渲染(render)位图字体,多种字体排列方式,旋转和缩放字体,字符串宽度计 算等 <3> 粒子系统(particle systems)和网格变形(distortion mesh) 高效的粒子系统,可用于创建烟雾、爆炸、魔法效果等,提供粒子系统的管理,支持定 界盒(bounding box)计算和冲突检测(collision detection) <4> 资源管理:通过简单的函数调用,来创建复杂的对象,自动的内存管理。对于资 源组(resource groups)采用预先缓存和特殊的清除处理(这是一种通过控制对象分配 和释放来提高效率的方法) <5> GUI:强大而灵活的GUI 管理,支持动画式的GUI <6> 矢量(Vectors),对于2D 矢量的完全支持 3)Authoring Tools 层 <1> 资源的打包(pack):HGE 使用ZIP 格式的资源包,你可以使用任何的打包工 具,甚至还可以给资源包加密 <2> 纹理(Texture)工具 <3> 粒子系统编辑器:能够设定粒子的速度,方向,生命周期,轨迹,颜色,透明等 <4> 位图字体编辑器:运行通过系统中已经安装的字体来创建位图字体,你可以使用 图形编辑器来为位图字体添加额外的效果 HGE 系列教材(2) --- 安装 HGE 在HGE 的文档中有详细谈到如何安装的问题,这里讲一下VC6 平台的安装问题: 1. 下载完HGE 之后,需要使用到lib\vc 文件夹下的库文件以及include 目录下的头文 件 2. 打开 Tools->Options->Directories 如上两图,添加路径 3. 在游戏开发中使用HGE 首先建立一个空的Win32 工程,然后选择Project->Settings...->Link 按图所示,输入hge.lib 和hgehelp.lib 当然,也可以使用预编译器指令pragram 来打到同样的目的。 HGE 系列教材(3) --- 初试 HGE 当HGE 安装完成之后,就可以使用了,关于HGE 的安装,可以参考《HGE 系列教材(2) --- 安装HGE》 现在使用HGE 开发一个极小的程序: 1. 包含hge.h 文件,并且定义一个HGE 的指针,通过这个指针,我们可以访问HGE Core Functions 层的函数。 #include <hge.h> HGE *pHge = 0; 使用完HGE 指针之后,需要释放这个指针,pHGE->Release(); 2. 帧函数(Frame Function)是一个用户定义的函数,每一帧时间,它会被HGE Engi ne 调用一次,函数返回true,则调用停止: bool FrameFunc() { if (hge->Input_GetKeyState(HGEK_ESCAPE)) { return true; } return false; } 3. 建立一个WinMain 函数,WinMain 函数是标准的Windows 应用程序入口,这里, 我们首先初始化HGE 指针: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { pHge = hgeCreate(HGE_VERSION); // ... pHge->Release(); return 0; } 通过HGE 指针,我们才可以访问HGE Engine 的接口。调用了hgeCreate 函数之 后,不要忘记了使用Release 函数释放资源。 4. 初始化操作: 有一些初始化操作需要完成,使得程序能够跑起来: // 设置帧函数 pHge->System_SetState(HGE_FRAMEFUNC, FrameFunc); // 设置窗口模式 pHge->System_SetState(HGE_WINDOWED, true); // 设置不使用声音 pHge->System_SetState(HGE_USESOUND, false); // 设置标题为"Minimal HGE" pHge->System_SetState(HGE_TITLE, "Minimal HGE"); 最后需要调用函数System_Initiate 来完成初始化操作,这个函数返回值是一个bool 类型的变量,如果是true 那么表示初始化成功,如果是false 表示出错,这时候可以通 过System_GetErrorMessage 函数来获取错误消息: if (pHge->System_Initiate()) { pHge->System_Start(); } else { MessageBox(NULL, pHge->System_GetErrorMessage(), "Error", MB_O K | MB_ICONERROR | MB_APPLMODAL); } 再程序结束的时候,需要释放资源: pHge->System_Shutdown(); pHge->Release(); 5. 整个完整的程序如下: #include <hge.h> HGE* pHge = 0; bool FrameFunc() { if (pHge->Input_GetKeyState(HGEK_ESCAPE)) { return true; } return false; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { pHge = hgeCreate(HGE_VERSION); pHge->System_SetState(HGE_FRAMEFUNC, FrameFunc); pHge->System_SetState(HGE_WINDOWED, true); pHge->System_SetState(HGE_USESOUND, false); pHge->System_SetState(HGE_TITLE, "HGE 小程序"); if (pHge->System_Initiate()) { pHge->System_Start(); } else { MessageBox(NULL, pHge->System_GetErrorMessage(), "Error", MB_O K | MB_ICONERROR | MB_APPLMODAL); } pHge->System_Shutdown(); pHge->Release(); return 0; } 注意,程序运行之后,一直调用函数FrameFunc 直到用户按下ESC,那么跳到pHge- HGE 系列教材(4) --- 初探 HGE Core Functions 层 HGE Core Functions 层中的函数需要通过HGE 指针来访问,就如《HGE 系列教 材(3) --- 初试HGE》所谈到的一样,通过调用hgeCreate 函数来初始化HGE 指针, HGE Core Functions 层中的函数,大致分层一下几类: 1. 接口函数(Interface functions): hgeCreate --- 初始化HGE 指针,这是一个全局函数,除了这个函数,HGE Cor e Funtions 中所有的函数都需要通过HGE 指针调用。 Release --- 释放HGE 接口,调用了hgeCreate 就应该调用Release 释放。 2. 系统函数(System functions): 这类函数都是以System_ 开头,后面加上表示函数意义的单词(不出现下划线), 之后介绍的函数也将使用这种命名方式,即类型前缀+ 有意义的单词: System_Initiate 初始化相关软件和硬件 System_Shutdown 恢复声音模式并且释放资源 System_Start 开始运行用户定义的帧函数 System_SetState 设置系统内部状态 System_GetState 返回内部状态的值 System_GetErrorMessage 返回最后出错的HGE 错误描述符 System_Log 在日志文件中书写格式化消息 System_Launch 运行一个URL 或者外部的可执行文件或数据文件 System_Snapshot 截屏并保存到一个文件 3. 资源函数(Resource functions): Resource_Load 从硬盘上读取资源到内存中 Resource_Free 从内存中删除读取的资源 Resource_AttachPack 附加一个资源包 Resource_RemovePack 移除一个资源包 Resource_RemoveAllPacks 移除之前关联的所有资源包 Resource_MakePath 建立一个绝对文件路径 Resource_EnumFiles 通过通配符来枚举文件 4. 初始化文件函数(initialization file functions) Ini_SetInt 在初始化文件中写入一个整数值 Ini_GetInt 从初始化文件中读取一个整数值 Ini_SetFloat 在初始化文件中写入一个浮点值(float) Ini_GetFloat 从初始化文件中读取一个浮点值(float) Ini_SetString 在初始化文件中写入一个字符串 Ini_GetString 从初始化文件中读取一个字符串 5. 随机数参数函数(Random number generation functions) Random_Seed 设置随机数产生器的种子 Random_Int 产生int 类型的随机数 Random_Float 产生float 类型的随机数 6. 计时函数(Timer functions) Timer_GetTime 返回从调用System_Initiate 函数到现在所用的时间(单位 为秒) Timer_GetDelta 返回上一次调用帧函数到现在所用的时间(单位为秒) Timer_GetFPS 返回当前FPS 的值 7. 声效函数(Sound effect functions) Effect_Load 载入从硬盘载入声音到内存 Effect_Free 从内存中删除载入的音效和相关的资源 Effect_Play 开始播放音效 Effect_PlayEx 开始播放音效,这个函数含有更多的参数 8. 更多查看HGE 的文档 HGE 系列教材(5) --- 输入、声音和渲染 建议读者对应HGE 的官方的例子:Tutorial 02 - Using input, sound and renderi ng 来阅读本文 渲染: 在HGE 中,四边形是一种图元,对应了结构体hgeQuad,另外还有三角形图元,对应 hgeTriple,为了渲染,我们现在需要使用hgeQuad 结构体,这个结构体如下: struct hgeQuad { hgeVertex v[4]; // 顶点描述了这个四边形 HTEXTURE tex; // 纹理的句柄或者为0 int blend; // 混合模式(blending mode) }; HGE 中图元对应的结构体总含有这3 个部分:顶点,纹理句柄,混合模式 struct hgeVertex { float x, y; // 屏幕的x,y 坐标 float z; // Z-order,范围[0, 1] DWORD col; // 顶点的颜色 float tx, ty; // 纹理的 x,y 坐标(赋值前需要规格化坐标间隔,使得 tx,ty 取 值范围在[0,1]) }; 规格化坐标间隔在后面的例子中会谈到 1. 颜色的表示: 颜色使用32 位表示,从左开始,8 位为Alpha 通道,8 位红色,8 位绿色,8 位蓝色 对于后24 位,如果全部为0,表示黑色,如果全部为1,表示白色 2. 定义颜色的运算: 我们把颜色看成一个四维向量,即alpha 通道,红色,绿色,蓝色这四个分量 <1> 颜色是可以相乘的 颜色的相乘是对应的四个分量分别相乘的结果,即:alpha 通道的值与alpha 通道的 值相乘,红色的值与红色的值相乘,绿色的值与绿色的值相乘,蓝色的值与蓝色的值相乘。 <2> 颜色是可以相加的 同上,对应分量相加。 颜色的每个分量使用浮点数表示,范围是[0-1],相加操作可能导致溢出,一种处理的方式 就是,如果溢出,则设定值为1。 3. 混合模式: 1)BLEND_COLORADD 表示顶点的颜色与纹理的纹元(texel)颜色相加,这使得纹理变亮,可见顶点颜色为0x0 0000000 将不造成任何影响。 2)BLEND_COLORMUL 表示顶点的颜色与纹理的纹元颜色相乘,这使得纹理变暗,可见顶点颜色为0xFFFFFFFF 将不造成任何影响。 注意:必须在1),2)中做一个选择,且只能选择1),2)中的一个。处理的对象是纹理 颜色和顶点颜色。 这里有一个技巧: 如果我们需要在程序中显示一个气球,这个气球的颜色不断变化,这时候我们并不需要准备 多张不同颜色的气球纹理,而只需要一张白色的气球纹理,设置blend 为BLEND_COL ORMUL,白色的R,G,B 值被表示成1.0,也就是说,纹理颜色和顶点颜色相乘的结果是 顶点的颜色,那么就可以通过修改顶点颜色,得到任意颜色的气球了。 3)BLEND_ALPHABLEND 渲染时,将对象的像素颜色(而非顶点的颜色)与当前屏幕的对应像素颜色进行alpha 混 合。alpha 混合使用到alpha 通道,对于两个像素颜色进行如下操作,得到一个颜色: R(C)=alpha*R(B)+(1-alpha)*R(A) G(C)=alpha*G(B)+(1-alpha)*G(A) B(C)=alpha*B(B)+(1-alpha)*B(A) 这里的BLEND_ALPHABLEND 使用的是对象像素的颜色的alpha 通道。可见如果对象像 素颜色alpha 通道为0,那么结果就是只有当前屏幕的像素颜色,也就是常常说的100 % 透明,因此,我们可以理解alpha 混合就是一个是图像透明的操作,0 表示完全透明, 255 表示完全不透明。 4)BLEND_ALPHAADD 渲染时,将对象的像素颜色与当前屏幕的对应像素颜色相加,结果是有了变亮的效果。 注意:这里的3),4)必选其一,且只能选其一。处理的对象是对象像素颜色和屏幕像素 颜色。 5)BLEND_ZWRITE 渲染时,写像素的Z-order 到Z-buffer 6)BLEND_NOZWRITE 渲染时,不写像素的Z-order 到Z-buffer 这里一样是二者选一 设置举例: quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE; // quad 为hgeQuad 变量 4. HGE 渲染 1)定义和初始化hgeQuad 结构体: hgeQuad quad; // 定义四边形 2)初始化hgeQuad 变量: // 设置混合模式 quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE; // 加载纹理 quad.tex = pHGE->Texture_Load("particles.png"); 注意,读取硬盘上资源的时候,可能会失败,因此通常都需要检查,例如: if (!quad.tex) { MessageBox(NULL, "Load particles.png", "Error", 0); } // 初始化顶点 for(int i=0;i<4;i++) { // 设置顶点的z 坐标 quad.v[i].z=0.5f; // 设置顶点的颜色,颜色的格式为0xAARRGGBB quad.v[i].col=0xFFFFA000; } // 这里假定载入的纹理大小为128*128,现在截取由点(96,64),(128,64), (128,96),(96,96)这四个点围成的图形。 quad.v[0].tx=96.0/128.0; quad.v[0].ty=64.0/128.0; // 规格化坐标间隔 quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0; quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0; quad.v[3].tx=96.0/128.0; quad.v[3].ty=96.0/128.0; 注意,对于hgeQuad 结构体,顶点quad.v[0] 表示左上那个点,quad.v[1] 表示右上 的点,quad.v[2] 表示右下的点,quad.v[3] 表示左下的点。 // 设置hgeQuad 在屏幕中的位置 float x=100.0f, y=100.0f; quad.v[0].x=x-16; quad.v[0].y=y-16; quad.v[1].x=x+16; quad.v[1].y=y-16; quad.v[2].x=x+16; quad.v[2].y=y+16; quad.v[3].x=x-16; quad.v[3].y=y+16; System_SetState(HGE_RENDERFUNC,RenderFunc); RenderFunc 原型和帧函数一样: bool RenderFunc(); 4)编写RenderFunc 函数: bool RenderFunc() { pHGE->Gfx_BeginScene(); // 在如何渲染之前,必须调用这个函数 pHGE->Gfx_Clear(0); // 清屏,使用黑色,即颜色为0 pHGE->Gfx_RenderQuad(&quad); // 渲染 pHGE->Gfx_EndScene(); // 结束渲染,并且更新窗口 return false; // 必须返回false } 补充:Load 函数是和Free 函数成对出现的,即在硬盘上加载了资源之后,需要Free 它们,例如: quad.tex = pHGE->Texture_Load("particles"); // ... pHGE->Texture_Free(quad.tex); 音效: 使用音效是很简单的 1. 载入音效: HEFFECT hEffect = pHGE->Effect_Load("sound.mp3"); 2. 播放: pHGE->Effect_PlayEx(hEffect); 或者pHGE->Effect_Play(hEffect); 1)Effect_Play 函数只接受一个参数就是音效的句柄HEFFECT xx; 2)Effect_PlayEx 函数较为强大,一共有四个参数: HCHANNEL Effect_PlayEx( HEFFECT effect, // 音效的句柄 int volume = 100, // 音量,100 为最大,范围是[0, 100] int pan = 0, // 范围是[-100, 100],-100 表示只使用左声道, 100 表示只使用右声道 float pitch = 1.0, // 播放速度,1.0 表示正常速度,值越大播放 速度越快,值越小播放越慢。这个值要大于0 才有效(不可以等于0) bool loop = false // 是否循环播放,false 表示不循环 ); 输入: 仅仅需要调用函数pHGE->Input_GetKeyState(HGEK_xxx); 来判断输入,应该在帧 函数中调用它,例如: bool FrameFunc() { if (pHGE->Input_GetKeyState(HGEK_LBUTTOM)) // ... if (pHGE->Input_GetKeyState(HGEK_UP)) // ... } HGE 系列教材(6) --- 程序流程与细节 HGE 的一些细节,通过源码可以更加清楚的了解,通过读源码,可以更加高效的使用HG E Engine。 必要的第一步: Help Classes 层建立于Core Functions 层之上,这并不意味着用户只需要关心Help Classes 而忽略Core Functions,因此我们需要获得一个HGE 指针,来使用Core F unctions 的函数: <1> 获取HGE 指针: HGE* pHGE = pgeCreate(HGE_VERSION); <2> 释放HGE 指针: 使用之后,需要释放HGE 指针。 pHGE->Release(); Create 和Release 过程使用了引用计数,也就是说,一般来看,除了第一次的Create 调用之外几乎不消耗CPU 时间和资源,每调用一次Create 函数,引用计数器就加一,只 有在第一次调用的时候才会真正的分配空间,调用Release 会使得引用计数器减一,当它 为0 的时候,才真正是释放资源。因此以下代码是可用的: while(true) { HGE* pHGE = pgeCreate(HGE_VERSION); // 确保不是第一次调用pgeCre ate 函数,因为如果是第一次调用,会分配内存。 // ... do something pHGE->Release(); } 此外,要成对的调用pgeCreate 和Release 函数,每次调用Release 之后,调用它的 指针将被赋值为0,例如: HGE* pHGE = hgeCreate(HGE_VERSION); pHGE->Release(); pHGE->Release(); // ERROR: pHGE == 0 另外,pHGE->Release 会调用pHGE->System_Shutdown(); 必要的第二步: 初始化: pHGE->System_Initiate(); 初始化语句放在Windows 入口函数中,这个函数将按顺序完成 1)窗口类的注册 2)创建窗口 3)初始化子系统 4)显示一个HGE 的LOGO(这个东西在HGE 里面被称之为HGE splash) 一般使用System_Initiate() 都会是这样的: if (pHGE->System_Initiate()) { pHGE->System_Start(); } else { MessageBox(NULL, pHGE->System_GetErrorMessage(), "Error", MB_O K | MB_ICONERROR | MB_APPLMODAL); } 必要的第三步: 调用: pHGE->System_Start(); 调用了System_Start 的目的是开始消息循环,见必要的第二步代码 pHGE->System_Start 和pHGE->System_Shutdown 是成对出现的,处于某些原 因,即使我们知道pHGE->Release 会调用System_Shutdown 函数,我们还是应该 去显示的调用System_Shutdown 函数。System_Shutdown 相比Release 要安全, 我们可以这样调用,而不会出错: pHGE->System_Start(); // ... Something pHGE->System_Shutdown(); pHGE->System_Shutdown(); // OK 不论如何,Create 和Release 成对调用,Start 和Shutdown 成对调用,那么就不会 有问题出现。 还有什么是需要的? System_SetState 函数 常常需要设置窗口大小或者是设置为全屏模式,需要设置是否使用声音等,这一系列操作被 称之为设置系统状态,统一通过调用pHGE->System_SetState 函数来完成,最为关键 的是设置帧函数,调用了pHGE->System_Start 之后,会在绘制每帧图像时调用帧函数。 pHGE->System_SetState(XXX, XXX) 通常可以在如何地方,如何情况下调用,不要 认为它们只能在pHGE->System_Initiate 之前调用 System_SetState 函数的第一个参数表示状态,在内部实现时,它是FSM 的状态,而 第二个参数表示值,通过这个函数,可以绑定状态和相关的值 补充一下,帧函数必须是一个全局函数,而不能是一个类的成员函数,并且帧函数的原型必 须是: bool FunName(void); 惯用法: 我们通常会在程序初始化之前设置状态,即在System_Initiate 调用之前,例如: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { pHGE->System_SetState(HGE_FRAMEFUNC, FrameFunc); pHGE->System_SetState(HGE_WINDOWED, true); pHGE->System_SetState(HGE_USESOUND, false); pHGE->System_SetState(HGE_TITLE, "HGE"); pHGE->System_SetState(HGE_SHOWSPLASH, false); // 用于去除 L OGO if (pHGE->System_Initiate()) { pHGE->System_Start(); } { MessageBox(NULL, pHGE->System_GetErrorMessage(), "Error", MB_O K | MB_ICONERROR | MB_APPLMODAL); } pHGE->System_Shutdown(); pHGE->Release(); return 0; } HGE 系列教材(7) --- 使用 Helper Classes 字体的使用: 1. 头文件 #include <hgeFont.h> 2. 载入字体 hgeFont* pFont; pFont = new hgeFont("font1.fnt"); // 不要忘记delete fnt 文件是一个字体描述文件(font description file),可以通过创作工具产生 3. 打印字体 pFont->printf(5, 5, HGETEXT_LEFT, "dt:%.3f\nFPS:%d (constant)", // 使用中文将出现“??” pHGE->Timer_GetDelta(), pHGE->Timer_GetFPS() ); 在渲染函数中打印文字,HGE 到目前版本1.81 依然不支持中文,只能使用第三方支持。 建议使用微妙的平衡(BOGY)提供的解决方案。 粒子系统的使用: 1. 建立一个hgeSprite 对象,hgeSprite 类的构造函数如下: hgeSprite( HTEXTURE tex, // 纹理的句柄 float x, // sprite 对应的纹理的x 坐标 float y, // sprite 对应的纹理的y 坐标(区别于顶点中的纹理坐标,这里无需规格 化坐标间隔) float w, // sprite 的宽 float h // sprite 的高 ); 注意,sprite 对应的纹理的坐标,是sprite 的左上的坐标。由此可见,一个精灵对应了 纹理中的一个四边形区域,实际的源码中,sprite 类含有一个hgeQuad 成员变量。 如果tex 为0,那么就使用白色作为纹理的数据(texture data) hgeSprite* pSpt = new hgeSprite(tex, 32, 32, 32, 32); 2. 设置混合模式,根据情况设置混合模式,后面详细讨论: pSpt->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_N OZWRITE); // 建议使用BLEND_ALPHAADD,这样看起来效果会好很多(增亮)。 3. 设置锚点(似乎和函数名字有点不符) void SetHotSpot( float x, // 锚点的x 坐标 float y // 锚点的y 坐标 ); 锚点是这样的一个点:进行一些操作的中心点。例如进行旋转操作的中心点,即旋转操作依 赖于这个点。通常设置sprite 的中心点为锚点。 4. 关联hgeParticleSystem pPar = new hgeParticleSystem("trail.psi", m_pSpt); // 关联hgeParticleSys tem psi 文件被称之为粒子系统描述文件(particle system description file),这个文件是 hgeParticleSystemInfo 结构对象的硬盘镜像,这里不做详细介绍。 5. 粒子系统中的基本参数介绍: 系统生命周期(System lifetime):粒子系统的生命周期,在这个周期内会产生新粒子 Emission:每秒产生多少个新的粒子 粒子生命周期(Particle lifetime):特定的某个粒子的生命周期 6. 设定Emission: pPar->info.nEmission=10; 7. 调用Fire 函数 pPar->Fire() 函数会重启粒子系统,但它不会影响当前活跃粒子 pPar->Render(); 9. MoveTo 函数 pPar->MoveTo(x, y); 用于移动粒子系统到(x,y)处 10. Update 函数 pPar->Update(m_pHGE->Timer_GetDelta()); 在帧函数中应该调用Update 且使用参数为m_pHGE->Timer_GetDelta() 使用 hgeSprite 渲染: 前面说了为了渲染,使用了hgeQuad,那样做是复杂的,我们完全可以使用sprite 来实 现,而不需要使用到过多的Core Functions 层的函数。 1. 创建sprite pSpt = new hgeSprite(tex, 96, 64, 32, 32); 2. 设置颜色 pSpr->SetColor(0xFFFFA000); SetColor 函数将为sprite 添加颜色,添加的方式由混合模式决定,设置混合模式,通过 调用函数pSpr->SetBlendMode 实现。 注意,这里设置的颜色是sprite 中hgeQuad 对象的顶点的颜色,四个顶点颜色将设为 相同,而混合模式设置的是sprite 中的hgeQuad 对象的blend 值。 pSpr->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NO ZWRITE); // 这里使用的纹理是alpha 通道渐变,颜色为白色的纹理,因此会使用到B LEND_COLORMUL,这点在《HGE 系列教材(5) --- 输入、声音和渲染》做了详细的 说明 3. 设置锚点: pSpr->SetHotSpot(16, 16); 4. 渲染 在渲染函数中,调用pSpr->Render(x, y); 方可 HGE 系列教材(8) --- hgeResourceManager helper class(本文未完成) hgeResourceManager 是一个资源管理类 1. 构造函数 hgeResourceManager( const char* scriptname = 0 ); scriptname 表示资源脚本文件名(Resource script filename),如果此参数为0,表 示不使用Resource script file 现在来介绍一下资源脚本: 资源脚本是一个文本文件,用于定义资源。资源文件由多个(或一个)命令(command) 组成,格式如下: Command ResourceName : BaseResourceName { Parameter1=Value1 ; 这里是注释 Parameter2=Value2 ... ParameterN=ValueN } 我们来看一个例子: Resource level1 { filename=levels\level1.dat resgroup=1 } 这里只有一个命令:Resource,Resource 命令定义了一个原生资源(raw resource) 注意,资源文件是大小写敏感的,资源文件中可以有注释,使用“;”开头。资源文件的参数 (parameter)是没有顺序限制的。 同种类型的资源,不可以使用相同的资源名(Resource Name)。在定义资源名或者文件 路径时,出现空格或者特殊字符,需要把整个字符串用双引号引起来。 BaseResourceName 是可选的,如果被指定,那么就表示对BaseResourceName 对 应的参数(Parameters)的拷贝,例如: Sprite wizard { texture=characters rect=0,0,32,32 hotspot=16,16 blendmode=COLORMUL,ALPHABLEND,NOZWRITE resgroup=1 } Sprite orc : wizard { rect=0,64,32,32 ; 设定新值 color=FF808000 ; 设定新值 } 这里orc 除了rect 和color 两个参数以外,其他参数值都和wizard 一样。 hgeResourceManager 是可以容错的,如果脚本出现错误,不会导致程序的终止,错误 信息将被写入日志文件。 1)Command(命令) Command 表明了资源的含义,含有以下几种: Include,Resource,Texture,Sound,Music,Stream,Target,Sprite,Animat ion,Font,Particle,Distortion,StringTable <1> Include 命令:Include 命令用于导入其他的资源脚本文件,例如: Include level2.res ; level2.res 是一个资源脚本文件 注意,自引用和循环引用是可行的,它们会被检查出来,并报告在日志文件中,例如: <2> Resource 命令:定义原生资源(raw resource) 参数: filename,resgroup。例如: Resource level1 { filename=levels\level1.dat ; 可以使用绝对或者相对路径,相对路径是相对于应 用程序所在的文件夹或者是相对于资源包的根目录,特别应该注意的是,如果它是一个相对 路径,相对的是应用程序或者资源包的根目录而不是脚本文件 resgroup=1 ; 资源组(resource group)标识符,0 表示没有特定的组 } <3> Texture 命令:定义一个纹理 参数:filename,mipmap,resgroup。例如: Texture background { filename=images\bg.jpg resgroup=1 } 由于没有设定mipmap 参数的值,因此它取默认值。 <4> Sound 命令:定义一个音效 参数:filename,resgroup。例如: Sound explosion1 { filename=sounds\expl1.ogg resgroup=1 } <5> Music 命令 HGE 系列教材(9) --- GUI(本文未完成) 1. hge 中GUI 对象和控件 hge 中GUI 对象被看作是一个控件的容器,hge 提供了创建GUI 对象的类hgeGUI 类 2. hgeGUI 类 1)AddCtrl 函数 void AddCtrl( hgeGUIObject *ctrl // hgeGUIObject 对象的指针 ); 我们通常可以有这样的写法: gui->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Play")); 这里hgeGUIMenuItem 是一个控件,继承于hgeGUIObject 类,注意,我们创建了 hgeGUIObject 对象,但是却没有去销毁它,因为hgeGUI 类的析构函数会去处理这些 问题。 2)SetNavMode 设置GUI 导航模式(Navigate mode): void SetNavMode( int navmode ); HGEGUI_NONAVKEYS - 无键盘导航 HGEGUI_LEFTRIGHT - 左右按键导航 HGEGUI_UPDOWN - 上下按键导航 HGEGUI_CYCLED - 循环 默认情况下,navmode 被设置为HGEGUI_NONAVKEYS,对于一个菜单,我们可以这 样设置: SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED); 使用上下键导航,并且循环。 设置光标sprite: void SetCursor( hgeSprite *sprite ); 设置光标对应的sprite,如果为0,表示不显示光标,默认情况为0。注意,光标不受G UI 对象的管理,也就是用户必须自己释放光标资源。 4)SetFocus void SetFocus( int id ); 每个控件都有一个对应的ID 号,这个ID 号被称之为控件的标识符,这里通过控件标识 符来设置焦点。键盘事件只会被分发到成为焦点的控件上。 5)Enter 开始GUI Enter 动画 3. hgeGUIObject hgeGUIObject 是一个抽象类,它有一个纯虚函数Render hgeGUIObject 类的子类的对象并不是GUI 对象,而是GUI 控件,这一点应该清楚 1)hgeGUIObject 的成员变量 hgeGUIObject 的成员变量都为public: // 必须在构造函数中初始化的变量 int id; // 控件标识符 bool bStatic; // 如果为true 控件无法成为焦点也不会接受键盘事件,同时它将被 navigate 例程忽略(前面已谈到设置navigate) bool bVisible; // 控件是否可见,如果为false,控件将不被渲染 bool bEnabled; // false 时,控件对用户的输入不作出任何回应,但是控件是可以 接受到用户的通知(区别于bStatic) hgeRect rect; // 控件有界框(bounding box)在屏幕上的区域 DWORD color; // 控件颜色 // 不需要在构造函数中初始化的变量 hgeGUI *gui; // GUI 对象指针 hgeGUIObject *prev; // 连接GUI 对象中的所有控件,子类不需要改变它 // hge 指针 static HGE *hge; 2)void Render(void) 渲染控件到屏幕 3)void Update(float fDt) fDt 上次调用Update 函数到现在所用的时间(单位是秒) 4)void Enter(void) 控件出现在屏幕上的时候被调用,用于播放控件出现时的动画 5)void Leave(void) 控件离开屏幕的时候被调用,用于播放控件离开屏幕的动画 6)bool IsDone(void) 判断控件出现动画和控件离开动画是否播放完毕 7)void Focus(bool bFocused) 控件获得焦点,bFocused 为true,反之为false 8)bool MouseMove(float x, float y) 以控件左上为原点,鼠标指针的坐标。如果控件状态改变,需要通知调用者,那么返回tr ue,否则返回false 9)bool MouseLButton( bool bDown) bDown 如果为true,表示按下鼠标左键,如果bDown 为false,表示松开鼠标左键 10)bool KeyClick( int key, int chr) key 表示按键的虚拟代码(Virtual code of the pressed key),见下表: HGEK_LBUTTON Left mouse button HGEK_RBUTTON Right mouse button HGEK_MBUTTON Middle mouse button (wheel button) HGEK_BACKSPACE BACKSPACE key HGEK_TAB TAB key HGEK_ENTER Any of the two ENTER keys HGEK_SPACE SPACE key HGEK_SHIFT Any of the two SHIFT keys HGEK_CTRL Any of the two CTRL keys HGEK_ALT Any of the two ALT keys HGEK_LWIN Left WINDOWS key HGEK_RWIN Right WINDOWS key HGEK_APPS APPLICATIONS key HGEK_PAUSE PAUSE key HGEK_CAPSLOCK CAPS LOCK key HGEK_NUMLOCK NUM LOCK key HGEK_SCROLLLOCK SCROLL LOCK key HGEK_PGUP PAGE UP key HGEK_PGDN PAGE DOWN key HGEK_HOME HOME key HGEK_END END key HGEK_INSERT INSERT key HGEK_DELETE DELETE key HGEK_LEFT LEFT ARROW key HGEK_UP UP ARROW key HGEK_RIGHT RIGHT ARROW key HGEK_DOWN DOWN ARROW key HGEK_0 Main keyboard '0' key HGEK_1 Main keyboard '1' key HGEK_2 Main keyboard '2' key HGEK_3 Main keyboard '3' key HGEK_4 Main keyboard '4' key HGEK_5 Main keyboard '5' key HGEK_6 Main keyboard '6' key HGEK_7 Main keyboard '7' key HGEK_8 Main keyboard '8' key HGEK_9 Main keyboard '9' key HGEK_A 'A' key HGEK_B 'B' key HGEK_C 'C' key HGEK_D 'D' key HGEK_E 'E' key HGEK_F 'F' key HGEK_G 'G' key HGEK_H 'H' key HGEK_I 'I' key HGEK_J 'J' key HGEK_K 'K' key HGEK_L 'L' key HGEK_M 'M' key HGEK_N 'N' key HGEK_O 'O' key HGEK_P 'P' key HGEK_Q 'Q' key HGEK_R 'R' key HGEK_S 'S' key HGEK_T 'T' key HGEK_U 'U' key HGEK_V 'V' key HGEK_W 'W' key HGEK_X 'X' key HGEK_Y 'Y' key HGEK_Z 'Z' key HGEK_GRAVE Grave accent (`) HGEK_MINUS Main keyboard MINUS key (-) HGEK_EQUALS Main keyboard EQUALS key (=) HGEK_BACKSLASH BACK SLASH key (\) HGEK_LBRACKET Left square bracket ([) HGEK_RBRACKET Right square bracket (]) HGEK_SEMICOLON Semicolon (;) HGEK_APOSTROPHE Apostrophe (') HGEK_COMMA Comma (,) HGEK_PERIOD Main keyboard PERIOD key (.) HGEK_SLASH Main keyboard SLASH key (/) HGEK_NUMPAD0 Numeric keyboard '0' key HGEK_NUMPAD1 Numeric keyboard '1' key HGEK_NUMPAD2 Numeric keyboard '2' key HGEK_NUMPAD3 Numeric keyboard '3' key HGEK_NUMPAD4 Numeric keyboard '4' key HGEK_NUMPAD5 Numeric keyboard '5' key HGEK_NUMPAD6 Numeric keyboard '6' key HGEK_NUMPAD7 Numeric keyboard '7' key HGEK_NUMPAD8 Numeric keyboard '8' key HGEK_NUMPAD9 Numeric keyboard '9' key HGEK_MULTIPLY Numeric keyboard MULTIPLY key (*) HGEK_DIVIDE Numeric keyboard DIVIDE key (/) HGEK_ADD Numeric keyboard ADD key (+) HGEK_SUBTRACT Numeric keyboard SUBTRACT key (-) HGEK_DECIMAL Numeric keyboard DECIMAL key (.) HGEK_F1 F1 key HGEK_F2 F2 key HGEK_F3 F3 key HGEK_F4 F4 key HGEK_F5 F5 key HGEK_F6 F6 key HGEK_F7 F7 key HGEK_F8 F8 key HGEK_F9 F9 key HGEK_F10 F10 key HGEK_F11 F11 key HGEK_F12 F12 key 如果控件状态修改了,希望通知调用者,那么返回true,否则为false

2013-06-22

hge中文教程

官方翻译过来的教程,比较详细,当然也有部分很粗略。 HGE in a child window HGE子窗口 Running HGE in a child window hosted by a Windows application may be useful to create authoring tools and ActiveX controls or to integrate HGE into a third party IDE. Here follow the guidelines how to do that. 运行HGE在主机的子窗口经由Windows系统可以帮助建立创造工具和ActiveX控制器或者将HGE整合到第三方IDE中。这里需要遵循一定的规定。 Creating HGE window as a child 建造HGE子窗口 To run HGE in a child window mode you should just specify the parent window handle. To do this set HGE_HWNDPARENT system state before calling to System_Initiate: 想要运行在子窗口模式运行HGE你必须指定出父窗口的名称。在调用System_Initiate之前需要先设置HGE_HWNDPARENT的系统状态: hge->System_SetState(HGE_HWNDPARENT, hwnd); Mouse cursor 鼠标指针 You may prefer HGE to use standard Windows cursor while in child window mode. This can be done by setting HGE_HIDEMOUSE system state to false: 你可以在将HE做为子窗口的模式下使用标准的Windows 指针。可以设定HGE_HIDEMOUSE系统状态为假: hge->System_SetState(HGE_HIDEMOUSE, false); Dispatching application's messages and running Frame Function 分派请求信息和运行框架函数 To provide additional flexibility System_Start behaves a bit differently in child window mode. First, it returns after just one call to user's frame function regardless of the value returned by it. Second, it doesn't dispatch window messages.So you should set up your own message processing loop.Here's the simpliest loop enough to run HGE properly: 在不同的子窗口模式下System_Start应灵活的控制使用。首先,不必在意调用使用者框架函数之后的返回值的内容。其次,不能分派窗口信息。所以你需要建立你的专有信息循环程序。如下这样简单的循环程序足够完全运行HGE: for(;;) { if(hge->System_GetState(HGE_HWND)) hge->System_Start(); if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) break; DispatchMessage(&msg); } } Moving and resizing HGE window 移动和改变HGE窗口大小 You can move and resize HGE window with WinAPI functions like MoveWindow. When it's window resized, HGE will reinitiate DirectX to meet new window dimensions: 你可以像用WinAPI函数那样移动和调整HGE窗口大小。调整好窗口大小之后,HGE将会控制DirectX去迎合新窗口的尺寸: MoveWindow(hge->System_GetState(HGE_HWND), x, y, width, height, true); Destroying HGE window 终结HGE窗口 HGE has lots of resources associated with it's window. So you should use System_Shutdown call to free them, don't rely on just destroying the window.The good place to do this is WM_DESTROY handler of the parent window: HGE的很多资源都是和它的窗口相互关联的。所以你需要使用System_Shutdown命令去释放它们,不能依赖于终结窗口去释放它们。在父窗口下使用WM_DESTROY: case WM_DESTROY: FreeLoadedHGEResources(); hge->System_Shutdown(); PostQuitMessage(0); return FALSE; Child window mode limitations 子窗口模式的限制 1. To accept keyboard events in child window mode HGE window must have input focus. It gains focus automatically when you click somewhere inside. Use the following call to set the focus explicitly: 1.在子窗口模式下要运行键盘事件HGE窗口必须输入关键点。当你点击内部的任何地方时都是自动的建造一个关键点。使用各焦点的时候必须要确定准确的焦点。 SetFocus(hge->System_GetState(HGE_HWND)); 2. Switching into fullscreen is unavailable when running in child window mode. Regardless of HGE_WINDOWED system state HGE will run in a window. 2.在运行子窗口模式的时候是很难转换到全屏模式的。HGE_WINDOWED系统状态可以不顾忌HGE而自行运行一个窗口的。

2013-06-22

空空如也

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

TA关注的人

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