• About
    • Resume
A Game Developer also plays some guitar

Author Archives: Benny Chen

A game developer, a music lover, and a partisan fan of F.C. Barcelona

Forca Barca!

April 21, 2010 8:24 pm / 1 Comment / Benny Chen

任何人在比赛前对你说出这样的结果,你都会说他是个疯子。但事实就是这样,这就是足球,这有如腥风血雨的一夜,巴萨在梅阿查,被国米人肆虐的撒欢,吞下了两年来最大的一场失利。就算全世界都在赞美你的美丽,赞美你的战无不胜,赞美你是这个星球上的王中王,但这就是足球,没有永远的常胜将军,我们要学会接受失利。

我想尽力去忘记昨夜的痛楚,但依然心如刀绞。

输球了就是输球了,不必埋怨球队长途驱车10小时的疲劳,也不必埋怨运气的不佳,更没有理由埋怨裁判的不公,现在不是埋怨的时候,更不是悲观丧气的时候,因为180分钟的比赛才进行了一半而已。

期待巴萨的将士们及时调整自我,恢复自信。我们只是暂时1:3落后,我期待下一个90分钟的比赛,回到属于我们的诺坎普。如果国米能够主场3:1赢了我们,why we couldn’t? We could do better, because we are Barcelona!

我爱巴萨。Forca Barca!

Posted in: Visca Barça / Tagged: barca, Champions League

悲剧

April 5, 2010 7:42 pm / 5 Comments / Benny Chen

最近真是祸不单行,前几天才刚把iTouch弄丢了,这两天我的笔记本硬盘又不幸丢失。

硬盘不是好端端的被包在笔记本中么,怎么会丢失呢。事情是这样的,我那用了快5年的笔记本终于开始罢了工,于是就到中关村送修,但因为硬盘里的数据非常贵重,怕维修过程中受损,于是就拆卸下带了回来,但昨夜跟几个朋友去后海酒吧high大了,今早硬盘早已不知了踪影。还不如扔在维修点呢,悲剧……

真是郁闷之际。

丢一个不值钱的硬盘真的没什么,但是——

因为很多数据还没有来得及备份,就这样,我从大学2005年到现在几乎所有的照片全部丢失,我学吉他以来收集的吉他谱全部丢失,一年以来日积月累辛苦整理的VOA听写资料全部丢失,等等等等各种资料。。。。

我欲哭无泪。

不养成及时备份的好习惯,这就是血的教训。

但也不完全是悲剧吧,主要有以下几点:

  1. 硬盘绝不包含任何艳照;
  2. 照片基本全丢,但还好在各种个人相册、空间中上传了不少,所以一些珍贵的照片还能找到。但尽管如此,这个损失还是最惨重的。未来的很多很多年以后,当去回忆生命中的这段时间时,又失去了很多很多回忆的画面。(我已经失去过一次了,05年第一台笔记本被偷就丢了很多照片)
  3. 虽然吉他谱全丢了,但我真练不了多少,反正以后要练什么再从网上下吧。
  4. 坚持了一年的VOA资料丢失了固然可惜(其实VOA我iTouch里算是一份备份的,但iTouch已经先去了),但我这一年通过VOA带来的进步是绝对不会丢失的。
  5. 与计算机技术相关的资料我基本都是有备份的。
  6. 最后严重感谢DropBox,使得与我毕业设计相关的重要资料在这场灾难中得以幸存。

最近真是衰到底了,这难道就是传说中的本命年效应么?穿红色儿的真一点也不管用。

Posted in: A Day in the Life

Faint!

March 29, 2010 10:08 pm / 1 Comment / Benny Chen

以后干什么事热血冲动之前,还是最好先做一下survey。前几天异常兴奋的开始翻译Google的C++风格指南,结果今天到Google上简单一搜搜出了一堆,这神圣的事情已经被无数人干过了。

Faint!

我也只是才翻译了一个chapter,但已经没有必要再继续下去了。

Google 开源项目风格指南 – 完整中文版在这里:http://code.google.com/p/zh-google-styleguide

