整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          新的 HTML 標(biāo)簽:絕對改變游戲規(guī)則

          新的 HTML 標(biāo)簽:絕對改變游戲規(guī)則

          了新的 <dialog> 標(biāo)記,前端開發(fā)將從此不同...

          ?之前:

          看看我創(chuàng)建一個(gè)對話框要花費(fèi)多少功夫。僅 CSS 就有近 20 行:

          這還只是用于對話框功能的 CSS,它看起來仍然非常基本:

          但是,使用新的 <dialog> 標(biāo)簽又如何呢?

          ? 現(xiàn)在:

          <button id="open">Open</button>
          <dialog id="dialog">
            ? Lighting strikes the earth 44 times every second!
            ? 閃電每秒擊中地球44次!
          </dialog>

          JS:

          const dialog=document.getElementById('dialog');
          const open=document.getElementById('open');
          
          open.addEventListener('click', ()=> {
            dialog.showModal();
          });

          我們甚至可以使用 show() 方法來顯示非模式對話框--沒有背景,干擾較少:

          const dialog=document.getElementById('dialog');
          const open=document.getElementById('open');
          
          open.addEventListener('click', ()=> {
            // ? show() 方法
            dialog.show();
          });

          對話框一直是強(qiáng)力吸引用戶注意力并向其傳遞信息的有力方式。

          從 Material Design 到 Fluent Design,它一直是每個(gè)用戶界面設(shè)計(jì)系統(tǒng)的主打功能。

          但是,即使它們再常見,我們也不得不借助第三方庫或創(chuàng)建自定義組件來使用它們。

          其中許多圖書館甚至沒有遵循關(guān)于可用性和可訪問性的官方建議......

          例如:按 Escape 鍵應(yīng)該可以解除頁面上的對話框,但許多自定義對話框都不會這樣做。

          因此, <dialog> 改變了這一切。

          自動打開對話框

          open 屬性使對話框從打開頁面的那一刻起就一直處于打開狀態(tài):

          <dialog id="dialog" open>
            長頸鹿比人類更有可能被閃電擊中。事實(shí)上,它們的可能性是人類的30倍。
          </dialog>

          自動關(guān)閉按鈕

          是的,可以使用標(biāo)準(zhǔn)事件偵聽器和 close() 方法添加關(guān)閉功能:

          const close=document.querySelector('#dialog .close');
          
          close.addEventListener('click', ()=> {
            dialog.close();
          });

          但是內(nèi)置的 <dialog> 可以讓這一切變得更加簡單--無需 JavaScript:

          <dialog id="dialog">
            ? 在 codingbeautydev.com 獲取基本的編碼技能和知識
            <br />
            <form method="dialog">
              <button class="close">關(guān)閉</button>
            </form>
          </dialog>

          如何正確設(shè)計(jì)

          <dialog> 樣式

          <dialog> 有一個(gè)特殊的 ::backdrop 偽元素,用于設(shè)計(jì)背景墻的樣式:

          ::backdrop {
            background-image: linear-gradient(
              45deg,
              magenta,
              rebeccapurple,
              dodgerblue,
              green
            );
            opacity: 0.75;
          }

          主要元素的樣式簡單明了:

          dialog {
            background-color: black;
            color: white;
          }

          最后

          有了新的 HTML <dialog> 標(biāo)記,在我們的網(wǎng)絡(luò)應(yīng)用程序中創(chuàng)建模式和對話框變得前所未有的簡單和快捷。

          建Web游戲



          今天小編教大家如何用Python編程語言創(chuàng)建Web游戲,如果你能完成,你就可以算是一個(gè)能力相當(dāng)不錯(cuò)的Python初學(xué)者了。雖然還需要多讀一些書,多寫一些程序,不過你已經(jīng)具備進(jìn)一步學(xué)習(xí)的功底了。接下來的學(xué)習(xí)就只是時(shí)間、動力及資源的問題了。

          在這個(gè)習(xí)題中,我們不會去創(chuàng)建一個(gè)完整的游戲,相反,我們會為習(xí)題42中的游戲創(chuàng)建一個(gè)“引擎”(engine),讓這個(gè)游戲能夠在瀏覽器中運(yùn)行起來。這會涉及重構(gòu)習(xí)題42中的游戲,混合習(xí)題47中的結(jié)構(gòu),添加自動測試代碼,最后創(chuàng)建一個(gè)可以運(yùn)行這個(gè)游戲的Web引擎。

          這是一個(gè)很龐大的習(xí)題。預(yù)計(jì)你要花一周到一個(gè)月才能完成。最好的方法是一點(diǎn)一點(diǎn)來,每晚完成一點(diǎn),在進(jìn)行下一步之前確認(rèn)上一步已經(jīng)正確完成。

          重構(gòu)習(xí)題43中的游戲

          你已經(jīng)在兩個(gè)習(xí)題中修改了gothonweb項(xiàng)目,這個(gè)習(xí)題中會再修改一次。你學(xué)習(xí)的這種修改的技術(shù)叫做“重構(gòu)”,或者用我喜歡的講法來說,叫“修理”。重構(gòu)是一個(gè)編程術(shù)語,它指的是清理舊代碼或者為舊代碼添加新功能的過程。你其實(shí)已經(jīng)做過這樣的事情了,只不過不知道這個(gè)術(shù)語而已。重構(gòu)是軟件開發(fā)中經(jīng)歷的最習(xí)以為常的事情。

          在這個(gè)習(xí)題中你要做的是將習(xí)題47中的可以測試的房間地圖和習(xí)題43中的游戲這兩樣?xùn)|西合并到一起,創(chuàng)建一個(gè)新的游戲結(jié)構(gòu)。游戲的內(nèi)容不會發(fā)生變化,只不過我們會通過“重構(gòu)”讓它有一個(gè)更好的結(jié)構(gòu)而已。

          第一步是將ex47/game.py的內(nèi)容復(fù)制到gothonweb/map.py中,然后將tests/ex47_tests.py的內(nèi)容復(fù)制到tests/map_tests.py中,然后再次運(yùn)行nosetests,確認(rèn)它們還能正常工作。

          注意

          從現(xiàn)在開始,我不會再展示運(yùn)行測試的輸出了,我假設(shè)你會回去運(yùn)行這些測試,而且知道什么樣的輸出是正確的。

          將習(xí)題47的代碼復(fù)制完畢后,就該開始重構(gòu)它,讓它包含習(xí)題43中的地圖。我一開始會把基本結(jié)構(gòu)為你準(zhǔn)備好,然后你需要去完成map.py和map_tests.py里邊的內(nèi)容。

          首先要做的是用Room這個(gè)類來構(gòu)建地圖的基本結(jié)構(gòu)。

          map.py

          1  class Room(object):
          2  
          3      def __init__(self, name, description):
          4          self.name=name
          5          self.description=description
          6          self.paths=[]
          7  
          8      def go(self, direction):
          9           return self.paths.get(direction, None)
          10  
          11      def add_paths(self, paths):
          12           self.paths.update(paths)
          13  
          14  
          15  central_corridor=Room("Central Corridor",
          16  """
          17  The Gothons of Planet Percal #25 have invaded your ship and destroyed
          18  your entire crew.  You are the last surviving member and your last
          19  mission is to get the neutron destruct bomb from the Weapons Armory,
          20  put it in the bridge, and blow the ship up after getting into an 
          21  escape pod.
          22  
          23  You're running down the central corridor to the Weapons Armory when
          24  a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume
          25  flowing around his hate filled body.  He's blocking the door to the
          26  Armory and about to pull a weapon to blast you.
          27  """)
          28  
          29  
          30  laser_weapon_armory=Room("Laser Weapon Armory",
          31  """
          32  Lucky for you they made you learn Gothon insults in the academy.
          33  You tell the one Gothon joke you know:
          34  Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr.
          35  The Gothon stops, tries not to laugh, then busts out laughing and can't move.
          36  While he's laughing you run up and shoot him square in the head
          37  putting him down, then jump through the Weapon Armory door.
          38  
          39  You do a dive roll into the Weapon Armory, crouch and scan the room
          40  for more Gothons that might be hiding.  It's dead quiet, too quiet.
          41  You stand up and run to the far side of the room and find the
          42  neutron bomb in its container.  There's a keypad lock on the box
          43  and you need the code to get the bomb out.  If you get the code
          44  wrong 10 times then the lock closes forever and you can't
          45  get the bomb.  The code is 3 digits.
          46  """)
          47  
          48  
          49  the_bridge=Room("The Bridge",
          50  """
          51  The container clicks open and the seal breaks, letting gas out.
          52  You grab the neutron bomb and run as fast as you can to the
          53  bridge where you must place it in the right spot.
          54  
          55  You burst onto the Bridge with the netron destruct bomb
          56  under your arm and surprise 5 Gothons who are trying to
          57  take control of the ship.  Each of them has an even uglier
          58  clown costume than the last.  They haven't pulled their
          59  weapons out yet, as they see the active bomb under your
          60  arm and don't want to set it off.
          61  """)
          62  
          63  
          64  escape_pod=Room("Escape Pod",
          65  """
          66  You point your blaster at the bomb under your arm
          67  and the Gothons put their hands up and start to sweat.
          68  You inch backward to the door, open it, and then carefully
          69  place the bomb on the floor, pointing your blaster at it.
          70  You then jump back through the door, punch the close button
          71  and blast the lock so the Gothons can't get out.
          72  Now that the bomb is placed you run to the escape pod to
          73  get off this tin can.
          74  
          75  You rush through the ship desperately trying to make it to
          76  the escape pod before the whole ship explodes.  It seems like
          77  hardly any Gothons are on the ship, so your run is clear of
          78  interference.  You get to the chamber with the escape pods, and
          79  now need to pick one to take.  Some of them could be damaged
          80  but you don't have time to look.  There's 5 pods, which one
          81  do you take?
          82  """)
          83  
          84  
          85  the_end_winner=Room("The End",
          86  """
          87  You jump into pod 2 and hit the eject button.
          88  The pod easily slides out into space heading to
          89  the planet below.  As it flies to the planet, you look
          90  back and see your ship implode then explode like a
          91  bright star, taking out the Gothon ship at the same
          92  time.  You won!
          93  """)
          94  
          95  
          96  the_end_loser=Room("The End",
          97  """
          98  You jump into a random pod and hit the eject button.
          99  The pod escapes out into the void of space, then
          100  implodes as the hull ruptures, crushing your body
          101  into jam jelly.
          102  """
          103  )
          104  
          105  escape_pod.add_paths({
          106      '2': the_end_winner,
          107      '*': the_end_loser
          108  })
          109  
          110  generic_death=Room("death", "You died.")
          111  
          112  the_bridge.add_paths({
          113      'throw the bomb': generic_death,
          114      'slowly place the bomb': escape_pod
          115  })
          116  
          117  laser_weapon_armory.add_paths({
          118      '0132': the_bridge,
          119      '*': generic_death
          120  })
          121  
          122  central_corridor.add_paths({
          123      'shoot!': generic_death,
          124      'dodge!': generic_death,
          125      'tell a joke': laser_weapon_armory
          126  })
          127  
          128  START=central_corridor

          你會發(fā)現(xiàn)Room類和地圖有一些問題。

          1.我們必須把以前放在if-else結(jié)構(gòu)中的房間描述做成每個(gè)房間的一部分。這樣房間的次序就不會被打亂了,這對我們的游戲是一件好事。這是你后面要修改的東西。

          2.原版游戲中我們使用了專門的代碼來生成一些內(nèi)容,如炸彈的激活鍵碼、艦艙的選擇等,這次我們做游戲時(shí)就先使用默認(rèn)值好了,不過后面的附加練習(xí)里,我會要求你把這些功能再加到游戲中。

          3.我為游戲中所有錯(cuò)誤決策的失敗結(jié)尾寫了一個(gè)generic_death,你需要去補(bǔ)全這個(gè)函數(shù)。你需要把原版游戲中所有的場景結(jié)局都加進(jìn)去,并確保代碼能正確運(yùn)行。

          4.我添加了一種新的轉(zhuǎn)換模式,以"*"為標(biāo)記,用來在游戲引擎中實(shí)現(xiàn)“捕獲所有操作”的功能。

          等把上面的代碼基本寫好以后,接下來就是你必須繼續(xù)寫的自動測試tests/map_test.py了。

          map_tests.py

          1  from nose.tools import *
          2  from gothonweb.map import *
          3  
          4  def test_room():
          5       gold=Room("GoldRoom", 
          6                      """This room has gold in it you can grab. There's a
          7                      door to the north.""")
          8       assert_equal(gold.name, "GoldRoom")
          9       assert_equal(gold.paths, {})
          10  
          11  def test_room_paths():
          12      center=Room("Center", "Test room in the center.")
          13      north=Room("North", "Test room in the north.")
          14      south=Room("South", "Test room in the south.")
          15  
          16      center.add_paths({'north': north, 'south': south})
          17      assert_equal(center.go('north'), north)
          18      assert_equal(center.go('south'), south)
          19  
          20  def test_map():
          21      start=Room("Start", "You can go west and down a hole.")
          22      west=Room("Trees", "There are trees here, you can go east.")
          23      down=Room("Dungeon", "It's dark down here, you can go up.")
          24  
          25      start.add_paths({'west': west, 'down': down})
          26      west.add_paths({'east': start})
          27      down.add_paths({'up': start})
          28  
          29      assert_equal(start.go('west'), west)
          30      assert_equal(start.go('west').go('east'), start)
          31      assert_equal(start.go('down').go('up'), start)
          32  
          33  def test_gothon_game_map():
          34      assert_equal(START.go('shoot!'), generic_death)
          35      assert_equal(START.go('dodge!'), generic_death)
          36  
          37      room=START.go('tell a joke')
          38      assert_equal(room, laser_weapon_armory)

          你在這個(gè)習(xí)題中的任務(wù)是完成地圖,并且讓自動測試可以完整地檢查整個(gè)地圖。這包括將所有的generic_death對象修正為游戲中實(shí)際的失敗結(jié)尾。讓你的代碼成功運(yùn)行起來,并讓你的測試越全面越好。后面我們會對地圖做一些修改,到時(shí)候這些測試將用來確保修改后的代碼還可以正常工作。

          會話和用戶跟蹤

          在Web應(yīng)用程序運(yùn)行的某個(gè)位置,你需要追蹤一些信息,并將這些信息和用戶的瀏覽器關(guān)聯(lián)起來。在HTTP協(xié)議的框架中,Web環(huán)境是“無狀態(tài)”的,這意味著你的每一次請求和你的其他請求都是相互獨(dú)立的。如果你請求了頁面A,輸入了一些數(shù)據(jù),然后點(diǎn)了一個(gè)頁面B的鏈接,那你發(fā)送給頁面A的數(shù)據(jù)就全部消失了。

          解決這個(gè)問題的方法是為Web應(yīng)用程序建立一個(gè)很小的數(shù)據(jù)存儲,給每個(gè)瀏覽器進(jìn)程賦予一個(gè)獨(dú)一無二的數(shù)字,用來跟蹤瀏覽器所做的事情。這個(gè)存儲通常用數(shù)據(jù)庫或者存儲在磁盤上的文件來實(shí)現(xiàn)。在lpthw.web這個(gè)小框架中實(shí)現(xiàn)這樣的功能是很容易的,下面就是一個(gè)這樣的例子。

          session.sample.py

          1  import web
          2  
          3  web.config.debug=False
          4  
          5  urls=(
          6        "/count", "count",
          7        "/reset", "reset"
          8  )
          9  app=web.application(urls, locals())
          10  store=web.session.DiskStore('sessions')
          11  session=web.session.Session(app, store, initializer=['count': 0])
          12  
          13  class count:
          14       def GET(self):
          15            session.count +=1
          16            return str(session.count)
          17  
          18  class reset:
          19       def GET(self):
          20            session.kill()
          21            return ""
          22  
          23  if __name__=="__main__":
          24      app.run()

          為了實(shí)現(xiàn)這個(gè)功能,需要創(chuàng)建一個(gè)sessions/文件夾作為程序的會話存儲位置,創(chuàng)建好以后運(yùn)行這個(gè)程序,然后檢查/count頁面,刷新一下這個(gè)頁面,看計(jì)數(shù)會不會累加上去。關(guān)掉瀏覽器后,程序就會“忘掉”之前的位置,這也是我們的游戲所需的功能。有一種方法可以讓瀏覽器永遠(yuǎn)記住一些信息,不過這會讓測試和開發(fā)變得更難。如果你回到/reset頁面,然后再訪問/count頁面,你可以看到你的計(jì)數(shù)器被重置了,因?yàn)槟阋呀?jīng)關(guān)掉了這個(gè)會話。

          你需要花點(diǎn)時(shí)間弄懂這段代碼,注意會話開始時(shí)count的值是如何設(shè)為0的,另外再看看sessions/下面的文件,看能不能打開。下面是我打開一個(gè)Python會話并解碼的過程:

          >>> import pickle
          >>> import base64
          >>> base64.b64decode(open("sessions/XXXXX").read())
          "(dp1\nS'count'\np2\nI1\nsS'ip'\np3\nV127.0.0.1\np4\nsS'session_id'\np5\nS'XXXX'\np6\ns."
          >>>
          >>> x=base64.b64decode(open("sessions/XXXXX").read())
          >>>
          >>> pickle.loads(x)
          {'count': 1, 'ip': u'127.0.0.1', 'session_id': 'XXXXX'}

          所以,會話其實(shí)就是使用pickle和base64這些庫寫到磁盤上的字典。存儲和管理會話的方法很多,大概和Python的Web框架那么多,所以了解它們的工作原理并不是很重要。當(dāng)然如果你需要調(diào)試或者清空會話,知道點(diǎn)兒原理還是有用的。

          創(chuàng)建引擎

          你應(yīng)該已經(jīng)寫好了游戲地圖和它的單元測試代碼。現(xiàn)在要你制作一個(gè)簡單的游戲引擎,用來讓游戲中的各個(gè)房間運(yùn)轉(zhuǎn)起來,從玩家收集輸入,并且記住玩家所在的位置。我們將用到你剛學(xué)過的會話來制作一個(gè)簡單的引擎,讓它可以:

          1.為新用戶啟動新的游戲;

          2.將房間展示給用戶;

          3.接收用戶的輸入;

          4.在游戲中處理用戶的輸入;

          5.顯示游戲的結(jié)果,繼續(xù)游戲,直到玩家角色死亡為止。

          為了創(chuàng)建這個(gè)引擎,你需要將bin/app.py搬過來,創(chuàng)建一個(gè)功能完備的、基于會話的游戲引擎。這里的難點(diǎn)是,我會先使用基本的HTML文件創(chuàng)建一個(gè)非常簡單的版本,接下來將由你完成它。基本的引擎是下面這個(gè)樣子的:

          app.py

          1  import web
          2  from gothonweb import map
          3  
          4  urls=(
          5      '/game', 'GameEngine',
          6      '/', 'Index',
          7  )
          8  
          9  app=web.application(urls, globals())
          10  
          11  # little hack so that debug mode works with sessions
          12  if web.config.get('_session') is None:
          13        store=web.session.DiskStore('sessions')
          14        session=web.session.Session(app, store,
          15                                            initializer=['room': None])
          16      web.config._session=session
          17  else:
          18       session=web.config._session
          19  
          20  render=web.template.render('templates/', base="layout")
          21  
          22  
          23  class Index(object):
          24       def GET(self):
          25          # this is used to "setup" the session with starting values
          26          session.room=map.START
          27          web.seeother("/game")
          28  
          29  
          30  class GameEngine(object):
          31  
          32      def GET(self):
          33           if session.room:
          34                return render.show_room(room=session.room)
          35           else:
          36              # why is there here? do you need it?
          37              return render.you_died()
          38  
          39      def POST(self):
          40           form=web.input(action=None)
          41  
          42          # there is a bug here, can you fix it?
          43          if session.room and form.action:
          44               session.room=session.room.go(form.action)
          45  
          46          web.seeother("/game")
          47  
          48  if __name__=="__main__":
          49      app.run()

          在這個(gè)腳本里你可以看到更多的新東西,不過了不起的事情是,整個(gè)基于網(wǎng)頁的游戲引擎只要一個(gè)小文件就可以做到了。這段腳本里最有技術(shù)含量的就是將會話帶回來的那幾行,這對于調(diào)試模式下的代碼重載是必需的,否則每次刷新網(wǎng)頁,會話就會消失,游戲也不會再繼續(xù)了。

          在運(yùn)行bin/app.py之前,你需要修改PYTHONPATH環(huán)境變量。不知道什么是環(huán)境變量?要運(yùn)行一個(gè)最基本的Python程序,你就得學(xué)會環(huán)境變量,用Python的人就喜歡這樣:

          在終端輸入下面的內(nèi)容:

          export PYTHONPATH=$PYTHONPATH:.

          如果用的是Windows,那就在PowerShell中輸入以下內(nèi)容:

          $env:PYTHONPATH="$env:PYTHONPATH;."

          你只要針對每一個(gè)shell會話輸入一次就可以了,不過如果你運(yùn)行Python代碼時(shí)看到了導(dǎo)入錯(cuò)誤,那就需要去執(zhí)行一下上面的命令,或者是因?yàn)槟闵洗螆?zhí)行的有錯(cuò)才導(dǎo)致導(dǎo)入錯(cuò)誤的。

          接下來需要刪掉templates/hello_form.html和templates/index.html,然后重新創(chuàng)建上面代碼中提到的兩個(gè)模板。下面是一個(gè)非常簡單的templates/show_room.html,供你參考。

          show_room.html

          $def with (room)
          
          <h1> $room.name </h1>
          
          <pre>
          $room.description
          </pre>
          
          $if room.name=="death":
              <p><a href="/">Play Again?</a></p>
          $else:
              <p>
              <form action="/game" method="POST">
                  - <input type="text" name="action"> <input type="SUBMIT">
              </form>
              </p>

          這就用來顯示游戲中的房間的模板。接下來,你需要在用戶跑到地圖的邊界時(shí),用一個(gè)模板告訴用戶,他的角色的死亡信息,也就是templates/you_died.html這個(gè)模板。

          you_died.html

          <h1>You Died!</h1>
          
          <p>Looks like you bit the dust.</p>
          <p><a href="/">Play Again</a></p>

          準(zhǔn)備好這些文件就可以做下面的事情了。

          1.再次運(yùn)行測試代碼tests/app_tests.py,這樣就可以測試這個(gè)游戲。由于會話的存在,你可能頂多只能實(shí)現(xiàn)幾次點(diǎn)擊,不過你應(yīng)該可以做出一些基本的測試來。

          2.刪除sessions/*下的文件,再重新運(yùn)行一遍游戲,確認(rèn)游戲是從一開始運(yùn)行的。

          3. 運(yùn)行python bin/app.py腳本,試玩一下你的游戲。

          你需要和往常一樣刷新和修正你的游戲,慢慢修改游戲的HTML文件和引擎,直到實(shí)現(xiàn)游戲需要的所有功能為止。

          期末考試

          你有沒有覺得我一下子給了你超多的信息呢?那就對了,我想要你在學(xué)習(xí)技能的同時(shí)有一些可以用來鼓搗的東西。為了完成這個(gè)習(xí)題,我將給你最后一套需要你自己完成的練習(xí)。你會注意到,到目前為止你寫的游戲并不是很好,這只是你的第一版代碼而已,你現(xiàn)在的任務(wù)就是讓游戲更加完善,實(shí)現(xiàn)下面的這些功能。

          1.修正代碼中所有我提到和沒提到的bug,如果你發(fā)現(xiàn)了新bug,你可以告訴我。

          2.改進(jìn)所有的自動測試,以便可以測試更多的內(nèi)容,直到你可以不用瀏覽器就能測到所有的內(nèi)容為止。

          3.讓HTML頁面看上去更美觀一些。

          4.研究一下網(wǎng)頁登錄系統(tǒng),為這個(gè)程序創(chuàng)建一個(gè)登錄界面,這樣人們就可以登錄這個(gè)游戲,并且可以保存游戲高分。

          5.完成游戲地圖,盡可能地把游戲做大,功能做全。

          6.給用戶一個(gè)“幫助系統(tǒng)”,讓他們可以查詢每個(gè)房間里可以執(zhí)行哪些命令。

          7.為游戲添加新功能,想到什么功能就添加什么功能。

          8.創(chuàng)建多個(gè)地圖,讓用戶可以選擇他們想要玩的一張地圖來進(jìn)行游戲。你的bin/app.py應(yīng)該可以運(yùn)行提供給它的任意地圖,這樣你的引擎就可以支持多個(gè)不同的游戲。

          9.最后,使用在習(xí)題48和習(xí)題49中學(xué)到的東西創(chuàng)建一個(gè)更好的輸入處理器。你手頭已經(jīng)有了大部分必要的代碼,只需要改進(jìn)語法,讓它和你的輸入表單以及游戲引擎掛鉤即可。

          祝你好運(yùn)!

          常見問題回答

          我在游戲中用了會話(`session)`,不能用nosetests測試。

          你需要閱讀并了解帶reloader的會話:http://webpy.org/cookbook/session_with_reloader。

          我看到了ImportError。

          錯(cuò)誤路徑,錯(cuò)誤Python版本,PYTHONPATH沒設(shè)置對,漏了__init__.py文件,拼寫錯(cuò)誤,都檢查一下吧。

          近期的新聞中,當(dāng)《賽博朋克2077》對AMD處理器優(yōu)化不好的時(shí)候,有人祭出了終極大法——修改執(zhí)行文件!對很多玩家來說,這個(gè)修改過程能看懂,但它提供的那一串代碼到底是什么?它代表的16進(jìn)制又是啥意思?可能很多新晉玩家就不知道了,那咱們今天就來說說這事兒吧。

          16進(jìn)制就是以0~F代表0~15的一種表達(dá)方式,在修改時(shí)看到的一般是兩個(gè)一組,可以表達(dá)0(00)~255(FF)。相對于二進(jìn)制的0,1,它可以在較短的代碼內(nèi)更多的信息,比如255擁16進(jìn)制寫成FF,二進(jìn)制就要寫成11111111(不用數(shù)了,是8個(gè)1)。顯然16進(jìn)制用來一些表達(dá)一些復(fù)雜設(shè)置、大型數(shù)字更方便。

          因?yàn)檫@個(gè)優(yōu)勢,所以很多游戲會使用16進(jìn)制來表達(dá)數(shù)字,比如有些老游戲中會看到最高級別、屬性、最高人數(shù)是15、255、65535(FFFF)等比較怪的數(shù)字。這有沒有讓你有點(diǎn)聯(lián)想?沒錯(cuò),了解16進(jìn)制之后就可以修改這些屬性了。

          這里要注意三個(gè)問題,首先是10進(jìn)制的轉(zhuǎn)換,我們可以使用https://tool.lu/hexconvert/等在線轉(zhuǎn)換工具。其次是順序問題,有些文件中的16進(jìn)制排列是反向的,比如65534應(yīng)該表達(dá)為FF FE,但在有些文件中是FE FF。最后就是在修改時(shí)一定一定要注意備份文件,一旦修改了錯(cuò)誤位置,輕則屬性混亂,重則存檔甚至整個(gè)游戲都無法打開。

          然后就是具體的修改方法了,我們選擇的是目前比較流行的16進(jìn)制編輯工具,UltraEdit旗下的hex-editor(https://www.ultraedit.com/language/hex-editor.html)。以前面提到的《賽博朋克2077》優(yōu)化設(shè)置為例,安裝hex-editor并用它打開Cyberpunk2077.exe。

          然后我們必須確定相關(guān)的整個(gè)字符串,比如75 30 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08,這樣才能更好地確定修改位置,盡量避免改錯(cuò)。然后選擇“Edit→Find”功能,輸入這串字符,找到相關(guān)位置,當(dāng)然不一定要輸全也可能找到位置,但也必須確認(rèn)后續(xù)字符完全相同。之后把字符串頭部的75改成EB,存檔就好了。

          至于存檔文件就更簡單了,可以選擇一個(gè)比較大而且容易變化的數(shù)字,比如軍糧數(shù)量,存檔后在存檔文件里用16進(jìn)制字符查找,記下來位置。然后減少或增加軍糧,再次存檔,看看之前記下的位置中,哪一個(gè)數(shù)據(jù)變成了新的數(shù)量,之后修改并載入試試看。這里要注意的是,一個(gè)數(shù)據(jù)可能會存在多處,如果多次嘗試發(fā)現(xiàn)幾個(gè)地方的數(shù)據(jù)都在同時(shí)變化,那么就都修改好了。

          最后有個(gè)超超超級重要的事要說明,修改屬性、數(shù)量等參數(shù)的方法只適用于純粹的單機(jī)游戲或者僅聯(lián)網(wǎng)進(jìn)行正版授權(quán)驗(yàn)證的游戲。對于網(wǎng)游或者一些存檔會在網(wǎng)上備份的聯(lián)網(wǎng)“單機(jī)”游戲來說,這樣的修改不僅很可能不奏效,而且還可能涉及作弊,會被平臺懲罰,小伙伴們就千萬不要嘗試?yán)病?/span>


          主站蜘蛛池模板: а天堂中文最新一区二区三区| 在线电影一区二区| 蜜臀Av午夜一区二区三区| 亚洲高清毛片一区二区| 中文字幕一区二区三区有限公司| 日韩人妻精品无码一区二区三区| AV无码精品一区二区三区| 日本韩国一区二区三区| 日本免费电影一区| 国产免费播放一区二区| 国精产品一区一区三区免费视频| 无码av免费一区二区三区| 相泽南亚洲一区二区在线播放| 亚洲中文字幕丝袜制服一区| 无码人妻久久一区二区三区| 亚无码乱人伦一区二区| 久久se精品一区二区影院| 亚洲午夜在线一区| www一区二区三区| 骚片AV蜜桃精品一区| 深夜福利一区二区| 精品无码一区二区三区爱欲九九| 国产精品视频免费一区二区| 国产日韩精品一区二区三区在线 | 无码av免费一区二区三区| 日本一区二区三区久久| 无码人妻精品一区二区三区久久| 日韩美女在线观看一区| 亚洲视频免费一区| 国产免费一区二区三区不卡 | 91久久精品国产免费一区| 日本夜爽爽一区二区三区| 精品国产AV一区二区三区| 激情内射日本一区二区三区| 无码人妻精一区二区三区| 中文字幕在线看视频一区二区三区 | 国产精品日韩欧美一区二区三区| 手机看片一区二区| 极品少妇伦理一区二区| 国产精品无码一区二区三区不卡| 久久一区二区精品|