python实现植物大战僵尸游戏实例代码


Posted in Python onJune 10, 2019

开发思路

完整项目地址:https://github.com/371854496/...

觉得还OK的话,点下Star,作者不易,thank you!

python实现植物大战僵尸游戏实例代码

实现方法

1.引入需要的模块,配置图片路径,设置界面宽高背景颜色,创建游戏主入口。

#1引入需要的模块
import pygame
import random
#1配置图片地址
IMAGE_PATH = 'imgs/'
#1设置页面宽高
scrrr_width=800
scrrr_height =560
#1创建控制游戏结束的状态
GAMEOVER = False
#1主程序
class MainGame():
  #1加载游戏窗口
 def init_window(self):
  #1调用显示模块的初始化
  pygame.display.init()
  #1创建窗口
  MainGame.window = pygame.display.set_mode([scrrr_width,scrrr_height]) #
 #1开始游戏
 def start_game(self):
  #1初始化窗口
  self.init_window()
  #1只要游戏没结束,就一直循环
  while not GAMEOVER:
   #1渲染白色背景
   MainGame.window.fill((255, 255, 255))
   #1实时更新
   pygame.display.update()
#1启动主程序
if __name__ == '__main__':
 game = MainGame()
 game.start_game()

2.文本绘制,创建要动态改变的属性,渲染的位置

#2 创建关数,得分,剩余分数,钱数
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.按左键创建向日葵 2.按右键创建豌豆射手', 26, (255, 0, 0))
 MainGame.window.blit(text1, (5, 5))

#2 渲染的文字和坐标位置
  MainGame.window.blit(self.draw_text('当前钱数$: {}'.format(MainGame.money), 26, (255, 0, 0)), (500, 40))
  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.创建地图类,初始化地图和坐标

#3 创建地图类
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 存储所有地图坐标点
 map_points_list = []
 #3 存储所有的地图块
 map_list = []
 
 #3 初始化坐标点
 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 初始化坐标和地图
 self.init_plant_points()
 self.init_map()
 
 #3 需要反复加载地图
 self.load_map()

4.创建植物类,图片加载报错处理,加载植物方法

#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.创建向日葵类

#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 时间计数器
  self.time_count = 0

 #5 功能:生成阳光(生产钱)
 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.创建豌豆射手类

#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 发射计数器
  self.shot_count = 0

 #6 增加射击方法
 def shot(self):
  #6 记录是否应该射击
  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
   # 计数器到25发射一次
   if self.shot_count == 25:
    #6 基于当前豌豆射手的位置,创建子弹
    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 增加豌豆射手发射处理
 def load_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)
  #6 调用加载植物的方法
  self.load_plants()

7.创建子弹类

#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 在屏幕范围内,实现往右移动
  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):
    #打中僵尸之后,修改子弹的状态,
    self.live = False
    #僵尸掉血
    zombie.hp -= self.damage
    if zombie.hp <= 0:
     zombie.live = False
     self.nextLevel()
 #7闯关方法
 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 调用子弹是否打中僵尸的方法
   b.hit_zombie()
  else:
   MainGame.peabullet_list.remove(b) 
 #7 调用加载所有子弹的方法
 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('按下鼠标按键')
   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 -= 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('当前植物列表长度:{}'.format(len(MainGame.plants_list)))
     map.can_grow = False
     MainGame.money -= 50
     
     #8 调用事件处理的方法
     self.deal_events()

9.创建僵尸类