Posted in: C++

[译]Google的C++风格参考指南(1)– 头文件

March 28, 2010 8:15 pm / Leave a Comment / Benny Chen

译者的话:

在一个开发团队中,很重要的一点是要遵循一个统一的风格,这样才能便于相互之间在代码上进行快速的交流和理解。反之,如果团队中的每个人只是按照自己的个性去写属于个人风格的代码,这必然会造成项目代码的五花八门,互相之间难以沟通,整个项目的代码质量低下,BUG率攀高,软件的可维护率也极差。长此以往,国将不国,团队将不团队,最终软件极有可能以一种极其混乱的状态收尾,这真是一个悲剧。

每一个C++程序员都有自己的编程风格,虽然大家的风格迥异,但也一定有一些共通的地方。我希望能找到一个对于C++风格的归纳和总结,这样在以后我的工作中,对我自己,甚至对我工作的团队,当然也对于正在阅读的你,能够有一个帮助和参考。所以,我决定翻译Google的这篇C++风格参考指南。当然,真正促使我去翻译这篇文章的原因是,我是一个C++技术和简洁代码风格的狂热追捧者。

注意,这只是一篇参考,它是Google的C++风格,你并不一定严格的遵循所有的规则,永远记住很重要的一点,风格永远跟着你的团队走。

本人能力有限,所以不一定每个地方都翻译的准确,另外一些不太好翻译的专业名词首次出现时,我会标注英文原文。

原文:Google C++ Style Guide

背景 (Background)

C++是很多Google开源项目所使用的开发语言。正如每一个C++程序员所熟知的,C++有很多强大的功 能,但功能强大也同时意味着复杂性(complexity),使得代码bug率更高且难以阅读和维护。

这篇参考指南 (guide)的目的在于,通过详细描述应该做的(dos)和不应该做的(don’ts),来控制我们撰写C++代码时的复杂性。这些规则令程序员在高效利用C++语言特性的同时,还能让手工写出的所有代码(code base)易于管理。

风格(style),或者可 读性(readability),我们把它称作为“用来管理我们C++代码的常用惯例(convention)”。不过用“风格”这个术语有些不当,因为这些惯例并不只是指代码源文件的格式。

让代码可管理,一种方式是加强代码的一致性(consistency)。令任何一个程序员能够快速的理解另一个程序员所写的代码是非常重要的。如果代码保持统一的风格并且遵循惯例,我们可以更加轻松的使用“模式匹配”(pattern- matching)推断出,不同的符号分别代表什么。创造这种代码公共性(common)需要习语(idiom)和模式(pattern),使得代码易于理解。在某些情况下,也许有好的理由来改变某些风格规定,但为了获得一致性,不管怎样我们还是得保持风格。

这篇参考指南所关注的另一点是C++的功能膨胀问题。C++是一个有很多高级特性的庞大语言。在某些情况下,我们限制甚至禁止使用一些特性。这样做是为了保持代码的简洁,并避免因使用这些特性而带来各种常见的错误和问题。指南里会列出这些特性,并解释为何限制使用它们。

Google 所开发的开源项目遵守这篇参考指南里所列出的规定。

注意,这篇指南不是C++教程,我们认为所有正在阅读的同志们都是熟悉C++的。

头文件(Header Files)

一般而言,每个.cc文件都有一个关联.h文件。但也有一些例外,比如用于单元测试(unit test)的.cc文件或者只包括一个main()函数的小型.cc文件。

正确的使用头文件可以让代码的可读性、规模(scale)和性能(performance)得到很大的改观。

接下来介绍的一些规则将会引导你越过使用头文件时的各种陷阱。

#define防护(The #define Guard)

所有的头文件都应该使用#define防护来防止多重包含(multiple inclusion),格式是<PROJECT>_<PATH>_<FILE>_H_

为了保证唯一性(uniqueness),该格式应该基于源文件在整个项目中的路径。比如说,项目foo中的头文件foo/src/bar/baz.h应该用如下的格式:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

…

#endif // FOO_BAR_BAZ_H_

头文件依赖(Header File Dependencies)

