Py学习  »  Python

用Python写了一个植物大战僵尸

Python面试官 • 3 周前 • 34 次点击  


来源:https://blog.csdn.net/Gtieguo


大家好,我是 面师兄。

今天给大家推荐一个 Python 的练手项目。

用 Python 写个植物大战僵尸!

直接开搞!


1. 引入需要的模块

import pygameimport random

2. 配置图片地址

IMAGE_PATH = 'imgs/'

3. 设置页面宽高

scrrr_width = 800scrrr_height = 560

4. 创建控制游戏结束的状态

GAMEOVER = False

5. 图片加载报错处理

LOG = '文件:{}中的方法:{}出错'.format(__file__, __name__)

6. 创建地图类

class Map():

7. 存储两张不同颜色的图片名称

map_names_list = [IMAGE_PATH + 'map1.png', IMAGE_PATH + 'map2.png']

8. 初始化地图

def__init__(self, x, y, img_index):self.image = pygame.image.load(Map.map_names_list[img_index])    self.position = (x, y)

9. 是否能够种植

self.can_grow = True

10. 加载地图

defload_map(self):    MainGame.window.blit(self.image, self.position)

11. 植物类

classPlant(pygame.sprite.Sprite):def__init__(self):super(Plant, self).__init__()        self.live = True

12. 加载图片