#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 调用游戏结束方法
    MainGame().gameOver()

 #9 判断僵尸是否碰撞到植物,如果碰撞,调用攻击植物的方法
 def hit_plant(self):
  for plant in MainGame.plants_list:
   if pygame.sprite.collide_rect(self,plant):
    #8 僵尸移动状态的修改
    self.stop = True
    self.eat_plant(plant)
 #9 僵尸攻击植物
 def eat_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 将僵尸加载到地图中
 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 调用是否碰撞到植物的方法
    zombie.hit_plant()
   else:
    MainGame.zombie_list.remove(zombie)    

 #9 调用初始化僵尸的方法
  self.init_zombies()
  
 #9 调用展示僵尸的方法
   self.load_zombies()
   #9 计数器增长,每数到100,调用初始化僵尸的方法
   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.游戏结束方法

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python引用类型和值类型的区别与使用解析
Oct 17 Python
django 开发忘记密码通过邮箱找回功能示例
Apr 17 Python
如何安装多版本python python2和python3共存以及pip共存
Sep 18 Python
在python 中实现运行多条shell命令
Jan 07 Python
Python完成哈夫曼树编码过程及原理详解
Jul 29 Python
Python numpy线性代数用法实例解析
Nov 15 Python
对python中assert、isinstance的用法详解
Nov 27 Python
Python for循环通过序列索引迭代过程解析
Feb 07 Python
python+selenium+Chrome options参数的使用
Mar 18 Python
解决python中显示图片的plt.imshow plt.show()内存泄漏问题
Apr 24 Python
DRF使用simple JWT身份验证的实现
Jan 14 Python
解决Python中的modf()函数取小数部分不准确问题
May 28 Python
python中的协程深入理解
Jun 10 #Python
Python中asyncio模块的深入讲解
Jun 10 #Python
Python中的asyncio代码详解
Jun 10 #Python
Django集成CAS单点登录的方法示例
Jun 10 #Python
详解Python中的测试工具
Jun 09 #Python
Python中函数参数匹配模型详解
Jun 09 #Python
Python程序包的构建和发布过程示例详解
Jun 09 #Python
You might like
详细介绍PHP应用提速面面观
2006/10/09 PHP
WML,Apache,和 PHP 的介绍
2006/10/09 PHP
php 变量定义方法
2009/06/14 PHP
PHP 遍历文件实现代码
2011/05/04 PHP
php中读写文件与读写数据库的效率比较分享
2013/10/19 PHP
PHP整数取余返回负数的相关解决方法
2014/05/15 PHP
php定义一个参数带有默认值的函数实例分析
2015/03/16 PHP
thinkphp5框架实现数据库读取的数据转换成json格式示例
2019/10/10 PHP
jQuery 自定义函数写法分享
2012/03/30 Javascript
jquery取子节点及当前节点属性值的方法
2014/09/09 Javascript
jquery判断单选按钮radio是否选中的方法
2015/05/05 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
2015/10/15 Javascript
Bootstrap Paginator分页插件使用方法详解
2016/05/30 Javascript
JS查找字符串中出现最多的字符及个数统计
2017/02/04 Javascript
浅谈$_FILES数组为空的原因
2017/02/16 Javascript
微信小程序之滚动视图容器的实现方法
2017/09/26 Javascript
vue watch监听对象及对应值的变化详解
2018/02/24 Javascript
深入浅析Vue中的Prop
2018/06/10 Javascript
浅谈layui 绑定form submit提交表单的注意事项
2019/10/25 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
Python中的两个内置模块介绍
2015/04/05 Python
Python 在OpenCV里实现仿射变换—坐标变换效果
2019/08/30 Python
Django xadmin开启搜索功能的实现
2019/11/15 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
详解pandas赋值失败问题解决
2020/11/29 Python
玖熙女鞋美国官网:Nine West
2016/10/06 全球购物
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
英国健康和美容技术产品购物网站:CurrentBody
2019/07/17 全球购物
优秀学生自我鉴定范例
2013/12/18 职场文书
校长先进事迹材料
2014/02/01 职场文书
建筑安全生产责任书
2014/07/22 职场文书
部门活动策划方案
2014/08/16 职场文书
党员先进性教育整改措施
2014/09/18 职场文书
公安纪律作风整顿剖析材料
2014/10/10 职场文书
常务副总经理岗位职责
2015/02/02 职场文书
微前端qiankun改造日渐庞大的项目教程
2022/06/21 Javascript