【Python游戏】今天小编用Python实现了一个植物大战僵尸小游戏 | 附源码

news2025/1/12 0:59:15

前言

halo,包子们下午好
今天给打击整一个植物大战僵尸 无广告版本 哈哈
说实话,现在的小游戏很多都是有广告,多少有点难受
今天给大家直接安排

相关文件

关注小编,私信小编领取哟!
当然别忘了一件三连哟~~

源码点击蓝色字体领取
Python零基础入门到精通视频合集

【整整800集】Python爬虫项目零基础入门合集,细狗都学会了,你还不会?

开发工具

Python版本:3.7.8
相关模块:
pygame模块;
random模块;
以及一些python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

效果展示

开始界面

在这里插入图片描述

游戏界面

在这里插入图片描述

代码展示

导入模块

#1 引入需要的模块
import pygame
import random

配置图片地址

IMAGE_PATH = 'imgs/'

设置页面宽高

scrrr_width=800
scrrr_height =560

创建控制游戏结束的状态

GAMEOVER = False

图片加载报错处理

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

创建地图类

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)

植物类

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)

向日葵类

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)

豌豆射手类

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
            #6 计数器到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)

豌豆子弹类

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)

僵尸类

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)

主程序

class MainGame():
    #2 创建关数,得分,剩余分数,钱数
    shaoguan = 1
    score = 0
    remnant_score = 100
    money = 200
    pygame.display.set_caption("植物大战僵尸 公众号:Python日志  学习交流群:494958217")
    #3 存储所有地图坐标点
    map_points_list = []
    #3 存储所有的地图块
    map_list = []
    #4 存储所有植物的列表
    plants_list = []
    #7 存储所有豌豆子弹的列表
    peabullet_list = []
    #9 新增存储所有僵尸的列表
    zombie_list = []
    count_zombie = 0
    produce_zombie = 100
    #1 加载游戏窗口
    def init_window(self):
        #1 调用显示模块的初始化
        pygame.display.init()
        #1 创建窗口
        MainGame.window = pygame.display.set_mode([scrrr_width,scrrr_height])

    #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))

    #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()

    #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)

    #7 加载所有子弹的方法
    def load_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事件处理

    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

    #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)
    #1 开始游戏
    def start_game(self):
        #1 初始化窗口
        self.init_window()
        #3 初始化坐标和地图
        self.init_plant_points()
        self.init_map()
        #9 调用初始化僵尸的方法
        self.init_zombies()
        #1 只要游戏没结束,就一直循环
        while not GAMEOVER:
            #1 渲染白色背景
            MainGame.window.fill((255, 255, 255))
            #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 需要反复加载地图
            self.load_map()
            #6 调用加载植物的方法
            self.load_plants()
            #7  调用加载所有子弹的方法
            self.load_peabullets()
            #8 调用事件处理的方法
            self.deal_events()
            #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)
            #1 实时更新
            pygame.display.update()

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

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

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

相关文章

java基于Springboot的社区维修平台-计算机毕业设计

项目介绍 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于社区维修平台所牵扯的管理及数据保存都是非常多的&#xff0c;例如住户管理、社区公告管理、维修工管理、维修订单管理、接单信息管理、订单信息管理、在线沟通管理、举报信息管理、留言板管理、系统管理…

4G远程智能巡检摄像机功耗测试对比

对于一款输电线路监控设备&#xff0c;由于装在铁塔上面&#xff0c;对于功耗&#xff0c;电网上面的应用&#xff0c;尤为重要&#xff0c;如何得做到低功耗&#xff0c;一直大家研究的地方&#xff0c;解决了功耗&#xff0c;基本产品成功了一半&#xff0c;而合方圆在电网行…

对称加密算法(一)(替换算法,Caesar, Playfair, Hill Cipher,Polyalphabetic Cipher)

文章目录Symmetric Cipher ModelSubstitution TechniquesCaesar CipherMonoalphabetic CiphersPlayfair CipherHill CipherPolyalphabetic CipherVigenere CipherVernam CipherOne-Time PadReferences对称加密&#xff0c;也被称为传统加密、单钥加密或私钥加密&#xff0c;是 …

Flink系列-1、流式计算简介

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 大数据系列文章目录 官方网址&#xff1a;https://flink.apache.org/ 学习资料&#xff1a;https://flink-learning.org.cn/ 目录数据的时效性…

【pytorch】使用pytorch自己实现LayerNorm

pytorch中使用LayerNorm的两种方式&#xff0c;一个是nn.LayerNorm,另外一个是nn.functional.layer_norm 1. 计算方式 根据官方网站上的介绍&#xff0c;LayerNorm计算公式如下。 公式其实也同BatchNorm,只是计算的维度不同。 下面通过实例来走一遍公式 假设有如下的数据 …

JQuery 高级

目录 1. 动画 1. 三种方式显示和隐藏元素 1. 默认显示和隐藏方式 2. 滑动显示和隐藏方式 2. 遍历 1. js的遍历方式 2. jq的遍历方式 5. 插件&#xff1a;增强JQuery的功能 1 . 实现方式&#xff1a; 1. $.fn.extend(object) * 增强通过Jquery获取的对象的…

