-
2008-08-16
【转贴】【老坛子转移贴】淺談遊戲程式設計入門 __下 - [Windows App Dev]
Let's Rock'n Roll
马步扎稳之后,就可以开始来玩玩真正有趣的柀ξ鲊樱?
『Graphics,是一个游戏的程序设计中,相当重要的一个部分,也常常是一个游戏的程序设计师的最主要工作。当然,也可以说是程序设计中,最有趣的一件事。』
「那么要从哪里开始?」首先,我们必须了解,要去写一个3D的程序,并不是全部从无到有的从头做起、一个一个轮子的造出来;而是去使用一组别人已经 做好的基本功能,像堆积木一样的一步步堆砌出我们梦想中的城堡。我们无须去在意每一块积木的内部构造是什么、或从何而来,而是应该学习如何利用这些不同积 木的不同特性,建造出最合适的目标。转换成程序的观点来说,就是世界上的某几个大头,制订了一组标准的3D绘图函式以供其它人使用;而一般的程序设计师, 就只需要去了解该函式的接口及使用方法就可以了。如此的一组函式及接口,也就是常被人称做 API (Application Programming Interface) 的柀ξ鳌?
或许你已经听过,目前主流的3D绘图 API 由两大流派分庭抗礼 — 分别是 DirectGraphics 以及 OpenGL。那应该学一个比较好呢?是的,相信这也是困扰着很多初学者的问题之一。「网络上好像关于 OpenGL 的资源比较多耶?」……「可是游戏业界好像都是用 DirectGraphics 居多耶?」…………。
『我的建议是:两者都学。』
唯有兼容并蓄、纳百家之长于一身,才能在遇到问题时,提出最合适的解决方法。OpenGL 与 DirectGraphics 可说是各有优缺点:OpenGL 的程序接口固定性很大,操作方式简单、易于学习;但它只提供一些基本功能的函式,并且它的版本更新太慢,若遇到新的技术出来,往往只能以 extension 的附加卷标功能来加强。而 DirectX 的使用方法则较为繁杂,但它也提供了更多进阶功能的函式可供使用;而它的版本几乎每年更新,是好事也是坏事,往往新版 DirectX 的程序接口都会和旧版有不小的相异之处,特别是从 DX7 到 DX8 的转变更是剧烈;这对所有的程序设计师来说,都是一场又一场「程序引擎重写」的恶梦。
『然而,对一个对没有3D图学背景、初学3D程序设计的人来说,我建议从 OpenGL 开始。』
理由如下:OpenGL 的使用方法较 DirectX 简易且直觉,可以让初学者专注于真正重要的3D图学基础的学习上。包括书籍、教学网站、原始码,OpenGL 拥有相当多的资源可供学习及参考。并且 OpenGL 的接口固定、很少变动,新版本的 OpenGL 通常都能够和旧版本完全兼容;不用担心学了之后,或甚至还没学完全,每过一年就要再重新学习一次新的函式界面。OpenGL 只提供基本绘图功能的 API 函式,想读取一张位图进来?想秀出一些简单的 model?抱歉,这些全都得自己来完成;因而可以藉此来磨练自己的一些基本程序能力与观念。
我认为,只要确实的掌握住了3D图学的原理,所谓的 OpenGL 和 DirectGraphics 的差别,也不过是函式的呼叫接口不同罢了。学习 3D 程序设计,不是要去死背一大堆函式的用法及参数的使用;而是应该要真正踏实的了解 3D 的理论基础与架构。观念融会贯通之后,自然也就能萤︻恻酝�恕W会程序的使用方法,往往只是最容易的事;而真正困难,并且值得去深入思考学习的,应该是 其程序的设计思维模式与程序背后所建构的理论基础。
我个人相信,OpenGL 与 DirectX 各有它们的一片天空与其支持拥护者;虽然说其实这两者有越来越相像的趋势。毕竟它们就像是一对异卵的孪生兄弟一样,虽然外貌有些许的不同,可是骨子里的血 液精髓,还是出自同一个父母的根源。或许未来五年十年内也会一样,两者继续保持分庭抗礼的姿态;有人发明了一个新的理论,想立即找一个简单又好用的绘图 API 来做验证,又不想局限在 MS 的操作系统平台上,OpenGL 仍然是不二人选;有人想开发一个功能强大、各方面都最佳化、将硬件的效能发挥到极限的超强 3D 引擎,DirectGraphics 可以表现的非常亮眼。所以,一个能依据不同的发展需求,而选择不同的工具来达成目的的人,才会是一个最称职的程序设计者。
Explore Another World
和3D程设有了第一次的亲密接萤χ幔葎eHIGH过了头;还有其它你没见识过的世界呢!
当学习了一段日子的3D程设之后,脑子里所累积的基本知识应该会开始逐渐成形:「开始可以把心中所想的 idea 给具现化了对吧?」「开始觉得以前的想法,可能不再只是遥不可及的梦了吧?」如果你已经具备了这样的智识及能力,我要说声:「恭喜你!」你已经正确的踏出 了成功的第一个脚步了
『想写一个3D,或甚至2D的小游戏,已经不是很难的问题了。』
等等等,先别太急。一个游戏程序的组成元素有很多,除了实时运算的3D对象之外,要不要有美美的2D图片呢?玩家的操作接口是要用鼠标、键盘还是游 戏杆呢?别忘了还有游戏中的各种音效;当然,如果有背景音乐的话就更完美了!那来个多人联机如何?....... 有太多太多的想法可以实现。
所以呢,现在可以看自己的需要,或是自己针对哪一方面的知识比较感兴趣,可以补充一些 Graphics programming 之外的其它知识。知识的累积,不仅应具有深度,更应能兼具广度。想使用 joystick 来做游戏的控制器,或想对键盘鼠标做更进一步的掌控与回应吗?试试 DirectInput 的强大威力吧;想在自己的游戏中播放音乐或音效吗?可以试试学习 DirectAudio 的使用;想写个简单的区域联机小游戏吗?可以试试 DirectPlay 的简单网络功能;此外,如果有机会的话,能玩玩 Photo Shop、3ds Max、Maya 之类的2D或3D美术应用软件也都是很不错的经验。
这个部分所提到的知识都是选择性的,站在一个学习者的观点来看,最好是自己对某方面真的有兴趣,才更进一步的深入去学习;如果不是出自于自愿性、自 发性的学习,往往都会变成只是三两天的热度、难以持久。总而言之,朝着自己有兴趣的方向发展下去,才会有源源不绝的动力可以继续往前迈进啰!
回复:
浅谈游戏程序设计入门 - [进阶篇]
Show Me Demo
让我们把焦点转回游戏程设的核心工作上:也就是 Graphics API — DirectGraphics 与 OpenGL 的学习上。无论是学习何种 API,一开始免不了都是需要熟记很多很多的函式名称、呼叫方式、传入参数等等繁复的柀ξ鳌H会徇€需要把整个绘图 API 的程序设计流程架构,从头到尾的彻底了解;在学习 API 时很重要的一件事,就是要用心去思考绘图 API 设计者的想法,尽可能的掌握住这个绘图 API 的「设计思维」,以其思维模式来学习。如果能够掌握住了这个重点,则我相信不管是在学习绘图 API 的理论,或甚至是记忆函式的名称等等,都会变成是很自然而然的容易理解。记得试着多问自己「why」与「why not」。
『学习,应该是一种主动性的思考,而非仅止于被动性的知识填充而已。』
当你确定自己已经建立起正确的观念与思维模式时,就该开始来写写小程序啰。对于初学者来说,从无到有,往往是最难跨出的一步;如果想自己从零开始,一行行 的撰写程序代码,可能到最后才发现辛苦的结果,全部变成不解的程序 bug。如果觉得自己可能还没办法,独立完整的完成一个程序,那么比较好的方法就是:先参考别人的程序代码。无论是 DXG 或 OGL,在各种书籍与网站中,都有为数不少的范例程序存在。藉由 trace 一个范例的完整程序代码,可以因此而学到很好的程序写作方式。如果已经把整个范例的程序代码都了解的差不多了,或者还有疑惑不明白之处,可以试着改变程序 中的一些变量或函式呼叫,看看程序的结果会有什么变化,这也是一种很不错的学习方式。
『学习 Graphics API 最重要的是什么?熟记函式和参数?搞懂整个理论架构?』
都不是。最重要的是:动手做。如果所谓的学习,只是脑袋里记了一大堆不知所以然的柀ξ鳎苌僬嬲齽幽X去想、动手去做,那么所有的一切,可以说都是白费 功夫。没有实际踏实的程序写作经验,几个月后,记忆里只会剩下一堆不连续的残片碎影罢了。很多写程序时要注意的小地方或小技巧,我们称之为 tip 或 trick;一般的书籍或网站多只提供概略性的教学,对于实做上细节的一些小技巧,就需要自己亲身经历过,才能真正体会到的。简而言之,就像是一种经验值 的累积啰;现在很辛苦的练等级,到了真正要面临大阵仗、大魔王的时候,才不会临场怯阵、纰漏百出。
如果对整个 API 已经有了相当程度的了解,加上时间经验的累积之后,就可以开始动脑想一些有趣的点子来做啰。有三角形、有灯光、有材侃Γ梢宰鲂┦颤N?让灯光的颜色随着 时间变化如何?还是改变材侃Φ淖鹗俗屛矬w外表有变化?还有透明度也可以做很多变化!工具在你手上,创意在你脑中;魔法人人会变,巧妙却各有不同。之前经 历过这么长的学习曲线,一路筚路蓝咯Α⑴G斩棘的到了这里,终于是可以自由挥洒的时候了,快把自己脑中存积已久的所有点子都压榨出来吧! : )
『嗯?有什么地方不对劲吗?』
随着自己写的小程序数目一直累积下来,或许你已经发觉到一件事实:「其实根本不用每次都从零到有的一行行程序代码撰写,对吧?」没错,一般来说都会存在有 一部份的程序代码是重复的、不变的;例如:窗口程序的初始化、绘图 API 一定会做的初始化之类的动作。那应该怎么做比较好?需要的时候再从之前的程序 “copy-paste”?不,这绝对是既没有效率又存有风险的方法。什么是最好的做法?最好的做法,就是把每次都会重复使用的程序代码,写成一个骨干架 构 (framework)。所谓骨干架构部分,通常是一个程序中变异性很小的程序代码;例如窗口程序的繁复初始化动作,动辄数百行程序代码以上,但却有很大 的固定性,所以就非常适合写成骨干架构。如果我们把骨干部分的程序代码,独立在一个 source file 中,而把真正相关绘图部分的程序代码抽离出来到另一个 source file 中;把所有不相关的闲杂人等,写成一个 source file 一次解决,从此不需要再烦恼那些不相关的柀ξ鳎灰覀俨阎饕L图部分的程序代码撰写完成后,再和以前就写好的骨干程序做编译连结,就可以让项目 (project) 的整体架构看起来更清楚易懂,也大幅增加了项目的结构性。
『除了最基本的 framework 之外,还觉得需要什么吗?』
没错,你需要自己的图书馆 (library)。什么是 library?让我举个例子来说明:如果你所学习的 API 是 OpenGL,你可能会发现,不管是 BMP、TGA 或 JPG 等等所有的图档格式,都需要自己撰写程序代码来读取。OK,那就写吧。The same as old,你会发现到,无论所需读取的是哪一种格式的图档,我们的目的都是很相近类似的:就是做为多边型的材侃?(texture)。那我们何不以 C++ 的对象导向模式,写出一个专门处理相关 texture 大大小小事务的类别呢?把读取每一种图档的 function 写在 texture class 的成员函式中,并且一样的把它独立成一个 source file;如此一来,只要每当需要处理 texture 相关程序时,就把已经写好的 texture source file 和我们的项目做编译连结,够简单又结构化,看起来很棒吧?
同理可证,除了处理 texture 的类别外,还有文字的输出呢?定时器的控制呢?键盘鼠标的操纵?………别忘了还有最基本的矩阵和向量!把所有你能想到的基本功能,都写成一个个的独立 source file,只在需要的时候才和它编译连结;如此不但程序代码易于维护除错,未来的扩展性也相对的宽广许多!而这一个个的 source file 集合起来,就是所谓的 library 啰。就像是自己家里有座图书馆一样,架上摆着分类齐全、功能众多的各种书本,可以依照自己的需求而选取不同的书本来运用;而不是把几万行的程序全都浓缩在 一本书 (source file) 中,时日一久,如果生了臭虫,恐怕连原作者都不认识书的内容了!
『所以,在写小程序赚取经验值的同时,最重要的工作就是要开始建立起自己的 library。』
其实不管是在网络或书籍范例中,都可以看到很多别人写的 library;有一些 library 甚至还具备了很强大的功能。但是我并不建议在自己的程序中使用别人的 library。有什么坏处?以学习者的立场来看,使用别人的 library 所能学到的知识远逊于自己辛苦写出来的。参考别人的 library 写法,或许是个不错的主意,但是要记得:自己的 library,自己应该要看得懂才行。否则别说是扩充功能了,就连善加利用可能也没办法做到。在写 library 的过程中,就可以看出之前学习的成果如何了;如果程序语言、数据结构的基础没有学好,现在肯定会是最痛苦的一刻。在撰写自己的 library 之时,也未必要一次就写出功能非常齐全的对象类别;如果使用对象导向设计模式来撰写 library,就可以利用其可扩充的弹性,在有需要的时候才写新出的功能,并加入相对应的成员函式;如此又可减轻了初始设计的负担。
Hardcore Stuff
经过漫长的旅程,写过几个小 demo,拥有一些自己的 library 之后,应该可以感受到一点游戏程设的乐趣与魅力了吧?但是这样的知识,可能还是不足以达到设计你心目中理想游戏的能力,对吧?基本知识有了,绘图 API 熟了,接下来呢?让我们更进一步来看看比较深入的游戏程设世界。
『Ok, let’s talk something seriously.』
我想,只要是对于游戏设计稍有兴趣的人,在玩一款游戏的时候,多少都会问自己:「这个游戏是怎么做的?」是的,如果你是一路踏实努力走来的学习者, 你现在更应该认真思考这些问题。除了以玩家的身份体验一款游戏的乐趣之外,更要以设计者的角度来看这款游戏。在此,网络上的许多网站,就扮演了很重要的学 习媒介角色。相信你在学习过程中偶尔都会听过一些奇怪的名词术语,像是:BSP、Portal、Octree、LOD、Lightmap、Ray tracing ………等等。这些就是游戏设计的相关技术名词。你知道这些技术和游戏程序有什么关连性吗?你好奇这些技术如何应用在游戏程设中吗?在此,你的英文能力 (或翻译软件
) 就十分的重要了。
『你想知道的一切,网络上都找的到答案。』
网络资源的利用可以说是学习过程中非常重要,并且不可或缺的一环。以国外的三大游戏设计网站 Gamasutra、Flipcode 和 Gamedev 来比较:Gamasutra 通常会提供相当深入、内容充实的研究主题,包含了游戏程设、美术,甚至音乐与企画管理,非常适合想对某一特定主题深入探讨的人;此外,Gamasutra 也是 Game Developer 这本着名游戏设计杂志的相关网站。Flipcode,也会不定期有教学文章的更新,主题多数都蛮具实用性的;并且 Flipcode 的 Image Of The Day 区域提供大家一个展示程序的地方,在此往往可以看到不少有意思的作品,绝对是这个网站不可不看的部分。Gamedev 相较于另外两者,在业界新闻及教学文章的更新速度都比较快,并且文章的数量很多、分类详细,不过其所提供的教学文章多以概论为主,少有比较深入的探讨。
『到此为止,才算是真正开始逐步踏入游戏程设殿堂的时候。』
只要稍微浏览过国外游戏设计网站的话,应该不难发现,其中的文章数目及种类实在太多太多了。其实对一个初学者而言,这个样子反而不见得是一件好事。 可能会不知从何开始学习,文章里充斥着一大堆看不懂的专业术语,甚至可能搞不清楚自己想要学习什么。万事起头难,刚开始或许一整篇文章,从头到尾仔细的阅 读了两次,还是只懂得其中的两三成内容;这个时候就需要踏实的投注时间与精力,点点滴滴的累积知识的广度。文章看得多了,程序写得勤了,渐渐的就可以了解 七、八成以上的内容啰。每篇文章所讲的主题,就像是一个个的「点」,如何找出点与点之间的「关系」,将这一个个的「点」连成「线」,进而化成一个知识的 「面」,也是学习中值得思考的一件事。
除了每个网站的教学文章之外,附属于网站之下的讨论区也是一个非常重要的资源。试着用英文表达你的诚恳、发出你的问题,即使文法不是百分百正确、即 使找不到合适的词汇表达你的意思,你会发现总是有许多热心的人很乐意帮助你的。在国外讨论区回答问题的人,往往都很愿意帮助别人解答疑惑,就算是自己不熟 悉的问题,也会提出自己的经验和想法,甚至连程序代码的展示也毫不吝啬;所以只要你问的问题够好 (我相信唯有好的问题才能导引出好的答案),往往可以得到远超过你所想象的丰富收获、学到很多有用的知识。在发问前,也可以先搜寻看看该讨论区有没有类似 的讨论,或许你的问题早已有人问过了。记得不要再问「DirectX and OpenGL, which one is better?」这种问题啰! : )
『网络的信息是学习新知技术最好的一条途径,那如果想对基础的原理有更深的认识呢?』
别无二法,就是书本。书本可以说是学习知识最扎实的 (也或许是最痛苦的
)
途径。其实真正学习的最好最好方法,就是找到一个好老师加上一本好书。不管任何知识,如果有了好老师的授业解惑,绝对有事半功倍之效;很可惜的是,一位称
职的好老师真的很难找,特别是在游戏程设这个怪领域中。所以靠人靠天,最后还是靠自己最实在;书本,就是闭关练功的武林密笈、不二法门。或许你会怀疑,已
经学会了程序语言、窗口程序、绘图
API,为什么还要看书?书里写的不都是一堆无聊的理论加上复杂的数学式吗?正如在之前的文章所提到的,了解理论并不见得会带来什么立即的效益,也不一定
能增强写程序的功力;但是书本的知识,能够帮助你更确实的掌握住事物的本侃�A与思维模式。特别是在日趋复杂的游戏程序设计中,如果没有深厚稳固的理论
基础所建构起的法则做为地基,恐怕难以负担起越来越庞大复杂的游戏程序架构。
还是那句老话:「想创造规则的人,必先了解规则。」每一本好书,都是前人以无可计数的时间经验所得来的心血结晶,集英荟萃之后以文字的形式传诸于 世,让所有有心学习知识的人都能因此受惠。从书本中,我们可以轻易的学到前人的知识经验与心血结晶;原来可能自己要花费数年时间才能领悟的道理,现在只需 要从阅读书本中的知识就能轻易习得。以 3D 计算机图学来说,了解其背后的许多理论基础,更能帮助你更快的学习并吸收新的知识。例如在了解了 Phong reflection model 的定义之后,就可以很容易的理解为什么光源的组成要分成 ambient、diffuse 及 specular 三个成分了;如果了解 3D 计算机图学的发展历史,就不难理解为什么目前的 3D 绘图主流方式还是以 polygonal mesh 为主了;诸如此类,太多太多的例子可以举。理论知识这柀ξ鳎粫悄阋粫r的饭碗;却会是你一辈子的财富。
Build Up Toolbox
熟悉了一些游戏的核心技术之后,就可以开始建立自己的工具箱了。何谓工具箱?一般常见的讲法就是「编辑器」(editor)。编辑器大致上有两种用 途:一是做为程序的测试工具,二是做为游戏开发的编辑工具。以第一种用途来说,例如你想用之前文章提过的侃�c系统 (Particle System) 来做一个施放魔法时的特效场面。要怎么要才能知道所写出来的程序代码有没有符合需求呢?这个时候就可以写一个侃�c系统的编辑器工具,把所有可以调整的变 量全部列在编辑器的面版中,可能会包括侃�c大小、位置、颜色、速度及运动法则等等要素。然后就可以在编辑器的面版上,直接调整变数的值,实时的观察侃 �c系统的变化情形如何。使用这种方法,就能够很便利的以各种不同数据测试程序的结果,而不是每次都要在程序代码中更改数据后,再重新编译连结整个程序。 更大的好处,就是可以让不懂程序代码的人,也能直觉性的调整并控制程序的呈现结果。所以建立编辑器之后,就算是复杂的交叉数据测试,也会变得容易、而且直 觉许多。
编辑器的第二种用途呢?举个例子来说,Quake 3 Arena 中宛如艺术品般惊为天人的美丽场景是如何制作的?如果你对游戏设计的核心技术已经具备有基本概念,就应该能够了解,它的场景不可能是由几位程序设计者,一 个一个对象的撰写程序代码而完成整个复杂场景的。那应该是用什么样的方式来建立复杂的游戏场景呢?就是依靠所谓的编辑器。一般来讲,一个完整的 3D 场景就称做一个 level,而编辑场景用的就叫做关卡或场景编辑器 (level/map editor)。通常编辑器是由程序设计者,将所有可能会使用到的功能先设计完全,并做出一个易于操作的使用者接口;如此一来就可以让专门负责场景的设计 者 (level designer) 来完成所有的关卡与场景。只要编辑器的功能够强大齐全,甚至不用懂得任何程序代码,也可以设计出非常棒的场景;而这正是编辑器的真正威力。
编辑器的真正目的应该是化繁为简的能力。最理想的状态应该要做到,不需要任何说明文件与教学,任何稍具游戏设计概念的人都可以轻易上手才是。编辑器 的产生也使得游戏开发的分工变得更合理可行;只要程序将人物的对话编辑器写好之后,就可以交给企画负责编撰人物的文案;如果程序开发出够强的场景编辑器, 就可以让美术来负责整个场景的建模与成形了。所以编辑器往往是游戏的制作过程中,相当重要的一个部分。如果说一个游戏的开发时间,有百分之五十投注在设计 开发编辑器的过程上也不为过!
『我知道你在想什么。』
到了这里,又要再次面临类似的问题:Borland C++ Builder 与 MS Visual C++,到底要选择何者做为开发工具用的编译器?我的答案还是一样的平凡:两者都学了再说。在之前的文章提过,要写出比较进阶的窗口程序,可以用 Win32 SDK、Borland 的 VCL 或是 Microsoft 的 MFC。其实编辑器就是属于一种进阶的窗口程序设计,因为它会包含很多复合性的元素,如绘图 API 的呈现、对话盒、控制面版与档案的储存加载等等。在各大程序设计讨论区,BCB 与 MSVC 的批评比较,绝对不亚于 OpenGL 与 DirectX 的情形。如果用另一种方式来比喻的话,BCB 就像是家里的万能老妈一样,会帮你把所有想做的事情都打理的很好;只要用「拖拉点放」的方式,就可以完成大部分的窗口组件设计。而 MSVC 就像是精打细算的老婆一样,所有要完成的事情都要跟她报备,照着规矩一项一项的来做;虽然有一些便利的设计精灵可以应用,可是大部分还是要用「手工打造」 的方式,循序渐进的来完成。
而两者的缺点呢?BCB 常被人所诟病的,就是其不佳的程序编译效率及执行效能;而 MSVC 则是 MFC 的学习曲线太长,庞大复杂的 MFC 结构,往往使初学者望之却步。我的建议还是相同,不管别人的说法如何,还是只有自己亲身用过之后才能体会其优劣胜败之处。两者都学习之后,或许才会发现在 别人眼里是优点的地方,自己不以为然;而在别人眼里是缺点的地方,自己却不以为意。不论是 BCB 或 MSVC,都只是一种工具,为了达成某些目的而被造出来的工具;所以,能因地制宜,选择合适的工具,看何者用的比较顺手就使用何者,或许才是比较好的方 式。
On The Way
『什么?你是认真的吗?这么无聊的三篇文章你都能看到这里了喔,真服了你耶。』
『嗯?你说你前面的所有学习步骤都完成了,接下来呢?』
『不,如果你会有这个疑问,表示你还没到达这里。』
『………………………』
『好吧,好吧,如果你真的好奇的话,让我们再来稍微谈谈之后的路。』
其实很容易,至此有几个简单的选择;一是对自己有兴趣的主题继续深入研究,往深度发展;二是再寻找其它没学习过的主题,往广度发展;第三,还有别的 吗?就是写 GAME!跟我念一次,G‧A‧M‧E,GAME!别忘了我们一路从这漫长艰辛的路程走来,为的是什么目的。现在你终于可以大声的说:我有能力写出一个游 戏了!开始激发你的创意,爆发你的潜能,构思设计一个 GAME 吧! : )
最后再提一件事情。或许你也会常常听到某某游戏用了什么「3D 引擎」之类的。嗯?你说这一系列的文章,怎么从来没有谈过有关 3D 引擎的主题?咳咳,请记得这篇文章的主题是「浅谈游戏程序设计入门」,不是什么「如何在 30 天内做好一个 3D 引擎」、「快快乐乐学做 3D 引擎」,或「如何在 30 岁前拥有人生第一个 3D 引擎」之类的OK?……………好啦,讲认真的,3D 引擎真的是非常复杂的柀ξ鳎^非像这样的三两篇文章可以解决的。也不是我目前的能力可以分享的。其实像之前所提到的编辑器工具,可以说就是 3D 引擎的一个重要核心;不过 3D 引擎同时还必须整合美术及音乐的部分,将一切制作游戏所需的元素都考虑进去,才能算得上是一个完整的、真正的「3D 游戏引擎」。不过我的建议是,就算你已经学习至此,还是先不要想太多 3D 引擎的柀ξ鳎焕^续充实自己,累积写程序的经验,利用自己现有的知识与技术,做出一个有趣的小游戏吧!
一向惯于以文字表达的我,到了这里还是不禁要怀疑:这些辛苦敲打出来的文字,究竟能不能适当地表达我心里真正想说的话呢?真正能了解我想表达的意思 的人有多少呢?而真正能努力做到并且达成目标的人又有多少呢?…………………好吧,我承认我想太多了 (其实是已经不知道要说什么了 ~_~)。总而言之,基本上这一系列文章的重点差不多已经告一个段落,在接下来的最后一篇文章中,我会以自己亲身的学习经验为例,和大家做个分享。还请大 家多多指教。
-
2008-08-16
【转贴】【老坛子转移贴】淺談遊戲程式設計入門 __上 - [Windows App Dev]
http://www.pixelgame.net/bbs/viewthread.php?tid=18752
【老坛子转移贴】淺談遊戲程式設計入門,作者:V子
以下内容来自GAME RESOURCE
标题作者:HalfLucifer
后面的内容全部上述。所有版权归原作者和引处所有。
--------------------------
浅谈游戏程序设计入门 - [概论篇]
Introduction And Assertion
『我想做游戏!』
『我的梦想就是做出一个怎样怎样的游戏..』
我们之中的许多人从小就是玩游戏长大的,游戏是人类的天性与本能;人类的「游戏心」自古至今没有改变过,只是不停地在演进。从最原始单纯的运动竞 赛,到今日各种各样的电子娱乐,莫一不是为了满足人类的「游戏心」。游戏的理由,或许你我心中都有一个不尽相同的答案,但是它的本侃κ冀K是相同的 — for fun。然而在玩着游戏的我们之中,开始有了一群人,不满于现存的游戏世界与游戏规则。「那么我们就自己创造一个新的世界吧。」他们想。于是世界的命运巨 轮缓缓的转动,在人类的游戏史上,又写下了崭新的一页。
『嗯?你也想加入他们?..... 那你会什么?』
『无比的热诚,学习力强,有潜力,喔,还有一大卡车的好点子.......?』
工作、兴趣、赚钱、养家活口、理想、梦想、伟大的抱负、台湾的史克威尔,无论你的理由是什么,无可否认地,做游戏这一行的确是有种无可置信的超凡魅 力,使多少人前仆后继的梦想着投入这一行里。若以现今台湾的游戏公司来讲,一般最常见的核心职称有:企画、美术及程序三种类。如果你的梦想或心愿或目标刚 好是程序,游戏程序设计的话,那么我必须要说:「你或许选择了一条最难走的路了。」
在许多电子讨论版上,不时总会看到有发文者问:「请问游戏设计如何入门?」「请问游戏设计的入门书籍...」诸如此类的问题。可惜我到目前为止,还 没见过任何一篇较有系统性的专文,能就各种不同的角度,给予提问者一个适当的答案。我想这也是因为问题的方向太大、涵盖范围太广,要做出完整的答复,也不 是简单的三、四十行字句可以完全表达的。想当初,自己也是一路跌跌撞撞的到处提问题、埋头苦读了好一阵子,再把努力后的成果拚拚凑凑起来,勉强才为略窥得 游戏程设的一点朦胧身影。所以,我想我能体会到,要入这一行门有多难多辛苦。
『路很长。不前进,不如趁早回头。』
在这一系列的四篇文章中,我将由浅入深逐一论述,做一个游戏程序设计者,所应培养具备的基础能力。声明在先,我,作者本人,目前并非任职于游戏业界 中,也从未参与过任何游戏的开发过程。在文章中所提到的一切论述与观点,皆是自己由自学过程中整理归纳出来的方法途径,或许并没有完全的信服力。在业界前 辈们的眼光看来可能是野人献曝、不值一哂;不过我也希望我致力写出来的这些文章,还是能对一些刚入门、或不知从何入门的新手,有些微的帮助与贡献。也可以 算是抛砖引玉,希望先进前辈们不吝批评指教,写出更好的文章,造福有心人。
Make Sure What You Want
其实,游戏的程序设计,并不是那么难的事。可以在闲暇之余,找本 Visual Basic 的好书来读读,再稍具一点游戏程设的概念,要一个人做出一些很不错的小游戏也不是什么难事。「嗯?那为什么我还在这边正经八百的说着废话?」至此有两种可 能性存在:一,我是个多话又闲闲没事做的显然十足大笨蛋。二,我是个有着不同目的的潜伏型大笨蛋。
我觉得,无论要做什么,先弄清楚「自己真正想要的」是什么,是一件非常重要的事情。写游戏,可以是三五好友在课余工作后,大家共同投入的一种兴趣; 可以是程序高手无聊时自娱娱人的创作共享软件;当然,也可以是你未来的职业、理想的开端,或赚大钱的利器。好之者不如乐之者,工作即乐趣,乐趣即工作,可 能不再是一种无知的幻想。只要做好准备,历史的新页随时等着你去写下。
政府不支持、父母不愿意、学校不重视、资源不充足,从小在这里长大的我们,接受这个社会的教育,接受传统价值观的灌输,都可以深深的体会到,走这一 行的人将会遭遇到多大的阻力。「但是,那又怎样?」与其怨天怨地怪自己生错地方,何不从「自己」开始努力?只会空谈、只会埋怨、只会梦想,是到不了任何地 方的。如果每个有心的人,都能从自己开始,点点滴滴的累积实力,我相信这个「大环境」的风向,也会有改变的一天。
『是的,这一系列文章的主要目的是在于,培养足以踏入游戏程设业界的一些基本能力。』
因此,我期望能提供给已经确立志向、却不知如何入门的新手,一条最佳化的路径。省去一些新手可能会有的独自摸索与尝试错误的时间,早日踏入这片苦海,喔不,是美丽的乐园,携手共创另一个岛国奇迹 : p
附注两项很重要的说明:在之后的文章里,可能会到处充满我个人的偏见,例如请爱用 C++,如此之类的专断用语。如果因为我的文章引起任何的偏头痛或上吐下泻等不适症状,欢迎写信来骂我。我一定会虚心受教。另一项是,在这一系列的文章 中,主要我是以培养「实时3D游戏程序设计」入门基础的能力来撰文的。所以,如果你是希望知道多人在线游戏的设计,或有着美美图片的2D游戏设计,那你可 能会稍微失望了。但是大部分学习的道理都还是相通的,所以应该还是可以参考看看。关于为什么选择「3D」作为学习目标的原因,我就不在此赘述了,或许在之 后的其它文章再谈吧。
『路在眼前拓展开来,无止境的向地平线的那端延伸而去,始终无法看清这条路的终点有些什么。经过这条路的旅人们犹豫着。』
你只能做出选择。要走,或不走,端看自己个人的决定。我希望我的文章扮演着引路人的角色,为迷途的旅人们一解前路的疑惑。在这一系列文章中,我不会 教你「如何写出一个叫好又叫座的游戏」,不会「教授什么高深的游戏程序写作技巧」。也请不要花费力气和我争论「做出好游戏不一定需要什么高深的技术」或其 它之类的控诉。
『It's none of my business at all; I just show you the way.』
Basic Ability Requirement
在学习游戏程设的路上,一开始所应具备的最基本能力是什么?没错,就是一般最令学生头痛的「英文」和「数学」。「那到底是为什么?」或许你已经猜想 到一些显而易见的原因,现在再让我老生常谈的来补充一下,你应该趁你还有机会的时候,好好地和他们做个好朋友的理由。 对一个程序设计师来说,最重要的基本素养之一,就是就是吸收消化知识的速度与能力。在游戏程设的领域中,各种技术,尤其是3D图学,的进步往往是日新月 异,能够快速地将新来的知识转化为自己的智识,得以应用于做游戏的过程中,我想是一件非常重要的事。偏偏不巧,最新的知识原理或书籍文件,往往都是以英文 作为发表的语言;更不巧的是,我们生长的岛国不是以英文作为母语。因此,对于英文阅读能力的培养,绝对是相当重要且首要的事情之一。从今天起,不要总是一 直询问「有没有中文的某某书籍或网站」,是时候开始训练自己,对英文这语言的敏锐度与习惯性了。
嗯,那数学呢?它对游戏程序到底有什么重要性?过去很长一段日子以来,我也一直在问自己这个问题。直到我真的遇上它为止。或许很多人都听过,空间向 量、矩阵、线性代数,这些知识可以说是3D图学的基本架构。没错,可是需要了解多少呢?不是只要会用、记得它的规则就行了吗?一般来说,的确这样就够了。 然而,在你写作程序的经历日渐增长后,也许会在某个夜阑人静的深夜里,突然问起自己:「为什么这个方法是这样作用的?」
『想创造规则的人,必先了解规则。』
了解所谓「实做」背后的理论基础,一定会得到什么很大的好处吗?那也未必。但是了解它可以带来另一种不同于写程序的满足感。或许你会感到手中握住的 知识,因此变得踏实许多。同样的理论,可能可以用数种到数十种不同的方法来实做;但无论方法或接口怎么改变,只要掌握住它的「本侃Α梗匀豢梢哉业绤捣N 方法中的最佳化答案。我们可以把数学看作一种严谨的思考逻辑训练,磨练一个人的抽象化组织能力;任何最具体化的理论方法,都可以解构成数学中最基本的 model 来解释与描述其行为本侃Α?
总而言之,在你仍拥有机会的时候,不要放弃学习它的动力,无论是微积分、离散数学、工程数学、机率统计也好,虽然学习数学的过程可能是最充满痛苦,而成果可能是最隐晦难见的,但也许在某天的某个场合,它会以某种意想不到的形象,蹦出来帮了个大忙呢。
『OK,确定你站稳脚步了吗?我们要开始啰!』
浅谈游戏程序设计入门 - [基础篇]
Power Of Language
当然,这里所指的语言是专指「程序语言」而言。让我们一步步来进行。
『首先,请开始学习C++。』
嗯?什么?你说你会VB、会C语言?还有JAVA?ASP、SQL?让我再说一次:「请开始学习C++。」无论你之前学习过什么样的程序语言,请记 得,现在我们谈论的是最适合用来开发游戏程序核心的程序语言。C++无庸置疑是目前功能最强大、效率最好、操作弹性最佳,也是最复杂难懂的语言。因此,C ++用来开发游戏程序核心,至少在PC平台上,是最最合适的不二人选。
『OK,OK,我已经听到很多不以为然的声音了;请给我一点机会解释一下。』
C++是一个具备良好对象导向设计模式的一种语言,能相当完整的以「对象」为设计的着眼点来完成整个程序的分析及架构。在这里举一个实际应用上的例 子:大家都知道,在3D的程序设计中,「向量」的使用是非常广泛且多面的,如果我们能以「对象导向」的观点设计出一个「向量对象类别」,那么在之后的使用 上将会带来许多的便利性。怎么说呢?如果我们使用传统 structure-based 的设计模式来建立一个向量的新类别,我们通常会这样宣告:
typedef struct {
float x, y, z;
} Vector;
以此来表示一个自己定义的新类别 Vector,其内结构由 x、y、z 三个类别为浮点数的变量所组成。
「看起来还不错?」但是今天如果有需要做两个 Vector 类别的加减乘除呢?对不起,你必须一步一步的自己来做:
Vector vec1, vec2, vec3;
vec3.x = vec1.x + vec2.x;
vec3.y = vec1.y + vec2.y;
vec3.z = vec1.z + vec2.z;
「有没有更直觉的做法呢?」有的,在C++中,你可以自订类别的「运算子」来帮你更直觉化的完成这件事,例如:
operator+(Vector vec1, Vector vec2) {
vec3.x = vec1.x + vec2.x;
vec3.y = vec1.y + vec2.y;
vec3.z = vec1.z + vec2.z;
}
如此一来,以后在做 Vector 类别之间的加法时,只要简单的写:
vec3 = vec1 + vec2;
所有的工作,就由自订的加号运算子来帮助你完成,就像使用预设的加法运算子一样的直觉。在C++的语法中,你还可以为自订的「对象类别」,增加更多的「成 员函式」;我们可以把「成员函式」看做是去定义一个「对象」的某种「行为」或「方法」,藉此来达成对象与外界的沟通桥梁。例如一个 Vector 常有可能会需要使用内积、外积或向量长度的计算;而其它加减乘除的运算,也都是 Vector 这个对象的「行为」或「方法」。当我们把这些功能写成 Vector 的成员函式之后,我们就能更加直觉的了解并使用这些方法,同时也在无形中增加了程序代码的可重复利用性。
对象导向及C++语言的威力还不仅止于此,在对象类别中所定义的各种函式都可以做到虚拟与多型的机制拓展,更进一步的提供了「继承」这项崭新的设计思维。 何谓继承?所谓的继承,即是指对象架构的继承体系。如「人类」是属于「灵长类」下的一支,而「灵长类」又是属于「哺乳类动物」下的一支;于是我们可以说, 所有灵长类的动物必定具备有哺乳类动物的特侃Γ械娜祟惐囟ň邆溆徐`长类动物的特侃Α_@就是一种「继承」的架构。当我们在写程序时,若能依照架构 由上而下的来定义对象类别,则必定能够节省很多的时间和力气,写出更好的程序。
举一个例子来说明:如果今天我们要设计一个有关「侃�c」(particle) 的类别,要能够描述所有侃�c可能具备的特侃�翱赡馨l生的行为,用C++的观点该如何来做?假设我的世界中会有三种侃�c:雪、火、雨。于是我们开始设 计「雪」的对象类别…… 再来是「火」,…………… 最后还有「雨」。然后,我们可能会发现,其实这些侃�c会有许多共通的「本侃Α勾嬖冢徊还苁侨魏我环N侃�c,我们都需要它存有:侃�c位置、侃�c大 小、侃�c速度等等之类的数据。既然如此,我们何不把所有侃�c的共同特侃Τ殡x出来,成为一个抽象的 Particle 对象类别?如此一来,所有继承自它的对象类别 Snow、Fire、Rain 都可以拥有和 Particle 相同的「属性」及「特侃Α埂H会嵩僖啦煌│点的不同「行为」,个别去定义各自的成员函式。以后如果还需要定义其它种类的侃�c,只需要先从 Particle 继承而来,再来定义这个侃�c的不同之处就可以啦。 ([后注]:其实这里所举的「侃�c」这个例子,在实做上并不完全合适如此的继承架构。)
虽然它不是万灵药,但以对象导向的思维模式来写作程序,在多数的情况下,都是相当有利于每一个程序设计者的。而C++,正是包含了对象导向设计模式,目前最合适应用于PC平台游戏设计的程序语言。
『嗯?听起来好像真的很不错吧?』
很可惜的是,天下没有这么容易吃的午餐。既然C++有这么多的优点和这么强大的功能,那也就表示:C++是一种很难学习的程序语言。著名的作者侯捷 在 Effective C++ 一书的译序中就曾提到:「C++是一种难学易用的语言!C++的难学,不仅在其广博的语法,以及语法背后的语意,以及语意背后的深层思维,以及深层思维背 后的对象模型;C++的难学,还在于它提供了四种不同(但相辅相成)的程序设计思维模式:procedural-based, object-based, object-oriented, generic paradigm。」
因此在C++语言的学习曲线上,相较其它语言自然来的漫长许多。这通常是初学者真正第一个需要用力跨越的门坎。程序语言,并不是一种很直观的思维模 式。没有人与生俱来就熟悉这种语言,要亲近它、学会它、熟练它,一步一步都是需要灌注时间和心力下去累积的。阅读真正值得一看再看的好书、做各种程序的写 作练习、找个好老师学习,各种方法都是不能省略的。虽然在学习程序语言的过程中,会稍嫌单调无趣了些,但真正到了进阶的部分时,就会发现这个部分功力的重 要性。无论写的是哪一种的程序,程序语言就是最重要的「内功心法」;如果内功未臻成熟,就急着练些花俏的武功招式,最后的结果就是程序 bug 连连,使出来的招式总在意料之外发生破绽。不可不慎之。
在学习程序语言的过程中,也应该熟悉一些基本的「数据结构」,如各种 linked list、queue、stack、tree 等等的用法;如果能够懂一些基本的「算法」概念,对以后程序的设计也会有不小的帮助。关于程序编译器 (compiler) 的选择,其实在目前这个阶段使用什么编译器都是没有差别的;而在之后学习「窗口程序设计」及各种 Graphics API 时,就需要从 MS Visual C++ 或 Borland C++ Builder 两者中择一了。我的建议是使用 MS Visual C++。毕竟是在 Windows 上开发程序、毕竟将来可能用到 MS 老大的 DirectX,在一开始的时候先用 MS 的编译器,可能比较不会碰到太多非预期内的麻烦问题。
Handle Your Window
有了程序语言的基础之后呢?在你急着想学些3D的程序设计之前,先等一下,我们还得先拜拜码头:「先学会和我们可爱的 Windows 沟通沟通啰!」和 Windows 老大打好人际关系后,以后我们做起事来才会顺利的多。谁也不希望程序执行到半途,老是跑出「此程序执行无效,即将关闭」的蔚蓝画面吧?
『写程序归写程序,又关它 Windows 老大啥事了勒?』
话,不是这么说滴。我们要知道,所有计算机中的应用程序,都是建构在「操作系统」上面动作的;我们在 PC 上所写的游戏当然也算是应用程序的一种。而 Windows 正是扮演着「操作系统」这个角头老大的角色。由它来分配每个应用程序所可以使用到的内存以及 CPU,还有一般的键盘鼠标讯息也都是经由它来传送信息给应用程序的。所以啰,想在 Windows 上写作程序,当然需要先过这关啰。
『所以,现在有充分的理由开始学习 Windows SDK 啰。』
不,即使会使用 VB 来设计窗口应用程序,也并不代表真正了解窗口程序设计的意涵。我再说一次,直觉化如 VB 或 BCB 的拖拉点放「窗口组件」设计接口,也只是在你熟悉了窗口程序的核心概念之后,才能应用得宜、加速程序开发的。在那之前,好好的从基本的窗口程序写作开始学 习起,才是最正确并且合适的做法。
对一个习惯了在 DOS 上开发写作应用程序的人来说,在学习窗口程序设计的过程中,一开始最无法适应的就是找不到 main() 这个程序的起始点;在 Windows programming 中,都是以 WinMain() 取代 main() 了。除此之外,还有很多一开始比较难以接受的新概念:什么是讯息循环?不可或缺的 WndProc() 又是做什么的?怎么输出文字?………… 相当多在 DOS 上的程序用法或函式,到了 Windows 上却不管用了。如今,要在 Windows 上写出一个最简单基本的 “Hello, World” 小程序,也约略要写 100 行左右的程序代码。不过也不用担心太多,只要找到一本好书做为学习的教材,就能够很快的进入状况、熟悉环境了。在此当然不得不推崇 Charles Petzold 原著的 Programming Windows 这本书,内容真可谓是巨细靡遗,书中还包括了每一个范例程序的完整程序代码,不论是书的厚度或内容,都是相当地具有「份量」;目前此书也已有中译本。
『那么,SDK 的学习大概要到什么程度呢?』
以 Programming Windows 这本书为例,我想真的很少有人能够有足够的耐性与时间,完整的啃完厚达 1500 页的内容吧?何况其中的内容虽然非常丰富可观,但如果仅是以「游戏设计」为目标的话,倒也不需要懂这么多柀ξ鳌D屈N至少,要学到什么程度?我想,至少的 至少,要学会如何键盘及鼠标事件的操控,才能算是及格了。如果对如何使用 SDK 写出一些进阶功能的窗口有兴趣的话,例如像子窗口、菜单、加速键、对话盒、文字字体、多任务多绪之类较进阶的课题,就可以再往这本书后面的章节继续学习。 如果在此时不学习这些进阶的程序功能也是可以的,未来我们可以选择学习 SDK 之外的其它方法,如 MS 的 MFC,及 Borland 的 VCL,来实做一个进阶的窗口程序。有了以上的基本概念之后,才能再往下一个领域探索学习;如果在学会程序语言之后,没有先具备窗口程序的设计概念,就急 着想学 DirectX,到后来只会形成不得要领、四处碰壁的学习窘状罢了。
-
2008-08-15
【轉載】一个最简单的WIN32 SDK程序结构 - [Windows App Dev]
轉載自 http://blog.csdn.net/rance
/* The Very Simple Win32 SDK Program */
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil){
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass *//* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windowss default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;/* The class is registered, lets create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"PCGs Very Simple Windows Application", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we dont deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}return 0;
}
程序的结构如下:BEGIN
序言注释
编译预处理指令
窗口过程函数声明
窗口类名字字符串定义(作为全局变量)
主函数WinMain
{
窗口句柄定义;
消息结构定义;
窗口类定义;
窗口类初始化赋植;
尝试注册窗口类;
创建窗口;
显示窗口;
消息循环;
返回值(tagMSG::wParam);
}
窗口过程函数定义(处理各种消息)
END
-
2008-07-11
【轉帖】一个人要像一支队伍 - [GOSSIP]
一个人要像一支队伍(作者:醉钢琴)
小撮 2008-03-18 09:01:54 来自: 小撮 (北京)
前两天有个网友给我写信,问我如何克服寂寞。
她跟我刚来美国的时候一样,英文不够好,朋友少,一个人等着天亮,一个人等着天黑。“每天学校、家、图书馆、gym,几点一线”。我说我没什么好招,因为我从来就没有克服过这个问题。这些年来我学会的,就是适应它。“适应孤独,就像适应一种残疾”。
我觉得,快乐是可遇不可求的,但是充实是可求而不可遇的。快乐这件事,有很多“不以主观意志为转移”的因素。基因、经历、你恰好碰上的人。但是充实,是可以自力更生的。罗素说他生活的三大动力是对知识的追求、对爱的渴望、对苦难不可遏制的怜悯。你看,这三项里面,除了第二项,其他两项都是可以“强求”的,都具有耕耘收获的对称性。
我的快乐很少,当然我也不痛苦。主要是生活稀薄,事件密度非常低。就说昨天一天我都干了什么吧:
10点,起床,收拾收拾,把一本书看了一大半的明史的书看完。
1点,出门,找个coffee shop,从里面随便买点东西当午饭,然后坐那改一篇论文。(期间凝视窗外的纷飞大雪,创作梨花体诗歌一首)。
7点,回家,动手做了点饭吃,看了一个来小时的电视,回email若干。
10点,看了一张dvd,韩国电影“春夏秋冬春”。
12点,读关于冷战的书两章。
2点,跟蚊米通电话,上网溜达,准备睡觉。
这基本是我典型的一天:一个人。书,电脑,dvd。一个人。
一个星期平均会去学校听两次讲座。一周工作日平均跟朋友吃午饭一次,周末吃晚饭一次。
多么稀薄的生活啊,谁跟我接近了都有高原反应。
我这人其实一点也不孤僻。生活中认识我的人都知道,我是多么平易近人开朗活泼。有时候,我就是懒,懒得经营一个关系。还有一些时候,就是爱自由,觉得任何一种关系都会束缚自己。当然最主要的,还是知音难觅。我老觉得自己跟大多数人交往,总是只能拿出自己的一个子集。我很难找到和自己一样一望无际的人。
有时候也着急。不仅仅是因为错过了亲友之间的饭局、谈笑、温情,不仅仅因为一个文学女青年对故事、冲突、枝繁叶茂的生活有天然的向往,也因为一个人思想的先锋性总是通过碰撞来保持的。我担心,我老这样一个人呆着,会不会越来越傻?
好像的确是越来越傻。
但另一些时候,我又惊诧于自己的生命力。在这样缺乏沟通、交流、刺激、辩论、玩笑、聊天、绯闻、传闻、小道消息、八卦、msn……的生活里,没有任何“圈子”,多年来仅仅凭着自己跟自己对话,我竟然保持了创造力和战斗力,竟然写小说政论论文饱博客而且写得如此饱满热情,我刘瑜又是何等顽强的一株向日葵。
年少的时候,我觉得孤单是很酷的一件事。长大以后,我觉得孤单是很凄凉的一件事。现在,我觉得孤单不是一件事。
有时候,人所需要的是真正的绝望。
真正的绝望跟痛苦、跟悲伤、跟惨痛都没有什么关系,真正的绝望让人心平气和。你意识到你不能依靠别人,任何人,得到快乐、充实、救赎。那么,你面对自己,把这种意识贯彻到一言一行当中。
它还不是气馁,不是得过且过,不是“平平淡淡从从容容才是真”这样的狗屁歌词,它只是“命运的归命运,自己的归自己”这样一种实事求是的态度。
那天偶然想起我过去几年写的这三个小说,《孤独得象一颗星球》《那么,爱呢》《烟花》,吃惊地发现,这里面其实有一个轨迹,从忧伤到怨恨,然后再到绝望。
绝望,就意味着自由。
以前一个朋友写过一首诗,名字叫“一个人要象一支队伍”。我想象文革中的顾准、狱中的杨小凯、在文学圈之外写作的王小波,就是这样的人。怀才不遇,逆水行舟,一个人就象一支队伍,不气馁,有召唤,爱自由。
现在看来,我也只能面对内心招兵买马了,一个人成为一支队伍。人家一个人象一个军,我象一个营,一个连还不行吗?
当然我的队伍没有他们的那么坚定,肯定有逃兵,经常嚷嚷着要休息,但是,我还在招兵买马呢,还前进呢,还边走边唱南泥湾呢。
我想自己终究是幸运的,不仅仅因为那些外在的所得,而且因为上帝给我的顽强和禀赋。它告诉我an unexamined life is not worth living,教我用虚无、骄傲、愤世嫉俗超越那种浑浑噩噩随波逐流的生活,然后教我用是非感、责任心来超越那点虚无、骄傲、愤世嫉俗。
当罗素说知识、爱、同情心是他生活的动力时,我觉得这个风流成性的老不死简直就是我的亲哥。
因为这幸运,我原谅上帝给我的一切挫折、孤单,原谅他给我的敏感、抑郁和神经质,原谅他让X不喜欢我,让我不喜欢Y,让那么多人长得比我美,让那么多烂书卖得比我的好,甚至原谅他让我长到105斤,因为他把世界上最美好的品质给了我:不气馁,有召唤,爱自由。咦,怎么说到这儿了呢?本来是想谈谈自己克服寂寞的经验的,结果活活写成了一篇自我吹捧的范文,就当是本营长写给士兵们的战斗动员书吧,分析当前的形势和我们的任务。
-
2008-06-30
The Hacker Manifesto
The Hacker Manifesto
by
+++The Mentor+++
Written January 8, 1986
Another one got caught today, it's all over the papers. "Teenager Arrested in Computer Crime Scandal", "Hacker Arrested after Bank Tampering"...
Damn kids. They're all alike.
But did you, in your three-piece psychology and 1950's technobrain, ever take a look behind the eyes of the hacker? Did you ever wonder what made him tick, what forces shaped him, what may have molded him?
I am a hacker, enter my world...
Mine is a world that begins with school... I'm smarter than most of the other kids, this crap they teach us bores me...
Damn underachiever. They're all alike.
I'm in junior high or high school. I've listened to teachers explain for the fifteenth time how to reduce a fraction. I understand it. "No, Ms. Smith, I didn't show my work. I did it in my head..."
Damn kid. Probably copied it. They're all alike.
I made a discovery today. I found a computer. Wait a second, this is cool. It does what I want it to. If it makes a mistake, it's because I screwed it up. Not because it doesn't like me... Or feels threatened by me.. Or thinks I'm a smart ass.. Or doesn't like teaching and shouldn't be here...
Damn kid. All he does is play games. They're all alike.
And then it happened... a door opened to a world... rushing through the phone line like heroin through an addict's veins, an electronic pulse is sent out, a refuge from the day-to-day incompetencies is sought... a board is found. "This is it... this is where I belong..." I know everyone here... even if I've never met them, never talked to them, may never hear from them again... I know you all...
Damn kid. Tying up the phone line again. They're all alike...
You bet your ass we're all alike... we've been spoon-fed baby food at school when we hungered for steak... the bits of meat that you did let slip through were pre-chewed and tasteless. We've been dominated by sadists, or ignored by the apathetic. The few that had something to teach found us willing pupils, but those few are like drops of water in the desert.
This is our world now... the world of the electron and the switch, the beauty of the baud. We make use of a service already existing without paying for what could be dirt-cheap if it wasn't run by profiteering gluttons, and you call us criminals. We explore... and you call us criminals. We seek after knowledge... and you call us criminals. We exist without skin color, without nationality, without religious bias... and you call us criminals. You build atomic bombs, you wage wars, you murder, cheat, and lie to us and try to make us believe it's for our own good, yet we're the criminals.
Yes, I am a criminal. My crime is that of curiosity. My crime is that of judging people by what they say and think, not what they look like. My crime is that of outsmarting you, something that you will never forgive me for.
I am a hacker, and this is my manifesto. You may stop this individual, but you can't stop us all... after all, we're all alike. -
2008-06-30
Cast NOT pearls before swines.
看周圍這些沒有靈魂的豬仔,每天除了工作娛樂FUCK睡覺外就沒有別追求了,看他們這些傻逼,哦。。不對,他們傻嗎? 一個個精明的跟鬼似的,可以稱為“精逼”。一個個裝的跟人似的,身邊的多少不公正的事情從來不正眼看一下,什么玩意?!
操你媽個逼!
操你媽的所謂的公正!
操你媽的所謂的自由!
操你媽的所謂的和諧!
操你媽的所謂的人格!
操你媽的所謂的尊嚴!
操你媽的所謂的生活!
操你媽的所謂的理想!
操你媽的!全是假的!FUCK!
操你娘的!!!!
-
2008-05-04
Ubuntu8.04安装CHM阅读软件chmsee
执行sudo apt-get install chmsee
安装后chmsee不能运行,有以下的错误:
pppboy@boypc:~$ chmsee
chmsee: error while loading shared libraries: libxul.so: cannot open shared object file: No such file or directory
网上找了很多内容,一般都是firefox什么的,以前是用那个chmreader的插件,但现在已经firefox3.bata5了,这个不能用了,最后找到的答案,就这么简单:
cd /usr/lib
sudo ln -s xulrunner-1.9b5/libxul.so libxul.so
sudo ln -s xulrunner-1.9b5/libxpcom.so libxpcom.so
sudo ln -s xulrunner-1.9b5/libsqlite3.so libsqlite3.so
sudo ln -s xulrunner-1.9b5/libmozjs.so libmozjs.so
然后运行正常。 -
2008-05-04
使用grub引导第二块硬盘上的Windows
http://unix-cd.com/unixcd12/article_6254.html
使用grub引导第二块硬盘上的Windows
作者:guozheng2003 出处:www.cublog.cn. 更新时间: 2007年03月04日
新添一块儿硬盘给Linux使用,在旧的硬盘上安装了windows,在BIOS中设置新硬盘为第一个硬盘,因此计算机默认从新硬盘启动,仍然使用grub作为loader。
由于windows安装在第二块硬盘上,使用以前的方法来引导windows的时候并不能凑效:
root (hd1,0)
chainloader +1
查看了grub的文档,发现要引导DOS/Windows等系统时,如果其不在第一块硬盘上,还需要做一些特殊的设置,比如我的windows安装在第二块硬盘的第一个主分区上,我要使用grub来引导的话需要使用这样的grub命令:
map (hd0) (hd1)
map (hd1) (hd0)
root (hd1,0)
chainloader (hd1,0)+1
可以看出这两者的不同了吧?
在这里使用了map命令,map命令用来把一个硬盘设备映射为另一个,官方文档中是这样写的:
Map the drive from_drive to the drive to_drive. This is necessary when you chain-load some operating systems, such as DOS, if such an OS resides at a non-first drive.
chainloader的使用也有些不同,在这里要显式的指出windows所在的分区。 -
2008-05-04
grub map实现winxp启动zt
http://tonnyhan-cn.spaces.live.com/blog/cns!4D2771261F3057A!133.entry
11月28日
grub map实现winxp启动
我对linux的使用属于初级入门者,前几天在独立硬盘上安装linux以后,造成winxp不能启动,说道不能启动也不是一点也不能动,在bios里边将安装winxp的硬盘设置为第一启动顺序就可以顺利启动,我电脑的硬盘安装如下:20Gide硬盘一个,80g sata硬盘一个,因为20g的硬盘挂在ide0 的master上面,所以识别顺序在sata硬盘之前。在bios里边设置第一启动顺序为20gide硬盘,顺利安装完linux以后,可以正常启动,当 从grub菜单中选择启动winxp的时候,则出现不能启动问题,进入linux发现两个硬盘的描述符为/dev/hdb以及/dev/sda1,使用 fdisk -l出现下面信息:我使用fdisk -l得到如下结果
Disk /dev/hdb: 20.5 GB, 20547841536 bytes
255 heads, 63 sectors/track, 2498 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdb1 * 1 13 104391 83 Linux
/dev/hdb2 14 2498 19960762+ 8e Linux LVM
Disk /dev/sda: 80.0 GB, 80026361856 bytes
255 heads, 63 sectors/track, 9729 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 2040 16386268+ 7 HPFS/NTFS
/dev/sda2 2041 9729 61761892+ f W95 Ext'd (LBA)
/dev/sda5 2041 4590 20482843+ c W95 FAT32 (LBA)
/dev/sda6 4591 7140 20482843+ c W95 FAT32 (LBA)
/dev/sda7 7141 9729 20796111 7 HPFS/NTFS
而grub中引导信息如下:default=2
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.13-1.1532_FC4)
root (hd0,0)
kernel /vmlinuz-2.6.13-1.1532_FC4 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.13-1.1532_FC4.img
title Fedora Core (2.6.11-1.1369_FC4)
root (hd0,0)
kernel /vmlinuz-2.6.11-1.1369_FC4 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.11-1.1369_FC4.img
title Windows Xp SP2
rootnoverify (hd1,0)
chainloader +1看起来好像没问题,在北南(linuxsir.org斑竹)的帮助下在引导以前使用map改变启动顺序,则启动xp成功。title Windows Xp SP2map (hd0) (hd1)
map (hd1) (hd0)
rootnoverify (hd1,0)
chainloader +1可能还是主板上的ide的master与sata先后顺序的问题,没有深入看到底怎么回事,能用就好了。 -
2008-05-04
系统引导管理器GRUB学习笔记 zt
http://i.cn.yahoo.com/huangzhixiang@yahoo.cn/blog/p_7/
学习这部分知识,首先要学到问题的思路,其次你还要记住一些东西,是死记硬背下来!你会发现这点东东的确是很有用的!
一、 首先要了解的几个概念
1、 启动管理器
启动管理器是存储在磁盘开始扇区中的一段程序,例如,硬盘的MBR(Master Boot Record),在系统完成启动测试后,如果系统是从MBR启动,则BIOS(Basic Input/Output System)将控制传送给MBR。然后存储在MBR中的这段程序将运行。这段程序被称为启动管理器。它的任务就是将控制传送给操作系统,完成启动过程》 有许多可用的启动管理器,包括GNU GRUB (Grand Unified Boot Loader),Bootmanager, LILO (LInux LOader), NTLDR (boot loader for Windows NT systems),等等等.2、 什么是GRUB?
grub 是一个多重启动管理器。grub是GRand Unified Bootloader的缩写,它可以在多个操作系统共存时选择引导哪个系统。它可以引导的操作系统包括:Linux,FreeBSD,Solaris, NetBSD,BeOSi,OS/2,Windows95/98,Windows NT,Windows2000,WinXP。它可以载入操作系统的内核和初始化操作系统(如Linux,FreeBSD),或者把引导权交给操作系统(如 Windows 98)来完成引导。3、 GRUB的特点
1)特别适用于linux与其它操作系统共存情况。
支持大硬盘现在大多数Linux发行版本的lilo都有同样的一个问题:根分区(/boot分区)不能分在超过1024柱面的地方,一般是在 8.4G左右的地方,否则lilo不能安装,或者安装后不能正确引导系统。而grub就不会出现这种情况,只要安装时你的大硬盘是在LBA模式下, grub就可以引导根分区在 8G以外的操作系统。
2)支持开机画面
grub支持在引导开机的同时显示一个开机画面。对于玩家来说,这样可以制作自己的个性化开机画面;对于PC厂商,这样可以在开机时显示电脑的一些 信息和厂商的标志等。grub支持640x480,800x600,1024x768各种模式的开机画面,而且可以自动侦测选择最佳模式,与 Windows那 320x400的开机画面不可同日而语。
3)两种执行模式
grub不但可以通过配置文件进行例行的引导,还可以在选择引导前动态改变引导时的参数,还可以动态加载各种设备。例如你在Linux下编译了一个 新的核心,但不能确定它能不能工作,你就可以在引导时动态改变grub的参数,尝试装载这个新的核心进行使用。Grub的命令行有非常强大的功能,而且支 持如 bash或doskey一样的历史功能,你可以用上下键来寻找以前的命令。
4)菜单式选择
grub使用一个菜单来选择不同的系统进行引导。你还可以自己配置各种参数,如延迟时间,默认操作系统等。
5)分区大小改变后不必重新配置
grub是通过文件系统直接把核心读取到内存,因此只要操作系统核心的路径没有改变,grub就可以引导系统。
除此之外,Grub还有许多非常强大的功能。例如支持多种外部设备,动态装载操作系统内核,甚至可以通过网络装载操作系统核心。Grub支持多种文件系统,支持多种可执行文件格式,支持自动解压,可以引导不支持多重引导的操作系统,支持网络启动等。6) MBR和第一扇区
你可以简单的理解为MBR是整个硬盘的物理第一位置,而第一扇区是硬盘的物理第二位置.
7) 一个GRUB配置文件
基于本例的分区如下:
hda 15G
hda1 8G / RED HAT LINUX8.0
hda5 7G /home
hdc 20G
hdc1 6.4G WinXP
hdc5 6.4G
hdc6 6.4G
hdc7 6.4G
#fdisk -l
# Disk /dev/hdc: 255 heads, 63 sectors, 2434 cylinders
Units = cylinders of 16065 * 512 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 894 7181023+ b Win95 FAT32
/dev/hdc2 895 2434 12370050 f Win95 Ext'd (LBA)
/dev/hdc5 895 1787 7172991 b Win95 FAT32
/dev/hdc6 1788 2434 5196996 b Win95 FAT32
Disk /dev/hda: 255 heads, 63 sectors, 1867 cylinders
Units = cylinders of 16065 * 512 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 1020 8193118+ 83 Linux
/dev/hda2 1021 1802 6281415 83 Linux
/dev/hda3 1803 1867 522112+ 82 Linux swapgrub.conf,这个文件位于;/boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,0)
# kernel /boot/vmlinuz-version ro root=/dev/hda1
# initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=3
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.4.18-14)
root (hd0,0)
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/
initrd /boot/initrd-2.4.18-14.img
title Microsoft Windows XP
map (hd0) (hd1)
map (hd1) (hd0)
root (hd1,0)
chainloader (hd1,0)+1
makeactive
boot
二、解读grub.conf文件
我们将来看看grub.conf文件内语句,(注:...)内的东西是我们的解读内容.
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,0)
# kernel /boot/vmlinuz-version ro root=/dev/hda1
# initrd /boot/initrd-version.img
#boot=/dev/hda (注:以上以符号井"#"开头的行表示被注释掉,没有任何意义)
default=0 (注:默认的操作系统就是由default控制的。default后加一个数字n,表明是第 n+1个。需要注意的是,GRUB中,计数是从0开始的,第一个硬盘是hd0,第一 个软驱是fd0,等等。所以,default 0 表示默认的操作系统在这儿是 Red Hat Linux (2.4.18-14)如果你修改成1就是WinXP了)
timeout=3 (注:timeout表示默认等待的时间,这儿是3秒钟。超过3秒,用户还没有作出选 择的话,系统将自动选择默认的操作系统;当然你可以改成任何你乐意的时间)
splashimage=(hd0,0)/boot/grub/splash.xpm.gz (注:指定开机画面文件splash.xpm.gz的位置)
title Red Hat Linux (2.4.18-14) (注:表示Red Hat Linux的菜单项)
root (hd0,0) (注:表示第一个硬盘第一个分区,这里的root和系 统内的root不是一码事!详细如下说明)
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/ (注:指定内核的位置,详细说明如下 文)
initrd /boot/initrd-2.4.18-14.img (注:初始化)
title Microsoft Windows XP (注:表示Microsoft Windows XP的菜单项)
map (hd0) (hd1) (注:map是命令,详细如下)
map (hd1) (hd0)
root (hd1,0) (注:这是指第二个硬盘(从硬盘)上第一个分区)
chainloader (hd1,0)+1 (注:链式装入器,装入一个扇区的数据然后把引导 权交给它。详细说明如下)
makeactive
boot(注:在 Linux 中,当谈到 "root" 文件系统时,通常是指主 Linux 分区。但是,GRUB 有它自己的 root 分区定义。GRUB 的 root 分区是保存 Linux 内核的分区。这可能是您的正式 root 文件系统,也可能不是。我们讨论的是 GRUB,需要指定 GRUB 的 root 分区。进入 root 分区时,GRUB 将把这个分区安装成只读型,这样就可以从该分区中装入 Linux 内核。GRUB 的一个很“酷”的功能是它可以读取本机的 FAT、FFS、minix、ext2 和 ReiserFS 分区.到目前为止,您可能会感到一点疑惑,因为 GRUB 所使用的硬盘/分区命名约定与 Linux 使用的命名约定不同。在Linux 中,第一个硬盘的第五个分区称作 "hda5"。而 GRUB 把这个分区称作 "(hd0,4)"。GRUB 对硬盘和分区的编号都是从 0 开始计算。另外,硬盘和分区都用逗号分隔,整个表达式用括号括起。现在,可以发现如果要引导 Linux 硬盘 hda5,应输入 "root (hd0,4)"。
知道了内核在哪儿,还要具体指出哪个文件是内核文件,这就是kernel的工作。
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/说明/boot/vmlinuz-2.4.18-14就是要载入的内核。后面的都是传递给内核的参数。root=LABEL=/ 就是linux的硬盘分区表示法,ro是readonly的意思。initrd用来初始的linux image,并设置相应的参数。
命令map:当你有两块硬盘,一个无法从第二块硬盘启动的操作系统,例如Windowsxp,就可以使用map命令.你能够将hd0映射为hd1,将hd1映射为hd0。换句话说,你可以虚拟的交换两个硬盘而启动所需要的操作系统 。命令形式如下:
grub> map (hd0) (hd1)
grub> map (hd1) (hd0)
GRUB 使用了“链式装入器”(chainloader)。链式装入器从分区 (hd1,0) 的引导记录中装入winxp自己的引导装入器,然后引导它。这就是这种技术叫做链式装入的原因 -- 它创建了一个从引导装入器到另一个的链。这种链式装入技术可以用于引导任何版本的 DOS 或 Windows。
GRUB的配置文件要简单就这么简单,如果你要更个性化一点,试一试把“color light-gray/blue ”加在default语句的下面,下一次启动GRUB时,看看有什么变化,再试一试“color light-blue/red",惊喜吗? 有趣吧! )
三、如何使用grub?
1、安装
你可以从ftp://alpha.gnu.org/pub/gnu/grub 下载GRUB的源代码。
得到文件grub-0.97.tar.gz,所以这样做:
# tar -xvzf grub-0.97.tar.gz
这个命令将解开的文件和目录放在一个名为grub-0.97的目录中。现在运行如
下命令:
#cd grub-0.97
# ./configure如果你想定制GRUB,使之包含流行的文件系统和对网卡的支持,或者删除你不需要的网卡,可以运行如下命令:
# ./configure --help这个命令将输出所有的命令选项。现在可以使用—enable和—disable选项增加或
删除对特定网卡的支持。(注意:GRUB支持网络启动)
为了开始编译过程,键入如下命令:
# make
# make install至此你已经为安装GRUB真正做好了准备。
将GRUB的相关文件保存在诸如/boot/grub的目录中是一个好主意。为此,按如下步骤:
1)默认状态下,GRUB所有文件将安装在/usr/share/grub/i386-pc(或者在
/usr/local/share/grub/i386-pc目录下,这只取决于你的shell变量的设置。)
2)建立一个叫做/boot/grub的目录,然后拷贝下列文件到这个目录:
stage1 stage2 * stage1 5
稍候将解释这些文件。同时也要把GRUB(可能在/usr/sbin或者/usr/local/sbin
目录下)拷贝到/boot/grub目录下。
安装GRUB可以分为三个单独的步骤:
1]将“stage1”安装到MBR中。
2]设置“stage2”的地址或者位置。
3]设置一个菜单或选项,用来决定启动哪一个操作系统。使用下面的命令开始安装GRUB。
#cd /boot/grub
# ./grub这个命令根据BIOS的设置检测硬件设备,同时产生一些输出信息。这会花较长的时间。
end_request: I/O error, dev 02:00 (floppy), sector 0
GRUB version 0.5.96.1 (640K lower / 3072K upper memory)
TAB键可列出可能的命令列表。其它情况下TAB会列出设备或文件名。类似下面的提示会出现:
grub>现在,假设你将Linux安装在了第一块硬盘的第一个分区中或者/dev/hda1中。记住GRUB的命名规则,将上面的名字改为(hd0,0)。键入下面的命令:
grub> install (hd0,0)/boot/grub/stage1 (hd0) (hd0,0)/boot/grub/stage2
p (hd0,0)/boot/grub/menu.conf现在分析一下这个命令的细节。
install
一个内置的命令,它告诉GRUB将(hd0,0)/boot/grub/stage1安装到hd0的主引导纪录中。
(hd0,0)/boot/grub/stage2
告诉GRUB stage2映象的位置。
p with the the following options: (hd0,0)/boot/grub/menu.conf
为菜单的显示设置配置文件。下面是对这个命令用法的总结:
1.install
2.ource_of_stage1
3.where_to_install
4.source_of_stage2
5.p source_of_configuration_file现在,你完成了硬盘上的基本安装工作。
2、在软盘上的安装:
为了在软盘上安装GRUB,你要会用“dd”命令,并且了解它是如何工作的。为了做一张GRUB启动盘,你要将stage1和stage2文件放到软盘的开始扇区中。
安装stage1到软盘上:
插入一张已格式化的软盘,键入命令:
# dd if=stage1 of=/dev/fd0 bs=512 count=1命令的详细说明如下:
if=input file
i.e., stage1
of=output file
i.e., floppy drive (this may be different on your computer)
bs=bytes to read and write
Here it is 512 bytes.
count=how many times to perform this operation每次拷贝“bs”数目的块到目标地址。
安装stage2到软盘
# dd if=stage2 of=/dev/fd0 bs=512 seek=1
这里的步骤同stage1的相同,除了一个seek选项外。Seek选项将调过一个“bs”。例如,在上面的命令中bs的值是512,这样seek=1意味着将跳过软盘上前512个字节 ,从513字节开始。这将使得第一步操作不会覆盖stage1的前512字节。
现在你完成了基本的软盘驱动器安装。如果已经安装了grub要把grub重新安装到主引导扇区上,只需要简单打入makebootable命令就可以了。
四、 配置grub
grub启动时会在/boot/grub/中寻找一个名字为menu.lst的配置文件,如果找不到此文件则不进入菜单模式而直接进入命令行模式。
现在,我们来看一下如何在启动后进入各种操作系统,如何建立menu.conf文件。我们就从GRUB支持的启动过程开始。可以有两种方法来完成启动过程:
·A.通过调用内核本地启动
·B.连续启动或者将控制转给另一个引导器
A模式启动过程
1.配置跟设备或者告诉GRUB你的根文件系统。
2.告诉GRUB你的内核影像的位置,然后将参数传送给内核。
3.重新启动,试一下。
为了启动Linux,将内核以bzImage的文件名放在/boot/目录中,跟文件系统是
/dev/hda1,或者GRUB中的(hd0,0)。启动过程如下:
1.root (hd0,0) [This sets the root partition]
2.kernel /boot/bzImage root=/dev/hda1 [This sets the kernel]
B模式启动过程(这种模式假设当前的分区中安装了另一个启动管理器,例如LILO
或者NTLDR):
1.设置根分区但不要安装它
2.激活这个分区
3.配置需要启动的分区的第一个扇区
4.重新启动,看一下效果。
我们在试试启动安装在/dev/hdc1或者(hd1,0)的widows。启动windows的过程如下:
1.rootnoverify (hd1,0)
2.makeactive
3.chainloader +1 [+1 sets the first sector of the current root
partition]
4.boot [transfers the control and quits GRUB]
menu.conf文件:它用于建立启动多操作系统时的菜单。建立menu.conf并不难。它使用简单的英语,就象你在这一节看到的那样。
所有的菜单项目都以没有逗号分隔的“title TITLENAME”开头。你可以随意设置
TITLENAME。
设置Linux启动菜单步骤如下:
1.设置标题
2.设置根分区
3.设置内核的相应参数
4.启动
一个菜单例子:
title Red Hat Linux (2.4.18-14)
root (hd0,0)
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/
initrd /boot/initrd-2.4.18-14.img前面有#的行是一个注释。
建立启动Windows 或者 DOS的菜单:
title Windoze
rootnoverify (hd0,0)
makeactive
chainloader +1
boot
#----
又或者:
title Microsoft Windows XP
map (hd0) (hd1)
map (hd1) (hd0)
root (hd1,0)
chainloader (hd1,0)+1
makeactive
boot----
注意:root和rootnoverify都是一样的,把rootnoverify改成root也行。不过经过实践来看。有时引导win时,系统安装好 后,是rootnoverify (hdX.Y)这样形式的,这样会出现windows起不来,出现什么windows什么文件损坏的情况。这时,我们就要把在grub中,引导 windows的那段中的rootnoverify改为root
root英文的意思就是根的意思,在这里是让linux知道自己所处的位置,也就是我们所安装linux的/根分区所在的位置 。
----
如果你安装了两个版本的Windows—一个是你自己用的,另一个给你的家人用的—这样第二个就无法安装,因为有提示说Windows已经安装了。
有一种简单的方法可以安装两个版本的Windows,即在启动时隐藏一个分区而使用另一个。你甚至可以为你的分区设置密码保护,这样可以避免别人错误的加 载你的分区。下面介绍如何完成两个Windows的安装,hda1和hda2 或者 (hd0,0) 和(hd0,1),用到的命令有lock, password, hide 和 unhide。
建立windows 项目"My Entry":title My Entry
lock
unhide (hd0,0)
hide (hd0,1)
rootnoverify (hd0,0)
makeactive
chainloader +1
boot
#----
为了更好的使用lock命令,你需要在配置文件开头使用password命令。Password命令的语法如下:password secret(“secret”就是密码)。任何时候你都可以通过按p键儿输入密码。
建立Windows 项目"Family Entry"
title Family Entry
unhide (hd0,1)
hide (hd0,0)
rootnoverify (hd0,1)
makeactive
chainloader +1
boot
任何人都可以启动这个项目,而无须输入密码。
这有一个使用password命令的有趣的窍门。为了在缺省菜单列表或配置文件中隐藏某些项目,你可以使用下面的命令加载一个定制的列表:
password secret
在这个命令中,“secret”是密码,而/boot/grub/secret-list.conf是密码文件。这样做之前,你要先进入到根目录或者给出全路径名。例如:
password secret (hd0,4)/boot/grub/secret-list.conf
还有一个更重要的命令是“map”。当你有两块硬盘,一个无法从第二块硬盘启动的操作系统,例如Windows,就可以使用map命令。例如,你能够将 hd0映射为hd1,将hd1映射为hd0。换句话说,你可以虚拟的交换两个硬盘而启动所需要的操作系统 。命令形式如下:
grub> map (hd0) (hd1)
grub> map (hd1) (hd0)启动FreeBSD:
title FreeBSD 4.0
root (hd0,4,a)
kernel /boot/loader
boot
#----
这里我们调用了FreeBSD的启动管理器。Root (hd0,4,a)由四个参数,是因为
FreeBSD对一个单独分区进行了虚拟分割。我们称根分区为“a”。如果FreeBSD占
据了整个第二块硬盘,这里就应该是root (hd0,a)。这样,就不是调用内核而是调用FreeBSD的启动管理器,它要比调用内核更易使用。
(注意:推荐在使用OpenBSD和GNU/Hurd之前,要先试一下链式加载。)
现在你已经完成了基本的GRUB编译、安装和配置。你对GRUB了解的越多,就越会发现GRUB是一种控制启动的易用和高效的方法。
各种GRUB命令:
default xx表明xx是缺省的启动项目
timeout yy表明在yy秒后缺省启动项目将启动
fallback zz
在第一个启动项目失败后,过了timeout时间后,就将启动zz项目。
color
这个命令将生成彩色菜单。它的语法是:color normal current_selection。这两个域都可以有两个值,形如foreground/background。例如:
color green/black or light-gray/blue你也可以使用相关的数字。
记住:所有的值都是从0开始,所以0是第一个
六、 GRUB启动盘
要制作引导盘,需执行一些简单的步骤。首先,在新的软盘上创建 ext2 文件系统。然后,将其安装,并将一些 GRUB 文件复制到该文件系统,最后运行 "grub" 程序,它将负责设置软盘的引导扇区。
将一张空盘插入 1.44MB 软驱,输入:
# mke2fs /dev/fd0创建了 ext2 文件系统后,需要安装该文件系统:
# mount /dev/fd0 /mnt/floppy现在,需要创建一些目录,并将一些关键文件(原先安装 GRUB 时已安装了这些文件)复制到软盘:
# mkdir /mnt/floppy/boot
# mkdir /mnt/floppy/boot/grub
# cp /boot/grub/stage1 /mnt/floppy/boot/grub
# cp /boot/grub/stage2 /mnt/floppy/boot/grub再有一个步骤,就能得到可用的引导盘。
在linux bash中,从 root 用户运行“grub”,该程序非常有趣并值得注意,因为它实际上是GRUB 引导装入器的半功能性版本。尽管 Linux 已经启动并正在运行,您仍可以运行 GRUB 并执行某些任务,而且其界面与使用 GRUB 引导盘或将 GRUB 安装到硬盘 MBR 时看到的界面(即GRUB控制台)完全相同。
在 grub> 提示符处,输入:
grub> root (fd0)
grub> setup (fd0)
grub> quit现在,引导盘完成了。
如果要把GRUB装到硬盘上,也很容易。这个过程几乎与引导盘安装过程一样。首先,需要决定哪个硬盘分区将成为 root GRUB 分区。在这个分区上,创建 /boot/grub 目录,并将 stage1 和 stage2 文件复制到该目录中,可以通过重新引导系统并使用引导盘,或者使用驻留版本的 GRUB 来执行后一步操作。在这两种情况下,启动 GRUB,并用 root 命令指定 root 分区。例如,如果将 stage1 和 stage2 文件复制到 hda5 的 /boot/grub 目录中,应输入 "root (hd0,4)"。接着,决定在哪里安装 GRUB -- 在硬盘的 MBR,或者如果与 GRUB 一起使用另一个“主”引导装入器,则安装在特定分区的引导记录中。如果安装到 MBR,则可以指定整个磁盘而不必指定分区,如下(对于 hda):
grub> setup (hd0)如果要将 GRUB 安装到 /dev/hda5 的引导记录中,应输入:
grub> setup (hd0,4)现在,已安装 GRUB。引导系统时,应该立即以 GRUB 的控制台方式结束(如果安装到 MBR)。现在,应创建引导菜单,这样就不必在每次引导系统时都输入那些命令。
从软盘启动grub
制作启动盘后可以用软盘启动引导硬盘上的操作系统, 插入制作好的启动软盘,进入BIOS设定软盘启动。软盘启动成功后就会进入grub的命令行模式
grub>要启动一个操作系统,首先指定引导哪个分区上的系统,例如要引导指第一个硬盘上的第一个分区的操作系统,先键入
grub>root (hd0,0)接着如果要启动的是Windows系统,键入
grub>chainloader (hd0,0)+1注意(hd0,0)要随着硬盘和分区的不同而改变数字。
如果要引导Linux或其他系统,应键入
grub>kernel (hd0,0)/boot/vmlinuz root=/dev/hda1注意hda1参数也要随着硬盘和分区的不同而改变,如从第二个硬盘的第一个分区引导则用hdb1。
最后敲入boot就可以启动系统了。
在任何时候不能确定命令或者命令的参数都可以按Tab获得相关的帮助。用上下键可以获得命令的历史记录。其实这些命令就是menu.lst的启动描述,您也可以根据那些描述来自己键入启动命令,最后敲入boot就可以引导系统了。
七、GRUB的交互性
GRUB 最好的优点之一就是其强健的设计 -- 在不断使用它时请别忘了这点。如果更新内核或更改它在磁盘上的位置,不必重新安装 GRUB。事实上,如有必要,只要更新 menu.lst 文件即可,一切将保持正常。
只有少数情况下,才需要将 GRUB 引导装入器重新安装到引导记录。首先,如果更改 GRUB root 分区的分区类型(例如,从 ext2 改成 ReiserFS),则需要重新安装。或者,如果更新 /boot/grub 中的 stage1 和 stage2 文件,由于它们来自更新版本的 GRUB,很有可能要重新安装引导装入器。其它情况下,可以不必理睬!
GRUB的最大的特点就是交互性特别强。在开机时,按一下“c”,将进入GRUB 控制台。显示如下:
GRUB version 0.5.96.1 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ]
grub>欢迎使用 GRUB 控制台。现在,再研究命令:
将通过GRUB 控制台绕过lilo来启动RedHat linux,
grub> root (h现在,按一次 Tab 键。如果系统中有多个硬盘,GRUB 将显示可能完成的列表,从 "hd0" 开始。如果只有一个硬盘,GRUB 将插入 "hd0,"。如果有多个硬盘,继续进行,在 ("hd2") 中输入名称并在名称后紧跟着输入逗号,但不要按 Enter 键。部分完成的 root 命令看起来如下:
grub> root (hd0,现在,继续操作,再按一次 Tab 键。GRUB 将显示特定硬盘上所有分区的列表,以及它们的文件系统类型。在我的系统中,按 Tab 键时得到以下列表:
grub> root (hd0, (tab,按tab一下键)
Possible partitions are:
Partition num: 0, Filesystem type is fat, partition type 0x6
Partition num: 2, Filesystem type is ext2fs, partition type 0x83
Partition num: 4, Filesystem type unknown, partition type 0x7
Partition num: 5, Filesystem type is ext2fs, partition type 0x83
Partition num: 6, Filesystem type is fat, partition type 0xb
Partition num: 7, Filesystem type is fat, partition type 0xb
Partition num: 8, Filesystem type is ext2fs, partition type 0x83
Partition num: 9, Filesystem type unknown, partition type 0x82如您所见,GRUB 的交互式硬盘和分区名称实现功能非常有条理。这些,只需要好好理解 GRUB 新奇的硬盘和分区命名语法,然后就可以继续操作了
grub> root (hd0,8)
现在已安装了 root 文件系统,到装入内核的时候了
grub> kernel /boot/vmlinuz-2.4.2 root=/dev/hda5 ro
[Linux-bzImage, setup=0x1200, size=0xe1a30]
您已经安装了 root 文件系统并装入了内核。现在,可以引导了。只要输入 "boot",Linux 引导过程就将开始。是不是很cool啊,GRUB的menu.lst更像一个linux下的脚本程序。
八、常见grub除错方法的思路
首先进去Linux的rescue模式!
用软盘或光盘启动,然后在启动的提示符输入:linux rescue
按照提示进入一个Shell状态,你可以到/mnt/下面看到一个sysimage这么目录,进去以后,就是你安装linux的/分区.
使用命令将根分区变为当前目录的根分区:chroot /mnt/sysimage
然后转到/sbin/这个目录中.
使用fdisk -l 显示当前分区情况,然后使用#grub-install /dev/hdx(x为你使用的是那块硬盘安装的,一般情况下是hda)
使用exit推出chroot,再使用exit退出linux rescue模式,系统将重新启动!取出光盘,应该可以看到grub安装好了.
在具体的环境中,编辑/boot/grub/grub.conf文件和menu.lst文件.
九、GRUB背景,具体做法是怎样?
问:我想请教一下,要修改Mandrake 9下的GRUB背景,具体做法是怎样?
答: 文件/boot/grub/splash.xpm.gz 就是GRUB启动后的背景图象。
#gzip -d splash.xpm.gz
然后再
more splash.xpm
/* XPM */
static char * splash_xpm[] = {
"640 480 15 1",
" c None",
发现了什么?
我是从中知道了,这个图象是640*480象素的。15,1,不太明白什么意思但大概和色位色深有关系(专业术语不太懂)。剩下的事,就是把自已喜欢的图片做成的640*480的,然后再用GIMP修改一下色深,好像是14还是16 ,我记不太清了,自己试一下吧。
最后将图片保存成*.xpm格式,而且要保证当用more查看该图片时,得到的信息为“640 480 15 1"(记得千成不能弄错了,因为错了的话,有可能会使GRUB垮掉而不能启动系统哦!)最后将制作成的图片改名为splash.xpm,放在/boot/grub文件夹下(不用管splash.xpm.gz)
怎么样,是不是觉得很棒呢! -
2008-05-04
用GRUB启动安装在第二块硬盘上的Windows系统zt - [Unix/Linux]
http://blog.ccidnet.com/blog-htm-do-showone-uid-60710-type-blog-itemid-277240.html
用GRUB启动安装在第二块硬盘上的Windows系统
一般来说,Windows系统如果安装在第二块硬盘上,就不能够正常启动。使用GRUB的map命令,使第一块硬盘和第二块硬盘互相交换,则可以解决这个问题。
例子:
假设在第二块硬盘的第三个分区上安装了Windows 2003系统,GRUB的对应项的配置语句应该是:
title Windows 2003
map (hd0) (hd1)
map (hd1) (h