Python 植物大战僵尸

文章目录

  • 效果图
  • 项目结构
  • 实现思路
  • 源代码

效果图

请添加图片描述

项目结构

在这里插入图片描述

实现思路

下面是代码的实现思路:

  1. 导入必要的库和模块:首先,我们导入了Python的ostime库以及pygame库,还有植物大战僵尸游戏中用到的各个植物和僵尸的类。

  2. 初始化游戏和加载资源:接下来,我们初始化了Pygame库,并设置了游戏的背景尺寸。然后,我们加载了游戏所需的各种图像资源,包括背景、植物、僵尸等。

  3. 定义游戏元素和变量:我们定义了几个全局变量,包括阳光值、植物组、子弹组、僵尸组和阳光组。还定义了一些特殊事件,用于在游戏中生成新的植物、子弹、僵尸和阳光等。

  4. 编写游戏主循环:游戏的主循环在main()函数中。在主循环中,我们首先更新了植物、子弹和僵尸的位置和状态,然后在屏幕上绘制了这些元素。接下来,我们响应了用户的鼠标和键盘事件,包括选择植物、放置植物、收集阳光等。最后,我们更新了游戏界面并检查了游戏是否结束。

  5. 处理游戏事件:在主循环中,我们使用pygame.event.get()函数获取当前的游戏事件,并根据事件类型进行相应的处理。例如,当用户点击鼠标时,我们会判断用户是否点击了植物种子的图标,如果是,则将选择的植物类型设置为相应的值;如果用户点击了游戏区域,则根据选择的植物类型放置植物。

  6. 更新游戏状态和界面:在主循环中,我们还更新了游戏的状态,如减少阳光值、增加僵尸数量等。同时,我们也更新了游戏界面,如重新绘制阳光值、植物、僵尸等。

  7. 检查游戏结束条件:在主循环中,我们还检查了游戏是否结束。如果僵尸到达了终点,则游戏失败;如果僵尸数量大于一定值,则游戏胜利。

  8. 启动游戏:最后,我们在if __name__ == '__main__':代码块中调用了main()函数,启动游戏。

玩家可以选择不同的植物来抵御僵尸的进攻,并收集阳光来购买更多的植物。游戏通过不断生成新的僵尸和植物,以及响应用户的操作,来保持游戏的进行,直到游戏结束。

源代码

完整代码地址:https://gitcode.com/stormsha1/games/overview

pvz/main.py

