社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

Python面试官 • 2 周前 • 33 次点击  


来源: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
 
33 次点击