練習 43 - 面向對象的分析和設計基礎 - 笨辦法學Python3

練習 43. 面向對象的分析和設計基礎

這個練習我想說一下當你想要用 Python 創(chuàng)建一個東西,尤其是面向對象編程的時候,過程是怎樣的逗威。我說的“過程”指的是我會給出一些有序的步驟,但你也不用生搬硬套,因為它們也不一定適用每一個問題嵌洼。它們只不過是為很多編程問題提供一個很好的開端,而不是解決這類問題的唯一方法封恰,只是你可以參考的其中一種方法麻养。

過程如下:

  1. 把問題寫或者劃下來。

  2. 提煉出關鍵概念诺舔,并進行研究鳖昌。

  3. 為這些概念創(chuàng)建一個類的層級和對象關系圖。

  4. 寫下這些類的代碼低飒,并測試運行许昨。

  5. 重復和改進。

這是一種“自上而下”的方式褥赊,它從非常抽象糕档、松散的想法開始,然后慢慢提煉拌喉,直到想法變得具體速那,可以通過代碼來實現(xiàn)俐银。

我會先從寫下問題開始,盡可能地寫下我所能想到的點琅坡。可能我還會畫一兩張圖表残家、地圖之類的榆俺,甚至會給我自己寫一系列郵件來闡述這個問題。這樣能讓我針對這個問題把一些關鍵的概念表達出來坞淮,并且探索出關于該問題我可能已經(jīng)掌握的東西茴晋。

然后我會過一遍這些筆記、圖表以及描述回窘,從其中抽象出關鍵概念诺擅。這里有一個小技巧:把你所寫所畫的東西里面所有的名詞和動詞列一個表出來,然后寫下它們之間是如何相互關聯(lián)的啡直。這種方法讓我得到了一個關于下一步的類烁涌、對象和函數(shù)名的列表。我拿著這個概念列表酒觅,研究其中我不明白的點撮执,如果我需要的話,對其進行改進舷丹。

一旦我有了這個概念列表抒钱,我就創(chuàng)造了一個簡單的概念框架,以及它們作為類是如何相互關聯(lián)的颜凯。你可以經(jīng)常列你的名詞表谋币,然后問自己“這個跟其他的概念名詞類似嗎?也就是說症概,它們有共同的父類嗎蕾额?有的話應該叫什么?”重復這個過程直到你得到一個類的層級結構彼城,可能就是一個簡單的樹狀圖或者示意圖凡简。然后把所有的動詞挑出來,看看它們能不能作為每個類的函數(shù)名精肃,然后把它們放到你的樹狀圖里面秤涩。

等類的層級結構梳理清楚之后,我會坐下來司抱,寫一些基本的代碼框架筐眷,只是一些類和它們的函數(shù),沒有其他東西习柠。然后我會寫一些測試代碼匀谣,跑一下照棋,看這些類有沒有意義以及能不能正常運行。有時我會先寫測試代碼武翎,有時候就是一小段測試烈炭,一小段代碼,再一小段測試宝恶,以此類推符隙,直到我把整個程序構建起來。

最后垫毙,我會重復這個過程霹疫,并且在運行的過程中不斷精簡,在添加更多應用之前讓代碼更簡潔明了综芥。如果我在某個特定環(huán)節(jié)因為一個概念或者我沒有預料到的問題而卡殼丽蝎,我會坐下來,只運行這一部分膀藐,直到把問題弄明白之后再繼續(xù)屠阻。

我現(xiàn)在要通過一個游戲引擎和一個游戲練習來過一遍這個過程。

一個簡單的游戲引擎分析