import os
import time
import pygame
from pvz.plant.Peashooter import Peashooter
from pvz.plant.SunFlower import SunFlower
from pvz.plant.WallNut import WallNut
from pvz.plant.Sun import Sun
from pvz.plant.Sun2 import Sun2
from pvz.plant.JXC import JXC
from pvz.plant.Bullet import Bullet
from pvz.plant.BulletJXC import BulletJXC
from pvz.zombie.Zombie import Zombie
from pvz.zombie.ZombieLz import ZombieLz# 初始化pygame库
pygame.init()# 设置游戏背景尺寸,所有的资源图片都是基于这个尺寸制作的,不建议修改
background_size = (820, 560)# 创建游戏窗口并设置标题
screen = pygame.display.set_mode(background_size)
pygame.display.set_caption("植物大战僵尸")# 获取当前工作目录
base_path = os.getcwd()# 加载背景图片
bg_img_obj = pygame.image.load(os.path.join(base_path, 'images/a3.png')).convert_alpha()# 加载植物图片
sunFlowerImg = pygame.image.load(os.path.join(base_path, 'images/SunFlower/SunFlower_00.png')).convert_alpha()
wallNutImg = pygame.image.load(os.path.join(base_path, 'images/WallNut/wall_nut_00.png')).convert_alpha()
peaShooterImg = pygame.image.load(os.path.join(base_path, 'images/Peashooter/Peashooter00.png')).convert_alpha()
jxcImg = pygame.image.load(os.path.join(base_path, 'images/jxc/JXC00.png')).convert_alpha()# 加载阳光储蓄罐和种子图片
sun_back_img = pygame.image.load(os.path.join(base_path, 'images/SeedBank01.png')).convert_alpha()
sunflower_seed = pygame.image.load(os.path.join(base_path, 'images/SunFlower_kp.png'))
wall_nut_seed = pygame.image.load(os.path.join(base_path, 'images/Wallnut_kp.png'))
peashooter_seed = pygame.image.load(os.path.join(base_path, 'images/Peashooter_kp.png'))
jxc_seed = pygame.image.load(os.path.join(base_path, 'images/jxc_kp.png'))# 初始化阳光值为100
text = "1000"# 设置阳光值字体和颜色
sun_font = pygame.font.SysFont("黑体", 25)
sun_num_surface = sun_font.render(str(text), True, (0, 0, 0))# 创建植物组、子弹组、僵尸组和阳光组
spriteGroup = pygame.sprite.Group()
bulletGroup = pygame.sprite.Group()
zombieGroup = pygame.sprite.Group()
sun_sprite = pygame.sprite.Group()# 定义游戏时钟和特殊事件
clock = pygame.time.Clock()
GEN_SUN_EVENT = pygame.USEREVENT + 1  # 生成阳光事件
pygame.time.set_timer(GEN_SUN_EVENT, 2000)  # 每2秒生成一次阳光
GEN_BULLET_EVENT = pygame.USEREVENT + 2  # 生成子弹事件
pygame.time.set_timer(GEN_BULLET_EVENT, 2000)  # 每2秒生成一次子弹
GEN_ZOMBIE_EVENT = pygame.USEREVENT + 3  # 生成僵尸事件
pygame.time.set_timer(GEN_ZOMBIE_EVENT, 10000)  # 每10秒生成一次僵尸
GEN_SUN2_EVENT = pygame.USEREVENT + 4  # 生成双倍阳光事件
pygame.time.set_timer(GEN_SUN2_EVENT, 20000)  # 每20秒生成一次双倍阳光# 初始化选择的植物类型和僵尸数量
choose = 0
zombie_num = 0def main():"""游戏主函数,包含游戏主循环"""global zombie_num  # 僵尸数量全局变量global choose  # 选择的植物类型全局变量global text  # 阳光值全局变量global sun_num_surface  # 阳光值显示表面全局变量running = True  # 游戏是否运行标志index = 0  # 用于植物、子弹和僵尸的更新和绘制的索引while running:# 控制游戏帧率clock.tick(20)# 检查子弹和僵尸的碰撞,如果碰撞则减少僵尸的能量并移除子弹for bullet in bulletGroup:for zombie in zombieGroup:if pygame.sprite.collide_mask(bullet, zombie):if isinstance(bullet, BulletJXC):  # 如果是坚果的子弹,则减少2点能量zombie.energy -= 2bulletGroup.remove(bullet)else:  # 否则减少1点能量zombie.energy -= 1bulletGroup.remove(bullet)# 检查植物和僵尸的碰撞,如果碰撞则设置僵尸的GO标志为True,并将僵尸添加到植物的zombies列表中for sprite in spriteGroup:for zombie in zombieGroup:if pygame.sprite.collide_mask(sprite, zombie):zombie.GO = Truesprite.zombies.add(zombie)# 如果植物是坚果,则检查僵尸是否在攻击范围内,如果是则设置植物的攻击标志为True,并生成子弹if isinstance(sprite, JXC):if abs(zombie.rect.top - sprite.rect[1]) <= 40 and zombie.rect.left < 760:sprite.attack = Trueif sprite.att == 11:bullet_jxc = BulletJXC(sprite.rect, background_size, zombie.rect[0])bulletGroup.add(bullet_jxc)break# 在屏幕上绘制背景、阳光储蓄罐、阳光值和种子图片screen.blit(bg_img_obj, (0, 0))screen.blit(sun_back_img, (20, 0.5))screen.blit(sun_num_surface, (35, 50))screen.blit(sunflower_seed, (80, 5))screen.blit(peashooter_seed, (121, 5))screen.blit(wall_nut_seed, (162, 5))screen.blit(jxc_seed, (203, 5))# 更新和绘制植物、子弹、僵尸和阳光spriteGroup.update(index)spriteGroup.draw(screen)bulletGroup.update(index)bulletGroup.draw(screen)zombieGroup.update(index)zombieGroup.draw(screen)sun_sprite.update(index)sun_sprite.draw(screen)# 获取鼠标位置,并在鼠标位置上绘制选择的植物预览图(x, y) = pygame.mouse.get_pos()if choose == 1:screen.blit(sunFlowerImg, (x - sunFlowerImg.get_rect().width // 2, y - sunFlowerImg.get_rect().height // 2))if choose == 2:screen.blit(peaShooterImg,(x - peaShooterImg.get_rect().width // 2, y - peaShooterImg.get_rect().height // 2))if choose == 3:screen.blit(wallNutImg, (x - wallNutImg.get_rect().width // 2, y - wallNutImg.get_rect().height // 2))if choose == 4:screen.blit(jxcImg, (x - jxcImg.get_rect().width // 2, y - jxcImg.get_rect().height // 2))# 增加索引值index += 1# 处理pygame事件for event in pygame.event.get():# 处理生成双倍阳光事件if event.type == GEN_SUN2_EVENT:sun2 = Sun2()sun_sprite.add(sun2)# 处理生成僵尸事件if event.type == GEN_ZOMBIE_EVENT:zombie_num += 1zombie = Zombie()zombie_lz = ZombieLz()if 0 < zombie_num <= 15:zombieGroup.add(zombie)if zombie_num > 7:zombieGroup.add(zombie_lz)# 处理生成阳光事件if event.type == GEN_SUN_EVENT:for sprite in spriteGroup:if isinstance(sprite, SunFlower):now = time.time()if now - sprite.last_time >= 10:  # 如果距离上次生成阳光的时间大于等于10秒,则生成阳光sun = Sun(sprite.rect)sun_sprite.add(sun)sprite.last_time = now# 处理生成子弹事件if event.type == GEN_BULLET_EVENT:for sprite in spriteGroup:for zombie in zombieGroup:if isinstance(sprite, Peashooter) \and 0 < sprite.rect[1] - zombie.rect[1] < 50 \and zombie.rect[0] < 760:bullet = Bullet(sprite.rect, background_size)bulletGroup.add(bullet)break# 处理退出游戏事件if event.type == pygame.QUIT:running = False# 处理鼠标点击事件if event.type == pygame.MOUSEBUTTONDOWN:pressed_key = pygame.mouse.get_pressed()if pressed_key[0]:pos = pygame.mouse.get_pos()x, y = pos# 如果点击了种子按钮,则设置选择的植物类型if 80 <= x < 121 and 5 <= y <= 63 and int(text) >= 50:choose = 1elif 121 <= x < 162 and 5 <= y <= 63 and int(text) >= 100:choose = 2elif 162 <= x < 203 and 5 <= y <= 63 and int(text) >= 50:choose = 3elif 203 <= x < 244 and 5 <= y <= 63 and int(text) >= 100:choose = 4# 如果点击了游戏区域,则根据选择的植物类型放置植物elif 36 < x < 800 and 70 < y < 550:if choose == 1:true_x = x // 90 * 85 + 35  # 计算植物的左上角坐标true_y = y // 100 * 95 - 15can_hold = True  # 是否可以放置植物标志for sprite in spriteGroup:if sprite.rect.left == true_x and sprite.rect.top == true_y:can_hold = Falsebreakif not can_hold or true_y < 25:breaksunflower = SunFlower(time.time(), (true_x, true_y))  # 创建向日葵实例spriteGroup.add(sunflower)  # 将向日葵添加到植物组中choose = 0  # 重置选择的植物类型text = int(text)  # 将阳光值转换为整数text -= 50  # 减少50阳光my_font = pygame.font.SysFont("黑体", 25)  # 设置字体sun_num_surface = my_font.render(str(text), True, (0, 0, 0))  # 更新阳光值显示表面if choose == 2:true_x = x // 90 * 85 + 32true_y = y // 100 * 95 - 18can_hold = Truefor sprite in spriteGroup:if sprite.rect.left == true_x and sprite.rect.top == true_y:can_hold = Falsebreakif not can_hold or true_y < 25:breakpeashooter = Peashooter((true_x, true_y))  # 创建豌豆射手实例spriteGroup.add(peashooter)  # 将豌豆射手添加到植物组中choose = 0text = int(text)text -= 100  # 减少100阳光my_font = pygame.font.SysFont("黑体", 25)sun_num_surface = my_font.render(str(text), True, (0, 0, 0))if choose == 3:true_x = x // 90 * 85 + 35true_y = y // 100 * 95 - 15can_hold = Truefor sprite in spriteGroup:if sprite.rect.left == true_x and sprite.rect.top == true_y:can_hold = Falsebreakif not can_hold or true_y < 25:breakwall_nut = WallNut((true_x, true_y))  # 创建坚果实例spriteGroup.add(wall_nut)  # 将坚果添加到植物组中choose = 0text = int(text)text -= 50  # 减少50阳光my_font = pygame.font.SysFont("黑体", 25)sun_num_surface = my_font.render(str(text), True, (0, 0, 0))if choose == 4:true_x = x // 90 * 85 + 22true_y = y // 100 * 95 - 35can_hold = Truefor sprite in spriteGroup:if sprite.rect.left == true_x and sprite.rect.top == true_y:can_hold = Falsebreakif not can_hold or true_y < 25:breakjxc = JXC((true_x, true_y))  # 创建坚果墙实例spriteGroup.add(jxc)  # 将坚果墙添加到植物组中choose = 0text = int(text)text -= 100  # 减少100阳光my_font = pygame.font.SysFont("黑体", 25)sun_num_surface = my_font.render(str(text), True, (0, 0, 0))# 如果点击了阳光,则收集阳光并更新阳光值显示表面for sun in sun_sprite:if sun.rect.collidepoint(pos):sun_sprite.remove(sun)text = str(int(text) + 25)sun_font = pygame.font.SysFont("黑体", 25)sun_num_surface = sun_font.render(str(text), True, (0, 0, 0))# 检查僵尸是否到达终点或游戏是否胜利for zombie in zombieGroup:if zombie.rect.left == -120:  # 如果僵尸到达终点,则游戏失败print("你的脑子被僵尸吃了")running = Falseif zombie_num > 20:  # 如果僵尸数量大于20,则游戏胜利print("胜利")running = False# 更新游戏界面pygame.display.update()if __name__ == '__main__':main()