如果使用前置声明(forward declaration)就可以解决依赖,就不要用#include。

当你#include一个头文件的时候,你同时也引入了依赖关系————每当头文件有任何的修改,包含该头文件的代码也要重新编译。如果你的头文件还包含了其他的头文件,那任何对于这些文件的修改会导致任何包含了你的头文件的代码重新编译。因此,我们倾向于尽量减少使用#include,尤其避免在一个头文件中包含另一个头文件。

使用前置声明,可以显著的减少在你的头文件中#include其他头文件的次数。比如说,如果你的头文件要用到class File,但你不需要访问class File的详细定义,那你的头文件只需前置声明class File即可,而不是#include “file/base/file.h”。

那在哪些情况下,我们是只使用一个类(比如 class Foo),而无需访问它的定义呢?

  • 声明类数据成员类型为 Foo* 或者 Foo&
  • 声明(但不定义)参数或返回值为Foo的函数
  • 声明静态数据成员类型为Foo。这是因为静态数据成员在class之外定义

另 一方面,如果你的类继承自Foo或者你有一个类数据成员是Foo,那就必须包含Foo的头文件。

有些时候,使用指针 (scoped_ptr 更佳)成员而不是对象成员(object member)是明智的。然而这却降低了代码的可读性,并且导致性能损失。所以,如果这么做的目的只是减少头文件中的#include,那就别这么做。

当 然,.cc文件必须需要它所使用的类的定义,所以它会#include比较多的头文件。

内联函数(Inline Functions)

只当函数很小,比如只有10行或更少时,才定义它为内联函数。

解释:你可以以这种方式定义函数,该方式允许编译器将函数内联展开,而不是以传统的函数调用机制去调用它们。

优点:内联函数可以产生更加高效的目标代码(object code),但前提是内联函数要足够小。你可以随意的将这些函数设置为内联函数:访问函数(accessor),设置函数(mutator),以及其他的短小的并与性能紧密相关的函数。

缺点:过度使用内联函数会导致程序变慢。内联一个函数时,根据该函数的大小,内联会增加或降低代码的规模。内联一个很小的访问函数通常会降低代码规模,而内联一个非常庞大的函数则会大大增加代码的规模。在现代的处理器 (processor)上,因为使用指令缓存(instruction cache)的缘故,短小的代码通常跑的更快。

结论:

一个不错的经验法则是,不要内联超过10行的函数。要小心析构函数,它们通常要比表面上看到的要长很多,因为它们会隐式的调用成员或者基类的析构函数。

另一个有用的经验是,内联带有循环或者switch语句的函数是低效的(除非循环或switch语句从未被执行过)。

还有重要的一点是,就算函数被声明为内联,但它不一定就被内联。比如说,虚函数或者递归函数通常都不被内联。一般我们也不应该声明递归函数为内联函数。而通常我们把一个虚函数声明为内联函数的主要原因是,将它的定义放在类定义内,这样是为了图方便或者将它文档化(document)的行为,比如说在访问函数和设置函数上我们就是这么干的。

-inl.h文件(The -inl.h Files)

当你需要使用复杂的内联函数时,你可以使用文件名 后缀为-inl.h的文件来定义它。

内联函数的定义要放在头文件里,这样编译器在函数调用点才能访问到定义用于内联。然而,函数的实现代码通常放在.cc中,而且我 们也不喜欢把太多的实际代码放在.h文件中,除非这么做有利于可读性或性能。

如果一个内联函数的定义很短, 里面几乎没有任何逻辑,你应该把这样的定义代码放到.h文件中。比如说,访问函数和设置函数应毫无疑问地放在类定义中。稍复杂一些的内联函数定义也可能放 在.h文件中,这样能方便实现者(implementer)和调用者(caller)。尽管这样做可能使得.h文件有些笨重,但你可以把代码放到另一个 -inl.h文件中。这将实现(implementation)从类定义中分离,而且使得实现能够在需要的地方被包含。

-inl.h 文件还可以用于函数模板的定义,这使得你的模板定义易于阅读。

