读《游戏编程模式》(上)

大家好,我是光源。

偶然在微信读书里瞥到这个书名不禁有一些好奇,尝试看了几页发现还蛮有趣的。

作为非游戏从业人员,对于游戏开发本身就有一些好奇,又是一本讲编程模式的书 —— 不会太钻技术细节,一些思想还可以触类旁通沿用到非游戏程序设计中。

书籍开篇是介绍了作者自身对于游戏开发的经历和思考,非常赞同作者的一个观点是讲设计模式的书有很多,讲游戏开发引擎设计、渲染等技术方向的书也不少,唯独讲怎么好好做(游戏的)程序设计的书特别少。

我的共鸣在于之前看过的设计模式相关书籍都执着于设计模式本身,致力于将设计模式的细节讲得形象具体,而相关的使用场景、例子只是一点附赠品 —— 这样的叙述方式没错,但写出来的书很容易变成《代码大全》之类的工具书,缺乏了一些联系实际的感染力。

本书的可贵之处在于不仅联系实际、用实际问题引入对应的设计模式将设计模式本身说得明明白白,同时作者也是一个非常资深的专家级别开发者,介绍了设计模式的概念后,会去探索和扩展使用了设计模式之后的程序设计问题。

比如我们熟悉的观察者模式,作者先从「解耦」的角度阐述我们为什么需要观察者模式,然后又从实际应用的角度提出「维护观察者列表时如何处理线程安全问题」和「大量的内容动态分配要如何规避」。

又比如单例模式,对于单例模式作者从章节开头就表明,我们学习单例模式最需要学习的是「如何避免滥用单例模式」—— 稍有经验的开发者应该理解这个才是正确的态度。

还有状态模式。虽然以前也有在实际开发中用有限自动机去处理复杂业务,但在本书中,作者会一步一步拆解有限自动机的构建和思考过程,同时提出用于解决「多状态场景」的并发状态机、解决「状态复用」的层次状态机和解决「状态回溯」的下推状态机 —— 对于未接触过游戏编程的程序员来说,这些经验还是非常宝贵的。

从实际问题出发引出设计模式的,又基于实际问题提出专业从业者如何优化和解决,这些经验可以直接复用到日常开发中,对于初级到资深开发都非常有启发和参考价值。下面是读后感和读书笔记。

最近收获与反思

大家好,我是光源。

不知不觉已经 6 月份,计划年初要完成的事还未完成「年初」就已过去。自年后以来工作上投入度非常高,失去了几乎所有业余时间但也收获了一些认可,算是在新环境新工作里稳定下来(距离去年入职时间也过去半年多了,谈不上「新」工作了,哈哈)。

在这段时间里有一些新的思考,记录成此文。

最近正是高考。我们年少时应该都有过这样的幻想:假如我们当初有 xx 那么勤奋我们肯定能考上更好的大学、假如我们在高中时不贪玩一定能考得更好…… 但年岁渐长,我们渐渐懂得很多事重来多少次都是一样,我们的认知、我们的习惯、我们的性格、我们处理事情的方式决定了我们那一刻只会做出同一种选择。

内向者很难变得口若悬河活跃外放,好动者很难学会心无旁骛地应对枯燥的练习,怯懦者很难从容应对各种挑战。

时间给我们以智慧,让我们渐渐懂得自己能做什么和不能做什么。当然,有大毅力者绝对可以通过科学的方法和大量的练习突破自身的桎梏,但对于普通人而言,认清自己能力范围、与自己的优势劣势和谐相处并非是坏事

回到我自身,因为去年 10 月底更换了工作平台,这半年来一直在调整使用时间和精力的方式期望能符合我自己的生活节奏。所得的收获是,在没有保证足够休息时间的前提下,我的精力并不足以在工作之余做其他事。

以前给自己定计划时总把工作之外的时间排得满满的,虽然「仁慈地」排了半个小时中途休息时间,但实践下来,工作之后就算有时间也无剩余的精力去使用起来。

接受自己不是超人吧,我对自己说。

抱怨并没有什么用,当初接受这个 offer 时就已经做好足够的心理建设,且工作是真的忙并不是磨洋工。

我可以做的是如何是适应环境并超脱这个环境。(说起来还有点小兴奋?)

可以从两个方向做优化,时间和精力。

是时候再刷一遍《哈佛幸福课》

大家好,我是光源。