完整代码地址:https://gitcode.com/stormsha1/games/overview

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/831535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始学AI绘画,万字Stable Diffusion终极教程(一)

【第1期】SD入门 2022年8月&#xff0c;一款叫Stable Diffusion的AI绘画软件开源发布&#xff0c;从此开启了AIGC在图像上的爆火发展时期 率先学会SD的人&#xff0c;已经挖掘出了越来越多AI绘画有趣的玩法 从开始的AI美女、线稿上色、真人漫改、头像壁纸 到后来的AI创意字、AI…

Android性能优化面试题汇总

Android的性能优化涉及多个方面,如启动优化、稳定性优化、内存优化、网络优化、电量优化、安全优化等方面。 一、稳定性优化 1.1 你们做了哪些稳定性方面的优化 随着项目的逐渐成熟,用户基数逐渐增多,DAU持续升高,我们遇到了很多稳定性方面的问题,对于我们技术同学遇到…

如何在 Ubuntu 16.04 上使用 WireGuard 创建点对点 VPN

简介 WireGuard 是一种现代、高性能的 VPN&#xff0c;旨在提供易于使用的同时又具有强大的安全性。WireGuard 专注于在网络接口上使用公钥认证加密来提供安全连接。这意味着&#xff0c;与大多数 VPN 不同&#xff0c;它不强制执行拓扑结构&#xff0c;因此可以通过操纵周围的…