当然不要忘了,像其他的头文件一样,-inl.h文件 也需要#define防护。

函数参数顺序(Function Parameter Ordering)

当定义一个函数时,参数的顺序应该是:先输入参数,再输出参数。

C/C++函数的参数可以是函数的输入,函数输出,或者两者兼有。输入参数通常是值(values)或者常量引用(const reference),而输出参数和输入/输出参数是非常量指针(non-const pointer)。对于函数参数的排序,将纯输入参数放在任何输出参数之前。尤其不要因为一个参数是新添加的,就把它放在函数参数的最后,要将纯输入参数放在输出参数之前。

这不是个硬性规则。那种既是输入又是输出的参数(通常是class或者struct)会让情况变 得更复杂,还有一点,就像前面所说的一样,为了与相关函数保持一致性,也会需要违背这一规则。

文件包含的名字和顺序(Names and Order of Includes)

请使用以下标准顺序以保证可读性,并且避免隐藏的依赖:C库,C++库,其他库的.h,你的项目的.h。

所有项目的头文件应作为项目源文件目录的后代列出,不要使用UNIX中的目录快捷方式 . (当前目录)和 .. (父目录)。

举个例子,google-awesome-project/src/base/logging.h应该以#include “base/logging.h”的格式包含。

在 dir/foo.cc中,该文件的主要目的是实现或者测试在dir2/foo2.h中的东西,文件包含应按照如下排序:

  1. dir2/foo2.h (首选位置(preferred location) — 请见下面的详细说明).
  2. C system files.
  3. C++ system files.
  4. Other libraries’ .h files.
  5. Your project’s .h files.

首选的排序(preferred ordering,译者注:在以上例子中为dir2/foo2.h )降低了隐藏的依赖。我们希望每个头文件能够自我编译。最简单的方式就是确保它们中的每一个都在某个.cc文件中是第一个被#include的。

dir/foo.cc and dir2/foo2.h通常在同一目录下(比如base/basictypes_unittest.cc and base/basictypes.h),但也可能在不同的目录下。

在每个部分(section)中,根据字母顺序排列是不错的方式。

举个例子,google-awesome-project/src/foo/internal/fooserver.cc中的文件包含顺 序可能是这样:

#include “foo/public/fooserver.h” // 首选位置

#include <sys/types.h>
#include <unistd.h>

#include <hash_map>
#include <vector>

#include “base/basictypes.h”
#include “base/commandlineflags.h”
#include “foo/public/bar.h”

未完待续…

Posted in: C++ / Tagged: C++, Google, 参考指南, 头文件, 风格

一切就像是电影

March 20, 2010 10:51 pm / Leave a Comment / Benny Chen

真的很想写点什么来纪念下这平凡而重大的一天,但我已经累的虚脱了。

Posted in: A Day in the Life

只识弯弓射大雕

March 15, 2010 12:51 pm / 2 Comments / Benny Chen

北京的这个冬天真他妈的长,都3月了,雪还一场接一场的下。

但奇怪的是只要碰上踢球,就绝对是好天气。

最近开始恢复了踢球,这两个周末分别打了两场比赛,我们的球队一胜一平,战绩是不错的,但我的个人状态是惨不忍睹的。我的状态和体力在这个漫长的冬天里几乎被消磨殆尽,I really fucking hate winter.

这张照片是在上周末的比赛中。这动作,被人抓拍的极汗。这不是护球像李毅,更不是护球像亨利,这是护球像成吉思汗大帝,只识弯弓射大雕。

Posted in: FCB BJ / Tagged: 巴萨, 踢球

Podium Finish

February 11, 2010 4:15 pm / Leave a Comment / Benny Chen

最近在恶补前一段时间欠下的VOA债,难得遇到了一篇讲体育的,当中有这么一句话:

Both men are world champions and both have World Cup podium finishes this season.

句子没什么难的,关键是不知道podium finish是什么意思。podium我知道是讲台的意思,但什么叫拥有World Cup的podium finish呢。google之后,刚看到映入眼帘的几张图,就立马明白了是什么意思。