不知道何时起「幸福」和「快乐」这些美好的词汇逐渐离我们远去,生活的周遭充斥着各种各样负面的信息:房价高负担好重、某某公司又裁员了、每天工作好久好累、养孩子压力大每天都好焦虑…… 当我们打开脉脉、打开微博、打开论坛,各种焦虑简直要把我们吞没。

人无远虑必有近忧,为当下和未来担忧固然是没错,但生活不能这样下去,在阳光灿烂的日子里还是希望能露出笑容。

就在我思索如何去改变时,突然想起好几年前看过的一个公开课《哈佛大学公开课:幸福课》,尽管细节已经忘记,但是看视频时的那种内心平静感却记忆下来。我想,是时候再刷一遍了。

这门公开课是讲什么的?

顾名思义,它主要围绕着「幸福」这个词展开。

我们来到这个世上,到底追求什么才是最重要的?塔尔博士(教授这门课的讲师)认为幸福感是衡量人生的唯一标准,是所有目标的最终目标。

「幸福」并不玄乎,它属于积极心理学的范畴,可以用科学的方式去研究。公开课中塔尔博士像一个老朋友一样将自己的经历和观点娓娓道来,引用的资料都有权威的研究和论文作为依据。

那么它是用来给我们加油打气的鸡汤么?当然不是。鸡汤之所以被称之为鸡汤,是因为鸡汤只有鼓舞士气的作用而无具体实操的指导,只能给我们在心理上做一次短暂的按摩其实没有卵用。

而幸福课是可以实操的。它告诉我们睡眠和爱情的重要性、如何去解决负面情绪、如何面对压力、如何让爱情天长地久等等 —— 我觉得是在教我们如何好好地生活

我特别喜欢这门课的场景布置,很像 TED 的演讲会场,黑暗的背景下一个不刺眼的舞台,讲师像冥想老师一样给你安静的力量,你会不知不觉放松下来听他讲述。

有几点让我特别有共鸣(以至于让我在几年后的现在还记得)。

第一是运动对情绪的重要性。当身边有朋友情绪不好或身体不好时我总会建议他们去运动下,特别是互联网行业,有时候运动对坐了一天椅子的身体也是一种释放。对于我个人而言,运动更是一种良药,不管生理上还有心理上都给我很多力量。当然我的感悟不够有依据,公开课中讲师是分享了相当多的资料并给出如何运动的建议。

第二是冥想。几年前看完公开课后我曾经一度迷上冥想,各种找冥想的书看。而大家熟知的乔布斯也是冥想的爱好者。虽然我始终不得要领最后放弃,但冥想的益处我是想当认可的。

第三是触摸、爱情和睡眠的重要性。脱离「触摸皮肤」这个限定,简单的拥抱、握手都是有益的,都能给我们力量。而睡眠则不必多说,身体和精神并不是分离的两个东西,身体不好会导致精神萎靡,精神差则身体也会出现各种病痛。

第四是完美主义。「完美主义」这点感触太深了。曾经很多次我尝试自己去做一个应用,结果在设计交互和视觉时就各种万般纠结最后甚至开始怀疑 idea 本身是否值得去做 —— 每每如此我总是叹息,「该死的完美主义」!

还有其他东西已然忘却。

写到这里,我忽然有一个念头,那就是虽然我不记得幸福课的一些细节,但它对我却影响至今。比如对运动、睡眠、爱情的看法(惭愧的是明知晚睡不好却没能坚持早睡早起)。

毕业后的几年,明显感觉压力大了焦虑多了,幸好我还有这剂良药。

这也是我推荐给大家的目的吧。

准备再刷一遍哈佛幸福课,为了防止忘记细节,这次可能会边看边记录一些笔记。《哈佛大学公开课:幸福课》在网易公开课里可以看到,每一集都非常长,假如有朋友看不下去视频的,可以后面直接看我的笔记。

非常欢迎有同好可以交流下。

小谈 Kotlin 的空处理

大家好,我是光源。

近来关于 Kotlin 的文章着实不少,Google 官方的支持让越来越多的开发者开始关注 Kotlin。不久前加入的项目用的是 Kotlin 与 Java 混合开发的模式,纸上得来终觉浅,终于可以实践一把新语言。本文就来小谈一下 Kotlin 中的空处理。

一、上手的确容易

先扯一扯 Kotlin 学习本身。

之前各种听人说上手容易,但真要切换到另一门语言,难免还是会踌躇是否有这个必要。现在因为工作关系直接上手 Kotlin,感受是 真香(上手的确容易)