我要制作的這個游戲叫做“來自25號行星的哥頓人”(Gothons from Planet Percal #25)额各,它是一個小型太空冒險游戲栏笆。因為我滿腦子都是這個概念,我就去探索這個想法臊泰,然后思考如何把這個游戲做出來蛉加。

43.1.1 寫或畫出這個問題

我會寫一小段關于這個游戲的文字:

“外星人入侵了一艘宇宙飛船,我們的英雄必須穿過迷宮般的房間打敗他們缸逃,這樣他才能逃到逃生艙去到下面的星球针饥。游戲更像是 Zork 之類的文字冒險游戲,并且有著很有意思的死亡方式需频。這款游戲的引擎會運行一張滿是房間或場景的地圖丁眼。當玩家進入游戲時,每個房間都會打印自己的描述昭殉,然后告訴引擎下一步該運行地圖中的哪個房間苞七。”

這時我有了一個關于這個游戲以及它如何運行的好想法挪丢,所以現(xiàn)在我要描述一下每個場景:

死亡(Death):玩家死的時候蹂风,會非常有意思。
中央走廊(Central Corridor):這是起點乾蓬,已經(jīng)有一個哥頓人站在那里惠啄,在繼續(xù)之前,玩家必須用一個笑話來擊敗他。
激光武器軍械庫(Laser Weapon Armory):這是英雄在到達逃生艙之前用中子彈炸毀飛船的地方撵渡。這里有一個鍵盤融柬,英雄必須猜出數(shù)字。
橋(The Bridge):另一個和哥頓人戰(zhàn)斗的場景趋距,英雄在這里放置了炸彈粒氧。
逃生艙(Escape Pod):英雄逃脫的地方,前提是他猜出正確的逃生艙节腐。

到這一步我可能會畫一幅映射圖外盯,或者為每個房間寫更多的描述——反正就是當我探究這個問題的時候,任何我腦子里冒出的想法铜跑。

43.1.2 抽取關鍵概念并予以研究

我現(xiàn)在有足夠的信息來提取其中的名詞门怪,并分析他們的類層級結構骡澈。首先锅纺,我會做一個所有名詞的列表:

? Alien(外星人)

? Player(玩家)

? Ship(飛船)

? Maze(迷宮)

? Room(房間)

? Scene(場景)

? Gothon(哥特人)

? Escape Pod(逃生艙)

? Planet(行星)

? Map(地圖)

? Engine(引擎)

? Death(死亡)

? Central Corridor(中央走廊)

? Laser Weapon Armory(激光武器軍械庫)

? The Bridge(橋)

我可能還會瀏覽一遍所有的動詞,看它們適不適合作為函數(shù)名肋殴,但是我會先暫時跳過這一步囤锉。

現(xiàn)在你可能也會研究一下每個概念以及任何你不明白的東西。比如护锤,我會玩幾個同類型的游戲官地,確保我知道它們是如何工作的。我可能還會研究船是如何設計的或者炸彈是怎么用的烙懦。還有一些技術性問題驱入,比如如何把游戲狀態(tài)儲存在數(shù)據(jù)庫中。當我完成這些研究氯析,我可能會基于這些新信息從第一步開始亏较,重新寫我的描述,并做概念提取掩缓。

43.1.3 為這些概念創(chuàng)建類的層級結構和對象地圖

我通過詢問“什么與其他東西類似?”雪情、“什么基本上就是另一個東西的另一個詞?”來把我已經(jīng)有的東西轉換成類的層級結構。

很快我就發(fā)現(xiàn)“房間”(“Room”)和“場景”(“Scene”)基本上是同一種東西你辣,取決于我想用它們來做什么巡通。在這個游戲中我選擇用“場景”。然后我意識到所有特定的房間比如“中央走廊”其實就是“場景”舍哄。我還發(fā)現(xiàn)“死亡”(“Death”)也可以說是場景宴凉,這確認了我選擇“場景”而不是“房間”的正確性,因為你可以說“死亡”是一種場景表悬,但如果說它是一個“房間”就有點奇怪了跪解。“迷宮”(“Maze”)和“地圖”(“Map”)也基本上是同一種東西,我會選擇用“地圖”叉讥,因為我更常用它窘行。我不想做一個戰(zhàn)斗系統(tǒng),所以我會暫時忽略“外星人”(“Alien”)和“玩家”(“Player”)這兩個東西图仓,先保存起來以備后用罐盔。“行星”(“Planet”)也可以是另一種場景救崔,而不是其他特定的東西惶看。

經(jīng)過上述思考過程,我開始創(chuàng)建一個看起來像這樣的類的層級結構:

  • Map
  • Engine
  • Scene
    • Death
    • Central Corridor
    • Laser Weapon Armory
    • The Bridge
    • Escape Pod

然后我會瀏覽一遍六孵,基于我描述里面的東西纬黎,想想看每個類下面需要些什么動作。例如劫窒,我從描述里知道本今,我需要一種方式來“運行”這個引擎,從地圖“到達下一個場景”主巍,到達“開場”冠息,并“進入”一個場景,我會像這樣把這些動作加上:

  • Map
    – next_scene
    – opening_scene
  • Engine
    – play
  • Scene
    – enter
    • Death
    • Central Corridor
    • Laser Weapon Armory
    • The Bridge
    • Escape Pod

注意我只把“enter”放在了“場景”下面孕索,所有“場景”下面的東西都會繼承這個動作逛艰,需要隨后再重寫。

43.1.4 編寫類代碼并通過測試來運行

一旦我有了這個類和函數(shù)的樹狀圖搞旭,我在我的編輯器里面打開一個源文件散怖,試著寫它們的代碼。通常我就是把樹狀圖里的東西復制粘貼到源文件里肄渗,然后把它們編輯成類镇眷。下面是它們最開始的樣子,文件最后放了一個小測試:

ex43_classes.py

1   class Scene(object): 
2
3       def enter(self):
4           pass
5
6
7   class Engine(object): 
8
9       def __init__(self, scene_map):
10          pass
11
12      def play(self):
13          pass
14
15  class Death(Scene): 
16
17      def enter(self):
18          pass
19
20  class CentralCorridor(Scene): 
21
22      def enter(self):
23          pass
24
25  class LaserWeaponArmory(Scene): 
26
27      def enter(self):
28          pass
29
30  class TheBridge(Scene): 
31
32      def enter(self):
33          pass
34
35  class EscapePod(Scene): 
36
37      def enter(self):
38          pass
39
40
41  class Map(object): 
42
43      def __init__(self, start_scene):
44          pass
45
46      def next_scene(self, scene_name):
47          pass
48
49      def opening_scene(self):
50          pass
51
52
53  a_map = Map('central_corridor')
54  a_game = Engine(a_map)
55  a_game.play()

在這個文件中你可以看到恳啥,我只是復制了層級結構中我想要的東西偏灿,并在最后加上了一些測試代碼來運行,看這個基本結構能不能成立钝的。在這個練習后面的幾部分翁垂,你會填上剩余的代碼,讓它像游戲描述中那樣運行硝桩。

43.1.5 重復和改進

過程的最后一步準確來說不是一個步驟沿猜,而像是一個 while 循環(huán)。你不可能一次完成這個過程碗脊。相反啼肩,你會再次回顧整個過程,并根據(jù)你從后續(xù)步驟中學到的信息對其進行改進。有時我會進入第三步祈坠,然后意識到我需要再回到第一步和第二步害碾,那我就會停下來,回到前面去做赦拘。有時我會靈光一閃慌随,跳到最后,把腦子里的解決方案代碼敲出來躺同,然后再回過頭來做前面的步驟阁猜,以確保我涵蓋了所有可能的情況。

在這個過程中你需要注意的另一個問題是蹋艺,它不僅僅是你在一個單一層面上做的事剃袍,而是當你遇到一個特定的問題時,你可以在每個層面上做的事情捎谨。假設我不知道怎么寫 Engine.play 這個方法民效。我可以停下來,把整個過程專注在這一個函數(shù)上來弄明白代碼應該怎么寫侍芝。

自上而下 vs 自下而上

這個過程通常被稱為“自上而下”研铆,因為它從最抽象的概念(上)開始埋同,然后一直向下到實際的應用州叠。我希望你能從現(xiàn)在開始分析這本書里遇到的問題時使用我剛才描述的這個過程,但是你應該知道編程中還有另一種解決問題的方式凶赁,那就是咧栗,從寫代碼開始,然后逐漸“上升”到抽象的概念虱肄,這種方式被稱為“自下而上”致板。它的步驟大致如下:

  1. 從問題中拿出一小部分,開始寫簡單的能運行的代碼咏窿。

  2. 然后用類和自動化測試來把代碼改進地更正式一些斟或。

  3. 抽象出你所使用的關鍵概念,試著探究一下它們集嵌。

  4. 針對正在發(fā)生的事情寫一段描述萝挤。

  5. 回過頭去繼續(xù)改進代碼,也可能把之前寫的刪掉重新開始根欧。

  6. 轉到這個問題的其他部分怜珍,然后重復以上步驟。

這個過程只有在你對編程已經(jīng)比較熟練并且面對問題能夠自然使用編程思維的情況下才會更好凤粗,同時酥泛,當你知道整個工程的一小部分、卻對全局概念的信息掌握不全的時候,這個方法也很好用柔袁。你可以將整個過程拆解成很多小塊呆躲,然后邊寫代碼邊探索,這樣可以幫助你一點一點地鉆研這個問題捶索,直到整個問題都得到解決歼秽。但是,請記住情组,你的解決方案很可能會曲折而怪異燥筷,所以我才把回顧、研究以及基于你所學到的東西對代碼進行改進和清理這些步驟加入到我的過程描述中院崇。

“來自25號行星的哥頓人”游戲代碼

停肆氓!接下來我要向你展示針對之前的問題我最終的解決方,但是我想讓你直接跳進去開始敲代碼底瓣,我希望你自己先基于描述粗略地寫出代碼框架谢揪,然后試著讓它運行,一旦你有了你的解決方案捐凭,你再回來看我是怎么做的拨扶。

我會把最終的 ex43.py 拆成幾個部分分別解釋,而不是直接把所有代碼一次全部給你茁肠。

ex43.py

1   from sys import exit
2   from random import randint
3   from textwrap import dedent

這是游戲所需庫的基本引入患民。唯一的新東西是從 textwrap 模塊導入 dedent 函數(shù)。這個函數(shù)將幫助我們使用 """ (三引號)字符串來編寫我們的房間描述垦梆。它就是簡單地從字符串的行首刪除空白匹颤。如果沒有這個函數(shù),使用 """ 樣式字符串就會失敗托猩,因為它們在屏幕上縮進的程度與Python代碼相同印蓖。

ex43.py

1   class Scene(object): 
2
3       def enter(self):
4           print("This scene is not yet configured.")
5           print("Subclass it and implement enter().")
6           exit(1)

正如你在框架代碼中看到的,我有一個基類 Scene京腥,它具有所有場景都具有的公共功能赦肃。在這個簡單的程序中,它們不會做太多的工作公浪,只是向你演示如何創(chuàng)建基類他宛。

ex43.py

1   class Engine(object): 
2
3       def __init__(self, scene_map):
4           self.scene_map = scene_map 
5
6           def play(self):
7               current_scene = self.scene_map.opening_scene()
8               last_scene = self.scene_map.next_scene('finished') 
9
10              while current_scene != last_scene:
11                  next_scene_name = current_scene.enter()
12                  current_scene = self.scene_map.next_scene(next_scene_name)
13
14              # be sure to print out the last scene
15              current_scene.enter()

我還有 Engine 類。你可以看到我已經(jīng)在使用 Map.opening_sceneMap.next_scene 這兩個方法了因悲。因為我已經(jīng)提前計劃好了堕汞,所以可以在寫出 Map 類之前就把這些方法寫下來并用起來。

ex43.py

1   class Death(Scene): 
2
3       quips = [
4           "You died. You kinda suck at this.",
5           "Your Mom would be proud...if she were smarter.",
6           "Such a luser.",
7           "I have a small puppy that's better at this.",
8           "You're worse than your Dad's jokes."
9           
10      ]       
11          
12      def enter(self):
13          print(Death.quips[randint(0, len(self.quips)-1)])
14          exit(1)

我的第一個場景很反常地設置為了 Death晃琳,主要是想向你展示你可以寫的最簡單的場景讯检。

1 class CentralCorridor(Scene):
2
3   def enter(self):
4       print(dedent("""
5           The Gothons of Planet Percal #25 have invaded your ship and
6           destroyed your entire crew. You are the last surviving
7           member and your last mission is to get the neutron destruct
8           bomb from the Weapons Armory, put it in the bridge, and
9           blow the ship up after getting into an escape pod.
10
11          You're running down the central corridor to the Weapons
12          Armory when a Gothon jumps out, red scaly skin, dark grimy
13          teeth, and evil clown costume flowing around his hate
14          filled body. He's blocking the door to the Armory and
15          about to pull a weapon to blast you.
16          """))
17
18      action = input("> ")
19
20      if action == "shoot!":
21          print(dedent("""
22              Quick on the draw you yank out your blaster and fire
23              it at the Gothon. His clown costume is flowing and
24              moving around his body, which throws off your aim.
25              Your laser hits his costume but misses him entirely.
26              This completely ruins his brand new costume his mother
27              bought him, which makes him fly into an insane rage
28              and blast you repeatedly in the face until you are
29              dead. Then he eats you.
30              """))
31          return 'death'
32
33      elif action == "dodge!":
34          print(dedent("""
35              Like a world class boxer you dodge, weave, slip and
36              slide right as the Gothon's blaster cranks a laser
37              past your head. In the middle of your artful dodge
38              your foot slips and you bang your head on the metal
39              wall and pass out. You wake up shortly after only to
40              die as the Gothon stomps on your head and eats you.
41              """))
42          return 'death'
43
44      elif action == "tell a joke":
45          print(dedent("""
46              Lucky for you they made you learn Gothon insults in
47              the academy. You tell the one Gothon joke you know:
48              Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr,
49              fur fvgf nebhaq gur ubhfr. The Gothon stops, tries
50              not to laugh, then busts out laughing and can't move.
51              While he's laughing you run up and shoot him square in
52              the head putting him down, then jump through the
53              Weapon Armory door.
54              """))
55          return 'laser_weapon_armory'
56
57      else:
58          print("DOES NOT COMPUTE!")
59          return 'central_corridor'

然后我創(chuàng)建了中央走廊琐鲁,這是游戲的開始。我把游戲的場景放在 Map 之前人灼,是因為我需要在隨后引用它們围段。你應該也看到了我在第4行用了 dedent 函數(shù)。稍后你可以嘗試刪除它投放,看看它會做什么奈泪。

ex43.py

1 class LaserWeaponArmory(Scene):
2
3   def enter(self):
4       print(dedent("""
5           You do a dive roll into the Weapon Armory, crouch and scan
6           the room for more Gothons that might be hiding. It's dead
7           quiet, too quiet. You stand up and run to the far side of
8           the room and find the neutron bomb in its container.
9           There's a keypad lock on the box and you need the code to
10          get the bomb out. If you get the code wrong 10 times then
11          the lock closes forever and you can't get the bomb. The
12          code is 3 digits.
13          """))
14
15      code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}"
16      guess = input("[keypad]> ")
17      guesses = 0
18
19      while guess != code and guesses < 10:
20          print("BZZZZEDDD!")
21          guesses += 1
22          guess = input("[keypad]> ")
23
24      if guess == code:
25          print(dedent("""
26              The container clicks open and the seal breaks, letting
27              gas out. You grab the neutron bomb and run as fast as
28              you can to the bridge where you must place it in the
29              right spot.
30              """))
31          return 'the_bridge'
32      else:
33          print(dedent("""
34              The lock buzzes one last time and then you hear a
35              sickening melting sound as the mechanism is fused
36              together. You decide to sit there, and finally the
37              Gothons blow up the ship from their ship and you die.
38              """))
39          return 'death'
40
41
42
43 class TheBridge(Scene):
44
45  def enter(self):
46      print(dedent("""
47          You burst onto the Bridge with the netron destruct bomb
48          under your arm and surprise 5 Gothons who are trying to
49          take control of the ship. Each of them has an even uglier
50          clown costume than the last. They haven't pulled their
51          weapons out yet, as they see the active bomb under your
52          arm and don't want to set it off.
53          """))
54
55      action = input("> ")
56
57      if action == "throw the bomb":
58          print(dedent("""
59              In a panic you throw the bomb at the group of Gothons
60              and make a leap for the door. Right as you drop it a
61              Gothon shoots you right in the back killing you. As
62              you die you see another Gothon frantically try to
63              disarm the bomb. You die knowing they will probably
64              blow up when it goes off.
65              """))
66          return 'death'
67
68      elif action == "slowly place the bomb":
69          print(dedent("""
70              You point your blaster at the bomb under your arm and
71              the Gothons put their hands up and start to sweat.
72              You inch backward to the door, open it, and then
73              carefully place the bomb on the floor, pointing your
74              blaster at it. You then jump back through the door,
75              punch the close button and blast the lock so the
76              Gothons can't get out. Now that the bomb is placed
77              you run to the escape pod to get off this tin can.
78              """))
79
80          return 'escape_pod'
81      else:
82          print("DOES NOT COMPUTE!")
83          return "the_bridge"
84
85
86 class EscapePod(Scene):
87
88  def enter(self):
89      print(dedent("""
90          You rush through the ship desperately trying to make it 
91          the escape pod before the whole ship explodes. It seems
92          like hardly any Gothons are on the ship, so your run is
93          clear of interference. You get to the chamber with the
94          escape pods, and now need to pick one to take. Some of
95          them could be damaged but you don't have time to look.
96          There's 5 pods, which one do you take?
97          """))
98
99      good_pod = randint(1,5)
100     guess = input("[pod #]> ")
101
102
103     if int(guess) != good_pod:
104         print(dedent("""
105             You jump into pod {guess} and hit the eject button.
106             The pod escapes out into the void of space, then
107             implodes as the hull ruptures, crushing your body into
108             jam jelly.
109             """))
110         return 'death'
111     else:
112         print(dedent("""
113             You jump into pod {guess} and hit the eject button.
114             The pod easily slides out into space heading to the
115             planet below. As it flies to the planet, you look
116             back and see your ship implode then explode like a
117             bright star, taking out the Gothon ship at the same
118             time. You won!
119             """))
120
121         return 'finished'
122
123 class Finished(Scene):
124
125     def enter(self):
126         print("You won! Good job.")
127         return 'finished'

