乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      用Python和Pygame寫游戲

       gljin_cn 2014-09-15

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

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

      pygame版植物大戰(zhàn)僵尸

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

      創(chuàng)意(抄襲)

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

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

      資源

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

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

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

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

      構(gòu)架

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

      開始——太陽花擺起來

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

      放心,一點都不比移動困難,溫習(xí)一下之前的Sprite篇(其實AI部分結(jié)束那個時候我就開始穿插寫實戰(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]

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

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

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

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

      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ù)。盡管看起來有變得復(fù)雜了一些,這一切都是值得的!_rate意味著一幀畫面要保持多少毫秒,passed_time則記錄著游戲經(jīng)過了多少毫秒(為了避免passed_time無限增大,我在合適的時候把它歸零了),我們通過這兩個參數(shù)計算出現(xiàn)在應(yīng)該顯示第幾幀,盡管形式不同,這和基于時間的移動是一個道理。希望大家能看明白(不明白的話多看幾遍……再看不明白的去復(fù)習(xí)第8部分,再不明白的,面壁去……哦,我是說咱倆都得去面壁)。

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

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

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

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約