<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開發(fā)植物大戰(zhàn)僵尸游戲(附github項目地址)

          共 11628字,需瀏覽 24分鐘

           ·

          2021-07-09 21:28


          作者:楷楷

          原文:https://segmentfault.com/a/1190000019418065


          大家好,歡迎來到 Crossin的編程教室 !

          今天給大家分享一個仿《植物大戰(zhàn)僵尸》的小游戲開發(fā)案例。

          完整項目地址:

          https://github.com/371854496/pygame

          (歡迎給作者的項目點下Star)


          開發(fā)思路


          1. 引入需要的模塊,配置圖片路徑,設(shè)置界面寬高背景顏色,創(chuàng)建游戲主入口。

          #1引入需要的模塊
          import pygame
          import random
          #1配置圖片地址
          IMAGE_PATH = 'imgs/'
          #1設(shè)置頁面寬高
          scrrr_width=800
          scrrr_height =560
          #1創(chuàng)建控制游戲結(jié)束的狀態(tài)
          GAMEOVER = False
          #1主程序
          class MainGame():
          #1加載游戲窗口
          def init_window(self):
          #1調(diào)用顯示模塊的初始化
          pygame.display.init()
          #1創(chuàng)建窗口
          MainGame.window = pygame.display.set_mode([scrrr_width,scrrr_height]) #
          #1開始游戲
          def start_game(self):
          #1初始化窗口
          self.init_window()
          #1只要游戲沒結(jié)束,就一直循環(huán)
          while not GAMEOVER:
          #1渲染白色背景
          MainGame.window.fill((255, 255, 255))
          #1實時更新
          pygame.display.update()
          #1啟動主程序
          if __name__ == '__main__':
          game = MainGame()
          game.start_game()


          2. 文本繪制,創(chuàng)建要動態(tài)改變的屬性,渲染的位置

          #2 創(chuàng)建關(guān)數(shù),得分,剩余分?jǐn)?shù),錢數(shù)
          shaoguan = 1
          score = 0
          remnant_score = 100
          money = 200
          #2 文本繪制
          def draw_text(self, content, size, color):
          pygame.font.init()
          font = pygame.font.SysFont('kaiti', size)
          text = font.render(content, True, color)
          return text

          #2 加載幫助提示
          def load_help_text(self):
          text1 = self.draw_text('1.按左鍵創(chuàng)建向日葵 2.按右鍵創(chuàng)建豌豆射手', 26, (255, 0, 0))
          MainGame.window.blit(text1, (5, 5))

          #2 渲染的文字和坐標(biāo)位置
          MainGame.window.blit(self.draw_text('當(dāng)前錢數(shù)$: {}'.format(MainGame.money), 26, (255, 0, 0)), (500, 40))
          MainGame.window.blit(self.draw_text(
          '當(dāng)前關(guān)數(shù){},得分{},距離下關(guān)還差{}分'.format(MainGame.shaoguan, MainGame.score, MainGame.remnant_score), 26,
          (255, 0, 0)), (5, 40))
          self.load_help_text()

          3. 創(chuàng)建地圖類,初始化地圖和坐標(biāo)

          #3 創(chuàng)建地圖類
          class Map():
          #3 存儲兩張不同顏色的圖片名稱
          map_names_list = [IMAGE_PATH + 'map1.png', IMAGE_PATH + 'map2.png']
          #3 初始化地圖
          def __init__(self, x, y, img_index):
          self.image = pygame.image.load(Map.map_names_list[img_index])
          self.position = (x, y)
          # 是否能夠種植
          self.can_grow = True
          #3 加載地圖
          def load_map(self):
          MainGame.window.blit(self.image,self.position)

          #3 存儲所有地圖坐標(biāo)點
          map_points_list = []
          #3 存儲所有的地圖塊
          map_list = []

          #3 初始化坐標(biāo)點
          def init_plant_points(self):
          for y in range(1, 7):
          points = []
          for x in range(10):
          point = (x, y)
          points.append(point)
          MainGame.map_points_list.append(points)
          print("MainGame.map_points_list", MainGame.map_points_list)

          #3 初始化地圖
          def init_map(self):
          for points in MainGame.map_points_list:
          temp_map_list = list()
          for point in points:
          # map = None
          if (point[0] + point[1]) % 2 == 0:
          map = Map(point[0] * 80, point[1] * 80, 0)
          else:
          map = Map(point[0] * 80, point[1] * 80, 1)
          # 將地圖塊加入到窗口中
          temp_map_list.append(map)
          print("temp_map_list", temp_map_list)
          MainGame.map_list.append(temp_map_list)
          print("MainGame.map_list", MainGame.map_list)

          #3 將地圖加載到窗口中
          def load_map(self):
          for temp_map_list in MainGame.map_list:
          for map in temp_map_list:
          map.load_map()

          #3 初始化坐標(biāo)和地圖
          self.init_plant_points()
          self.init_map()

          #3 需要反復(fù)加載地圖
          self.load_map()

          4. 創(chuàng)建植物類,圖片加載報錯處理,加載植物方法

          #4 圖片加載報錯處理
          LOG = '文件:{}中的方法:{}出錯'.format(__file__,__name__)
          #4 植物類
          class Plant(pygame.sprite.Sprite):
          def __init__(self):
          super(Plant, self).__init__()
          self.live=True

          # 加載圖片
          def load_image(self):
          if hasattr(self, 'image') and hasattr(self, 'rect'):
          MainGame.window.blit(self.image, self.rect)
          else:
          print(LOG)

          #4 存儲所有植物的列表
          plants_list = []

          5. 創(chuàng)建向日葵類

          #5 向日葵類
          class Sunflower(Plant):
          def __init__(self,x,y):
          super(Sunflower, self).__init__()
          self.image = pygame.image.load('imgs/sunflower.png')
          self.rect = self.image.get_rect()
          self.rect.x = x
          self.rect.y = y
          self.price = 50
          self.hp = 100
          #5 時間計數(shù)器
          self.time_count = 0

          #5 功能:生成陽光(生產(chǎn)錢)
          def produce_money(self):
          self.time_count += 1
          if self.time_count == 25:
          MainGame.money += 5
          self.time_count = 0
          #5 向日葵加入到窗口中
          def display_sunflower(self):
          MainGame.window.blit(self.image,self.rect)


          6. 創(chuàng)建豌豆射手類

              #6 豌豆射手類
          class PeaShooter(Plant):
          def __init__(self,x,y):
          super(PeaShooter, self).__init__()
          # self.image 為一個 surface
          self.image = pygame.image.load('imgs/peashooter.png')
          self.rect = self.image.get_rect()
          self.rect.x = x
          self.rect.y = y
          self.price = 50
          self.hp = 200
          #6 發(fā)射計數(shù)器
          self.shot_count = 0

          #6 增加射擊方法
          def shot(self):
          #6 記錄是否應(yīng)該射擊
          should_fire = False
          for zombie in MainGame.zombie_list:
          if zombie.rect.y == self.rect.y and zombie.rect.x < 800 and zombie.rect.x > self.rect.x:
          should_fire = True
          #6 如果活著
          if self.live and should_fire:
          self.shot_count += 1
          # 計數(shù)器到25發(fā)射一次
          if self.shot_count == 25:
          #6 基于當(dāng)前豌豆射手的位置,創(chuàng)建子彈
          peabullet = PeaBullet(self)
          #6 將子彈存儲到子彈列表中
          MainGame.peabullet_list.append(peabullet)
          self.shot_count = 0

          #6 將豌豆射手加入到窗口中的方法
          def display_peashooter(self):
          MainGame.window.blit(self.image,self.rect)

          #6 增加豌豆射手發(fā)射處理
          def load_plants(self):
          for plant in MainGame.plants_list:
          #6 優(yōu)化加載植物的處理邏輯
          if plant.live:
          if isinstance(plant, Sunflower):
          plant.display_sunflower()
          plant.produce_money()
          elif isinstance(plant, PeaShooter):
          plant.display_peashooter()
          plant.shot()
          else:
          MainGame.plants_list.remove(plant)
          #6 調(diào)用加載植物的方法
          self.load_plants()

          7. 創(chuàng)建子彈類

          #7 豌豆子彈類
          class PeaBullet(pygame.sprite.Sprite):
          def __init__(self,peashooter):
          self.live = True
          self.image = pygame.image.load('imgs/peabullet.png')
          self.damage = 50
          self.speed = 10
          self.rect = self.image.get_rect()
          self.rect.x = peashooter.rect.x + 60
          self.rect.y = peashooter.rect.y + 15

          def move_bullet(self):
          #7 在屏幕范圍內(nèi),實現(xiàn)往右移動
          if self.rect.x < scrrr_width:
          self.rect.x += self.speed
          else:
          self.live = False

          #7 新增,子彈與僵尸的碰撞
          def hit_zombie(self):
          for zombie in MainGame.zombie_list:
          if pygame.sprite.collide_rect(self,zombie):
          #打中僵尸之后,修改子彈的狀態(tài),
          self.live = False
          #僵尸掉血
          zombie.hp -= self.damage
          if zombie.hp <= 0:
          zombie.live = False
          self.nextLevel()
          #7闖關(guān)方法
          def nextLevel(self):
          MainGame.score += 20
          MainGame.remnant_score -=20
          for i in range(1,100):
          if MainGame.score==100*i and MainGame.remnant_score==0:
          MainGame.remnant_score=100*i
          MainGame.shaoguan+=1
          MainGame.produce_zombie+=50

          def display_peabullet(self):
          MainGame.window.blit(self.image,self.rect)

          #7 存儲所有豌豆子彈的列表
          peabullet_list = []

          #7 加載所有子彈的方法
          def load_peabullets(self):
          for b in MainGame.peabullet_list:
          if b.live:
          b.display_peabullet()
          b.move_bullet()
          #7 調(diào)用子彈是否打中僵尸的方法
          b.hit_zombie()
          else:
          MainGame.peabullet_list.remove(b)
          #7 調(diào)用加載所有子彈的方法
          self.load_peabullets()

          8. 事件處理

          #8事件處理

          def deal_events(self):
          #8 獲取所有事件
          eventList = pygame.event.get()
          #8 遍歷事件列表,判斷
          for e in eventList:
          if e.type == pygame.QUIT:
          self.gameOver()
          elif e.type == pygame.MOUSEBUTTONDOWN:
          # print('按下鼠標(biāo)按鍵')
          print(e.pos)
          # print(e.button)#左鍵1 按下滾輪2 上轉(zhuǎn)滾輪為4 下轉(zhuǎn)滾輪為5 右鍵 3

          x = e.pos[0] // 80
          y = e.pos[1] // 80
          print(x, y)
          map = MainGame.map_list[y - 1][x]
          print(map.position)
          #8 增加創(chuàng)建時候的地圖裝填判斷以及金錢判斷
          if e.button == 1:
          if map.can_grow and MainGame.money >= 50:
          sunflower = Sunflower(map.position[0], map.position[1])
          MainGame.plants_list.append(sunflower)
          print('當(dāng)前植物列表長度:{}'.format(len(MainGame.plants_list)))
          map.can_grow = False
          MainGame.money -= 50
          elif e.button == 3:
          if map.can_grow and MainGame.money >= 50:
          peashooter = PeaShooter(map.position[0], map.position[1])
          MainGame.plants_list.append(peashooter)
          print('當(dāng)前植物列表長度:{}'.format(len(MainGame.plants_list)))
          map.can_grow = False
          MainGame.money -= 50

          #8 調(diào)用事件處理的方法
          self.deal_events()

          9. 創(chuàng)建僵尸類

          #9 僵尸類
          class Zombie(pygame.sprite.Sprite):
          def __init__(self,x,y):
          super(Zombie, self).__init__()
          self.image = pygame.image.load('imgs/zombie.png')
          self.rect = self.image.get_rect()
          self.rect.x = x
          self.rect.y = y
          self.hp = 1000
          self.damage = 2
          self.speed = 1
          self.live = True
          self.stop = False
          #9 僵尸的移動
          def move_zombie(self):
          if self.live and not self.stop:
          self.rect.x -= self.speed
          if self.rect.x < -80:
          #8 調(diào)用游戲結(jié)束方法
          MainGame().gameOver()

          #9 判斷僵尸是否碰撞到植物,如果碰撞,調(diào)用攻擊植物的方法
          def hit_plant(self):
          for plant in MainGame.plants_list:
          if pygame.sprite.collide_rect(self,plant):
          #8 僵尸移動狀態(tài)的修改
          self.stop = True
          self.eat_plant(plant)
          #9 僵尸攻擊植物
          def eat_plant(self,plant):
          #9 植物生命值減少
          plant.hp -= self.damage
          #9 植物死亡后的狀態(tài)修改,以及地圖狀態(tài)的修改
          if plant.hp <= 0:
          a = plant.rect.y // 80 - 1
          b = plant.rect.x // 80
          map = MainGame.map_list[a][b]
          map.can_grow = True
          plant.live = False
          #8 修改僵尸的移動狀態(tài)
          self.stop = False

          #9 將僵尸加載到地圖中
          def display_zombie(self):
          MainGame.window.blit(self.image,self.rect)

          #9 新增存儲所有僵尸的列表
          zombie_list = []
          count_zombie = 0
          produce_zombie = 100

          #9 新增初始化僵尸的方法
          def init_zombies(self):
          for i in range(1, 7):
          dis = random.randint(1, 5) * 200
          zombie = Zombie(800 + dis, i * 80)
          MainGame.zombie_list.append(zombie)

          #9將所有僵尸加載到地圖中
          def load_zombies(self):
          for zombie in MainGame.zombie_list:
          if zombie.live:
          zombie.display_zombie()
          zombie.move_zombie()
          # v2.0 調(diào)用是否碰撞到植物的方法
          zombie.hit_plant()
          else:
          MainGame.zombie_list.remove(zombie)

          #9 調(diào)用初始化僵尸的方法
          self.init_zombies()

          #9 調(diào)用展示僵尸的方法
          self.load_zombies()
          #9 計數(shù)器增長,每數(shù)到100,調(diào)用初始化僵尸的方法
          MainGame.count_zombie += 1
          if MainGame.count_zombie == MainGame.produce_zombie:
          self.init_zombies()
          MainGame.count_zombie = 0
          #9 pygame自己的休眠
          pygame.time.wait(10)

          10. 游戲結(jié)束方法

          #10 程序結(jié)束方法
          def gameOver(self):
          MainGame.window.blit(self.draw_text('游戲結(jié)束', 50, (255, 0, 0)), (300, 200))
          pygame.time.wait(400)
          global GAMEOVER
          GAMEOVER = True

          以上就是整個游戲的開發(fā)思路和核心代碼,大家可以自己嘗試更改游戲參數(shù),或增加更多功能。


          如果文章對你有幫助,歡迎轉(zhuǎn)發(fā)/點贊/收藏~



          _往期文章推薦_

          GitHub上10個有趣的開源小游戲




          如需了解付費精品課程教學(xué)答疑服務(wù)
          請在Crossin的編程教室內(nèi)回復(fù): 666

          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  成人伊人观看视频 | 日韩黄色视频毛片 | 日本操逼小视频 | 可以在线观看的黄色 | 色导航在线 |