java计算机毕业设计ssm学生宿舍管理系统efyug(附源码、数据库)

java计算机毕业设计ssm学生宿舍管理系统efyug&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

取余,模运算,余数的正负问题,1497. 检查数组对是否可以被 k 整除

首先&#xff0c;我们来看数学中对余数的定义 0到除数之间的整数&#xff0c;所以当除数是负数的时候&#xff0c;余数也是负数。 举个例子&#xff1a; 接下来&#xff0c;我们看计算机中余数是怎么求的&#xff1f;&#xff1f;&#xff1f; 所有的语言和计算器都遵循了让商…

防火墙豁免实验

♥️作者&#xff1a;小刘在C站 ♥️每天分享云计算网络运维课堂笔记&#xff0c;疫情之下&#xff0c;你我素未谋面&#xff0c;但你一定要平平安安&#xff0c;一 起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;愿…

单商户商城系统功能拆解44—应用中心—小程序直播

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

shell 基本语法第四讲之(find(文件查找)、xargs(字符串拼凑)、sed(处理文本)、awk(文本处理)、crontab(系统定时器))

20、find(文件查找) 格式 find pathname -options [-print -exec -ok …] 命令说明举例-name按照文件名查找文件。find . -name “1.txt”-perm按照文件权限来查找文件。find . -perm 660-user按照文件属主来查找文件。-group按照文件所属的组来查找文件。-mtime -n n按照文件…

西电计网实验

《计算机通信与网络》网络实验 阅读须知&#xff1a;计网六次实验均已通过线下操作进行验收&#xff08;后面两次善意线上了&#xff09;&#xff0c;写报告由于描述流程困难&#xff0c;故采用eNSP对实验内容进行复现&#xff0c;故此报告实验的过程分析都是基于eNSP&#xf…

MBSE和刚亮相的B-21“突袭者”隐形轰炸机

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> 12月2日&#xff0c;B-21“突袭者”隐形轰炸机举行揭幕仪式。 摘译一篇来自制造商Northrop Grumman公司&#xff08;诺斯罗普格鲁曼公司&#xff09;网站上的文章片段。 利…

stm32cubemx hal学习记录:CAN

一、实验内容 RM C板&#xff0c;can1给can2发送数据 二、CAN总线简介 1、控制器局域网络&#xff1a;Controller Area Network 2、异步半双工通信 3、总线制 CAN由一对差分对&#xff08;两条线&#xff09;CANH和CANL组成 CANH电压比CANL高视为逻辑0&#xff08;显性电…

IDEA插件系列(3):Easy Javadoc插件——快速生成javadoc文档注释

1.插件介绍 Easy Javadoc插件。 能帮助开发者快速生成类、方法、属性等中文javadoc 2.安装方式 第一种安装方式是在线下载安装插件。 第二种安装方式是使用离线插件进行安装。 插件下载地址&#xff1a;https://plugins.jetbrains.com/plugin/12977-easy-javadoc 3.使…

梦开始的地方—— C语言预处理+编译过程

文章目录C语言程序的编译(预处理)1.编译和链接1) 编译的几个阶段预编译阶段编译阶段汇编阶段2) 链接2. 预处理1) 预定义符号2) #define3) #和##4) 带副作用的宏参数5) 宏和函数对比3. 常见预处理命令1) #undef2) 命令行定义3) 条件编译4) 文件包含5) 实现offsetofC语言程序的编…

Spring 中 @Autowired 修饰构造方法时注意事项

代码演示 给定一个类 One&#xff0c;然后看下的几种构造方法什么时候被调用 1、假设现在只有一个默认的空构造方法&#xff0c;代码如下&#xff1a; Component public class One {}然后追踪源码&#xff0c;如下所示&#xff1a; 先拿到所有声明的构造方法 然后挨个判断构…

总结Python设置Excel单元格样式的一切,比官方文档还详细

总结Python设置Excel单元格样式的一切&#xff0c;比官方文档还详细 Python对Excel表格处理非常方便&#xff0c;本文专门对Excel单元格样式设置进行总结&#xff0c;日常用到的设置基本都可以用openpyxl库完成。 创建一个表格 openpyxl是第三方库&#xff0c;如果你还没有安…

如何撰写好的科研论文:摘要(1)

导读 本系列将切片介绍如何写好科研论文&#xff0c;包含了&#xff1a;摘要&#xff0c;背景介绍&#xff0c;方法&#xff0c;结果&#xff0c;讨论等&#xff0c;本文[1]将从摘要开始。 1. 标准 Criteriapointline一般背景听众中的每个人都关心的事情。具体背景从每个人都关…

免费内网穿透工具测评对比,谁更好用 1

文章目录1. 前言2. 对比内容1.1官网主页对比1.2 用户注册对比1.3 用户功能页面对比1.4 客户端对比3. 结语1. 前言 自从接触到内网穿透服务&#xff0c;知道能把自家的电脑、树莓派、NAS等等一堆硬件改造成服务器后&#xff0c;笔者就陷入其中无法自拔&#xff0c;一会儿把树莓…