這是游戲的剩余場景,因為我知道我需要它們灸芳,并且已經(jīng)想過它們之間如何流轉涝桅,所以我能直接把代碼寫出來。

順便說一句烙样,我不會把所有這些代碼都輸入進去冯遂。還記得我說過要循序漸進,一點一點來≮嘶瘢現(xiàn)在我只給你們看最后的結果蛤肌。

ex43.py

1   class Map(object): 
2
3     scenes = {
4         'central_corridor': CentralCorridor(),
5         'laser_weapon_armory': LaserWeaponArmory(),
6         'the_bridge': TheBridge(),
7         'escape_pod': EscapePod(),
8         'death': Death(),
9         'finished': Finished(), 
10    }
11
12    def __init__(self, start_scene):
13      self.start_scene = start_scene 
14
15    def next_scene(self, scene_name):
16        val = Map.scenes.get(scene_name)
17        return val 
18
19    def opening_scene(self):
20        return self.next_scene(self.start_scene)

然后是我的 Map 類,你可以看到它把每個場景的名字存儲在一個字典里批狱,然后我用 Map.scenes 引用那個字典裸准。這也是為什么地圖出現(xiàn)在場景之后的原因,因為字典必須引用場景赔硫,所以場景必須先存在炒俱。

ex43.py