首先在代码阅读层面,对于有 Java 基础的程序员来说阅读 Kotlin 代码基本无障碍,除去一些操作符、一些顺序上的变化,整体上可以直接阅读。

其次在代码编写层面,仅需要改变一些编码习惯。主要是:语句不要写分号、变量需要用 var 或 val 声明、类型写在变量之后、实例化一个对象时不用 “new” …… 习惯层面的改变只需要多写代码,自然而然就适应了。

最后在学习方式层面,由于 Kotlin 最终都会被编译成字节码跑在 JVM 上,所以初入手时完全可以用 Java 作为对比。比如你可能不知道 Kotlin 里 companion object 是什么意思,但你知道既然 Kotlin 最终会转成 jvm 可以跑的字节码,那 Java 里必然可以找到与之对应的东西。

Android Studio 也提供了很方便的工具。选择菜单 Tools -> Kotlin -> Show Kotlin Bytecode 即可看到 Kotlin 编译成的字节码,点击窗口上方的 “Decompile” 即可看到这份字节码对应的 Java 代码。 —— 这个工具特别重要,假如一段 Kotlin 代码让你看得云里雾里,看一下它对应的 Java 代码你就能知道它的含义。

当然这里仅仅是说上手或入门(仅入门的话可以忽略诸如协程等高级特性),真正熟练应用乃至完全掌握肯定需要一定时间。

二、针对 NPE 的强规则

有些文章说 Kotlin 帮开发者解决了 NPE(NullPointerException),这个说法是不对的。在我看来,Kotlin 没有帮开发者解决了 NPE (Kotlin: 臣妾真的做不到啊),而是通过在语言层面增加各种强规则,强制开发者去自己处理可能的空指针问题,达到尽量减少(只能减少而无法完全避免)出现 NPE 的目的。

那么 Kotlin 具体是怎么做的呢?别着急,我们可以先回顾一下在 Java 中我们是怎么处理空指针问题的。

Java 中对于空指针的处理总体来说可以分为“防御式编程”和“契约式编程”两种方案。

最新靠谱可用的 Mac 环境下 FFmpeg 环境搭建

大家好,我是光源。

最近在尝试搭建 FFmpeg 开发环境时遇到一个蛋疼的事,Google 了 N 篇文章竟然没有一篇是可以跑起来的!

少部分教程是给出了自我矛盾的配置(是的,按照贴出来的代码和配置,他自己都跑不起来),大部分教程是看着挺全但忽略了某几个关键的点导致跑不起来,更蛋疼的是碰到报错后错误相关的文章也很少,当然还有一些是年代久远过时了。

于是在成功跑起来后,我将整个搭建过程整理出来,希望可以帮到后面的人。

本文基于 Mac OS X + Android Studio 3.2 + FFmpeg 3.3 + CMake。

文章会分为两部分,第一部分是总结一下碰到的几个坑,这样只是因为报错而无法继续的朋友可以先看看是否可以解决问题;第二部分是搭建过程的完整描述(我特意用另一台电脑测试过,可以完美跑起来)。

一、FFmpeg 搭建的常见问题

1. NDK 的问题

在编译之前,教程都会让我们修改命令中 NDK 的地址为自己本地的地址,我们当然自然而然地改成了 Android Studio 自带的 ndk-bundle。

然后编译的时候就发现会出现errno.h: No such file or directory字样的error。

这是因为 Android Studio 自带的 NDK 缺少相关的 .h 文件,从网上额外下载 NDK 然后编译时使用就可以解决问题。(基于 FFmpeg 3.3)

2. 编译命令的问题

报错信息形如

1
2
3
ffmpeg_build.sh: line 14: ./configure: No such file or directory

ffmpeg_build.sh: line 20: --extra-cflags=-Os -fpic -marm: command not found

之类的,请检查一下 Android 编辑脚本的 “/” 后是否有空格。

由于不同系统存在差异,最好找对应系统下他人验证可行的编译命令。

3. 编译相关的版本

编译过程有 NDK 版本、Android 版本、FFmpeg 版本、Android Studio 版本等,不同版本存在差异,最好是完全使用教程描述时的版本。

比如编译命令中包含的 Android 版本

1
export SYSROOT=$NDK/platforms/android-21/arch-arm/

这里的 android-21 改成 26 就不行,因为搜索了这两个文件夹只有 21 中有需要的 .h 文件。

Fork me on GitHub