defload_image(self):if hasattr(self, 'image'and hasattr(self, 'rect'):        MainGame.window.blit(self.image, self.rect)else:        print(LOG)

13. 向日葵类

classSunflower(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 = xself.rect.y = yself.price = 50self.hp = 100# 5 时间计数器        self.time_count = 0

14. 新增功能:生成阳光

defproduce_money(self):self.time_count += 1ifself.time_count == 25:        MainGame.money += 5        self.time_count = 0

15. 向日葵加入到窗口中

defdisplay_sunflower(self):    MainGame.window.blit(self.image, self.rect)

16. 豌豆射手类

classPeaShooter(Plant):def__init__(self, x, y):super(PeaShooter, self).__init__()# self.image 为一个 surfaceself.image = pygame.image.load('imgs/peashooter.png')self.rect = self.image.get_rect()self.rect.x = xself.rect.y = yself.price = 50self.hp = 200# 6 发射计数器        self.shot_count = 0

17. 增加射击方法

defshot(self):# 6 记录是否应该射击    should_fire = Falsefor zombie in MainGame.zombie_list:if zombie.rect.y == self.rect.y and zombie.rect.x 800and zombie.rect.x > self.rect.x:            should_fire = True# 6 如果活着ifself.live andshould_fire:self.shot_count += 1# 6 计数器到25发射一次ifself.shot_count == 25:# 6 基于当前豌豆射手的位置,创建子弹            peabullet = PeaBullet(self)# 6 将子弹存储到子弹列表中            MainGame.peabullet_list.append(peabullet)            self.shot_count = 0

18. 将豌豆射手加入到窗口中的方法

defdisplay_peashooter(self):    MainGame.window.blit(self.image, self.rect)

19. 豌豆子弹类

classPeaBullet(pygame.sprite.Sprite):def__init__(self, peashooter):self.live = Trueself.image = pygame.image.load('imgs/peabullet.png')self.damage = 50self.speed = 10self.rect = self.image.get_rect()self.rect.x = peashooter.rect.x + 60self.rect.y = peashooter.rect.y + 15
defmove_bullet(self):# 7 在屏幕范围内,实现往右移动ifself.rect.x < scrrr_width:self.rect.x += self.speedelse:self.live = False
# 7 新增,子弹与僵尸的碰撞defhit_zombie(self):for zombie in MainGame.zombie_list:if pygame.sprite.collide_rect(self, zombie):# 打中僵尸之后,修改子弹的状态,self.live = False# 僵尸掉血                zombie.hp -= self.damageif zombie.hp <= 0:                    zombie.live = Falseself.nextLevel()# 7闯关方法
defnextLevel(self):        MainGame.score += 20        MainGame.remnant_score -= 20for i in range(1100):if MainGame.score == 100 * i and MainGame.remnant_score == 0:                MainGame.remnant_score = 100 * i                MainGame.shaoguan += 1                MainGame.produce_zombie += 50
defdisplay_peabullet(self):        MainGame.window.blit(self.image, self.rect)

20. 僵尸类

classZombie(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 僵尸的移动
defmove_zombie(self):if self.live andnot self.stop:            self.rect.x -= self.speedif self.rect.x < -80:# 8 调用游戏结束方法                MainGame().gameOver()
# 9 判断僵尸是否碰撞到植物,如果碰撞,调用攻击植物的方法defhit_plant(self):for plant in MainGame.plants_list:if pygame.sprite.collide_rect(self, plant):# 8  僵尸移动状态的修改                self.stop = True                self.eat_plant(plant)# 9 僵尸攻击植物
defeat_plant(self, plant):# 9 植物生命值减少        plant.hp -= self.damage# 9 植物死亡后的状态修改,以及地图状态的修改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 修改僵尸的移动状态            self.stop = False
# 9 将僵尸加载到地图中
defdisplay_zombie(self):        MainGame.window.blit(self.image, self.rect)

21. 主程序

classMainGame():# 2 创建关数,得分,剩余分数,钱数    shaoguan = 1    score = 0    remnant_score = 100    money = 200# 3 存储所有地图坐标点    map_points_list = []# 3 存储所有的地图块    map_list = []# 4 存储所有植物的列表    plants_list = []# 7 存储所有豌豆子弹的列表    peabullet_list = []# 9 新增存储所有僵尸的列表    zombie_list = []    count_zombie = 0    produce_zombie = 100# 1 加载游戏窗口
definit_window(self):# 1 调用显示模块的初始化        pygame.display.init()# 1 创建窗口        MainGame.window = pygame.display.set_mode([scrrr_width, scrrr_height])
# 2 文本绘制defdraw_text(self, content, size, color):        pygame.font.init()        font = pygame.font.SysFont('kaiti', size)        text = font.render(content, True, color)return text
# 2 加载帮助提示defload_help_text(self):        text1 = self.draw_text('1.按左键创建向日葵 2.按右键创建豌豆射手'26, (25500))        MainGame.window.blit(text1, (55))
# 3 初始化坐标点definit_plant_points(self):for y in range(17):            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 初始化地图definit_map(self):for points in MainGame.map_points_list:            temp_map_list = list()for point in points:# map = Noneif (point[0] + point[1]) % 2  == 0:                    map = Map(point[0] * 80, point[1] * 800)else:                    map = Map(point[0] * 80, point[1] * 801)# 将地图块加入到窗口中                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 将地图加载到窗口中defload_map(self):for temp_map_list in MainGame.map_list:for map in temp_map_list:                map.load_map()
# 6 增加豌豆射手发射处理defload_plants(self):for plant in MainGame.plants_list:# 6 优化加载植物的处理逻辑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)
# 7 加载所有子弹的方法defload_peabullets(self):for b in MainGame.peabullet_list:if b.live:                b.display_peabullet()                b.move_bullet()# v1.9 调用子弹是否打中僵尸的方法                b.hit_zombie()else:                MainGame.peabullet_list.remove(b)
# 8事件处理
defdeal_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('按下鼠标按键')                print(e.pos)# print(e.button)#左键1  按下滚轮2 上转滚轮为4 下转滚轮为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 增加创建时候的地图装填判断以及金钱判断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('当前植物列表长度:{}'.format(len(MainGame.plants_list)))                        map.can_grow = False                        MainGame.money -= 50elif 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('当前植物列表长度:{}'.format(len(MainGame.plants_list)))                        map.can_grow = False                        MainGame.money -= 50
# 9 新增初始化僵尸的方法definit_zombies(self):for i in range(17):            dis = random.randint(15) * 200            zombie = Zombie(800 + dis, i *  80)            MainGame.zombie_list.append(zombie)
# 9将所有僵尸加载到地图中defload_zombies(self):for zombie in MainGame.zombie_list:if zombie.live:                zombie.display_zombie()                zombie.move_zombie()# v2.0 调用是否碰撞到植物的方法                zombie.hit_plant()else:                MainGame.zombie_list.remove(zombie)# 1 开始游戏
defstart_game(self):# 1 初始化窗口        self.init_window()# 3 初始化坐标和地图        self.init_plant_points()        self.init_map()# 9 调用初始化僵尸的方法        self.init_zombies()# 1 只要游戏没结束,就一直循环whilenot GAMEOVER:# 1 渲染白色背景            MainGame.window.fill((255255255))# 2 渲染的文字和坐标位置            MainGame.window.blit(                self.draw_text('当前钱数$: {}'.format(                        MainGame.money), 26, (25500)), (50040))            MainGame.window.blit(                self.draw_text('当前关数{},得分{},距离下关还差{}分'.format(                        MainGame.shaoguan,                        MainGame.score,                        MainGame.remnant_score),26,                    (255,0,0)),                (5,40))            self.load_help_text()
# 3 需要反复加载地图            self.load_map()# 6 调用加载植物的方法            self.load_plants()# 7  调用加载所有子弹的方法            self.load_peabullets()# 8 调用事件处理的方法            self.deal_events()# 9 调用展示僵尸的方法            self.load_zombies()# 9 计数器增长,每数到100,调用初始化僵尸的方法            MainGame.count_zombie += 1if MainGame.count_zombie == MainGame.produce_zombie:                self.init_zombies()                MainGame.count_zombie = 0            pygame.time.wait(10)            pygame.display.update()
defgameOver(self):        MainGame.window.blit(            self.draw_text('游戏结束'50, (25500)), (300200))        print('游戏结束')        pygame.time.wait(400)global GAMEOVER        GAMEOVER = True

if __name__ == '__main__':    game = MainGame()    game.start_game()


写完的效果就是这样啦


觉得不错的,记得三连哦~

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/184019
 
34 次点击