Wiki上的话:In many sports, results in the top three of a competition are often referred to as podiums, or podium finishes.

podium在这里可以翻译为领奖台的意思,那么VOA上的这句话大致意思就是:他们都是世界冠军并且在本赛季的世界杯赛中都登上了领奖台(即进入了前三)。

Posted in: Learn a Word / Tagged: podium finish

Game Engine Framework

February 4, 2010 1:44 pm / 2 Comments / Benny Chen
FoC of Game

在这次找工作的过程中,有一道笔试题让我印象深刻,题目只有简单的一句话:please use pseudo code to write a game engine framework(请用伪代码写出一个游戏引擎的框架)

当时看到这道题,完全是一种头皮发麻的感觉,虽然我对游戏引擎还算比较熟悉,但它可是个“巨象”般的庞大结构,要在短短的90分钟的笔试时间内把它“摸”完(而且90分钟也不只这一道题),那可真是天方夜谭。所以我当时在试卷上留下的结果就是,草草的画了几个模块图了事。

之后我才意识到,我根本就完全没有理解这道题,或者说,是完全没有理解一个词的意义——framework。受游戏引擎庞大印象的牵连,我把framework想得太大了。

Framework对于IT人士来说貌似是个挺时髦的词,这个词也经常被我们挂在嘴边,我也如此。但问题是,我几乎从来没有去好好的留心过或者深究过,到底什么才是framework,什么样一个东西才能被称为framework,它的准确定义又是什么呢。

看一般英汉字典里对于framework的解释:

structure giving shape and support  框架; 结构

这只是给了我们framework的中文翻译而已,几乎还是没有给我们什么有用的信息。

记住一句话:有困难,找Wiki。当我看到Wiki上对software framework精确的定义时,突然间,一切都明白了。

原文URL:http://en.wikipedia.org/wiki/Software_framework

A software framework, in computer programming, is an abstraction in which common code providing generic functionality can be selectively overridden or specialized by user code providing specific functionality. Frameworks are a special case of software libraries in that they are reusable abstractions of code wrapped in a well-defined API, yet they contain some key distinguishing features that separate them from normal libraries.

Software frameworks have these distinguishing features that separate them from libraries or normal user applications:

1. inversion of control – In a framework, unlike in libraries or normal user applications, the overall program’s flow of control is not dictated by the caller, but by the framework.
2. default behavior – A framework has a default behavior. This default behavior must actually be some useful behavior and not a series of no-ops.
3. extensibility – A framework can be extended by the user usually by selective overriding or specialized by user code providing specific functionality
4. non-modifiable framework code – The framework code, in general, is not allowed to be modified. Users can extend the framework, but not modify its code.

这段话的大概意思是这样,首先表明了software framework是一种抽象体,这个抽象体通过一些公共代码提供了通用的系统功能,使用framework的用户可以在此基础上进行编码,以覆盖或者特化该系统中的相关功能。接着,这段话还说明framework也是一种库,但跟传统的软件库又不同。framework的特点被总结为以下4点:

  1. framework完全决定了程序的控制流,该控制流绝对不会被调用framework的用户(callee)改变,这就是framework跟传统的软件库不同的地方;
  2. framework提供默认行为,且这些默认行为绝对不是无意义的行为;
  3. 用户可以扩展framework的行为;
  4. framework本身的代码不允许被用户改变。

看到这里,我几乎是只有抱头痛哭的份了。因为,从开始学最基础的DirectX技术起,那每一个Demo中,不管多小的Demo,几乎就包含了这样的一种框架,抑或是说,一种游戏引擎框架。只要理解了framework的意思,这道题就根本不是什么问题。我是完全被“游戏引擎”这4个字吓住了,这道题的目的根本不是要你真正的写一个正规的游戏引擎(那是扯蛋),只要弄出一个基本架子即可,达到“麻雀虽小五脏俱全”的效果。

几乎所有的游戏或者说所有的图形渲染的程序,都是遵循下面这样一个过程,一个再熟悉不过的控制流。

FoC of Game

