<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 寫個消消樂小游戲

          共 6728字,需瀏覽 14分鐘

           ·

          2020-07-29 08:26

          332f5003e6c7920c46ae58c481121733.webp

          文 |?野客

          來源:Python 技術(shù)「ID: pythonall」

          c99a069a636da83f94c6884f0aa8f896.webp


          提到開心消消樂這款小游戲,相信大家都不陌生,其曾在 2015 年獲得過玩家最喜愛的移動單機游戲獎,受歡迎程度可見一斑,本文我們使用 Python 來做個簡單的消消樂小游戲。

          實現(xiàn)

          消消樂的構(gòu)成主要包括三部分:游戲主體、計分器、計時器,下面來看一下具體實現(xiàn)。

          先來看一下游戲所需 Python 庫。

          import osimport sysimport timeimport pygameimport random

          定義一些常量,比如:窗口寬高、網(wǎng)格行列數(shù)等,代碼如下:

          WIDTH = 400HEIGHT = 400NUMGRID = 8GRIDSIZE = 36XMARGIN = (WIDTH - GRIDSIZE * NUMGRID) // 2YMARGIN = (HEIGHT - GRIDSIZE * NUMGRID) // 2ROOTDIR = os.getcwd()FPS = 30

          接著創(chuàng)建一個主窗口,代碼如下:

          pygame.init()screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption('消消樂')

          看一下效果:

          2e676e7d3d8b8a41bc0b363038647321.webp

          再接著在窗口中畫一個 8 x 8 的網(wǎng)格,代碼如下:

          screen.fill((255, 255, 220))# 游戲界面的網(wǎng)格繪制def drawGrids(self): for x in range(NUMGRID):       for y in range(NUMGRID):           rect = pygame.Rect((XMARGIN+x*GRIDSIZE, YMARGIN+y*GRIDSIZE, GRIDSIZE, GRIDSIZE))           self.drawBlock(rect, color=(255, 165, 0), size=1# 畫矩形 block 框def drawBlock(self, block, color=(255, 0, 0), size=2):  pygame.draw.rect(self.screen, color, block, size)

          看一下效果:

          74a35193a3ef4ccdb1f1768c53c8b10c.webp

          再接著在網(wǎng)格中隨機放入各種拼圖塊,代碼如下:

          while True: self.all_gems = [] self.gems_group = pygame.sprite.Group()    for x in range(NUMGRID):       self.all_gems.append([])       for y in range(NUMGRID):           gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+x*GRIDSIZE, YMARGIN+y*GRIDSIZE-NUMGRID*GRIDSIZE], downlen=NUMGRID*GRIDSIZE)           self.all_gems[x].append(gem)           self.gems_group.add(gem)   if self.isMatch()[0] == 0:     break

          看一下效果:

          2c03bb92247f277c697bd87448c483bd.webp

          再接著加入計分器和計時器,代碼如下:

          # 顯示得分def drawScore(self):  score_render = self.font.render('分數(shù):'+str(self.score), 1, (85, 65, 0)) rect = score_render.get_rect() rect.left, rect.top = (55, 15) self.screen.blit(score_render, rect)# 顯示加分def drawAddScore(self, add_score): score_render = self.font.render('+'+str(add_score), 1, (255, 100, 100))    rect = score_render.get_rect() rect.left, rect.top = (250, 250)   self.screen.blit(score_render, rect)# 顯示剩余時間def showRemainingTime(self): remaining_time_render = self.font.render('倒計時: %ss' % str(self.remaining_time), 1, (85, 65, 0))    rect = remaining_time_render.get_rect()    rect.left, rect.top = (WIDTH-190, 15)  self.screen.blit(remaining_time_render, rect)

          看一下效果:

          0ed6f47ed89be5000dc8a4f1cccbe1b5.webp

          當(dāng)設(shè)置的游戲時間用盡時,我們可以生成一些提示信息,代碼如下:

          while True: for event in pygame.event.get():       if event.type == pygame.QUIT:          pygame.quit()          sys.exit()     if event.type == pygame.KEYUP and event.key == pygame.K_r:         flag = True    if flag:       break  screen.fill((255, 255, 220))   text0 = '最終得分: %s' % score text1 = '按 R 鍵重新開始'    y = 140    for idx, text in enumerate([text0, text1]):        text_render = font.render(text, 1, (85, 65, 0))        rect = text_render.get_rect()      if idx == 0:           rect.left, rect.top = (100, y)     elif idx == 1:         rect.left, rect.top = (100, y)     y += 60        screen.blit(text_render, rect) pygame.display.update()

          看一下效果:

          a29ab5586195707ec98e99e7e9bc28a2.webp

          說完了游戲圖形化界面相關(guān)的部分,我們再看一下游戲的主要處理邏輯。

          我們通過鼠標(biāo)來操縱拼圖塊,因此程序需要檢查有無拼圖塊被選中,代碼實現(xiàn)如下:

          def checkSelected(self, position): for x in range(NUMGRID):       for y in range(NUMGRID):           if self.getGemByPos(x, y).rect.collidepoint(*position):                return [x, y]  return None

          我們需要將鼠標(biāo)連續(xù)選擇的拼圖塊進行位置交換,代碼實現(xiàn)如下:

          def swapGem(self, gem1_pos, gem2_pos):    margin = gem1_pos[0] - gem2_pos[0] + gem1_pos[1] - gem2_pos[1] if abs(margin) != 1:       return False   gem1 = self.getGemByPos(*gem1_pos) gem2 = self.getGemByPos(*gem2_pos) if gem1_pos[0] - gem2_pos[0] == 1:     gem1.direction = 'left'        gem2.direction = 'right'   elif gem1_pos[0] - gem2_pos[0] == -1:      gem2.direction = 'left'        gem1.direction = 'right'   elif gem1_pos[1] - gem2_pos[1] == 1:       gem1.direction = 'up'      gem2.direction = 'down'    elif gem1_pos[1] - gem2_pos[1] == -1:      gem2.direction = 'up'      gem1.direction = 'down'    gem1.target_x = gem2.rect.left gem1.target_y = gem2.rect.top  gem1.fixed = False gem2.target_x = gem1.rect.left gem2.target_y = gem1.rect.top  gem2.fixed = False self.all_gems[gem2_pos[0]][gem2_pos[1]] = gem1 self.all_gems[gem1_pos[0]][gem1_pos[1]] = gem2 return True

          每一次交換拼圖塊時,我們需要判斷是否有連續(xù)一樣的三個及以上拼圖塊,代碼實現(xiàn)如下:

          def isMatch(self):  for x in range(NUMGRID):       for y in range(NUMGRID):           if x + 2 < NUMGRID:             if self.getGemByPos(x, y).type == self.getGemByPos(x+1, y).type == self.getGemByPos(x+2, y).type:                  return [1, x, y]           if y + 2 < NUMGRID:             if self.getGemByPos(x, y).type == self.getGemByPos(x, y+1).type == self.getGemByPos(x, y+2).type:                  return [2, x, y]   return [0, x, y]

          當(dāng)出現(xiàn)三個及以上拼圖塊時,需要將這些拼圖塊消除,代碼實現(xiàn)如下:

          def removeMatched(self, res_match): if res_match[0] > 0:        self.generateNewGems(res_match)        self.score += self.reward      return self.reward return 0

          將匹配的拼圖塊消除之后,我們還需要隨機生成新的拼圖塊,代碼實現(xiàn)如下:

          def generateNewGems(self, res_match):    if res_match[0] == 1:      start = res_match[2]       while start > -2:           for each in [res_match[1], res_match[1]+1, res_match[1]+2]:                gem = self.getGemByPos(*[each, start])             if start == res_match[2]:                  self.gems_group.remove(gem)                    self.all_gems[each][start] = None              elif start >= 0:                    gem.target_y += GRIDSIZE                   gem.fixed = False                  gem.direction = 'down'                 self.all_gems[each][start+1] = gem             else:                  gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+each*GRIDSIZE, YMARGIN-GRIDSIZE], downlen=GRIDSIZE)                   self.gems_group.add(gem)                   self.all_gems[each][start+1] = gem         start -= 1 elif res_match[0] == 2:        start = res_match[2]       while start > -4:           if start == res_match[2]:              for each in range(0, 3):                   gem = self.getGemByPos(*[res_match[1], start+each])                    self.gems_group.remove(gem)                    self.all_gems[res_match[1]][start+each] = None         elif start >= 0:                gem = self.getGemByPos(*[res_match[1], start])             gem.target_y += GRIDSIZE * 3               gem.fixed = False              gem.direction = 'down'             self.all_gems[res_match[1]][start+3] = gem         else:              gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+res_match[1]*GRIDSIZE, YMARGIN+start*GRIDSIZE], downlen=GRIDSIZE*3)               self.gems_group.add(gem)               self.all_gems[res_match[1]][start+3] = gem         start -= 1

          之后反復(fù)執(zhí)行這個過程,直至耗盡游戲時間,游戲結(jié)束。

          最后,我們動態(tài)看一下游戲效果。

          1022bbd0715db0565d28fdeb7a7b4ec7.webp

          總結(jié)

          本文我們使用 Python 實現(xiàn)了一個簡單的消消樂游戲,有興趣的可以對游戲做進一步擴展,比如增加關(guān)卡等。

          PS公號內(nèi)回復(fù)「Python」即可進入Python 新手學(xué)習(xí)交流群,一起 100 天計劃!


          老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點一下,如果感覺文章內(nèi)容不錯的話,記得分享朋友圈讓更多的人知道!

          fbae9a16aff4da8e34d3ccd269bfc48c.webp37d6db64906c5ce39fe9ca2c1841c3a9.webp

          代碼獲取方式

          識別文末二維碼,回復(fù):200729

          瀏覽 19
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  无码人妻在线视频 | 色色导航在线 | 亚洲一级av | 日韩第1页 | 手机在线免费看黄色电影一级片 |