<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 寫(xiě)個(gè)消消樂(lè)小游戲

          共 6394字,需瀏覽 13分鐘

           ·

          2020-08-20 17:12


          提到開(kāi)心消消樂(lè)這款小游戲,相信大家都不陌生,其曾在 2015 年獲得過(guò)玩家最喜愛(ài)的移動(dòng)單機(jī)游戲獎(jiǎng),受歡迎程度可見(jiàn)一斑,本文我們使用 Python 來(lái)做個(gè)簡(jiǎn)單的消消樂(lè)小游戲。

          實(shí)現(xiàn)

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

          先來(lái)看一下游戲所需 Python 庫(kù)。

          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)建一個(gè)主窗口,代碼如下:

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

          看一下效果:

          再接著在窗口中畫(huà)一個(gè) 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# 畫(huà)矩形 block 框def drawBlock(self, block, color=(255, 0, 0), size=2):  pygame.draw.rect(self.screen, color, block, size)

          看一下效果:

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

          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

          看一下效果:

          再接著加入計(jì)分器和計(jì)時(shí)器,代碼如下:

          # 顯示得分def drawScore(self):  score_render = self.font.render('分?jǐn)?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)# 顯示剩余時(shí)間def showRemainingTime(self):  remaining_time_render = self.font.render('倒計(jì)時(shí): %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)

          看一下效果:

          當(dāng)設(shè)置的游戲時(shí)間用盡時(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 鍵重新開(kāi)始'  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()

          看一下效果:

          說(shuō)完了游戲圖形化界面相關(guān)的部分,我們?cè)倏匆幌掠螒虻闹饕幚磉壿嫛?br>

          我們通過(guò)鼠標(biāo)來(lái)操縱拼圖塊,因此程序需要檢查有無(wú)拼圖塊被選中,代碼實(shí)現(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ù)選擇的拼圖塊進(jìn)行位置交換,代碼實(shí)現(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

          每一次交換拼圖塊時(shí),我們需要判斷是否有連續(xù)一樣的三個(gè)及以上拼圖塊,代碼實(shí)現(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)三個(gè)及以上拼圖塊時(shí),需要將這些拼圖塊消除,代碼實(shí)現(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

          將匹配的拼圖塊消除之后,我們還需要隨機(jī)生成新的拼圖塊,代碼實(shí)現(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í)行這個(gè)過(guò)程,直至耗盡游戲時(shí)間,游戲結(jié)束。

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

          總結(jié)

          本文我們使用 Python 實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的消消樂(lè)游戲,有興趣的可以對(duì)游戲做進(jìn)一步擴(kuò)展,比如增加關(guān)卡等。

          游戲源碼:

          https://github.com/JustDoPython/python-examples/tree/master/yeke/py-xxl

          作者:野客

          來(lái)源:Python 技術(shù)(pythonall)



          _往期文章推薦_

          用python寫(xiě)一個(gè)簡(jiǎn)單的貪吃蛇游戲




          瀏覽 58
          點(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>
                  777国产偷窥盗摄精品 | 波多野结衣无码NET,AV | 色老板在线最新地址 | 色妹子综合 | 黄色黄片在线免费观看 |