游戏的整个控制流就可以到这么简单,除了图上所描述的东西之外,再加上一系列的消息处理,就可以组成一个基本的游戏框架了。按照wiki上所描述的基本软件framework的4大特点,再来看看游戏引擎framework是如何体现的。

  1. 很显然,游戏的控制流如上图所示,使用framework的用户无法更改;
  2. 游戏引擎framework当然提供默认的行为,比如Initialize部分封装默认的窗口初始化和一系列的设备初始化等过程;
  3. Update和Render,是framework使用者真正进行艺术创造的地方,是游戏开发者的画板。
  4. 游戏引擎framework的代码同样不允许用户修改。

用代码来表现framework是很简单的,在面向对象的语言中一般用抽象类,既提供一些默认的实现,又提供抽象接口供用户扩展。而用户要使用这个framework,只需自定义一个类继承该抽象类,并提供各个抽象方法的实现。用户所需做的只是做一系列的填空题,当然填的如何精彩这就完全取决于用户了。

写这篇文章的真正目的不是为了说明一个游戏引擎的framework是怎么样的,只是借此来强化framework的概念,这样当我们下次再说出这个词的时候,能够知其所以然,而不是自欺欺人。

如果对游戏引擎framework感兴趣,这里有一个简单的游戏引擎framework的代码可供参考: http://gpwiki.org/index.php/SDL:Tutorials:Simple_Engine_Framework

Posted in: Game Programming, Some Experiences / Tagged: framework, game engine, 框架, 游戏引擎

2 More Accessories

January 22, 2010 6:26 pm / Leave a Comment / Benny Chen

刚给自己新添了两个guitar配件。g7thprotools-logo

因为最近一直在练Norwegian Wood这首歌,而这首歌是需要capo在2nd fret的,于是就迫切的在淘宝商城挑中了这款G7th Nashville Capo。号称是世界上最强的capo之一,我虽然吉他弹不起世界上最强之一,但这种小的配件还是用得起的,嘿嘿。之前自己曾经有过一个capo的,记得是花20块钱在王府井的一个商店里买的,不过后来就跟我的第一把民谣琴长眠在老家了。

这第二个配件完全是在搜寻capo过程中无意中看到的,没想到练指力还能有这么专业的指力训练器。一直觉得自己左手力量比较欠缺,需要加强,于是就毫不犹豫的买下了它,试着用用。买了个中等强度的,7磅,足足22公斤多。但俗话说不管练什么得讲究科学方法,盲目练只会适得其反,所以还得好好研究下这款Prohands指力训练器的用法。

Posted in: Guitar / Tagged: capo, g7th, prohands

Quotes from “Clean Code: A Handbook of Agile Software Craftsmanship” (1)

January 20, 2010 5:57 pm / 2 Comments / Benny Chen

最近在读这本Robert Martin的Clean Code,中文译本是《代码简洁之道》,我觉得非常好看。我一直比较注重写出简洁出色的代码,并且一直以为自己在这方面做的还不错,但随着这本书的阅读,虽然我的一些观点和想法被得到验证,但另外一些却完全被颠覆。也让我意识到离一个出色的专业程序员还有多大的差距。

We’ve all looked at the mess we’ve just made and then have chosen to leave it for another day. We’ve all felt the relief of seeing our messy program work and deciding that a working mess is better than nothing. We’ve all said we’d go back and clean it up later. Of course, in those days we didn’t know LeBlanc’s law: Later equals never.

这样的经历真是太普遍了,我们写了一堆烂代码并且实现了某个功能,颇有成就感,但同时我们也意识到这是一堆垃圾代码,并且提醒自己等未来有空了一定要回来收拾这堆垃圾。但——Later equals never,我们再也没回来过。
所以,垃圾要及时处理,不然就这样遗臭下去了。

Replace the temptation to create noise with the determination to clean your code. You’ll find it makes you a better and happier programmer.

程序员避免忧郁症的好方法就是遵循简洁之道。

And now note the word that Bjarne uses to describe the consequence of that inelegance. He uses the word “tempt.” There is a deep truth here. Bad code tempts the mess to grow! When others change bad code, they tend to make it worse.