1   a_map = Map('central_corridor')
2   a_game = Engine(a_map)
3   a_game.play()

最后是我通過制作地圖來運行游戲的代碼,在調用 play 使游戲工作之前卦停,我把地圖交給了引擎向胡。

你會看到

確保你理解了這個游戲恼蓬,并且你先試圖自己去解決它惊完。如果你被難住了,你可以通過閱讀我的代碼來作弊处硬,然后繼續(xù)嘗試自己解決它小槐。

以下是我運行我的游戲的結果:

練習 43 會話

$ python3.6 ex43.py

The Gothons of Planet Percal #25 have invaded your ship and destroyed your entire crew. You are the last surviving member and your last mission is to get the neutron destruct bomb from the Weapons Armory, put it in the bridge, and blow the ship up after getting into an escape pod.

You're running down the central corridor to the Weapons Armory when a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume flowing around his hate filled body. He's blocking the door to the Armory and about to pull a weapon to blast you.

> dodge!
 
Like a world class boxer you dodge, weave, slip and slide right as the Gothon's blaster cranks a laser past your head. In the middle of your artful dodge your foot slips and you bang your head on the metal wall and pass out. You wake up shortly after only to die as the Gothon stomps on your head and eats you.

You're worse than your Dad's jokes.

附加練習

  1. 改變它!也許你不喜歡這個游戲荷辕,因為太暴力了凿跳,也可能你對科幻不感興趣。先讓游戲運行起來疮方,然后把它變成你喜歡的樣子控嗜。這是你的電腦,你可以讓它做你想做的骡显。

  2. 我這段代碼有一個bug疆栏。為什么門鎖猜了11次?

  3. 解釋一下如何返回隔壁房間曾掂。

  4. 在游戲中添加作弊代碼,這樣你就可以通過比較難的房間壁顶。我可以通過在一行寫兩個字來實現(xiàn)這一點珠洗。

  5. 回到我的描述和分析,然后嘗試為這個英雄和他遇到的各種哥特人建立一個小的戰(zhàn)斗系統(tǒng)若专。

  6. 這實際上是“有限狀態(tài)機”(finite state machine)的一個小版本许蓖。讀讀相關的內容,你可能看不懂调衰,但無論如何都要試一試膊爪。

