祝所有habrozhitel美好。 我想向您介绍3年多后我如何返回一名业余游戏开发人员,从根本上改变该工具(以及一路走来-我的世界观),以及它的来龙去脉。 在削减下:
- 在旅程开始时简要介绍所有事实。 就像廉价的在线广告“之前”和“之后”中的图片“之前”一样。
- 在现代的前端自愿潜水,风格是“钱在哪里,Lebowski ?!”
- 在亲密的地方略有瘙痒,变成了通过做旧的事来学习新事物的强烈愿望。
- 意识到自己的无助
- 克服
- 美好的结局,就像您的这些电影一样。
免责声明
这篇文章在github上以草稿形式存在了两年,其几乎完整的版本于2017年底写成了对事件的热烈追捧。
市民,自我介绍!
在上一篇文章( https://habrahabr.ru/post/244417/ )中,我写了一些关于我自己的文章,更具体地说是关于我和gamedev如何连接的。 法律上-事实上,我不会-我编写游戏和引擎是为了娱乐和参加暖灯比赛。 从那以后,几乎没有什么变化。
对于进一步的叙述和施加必要的气氛,重要的是,在这个故事的开头,我是一个专业的.net Web开发人员,可以使用html5,css3和... jquery。 为了加强意外的“转机”,我们补充说,对JavaScript充满了不信任和厌恶,其特点是:
- 坦率地误解了所有关于语言的宣传;
- 关于类型化,框架的过时加速,数字+字符串惊奇等等的一系列笑话。 您知道这样一套完全标准的,有绅士风度的开发人员使用的是一种较旧的,更加成熟的语言(嘿,我知道.net平台比js还要年轻,但从字面上看并不是“成人”)。
来吧!
2017年9月。我使用崭新的技术堆栈(.net核心Web API + angular 4)开始了新的暖灯工作,而我的任务只是后端。 Angular这个词在我看来很讨厌,npm和nodejs与冰沙和陀螺踏板车紧密相关。 蒂姆利德(Timlid)看到并理解了这一点,并教给我一门关于如何发扬所有这种自发主义的短期课程。 就像关于楚科奇和太空中的狗的笑话一样。 我记得我需要开始的蝙蝠昵称(记住npm run start我觉得这对我温柔的性格是极端不必要的),并将自己沉浸在温暖和 管子 LED .net核心。
2017年10月。 蒂姆利德说,我们的前线工人立即缝制了4个项目,并向我提出要削减管理领域的某些内容。 他们说,这样做很容易,只需重复对实体N进行的操作,直到现在对实体M进行重复。致使同事们为我逃避陀螺踏板车和vape的笑声而烦恼,匆匆阅读了一些关于Angular的短期教育计划,通过复制粘贴和运气,我我生出一些可以保留的部分。 Timlid很满意,我很震惊,而且后端的任务似乎出现在了主板上...
但是没有 有很多后端支持者,已经为他们完成了很少的任务,并且前面没有耕地。 已经直接在门户网站上执行的一项新任务使我认真处理此事。 同事们努力折服我的裤子,带我去一家理发店,在一周的时间里,我开始阅读有关Angular,TypeScript,npm,webpack等的资料。 顺便说一下,有关恐龙现代Javascript的文章很有帮助-https: //habrahabr.ru/company/mailru/blog/340922/ 。
一段时间后,我能够完成简单的前端任务,感觉就像在没有女仆的情况下看门人一样。 我仍然对前端的笑话感到轻笑,我建议我的后卫们聚在一起,听听我对香蕉草莓的体验。 每个人都笑了,但是每个人都想秘密地了解在这个迅速的前端中发生了什么样的冒泡(实际上,不是)。
事不宜迟,我用我对Angular的基本了解重新介绍了Habr的上述文章。 Mitap伴随着一声巨响,随后,我花了一系列类似的话-关于后端的前端,但是对于我们的故事而言,它并不那么重要。 唯一重要的是,它们的实现使我对现代前端技术堆栈进行了更深入的研究。
发痒
在工作中,一切都变了,家庭生活中出现了一个相对平静的时光,并且出现了瘙痒。 这样,很小,仍然很脆弱,生活在潜意识的边界上。 他们说,三年前,我的脑海里忽然浮现出想法,我几乎完全停止了自己的业余爱好-编程游戏。 但是,如果您结合了新鲜的知识并且呢?
我看了很长时间的WebGL,但之前我对使用WebGL时没有任何帮助(键入,自动完成)感到恐惧。 在这里,请-肉中不存在的银色子弹,用同样的锤子将所有东西钉起来。 打字稿
对我来说,作为一个知道回调地狱之痛的人,var self = this,bind(this),undefined不是一个函数...因此,TypeScript在我看来甚至都不是新鲜的呼吸,而是蓝色星舰上的一种向导,它起源于天堂,懒洋洋地扔给我-儿子,忘记您以前对js的了解,我将向您展示兔子洞有多深。 这个类比看起来是否混乱,并且通常与其他类比大杂烩? 没错,就像TypeScript本身一样。
类,接口,类型,异步,编译错误和错别字,代码完成,没有铃鼓的工作,易于理解的let行为,而不是劝阻var范围内的var。 当然,过了一会儿,我意识到大部分这种幸福的赞助者根本不是TypeScript,而是现代版本(ES6及更高版本)中的JavaScript本身。 但是在那一刻,我似乎找到了一位先知,它将带领前端发展成为一个光明的先知, 共产主义者 未来。 除此之外,各种IDE在Intellisense领域的足够认真的发展以及对开发人员的帮助,也许您会理解我的小狗的喜悦。
无助
我的呼吸中第一个严重的打击是TypeScript本身。 尝试将其固定到一个空项目中使我理解-我无法理解除angular-cli之外的该死的东西,这对我来说是很多肮脏的工作。 我需要编译器吗? 好的,将其拧入package.json,进行npm安装,运行tsc等。 嗯,必须全局安装吗? 我将所有这些内容都忽略了战争的沉闷细节,我会说一段时间后,我学会了将main.ts变成main.js。 但是在我之前是忙于webpack。
是的,现在我意识到没有他也有可能做。 但是当用Typescript笨拙的手掌握时,周围的一切看起来都像angular-cli。 在实施webpack之后,我才知道TypeScript编译器本身能够“监视”文件中的更改,而无需webpack即可解决导入/导出的问题。
克服
大约一周后,我能够创建一个项目,在其中编写TypeScript代码,单击“保存”,一切按预期进行-webpack自动将我的所有文件重新编译为一个捆绑包,首先在其上运行TypeScript编译器,然后将构建文件放入一个单独的文件夹,我在其中复制了其他静态内容,并在那时的浏览器中,lite-server重新加载了页面。 我说一切都是自动发生的? 不,一切都是自动发生的。 乔伊无止境,我坐下来写了一个简单的竞技场射击游戏。
它从哪里开始 国土 是我的游戏吗? 当然,还有数学向量和矩阵之类的基本知识。 我在工作中成功克服了Not Not Invented Here综合症,但从业余爱好来看,它并没有消失。 我不想要现成的库,所以我坐下来写数学。 不,这太吵了。 我打开了以前的FreePascal框架( https://github.com/perfectdaemon/tiny-glr/ ),并开始从那里转换数学。
展望未来,我要说的是,总体而言,我的整个新框架是将旧版本从Free Pascal转换为TypeScript。 鉴于游戏开发人员三年以上的中断,我无法提出更好的架构,甚至无法记住过去的缺点。
一段时间后,我开始喘不过气来:动力自然降低,工作量增加。 然后在igdc上宣布了另一场比赛。 相信我,这场比赛是设定主题,技术和时间限制的出色外部动机。
比赛项目
我在上一篇文章中已经说过什么是 精神错乱 igdc ,但我会在这里简单重复一遍-这是一个热情洋溢的社区,举办中短期竞赛,以针对特定主题开发游戏。 没有现金奖励,知名赞助商和工作保障。 哦,是的,即使没有广告,也没有热情,并且自愿捐赠了用于托管和托管的域名。 等了将近15年。
竞赛主题- 垃圾游戏 。 拥有丰富多样的图形资源。 参与者的任务是仅使用游戏制作游戏。 流派和主题不受限制,由于只包含图形,因此允许使用任何声音和音乐。 历史悠久的技术限制与完全脱机启动而没有安装程序,下载等有关。
后者是一个小问题,因为当用户在本地打开html文件时,Chrome和该公司禁止执行许多操作。 WebGL可能无法打开,脚本也不想被拉,更不用说图形资源了。 有一种解决方法-我们为用户制作一个本地超小型Web服务器和一个启动脚本,该服务器将拾取该服务器并在所需地址打开用户喜欢的浏览器。
任务很简单,我在C#中遇到了一个6 KB的exe文件,附近有一个蝙蝠昵称,它定义了服务器和端口的根文件夹。
但是,这对于实现一个大而干净的目标的小障碍就足够了-为比赛编写游戏。
比赛游戏
通过查看资源,我意识到竞技场射击游戏的使用将非常可靠。
完成基本工作后,我开始选择所需的资源。 以纹理图集的形式进行的最终切片如下所示:

顺便说一下,游戏中从未使用过一些图集上烤的东西。 加载资源后,我为自己启动了一个新功能-Sprite动画。 事实证明,小时候我很高兴:

自己的物理学
将他人的物理学与发明自己的无限欲望联系起来似乎至少是亵渎神灵,而且在我看来,我的狂热生物甚至没有考虑过(我刚刚击败了精灵动画,还记得吗?)。 此外,在基于矩形(轴对齐的边界框,AABB)和圆的简单碰撞处理中,有什么困难? 很多东西。 从将角色卡在看不见的角落开始,到将世界上所有对象带到矩形和圆形的事实开始。
解决所有问题是不可能的,但是仍然出现了一些物理学:

声音
谨慎地认为这是困难的。 实际上,结果却以某种方式令人怀疑地简单而有效。 我们创建了一个音频上下文,创建了一个音频缓冲区,以浏览器可接受的任何格式在其中放置音乐/声音(我使用了wav),创建了一个节点并指出要从哪个缓冲区播放。
我使用bfxr( https://www.bfxr.net/ )生成的声音。
卡其色
拐杖,临时决定,podhachivaniya-很难找到只通过传闻知道这些单词的人。 比赛结束时,我插入了几个值得注意的备份。
没有文本输出-使用过的html
在比赛结束时,很明显,我没有时间将文本的渲染图传输到引擎。 即使没有发电机。 有很多选择,这是四个主要选择:
- 使用WebGL在位于画布顶部的透明2D画布上渲染文本。
- 制作没有文字的游戏
- 烘烤必要的单词并将其用作精灵
- 以HTML输出HUD
根据比赛的条款,可以仅使用提供的自定义像素字体,因此删除了第一个选项(在2D画布上渲染文本)。 只能使用系统字体来渲染画布。 通过fontface加载到CSS中的字体工作非常不稳定。
无文字播放是一个很棒的选择。 很可惜的是,那时我的创造力使我感到难过。
所需的最小词汇量很大,并且夸大了资产的规模。 另外,数字的显示仍然需要一定的逻辑。
最后,我们使用了真正的拐杖-我只是将HUD实现为画布下的html标记,将@fontface连接到css,并通过标准DOM API(getElementById)组织了更新。
游戏重启-document.location.reload()
玩家死亡时,他想关闭游戏或重新开始游戏。 不幸的是,如果您从一开始就没有提供某种重启机制,并且在一堆组织不善的课程上弄脏了整个游戏状态,那么您将无法获得很好的重启体验。 总会有一个神奇的地方没有被重置为零。
在这种情况下,一个很好的拐杖是通过标题中提到的document.location.reload()标题重新加载了普通页面。 鉴于最终版本的大小很小(少于300 kb,包括所有资源),并且游戏可以在本地运行,因此重启速度可以忽略不计。
发生什么事了
您可以在此处在线尝试: https : //perfectdaemon.imtqy.com/151/index.html
链接到存储库: https : //github.com/perfectdaemon/ts-game
包含该游戏源代码的存储库版本: https : //github.com/perfectdaemon/ts-game/releases/tag/0.1.0
结论是一个愉快的结局。
总之,我想简要概述在WebGL + TypeScript上编写游戏的主观利弊。
优点
- 编写一次,随处播放/调试。 我可以将游戏放到imtqy.com上,这很酷,任何人都可以使用浏览器从任何设备上进行游戏。 自然会有一些保留。
- 在进行了某些设置并添加TypeScript之后,使用现代JS并不是很糟糕。
- 方便创建上下文(与Win API和OpenGL相比)
- 有一个方便的工具(Visual Studio Code),它配备了完善的插件,并且确实有助于通过技巧,代码片段和有关问题区域的注释来编写代码。
缺点
- JavaScript在单个线程中运行。 问题甚至不在于您想在单独的流中考虑物理或逻辑。 分析表明,WebGL调用被阻止,即 他们等待控件从视频卡驱动程序返回,然后再继续执行代码。 尽管大多数WebGL调用返回的都是空。 许多功能的桌面OpenGL实现(在某些驱动程序中)可立即返回控制权,从而显着提高了渲染速度。
- 向左/向右走一小步-您就一个人了。 Angular和Typescript有问题吗? 堆栈溢出的前两个链接将为您提供帮助。 有想分别与Typescript交朋友并且出现一个奇怪的错误/问题吗? 准备好可能自己一个人的事实。 当然,作为一个以前使用非常流行的FreePascal + OpenGL堆栈(没有)的人,我已经习惯了。 但是对于像C ++这样的成熟语言,总会有一个印度人解决了这个问题。 然后是中国人,他们使用Guitar Hero和Arduino的控制器解决了这个问题。