当面对一堆烂代码时,很少有人愿意去收拾这堆烂摊子,结果就是让它们烂到极致.(让我想起之前做过的一个flash项目,接手时是噩梦般的代码,我只能东补西凑,到最后功能加的越多,越是恐怖的混乱,几乎完全无法维护)

You get the drift. Indeed, the ratio of time spent reading vs. writing is well over 10:1. We are constantly reading old code as part of the effort to write new code. Because this ratio is so high, we want the reading of code to be easy, even if it makes the writing harder. Of course there’s no way to write code without reading it, so making it easy to read actually makes it easier to write.

这和我以前一直所想的观点正好契合,写只有1次,而读会有N次(N会随着不同的项目有着巨大的差别),所以为了那更多更多次的读,多花时间在写上是绝对值得的。而Martin给出了读写的比例至少在10:1的样子,他还提出了“要想写容易,得先容易读“。

It was the bad code that brought the company down.

烂代码让这家公司歇菜了!烂代码的威力如此恐怖,对于这点,我坚信不疑。

Clean code is simple and direct. Clean code reads like well-written prose.

简洁的代码读起来应该像优美的散文。

One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king. Professionals use their powers for good and write code that others can understand.

聪明的程序员不等于专业的程序员。

In short, a programmer who writes clean code is an artist who can take a blank screen through a series of transformations until it is an elegantly coded system.

我热爱艺术,所以我热爱简洁漂亮的代码。我梦想成为一个艺术家,从程序员入手是个不错的选择。

Posted in: Some Experiences / Tagged: clean code, 代码简洁之道

Post Navigation

← Older Posts
Newer Posts →

LinkedIn

Milan Petrovic

Categories

  • In My Life (25)
    • A Day in the Life (8)
    • English Learning (2)
    • Learn a Word (7)
    • Something In The Way (8)
  • Music Heaven (8)
    • Guitar (1)
    • In Concert (1)
    • Lyrics (3)
  • OK Computer (54)
    • 3D (3)
    • C++ (10)
    • Computer Graphics (15)
    • Game Programming (23)
    • iOS (6)
    • Linux (1)
    • Lua (9)
    • My Projects (3)
    • Some Experiences (9)
    • Talking in Code (2)
    • Unity (2)
  • Quotations (2)
  • Uncategorized (1)
  • Visca Barça (24)
    • FCB BJ (5)

Recent Posts

  • [译]优化你的手机游戏(没有延迟的,才是健康的)- 一篇给游戏美术设计师读的文章
  • 新浪微博API for MOAI
  • 稍后继续
  • Unity Developer ++
  • Another Thread @ Moai Forum
  • 1st Day of Golden Week
  • 为SyntaxHighlighter添加新语言
  • 基于Lua的State Pattern
  • Class Diagram of Pacman
  • 基于Moai的Pacman

Recent Comments

  • 约修亚_RK on 为SyntaxHighlighter添加新语言
  • 爱装的小男孩 on 小心DLL链接静态库时的内存错误
  • happyfire on Game Loop的几种实现方式
  • William on 新浪微博API for MOAI
  • Benny Chen on 新浪微博API for MOAI
  • your man on 新浪微博API for MOAI
  • 你家男人 on 稍后继续
  • 逍遥 on 关于对std::vector的遍历
  • papa on Unity Developer ++
  • T客网 ︱ Techpot » Blog Archive » iOS开发与OpenGL ES相关问题整理(1) on iOS开发与OpenGL ES相关问题整理(1)

Tags

2d 3D 3dsmax 3ds max air Apply architecture Asia tour barca Beijing bilbao binary search blocked bob boost bruce springsteen C++ capo CGContextDrawImage Champions League Change DLL DX10 eval exporter flash framework frustum culling game game engine iniesta ios linux lua Moai opengles pacman plug-in plugin 北京 导出插件 崩溃 巴萨 游戏引擎 踢球
© Copyright 2026 - A Game Developer
Infinity Theme by DesignCoral / WordPress