常見問題

我在哪里可以找到我自己的游戲故事?你可以自己編嚎莉,就像你給朋友講故事一樣蚁飒。或者你可以從你喜歡的書或電影中選取一些簡單的場景萝喘。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末淮逻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阁簸,更是在濱河造成了極大的恐慌爬早,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件启妹,死亡現(xiàn)場離奇詭異筛严,居然都是意外死亡,警方通過查閱死者的電腦和手機饶米,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門桨啃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人檬输,你說我怎么就攤上這事照瘾。” “怎么了丧慈?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵析命,是天一觀的道長。 經(jīng)常有香客問我逃默,道長鹃愤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任完域,我火速辦了婚禮软吐,結果婚禮上,老公的妹妹穿的比我還像新娘吟税。我一直安慰自己凹耙,他們只是感情好鸟蟹,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著使兔,像睡著了一般建钥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虐沥,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天熊经,我揣著相機與錄音,去河邊找鬼欲险。 笑死镐依,一個胖子當著我的面吹牛,可吹牛的內容都是我干的天试。 我是一名探鬼主播槐壳,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喜每!你這毒婦竟也來了务唐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤带兜,失蹤者是張志新(化名)和其女友劉穎枫笛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刚照,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡刑巧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了无畔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啊楚。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖浑彰,靈堂內的尸體忽然破棺而出恭理,到底是詐尸還是另有隱情,我是刑警寧澤闸昨,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布蚯斯,位于F島的核電站,受9級特大地震影響饵较,放射性物質發(fā)生泄漏。R本人自食惡果不足惜遭赂,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一循诉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撇他,春花似錦茄猫、人聲如沸狈蚤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脆侮。三九已至,卻和暖如春勇劣,著一層夾襖步出監(jiān)牢的瞬間靖避,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工比默, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留幻捏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓命咐,卻偏偏與公主長得像篡九,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子醋奠,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354