条件依赖性的方法示例

5个条件判断一件事情是否发生&#xff0c;每个条件可能性只有2种&#xff08;发生或者不发生&#xff09;&#xff0c;计算每个条件对这件事情发生的影响力&#xff0c;条件之间有很强的依赖关系。 例一 如果条件之间有很强的依赖关系&#xff0c;那么简单地计算每个条件独立的…

[论文阅读] 测试时间自适应TTA

最初接触 CVPR2024 TEA: Test-time Energy Adaptation [B站]&#xff08;1:35:00-1:53:00&#xff09;https://www.bilibili.com/video/BV1wx4y1v7Jb/?spm_id_from333.788&vd_source145b0308ef7fee4449f12e1adb7b9de2 实现&#xff1a; 读取预训练好的模型参数设计需要更…

Vue 组件通信

组件通信 组件与组件之间的数据传递 组件的数据是独立的&#xff0c;无法直接访问其他组件的数据。通过组件通信&#xff0c;可以访问其他组件的数据。 组件关系 父子关系非父子关系 组件通信解决方案 父子关系 父->子 父组件通过props将数据传递给子组件 App.vue …

蛋白质PDB文件解析+建图(biopython+DGL)

PDB文件解析 PDB文件设计得非常好&#xff0c;能够比较完整地记录实验测定数据 读懂蛋白质PDB文件-腾讯云开发者社区-腾讯云 (tencent.com) 科学网—PDB文件格式说明 - 李继存的博文 (sciencenet.cn) 从蛋白质结构来看&#xff0c;首先它会有多种不同的测定模型&#xff0c…

python学习笔记----面向对象(十)

一、什么是类 类是一个抽象的模板&#xff0c;用于创建具体的实例。可以将类理解为一个蓝图&#xff0c;它定义了一系列对象共有的属性&#xff08;数据&#xff09;和方法&#xff08;函数&#xff09;。类是对一组具有相同属性和功能的对象的抽象。例如&#xff0c;你可以定…

