<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python隨身聽-源碼分析-經(jīng)典小游戲?-pacman

          共 5192字,需瀏覽 11分鐘

           ·

          2021-06-22 12:08


          周六了,讓我們按照老規(guī)矩,一起讀點(diǎn)代碼放松一下吧!

          今天要給大家看的代碼是一段游戲的代碼,這一次是一個(gè) 1980 年就誕生的經(jīng)典游戲:pacman,中文翻譯好像是吃豆人。其實(shí)就是一個(gè)迷宮,擺滿了各種小豆子,一個(gè)小黃人去邊走邊吃,里面會(huì)有幾個(gè)游蕩的鬼魂,撞到了會(huì)讓小黃人死翹翹,所以走起路來要小心啊!

          游戲動(dòng)圖:

          源碼

          建議先仔細(xì)閱讀一下,然后再往后看 DE8UG 對(duì)源碼的分析。

          from random import choice
          from turtle import *
          from freegames import floor, vector

          state = {'score': 0}
          path = Turtle(visible=False)
          writer = Turtle(visible=False)
          aim = vector(5, 0)
          pacman = vector(-40, -80)
          ghosts = [
          [vector(-180, 160), vector(5, 0)],
          [vector(-180, -160), vector(0, 5)],
          [vector(100, 160), vector(0, -5)],
          [vector(100, -160), vector(-5, 0)],
          ]
          tiles = [
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
          0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
          0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
          0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,
          0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
          0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          ]

          def square(x, y):
          "Draw square using path at (x, y)."
          path.up()
          path.goto(x, y)
          path.down()
          path.begin_fill()

          for count in range(4):
          path.forward(20)
          path.left(90)

          path.end_fill()

          def offset(point):
          "Return offset of point in tiles."
          x = (floor(point.x, 20) + 200) / 20
          y = (180 - floor(point.y, 20)) / 20
          index = int(x + y * 20)
          return index

          def valid(point):
          "Return True if point is valid in tiles."
          index = offset(point)

          if tiles[index] == 0:
          return False

          index = offset(point + 19)

          if tiles[index] == 0:
          return False

          return point.x % 20 == 0 or point.y % 20 == 0

          def world():
          "Draw world using path."
          bgcolor('black')
          path.color('blue')

          for index in range(len(tiles)):
          tile = tiles[index]

          if tile > 0:
          x = (index % 20) * 20 - 200
          y = 180 - (index // 20) * 20
          square(x, y)

          if tile == 1:
          path.up()
          path.goto(x + 10, y + 10)
          path.dot(2, 'white')

          def move():
          "Move pacman and all ghosts."
          writer.undo()
          writer.write(state['score'])

          clear()

          if valid(pacman + aim):
          pacman.move(aim)

          index = offset(pacman)

          if tiles[index] == 1:
          tiles[index] = 2
          state['score'] += 1
          x = (index % 20) * 20 - 200
          y = 180 - (index // 20) * 20
          square(x, y)

          up()
          goto(pacman.x + 10, pacman.y + 10)
          dot(20, 'yellow')

          for point, course in ghosts:
          if valid(point + course):
          point.move(course)
          else:
          options = [
          vector(5, 0),
          vector(-5, 0),
          vector(0, 5),
          vector(0, -5),
          ]
          plan = choice(options)
          course.x = plan.x
          course.y = plan.y

          up()
          goto(point.x + 10, point.y + 10)
          dot(20, 'red')

          update()

          for point, course in ghosts:
          if abs(pacman - point) < 20:
          return

          ontimer(move, 100)

          def change(x, y):
          "Change pacman aim if valid."
          if valid(pacman + vector(x, y)):
          aim.x = x
          aim.y = y

          setup(420, 420, 370, 0)
          hideturtle()
          tracer(False)
          writer.goto(160, 160)
          writer.color('white')
          writer.write(state['score'])
          listen()
          onkey(lambda: change(5, 0), 'Right')
          onkey(lambda: change(-5, 0), 'Left')
          onkey(lambda: change(0, 5), 'Up')
          onkey(lambda: change(0, -5), 'Down')
          world()
          move()
          done()

          運(yùn)行

          復(fù)制上述代碼到一個(gè) py 為后綴的文件,命名 pacman.py.

          在文件所在目錄打開控制臺(tái):運(yùn)行pip install freegames,然后運(yùn)行python pacman.py

          分析

          這個(gè)游戲代碼里面有很多和之前給大家解說的代碼(直接給公號(hào)后天回復(fù)搜索,然后搜游戲代碼即可)類似的地方,這里就直接略過了。我們只看看和之前不一樣的地方。

          整體布局

          這里是一個(gè)迷宮地圖,左上角還需要顯示分?jǐn)?shù),所以最開始的全局變量新建了兩個(gè) Turtle 對(duì)象,相當(dāng)于兩個(gè)畫筆,一個(gè)畫具體路徑,一個(gè)更新分?jǐn)?shù)。

          整體布局是采用 world 函數(shù)完成的。最開始定義的 tiles 列表,里面用 0 和 1 指代了每一塊瓦片的位置和是否有食物。繪制的時(shí)候,用 x,y 換算為從左上角開始的坐標(biāo)位置,然后開始調(diào)用 square 函數(shù)開始繪制地圖。注意這里整體偏左,因?yàn)橛疑辖且舫鑫恢糜涗浄謹(jǐn)?shù)。

          移動(dòng)與碰撞

          在 move 函數(shù)中,還是如之前一樣是一個(gè)定時(shí)循環(huán)。繪制每一次的動(dòng)作。

          最開始是分?jǐn)?shù)的統(tǒng)計(jì),采用重繪來進(jìn)行。然后清理屏幕,判斷小黃人的移動(dòng)是否合法。接下來用 offset 函數(shù)把小黃人坐標(biāo)映射回 tiles 列表的索引,去判斷是否吃到食物,如果吃到,則重繪當(dāng)前的方塊,注意這時(shí)候其實(shí)和繪制整體地圖時(shí)候一樣,只是不再繪制中間的食物。

          然后移動(dòng)小黃人,繪制為黃色。

          地圖里面的小幽靈們是一直移動(dòng)的,其實(shí)是循環(huán)每個(gè)的坐標(biāo)位置,判斷是否合法,合法就移動(dòng),不合法就給出一個(gè)設(shè)定好的坐標(biāo)。

          然后就判斷小黃人是否和幽靈碰撞,即 abs(pacman - point) < 20,撞到也就 game over 了!

          play!

          接下來就是啟動(dòng)游戲,開始玩了 ??

          ok,這就是本周六的源碼分析了,祝你閱讀愉快。目前在 Python 隨身聽的微信欄目里,已經(jīng)從周一到周日安排了:技術(shù)精選,基礎(chǔ)學(xué)習(xí),Python 練習(xí),項(xiàng)目連載,難點(diǎn)問答,源碼分析,DE8UG 雜談這些欄目,歡迎圍觀。有任何想法建議疑問歡迎留言,明天見~


          瀏覽 90
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费视频一二区 | 中国女人一级一次看片 | 五情丁香先锋视 | 中文字幕无码毛片免费看 | 操逼视频123 |