开心六月综合激情婷婷|欧美精品成人动漫二区|国产中文字幕综合色|亚洲人在线成视频

    1. 
      
        <b id="zqfy3"><legend id="zqfy3"><fieldset id="zqfy3"></fieldset></legend></b>
          <ul id="zqfy3"></ul>
          <blockquote id="zqfy3"><strong id="zqfy3"><dfn id="zqfy3"></dfn></strong></blockquote>
          <blockquote id="zqfy3"><legend id="zqfy3"></legend></blockquote>
          打開APP
          userphoto
          未登錄

          開通VIP,暢享免費電子書等14項超值服

          開通VIP
          用Python和Pygame寫游戲

          我們終于把pygame的方方面面都說了一遍,也經過了兩個小游戲的洗禮,如果您真的好好學習了每一部分并自動動手演練過,那就是一個很不錯的Python游戲開發(fā)人員啦!

          但是,不得不說我們到現(xiàn)在為止,寫的東西都不夠酷!pygame就這點能耐么?第一篇介紹pygame的時候,我就說了pygame很適合做一個植物大戰(zhàn)僵尸之類的游戲,OK,那么,這次開始我們就來用pygame山寨一個吧哈哈。

          游戲介紹就省略了,不過說實話這游戲我也沒玩幾關,感受了一下就關了。所以現(xiàn)在仿制的與真品相比肯定差了很多,這里只是稍微把我們學習的東西溫習應用一下而已,如果各位看到什么不對勁兒的東西,只要不是很致命,也就一笑而過吧。

          創(chuàng)意(抄襲)

          游戲是否賣座,創(chuàng)意是極為重要的。所有其他技術性的東西,比如畫面音樂都是有可替代性的,也就是說,可以通過學習獲得的,而創(chuàng)意則不同,植物大戰(zhàn)僵尸之前,有無數(shù)的塔防游戲,為什么沒有這么火?首先制作精良,上手容易,然后兩者的結合給人耳目一新,闖關的模式更是易于上手難于精通,非常具有可挖掘性。當然原因肯定不止這么多,不管是游戲還是電影,成功永遠有規(guī)律可循,然而卻永遠無法復制??梢詫W習一下它的好的地方,但光學習是不可能突破的。

          這個雖然極為重要,但不是我們的重點,我們這里基本就是抄襲——哦不,是參考,所以就不多講了(也沒有人能講出什么東西來)。

          資源

          好的游戲往往需要極為漂亮的畫面,這里也還是發(fā)揮拿來主義吧~ 各種背景角色啊音樂都解包復制過來就是了。怎么解包?網上搜一下。

          不過如果分析一下資源包里的文件,會發(fā)現(xiàn)它分的特別細,比如說一個太陽花,周圍一圈花瓣,居然是一個一個分開來存放的!這個引擎還挺有意思。我們的pygame不太適合用這樣的圖片資源,還是把每一幀完整的分別存放吧。當然可以一幀一個文件,有些麻煩,還增加讀盤時間?;叵胂耂urface里學習的東西,我們可以把這么多幀拼成一個圖片,然后取一部分就可以了。比如說太陽花,處理以后會是下面的樣子:

          每個幀都并列排開,太陽花的話一共有18個畫面,很長的一張圖。每個畫面都有共同的高度和寬度,所以一旦我們讀進這個文件并轉成Surface以后,就拆成18個Subsurface,在渲染的時候,分別畫出來,就有動態(tài)的效果了。

          很顯然我們在分割的時候需要知道寬度(高度的話,如果只有一行,就無所謂了),可以在代碼里寫好,我這里就是這么做的。不過也許自己在寫游戲的時候,美工和程序不在一起做,那么就需要良好溝通,或者這種小制作的話,就把圖片文件名規(guī)定一下,叫【sunflower_82x77_18.png】好了,意思是【名字_寬x高_數(shù).后綴】,這樣代碼可以根據讀入的文件名自動轉換。只是舉個例子,總之,游戲資源繁多,好好的管理是很重要的。

          構架

          因為只是做一個demo,太復雜的構架也就免了,這次我就隨便寫寫了。而且也沒有什么絕對優(yōu)秀的構架可以放到哪里都好用,根據要求自己選擇判斷才是重要的。

          開始——太陽花擺起來

          我們之前的各種動畫,變化的只有位置,在一款優(yōu)秀的游戲中,這個是不允許存在的,飛機什么的可能還好說一些,要是有人物走動的時候,腳也不動一下豈不見鬼了?不過,難道每畫一幀就換一個圖片貼上去么?好像很麻煩啊……

          放心,一點都不比移動困難,溫習一下之前的Sprite篇(其實AI部分結束那個時候我就開始穿插寫實戰(zhàn)了,發(fā)現(xiàn)缺少Sprite的知識實在不方便,就加了一個Sprite的介紹,實戰(zhàn)就挪到了最后),我們既然把畫圖全部交給Sprite來做,那么圖片的切換也可以交給它來做。

          Python
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          MAIN_DIR = os.path.split(os.path.abspath(__file__))[0]
          def load_image(file, width=None, number=None):
              file = os.path.join(MAIN_DIR, 'data/image', file)
              try:
                  surface = pygame.image.load(file).convert_alpha()
              except pygame.error:
                  raise SystemExit('Could not load image "%s" %s'%(file, pygame.get_error()))
              if width == None:
                  return surface
              height = surface.get_height()
              return [surface.subsurface(
                  Rect((i * width, 0), (width, height))
                  ) for i in xrange(number)]
          class SunFlower(pygame.sprite.Sprite):
              _width = 82
              _height = 77
              _number = 18
              images = []
              def __init__(self):
                  self.order = 0
                  pygame.sprite.Sprite.__init__(self)
                  if len(self.images) == 0:
                      self.images = load_image("sunflower.png", self._width, self._number)
                  self.image = self.images[self.order]
                  self.rect = Rect(0, 0, self._width, self._height)
              def update(self):
                  if self.order >= self._number - 1:
                      self.order = -1
                  self.order += 1
                  self.image = self.images[self.order]

          這里有兩個內容,一個是load_image函數(shù),它接受三個參數(shù),圖片文件名、每一幀的寬度和總幀數(shù),它所做的事情就是把圖片讀入之后分割Subsurface,把一個Subsurface的列表返回。這個函數(shù)被SunFlower類的初始化函數(shù)調用,返回值存放在靜態(tài)變量images里。

          為什么把Subsurface列表存為靜態(tài)變量,也是有含義的。這樣一來這個圖片只會第一次新建SunFlower類的實例的時候加載一次,下一次在新建一個太陽花的時候,就不會再讀取sunflower.png文件了,節(jié)約內存和時間。

          然后看update方法,這里做的事情便是是SunFlower當前的image指向下一個Subsurface(到頭的話重新開始),這樣每次blit的時候,就會和上一次有些差別,動態(tài)效果就出來了。

          不過對于“基于時間的移動”那部分學習的比較好的話,很肯會考慮到一個問題。我們這里是一幀切換一個畫面,萬一游戲變得很復雜或者運行的機器很糟糕,每一幀都花了大量時間的話,豈不是就動的很慢了?牛機器上的話,又要擺的像螺旋槳一樣看著就要飛起來似地……怎么辦?一樣,使用基于時間的幀切換!

          Python
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          class SunFlower(pygame.sprite.Sprite):
              _rate = 100
              _width = 82
              _height = 77
              _number = 18
              images = []
              def __init__(self):
                  self.order = 0
                  pygame.sprite.Sprite.__init__(self)
                  if len(self.images) == 0:
                      self.images = load_image("sunflower.png", self._width, self._number)
                  self.image = self.images[self.order]
                  self.rect = Rect(0, 0, self._width, self._height)
                  self.life = self._life
                  self.passed_time = 0
              def update(self, passed_time):
                  self.passed_time += passed_time
                  self.order = ( self.passed_time / self._rate ) % self._number
                  if self.order == 0 and self.passed_time > self._rate:
                      self.passed_time = 0
                  self.image = self.images[self.order]

          與上一個SunFlower類相比,我們多了一個_rate靜態(tài)變量,然后初始化的時候也多了一個passed_time靜態(tài)變量,update也多了一個參數(shù)。盡管看起來有變得復雜了一些,這一切都是值得的!_rate意味著一幀畫面要保持多少毫秒,passed_time則記錄著游戲經過了多少毫秒(為了避免passed_time無限增大,我在合適的時候把它歸零了),我們通過這兩個參數(shù)計算出現(xiàn)在應該顯示第幾幀,盡管形式不同,這和基于時間的移動是一個道理。希望大家能看明白(不明白的話多看幾遍……再看不明白的去復習第8部分,再不明白的,面壁去……哦,我是說咱倆都得去面壁)。

          這里不就先不給出完整的程序了,相信有了前面的經驗很容易就可以寫一個框子運行起來,自己試一下?如果你能看到類似左邊的畫面,你就贏了!準備迎接下一波驚喜吧。

          如果沒能成功的運行起來(雖然似乎有點不應該),也沒關系,這個系列完成以后會放出完整代碼的。

          本次使用的太陽花資源圖片: sunflower.png

          本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
          打開APP,閱讀全文并永久保存 查看更多類似文章
          猜你喜歡
          類似文章
          用 Python 寫個坦克大戰(zhàn)
          使用跨平臺Python模塊Pygame ---- 飛機大戰(zhàn)微信小游戲
          牛逼了!Python 開發(fā)植物大戰(zhàn)僵尸游戲
          詳解pygame中的精靈和精靈組
          Python 游戲編程之實現(xiàn)飛機大戰(zhàn)(含源代碼)
          Python實現(xiàn)超級瑪麗游戲系列教程01瑪麗登場
          更多類似文章 >>
          生活服務
          分享 收藏 導長圖 關注 下載文章
          綁定賬號成功
          后續(xù)可登錄賬號暢享VIP特權!
          如果VIP功能使用有故障,
          可點擊這里聯(lián)系客服!

          聯(lián)系客服