Jupyter Notebook魔术命令

Jupyter Notebook是一个基于网页的交互式笔记本&#xff0c;支持运行多种编程语言。 Jupyter Notebook 的本质式一个Web应用程序&#xff0c;便于创建和共享文学化程序文档&#xff0c;支持实现代码&#xff0c;数学方程&#xff0c;可视化和markdown。用途包括&#xff1a;数据…

2.6Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3-基础-Vue生命周期

在使用vue进行日常开发中&#xff0c;我们总有这样的需求&#xff0c;想在页面刚一加载出这个表格组件时&#xff0c;就发送请求去后台拉取 数据&#xff0c;亦或者想在组件加载前显示个loading图&#xff0c;当组件加载出来就让这个loading图消失等等这样或那样的需求。 要实…

【Python】模块和包

模块(Module)是一个python文件&#xff0c;能定义函数&#xff0c;类和变量&#xff0c;能包含可执行的代码。 一个模块就是一个工具包&#xff0c;里面有工具供我们使用&#xff0c;以实现功能。 类似于C语言的库函数 模块的导入 组合形式&#xff1a; import 模块名 fro…

Flutter笔记:Widgets Easier组件库(9)使用弹窗

Flutter笔记 Widgets Easier组件库&#xff08;9&#xff09;&#xff1a;使用弹窗 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

自定义拦截器jwt登录校验接口模拟账号登录

五一闲在宿舍&#xff0c;本来想写一个自己的简易博客网站&#xff0c;发现vue基础太差&#xff0c;做不出来页面效果于是便放弃&#xff0c;但也没有完全放弃。于是我分析了一下简易博客的后端实现流程&#xff0c;除了最基本的crud以外&#xff0c;在自己目前的对接口的分析中…

网络安全运维类面试非技术问题

1、你熟悉哪些品牌的安全设备 答&#xff1a;天融信的ngfw防火墙&#xff0c;老牌防火墙厂商&#xff0c;功能比较齐全&#xff0c;像流量检测&#xff0c;web应用防护和僵木蠕等模块都有&#xff0c;界面是红白配色&#xff0c;设计稍微有点老 2、IPS用的是哪个牌子的 答&…

Ubuntu启动后进入GRUB故障-Minimal BASH like line editing is supported.

目录 1.问题描述 2.解决方案 2.1 临时性办法 2.2 工具永久性修复 总结 1.问题描述 PC安装Ubuntu系统第二天重启后提示GUN GRUB version 2.04&#xff0c;之前是WindowsOS装Ubuntu后无法进入图形界面。具体原因据网友提供线索据说是由于在Windows上进行更新/重装/修改了引…

第Ⅰ章-V package.json文件详解

第Ⅰ章-Ⅰ 了解Vue3 创建一个Vue3项目 第Ⅰ章-Ⅱ Vue3自定义创建项目 项目文件详解 第Ⅰ章-III Vite 创建vue3 项目 第Ⅰ章-IV npm yarn pnpm 包管理器 第Ⅰ章-V package.json文件详解 简洁详解基本字段name 定义项目名称version 定义项目版本号description 对项目的简短描述m…

2024年 Java 面试八股文——Mybatis篇

目录 1. 什么是Mybatis&#xff1f; 2. 说说Mybatis的优缺点 3. Xml映射文件中&#xff0c;都有哪些标签 4. #{}和&{}有什么区别 5. Mybatis是如何进行分页的,分页插件的原理是什么 6. Mybatis是如何将sql执行结果封装为目标对象并返回的&#xff1f; 7. Mybatis是怎…

从 Servlet 到 DispatcherServlet(SpringMvc 容器的创建)

DispatcherServlet 的继承体系 SpringMvc 是一个具有 Spring 容器&#xff08;ApplicationContext&#xff09;的 Servlet。其中&#xff0c;HttpServlet 属于 JDK 的内容&#xff0c;从 HttpServletBean 开始&#xff0c;便属于 Spring 体系中的内容。 HttpServletBean&…

华为手机 鸿蒙系统-android studio识别调试设备,开启adb调试权限

1.进入设置-关于手机-版本号&#xff0c;连续点击7次 认证&#xff1a;有锁屏密码需要输入密码&#xff0c; 开启开发者配置功能ok 进入开发者配置界面 打开调试功能 重新在androd studio查看可运行running devices显示了&#xff0c; 不行的话&#xff0c;重启一下android …

【开源物联网平台】window环境下搭建调试监控设备环境

&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、使用docker脚本部署zlmediakit 1.1 …