zoukankan      html  css  js  c++  java
  • pygame快乐游戏编程模块

    Python菜鸟快乐游戏编程_pygame(博主录制,2K分辨率,超高清)

    https://study.163.com/course/courseMain.htm?courseId=1006188025&share=2&shareId=400000000398149

      (原创声明,转载引用需要指明来源)

    游戏编程模块pygame介绍

    pygame是一组旨在编写视频游戏的Python模块。Pygame可以使用python语言创建功能齐全的游戏和多媒体程序。Pygame具有高度的可移植性,几乎可以在所有平台和操作系统上运行。Pygame至今已被下载了数百万次。Pygame非常流行的一个原因是免费。 根据LGPL许可证发布的内容,您可以使用它创建开源,免费软件,共享软件和商业游戏。Pygame历史开始于2000年10月。六个月后发布了pygame 1.0版。pygame的目标是使可视化游戏编程变得简单。 pygame是Python和SDL混合的产物。 SDL由Sam Lantinga创建,与DirectX相比,SDL是用于控制多媒体的跨平台C库。它已用于数百种商业和开源游戏。

    迫不及待的想用pygame写一个自己的游戏了吗?用pip install pygame安装此模块吧。

    pygame官网

    学员查询pygame模块基础语法最好方法是访问官方文档,网址为

    https://www.pygame.org/docs/ref/surface.html

    pygame模块最常用的对象包括:顶层pygame包,颜色, 显示,绘画,事件,字体,图片,键盘,鼠标,常量, 多媒体,矩形, 表面,时间,音乐

    高级对象包括:游标,游戏杆, 图像蒙版,精灵,转换,计算机字体, 绘制形状,重叠式展示,像素阵列,像素复制,数学

    其他对象包括:相机,音频CDROM控制,例子,事件和队列交互, 快速事件,剪贴板支持,测试,触摸,版本。

    pygame 包是可供使用的最顶层的包。Pygame 被分成许多子模块,但是并不会影响程序使用 Pygame。

    pygame常见函数如下:

    pygame.init() — 初始化所有导入的 pygame 模块

    pygame.quit() — 卸载所有导入的 pygame 模块

    pygame.error() — 标准 pygame 异常模块

    pygame.get_error() — 获得当前错误信息

    pygame.set_error() — 设置当前错误信息

    pygame.get_sdl_version() — 获得 SDL 的版本号

    pygame.get_sdl_byteorder() — 获得 SDL 的字节顺序

    pygame.register_quit() — 注册一个函数,这个函数将在 pygame 退出时被调用

    pygame.encode_string() — 对 unicode 或字节对象编码

    pygame.encode_file_path() — 将 unicode 或字节对象编码为文件系统路径

    pygame常用对象为

    pygame.Surface表面

    pygame.draw绘图

    pygame.font字体

    pygame.image图片

    pygame.sprite精灵

    pygame.transform转换

    pygame.event事件

    pygame.time时间

    pygame.mixer.Sound声音

    Pygame语法比较多,且pygame不支持互动shell,不能一行行执行命令,因此最好学习方式是结合游戏实战编程。我们先用10行代码就完成第一个pygame游戏窗口,顺便了解pygame最主要的语法。

    首先输入import pygame,sys导入具有所有可用pygame模块的包和系统模块。

    pygame.display.set_mode()游戏窗口设置

    初始化游戏窗口
    set_mode(size=(0, 0), flags=0, depth=0, display=0) -> Surface

    size参数是一对数字,代表宽度和高度。 flags参数是其他选项的集合。

    depth参数代表用于颜色的位数。颜色位数范围range is {8...32},通常最好不要传递depth参数。对于系统,它将默认为最佳和最快的颜色深度。如果您的游戏需要特定的颜色格式,则可以使用此参数控制深度。 Pygame将模拟不可用的颜色深度,该深度可能很慢。

    如果我们想要让游戏窗口在显示器上全屏展示,我们用pygame.FULLSCREEN对象。
    windowSurface=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),pygame.FULLSCREEN)

    颜色color

     pygame.locals

     此模块包含pygame使用的各种常量。 它的内容会自动放置在pygame模块的命名空间中。 但是,应用程序可以使用pygame.locals仅包含pygame.locals import *的pygame常量。

    Event对象有一个名为type的成员变量(member variable,也叫作属性,attributes或properties),它告诉我们对象表示何种事件。针对pygame.locals模块中的每一种可能的类型,Pygame都有一个常量变量。第9行检查Event对象的type是否等于常量QUIT。记住,由于我们使用了from pygame.locals import *形式的import语句,主要输入QUIT就可以了,而不必输入pygame.locals.QUIT。

    如果Event对象是一个停止事件,就会调用pygame.quit()和sys.exit()函数。pygame. quit()是pygame.init()函数的一种相反的函数,它运行的代码会使得Pygame库停止工作。在调用sys.exit()终止程序之前,总是应该先调用pygame.quit()。通常,由于程序退出之前,Python总是会关闭pygame,这不会真的有什么问题。但是,在IDLE中有一个bug,如果一个Pygame程序在调用pygame.quit()之前就终止了,将会导致IDLE挂起。

    键盘按键

    event.key==ord('a')
    字母a-z:  ord('a')----ord('z'),  ord()内字母必须小写,否则出错。传递的是键盘对应小写字母的ASCII值

    event.key==K_LEFT
    箭头键arrow keys: K_LEFT, K_RIGHT, K_UP, K_DOWN.键盘右边的四个箭头按键
    退出键ESC: K_ESCAPE

    因为导入了from pygame.locals import*,所以我们可以用K_LEFT代替pygame.locals.K_LEFT

    Table 20-1: Constant Variables for Keyboard Keys
    Pygame Constant VariableKeyboard KeyPygame Constant VariableKeyboard Key
    K_LEFT Left arrow K_HOME Home
    K_RIGHT Right arrow K_END End
    K_UP Up arrow K_PAGEUP PgUp
    K_DOWN Down arrow K_PAGEDOWN PgDn
    K_ESCAPE Esc K_F1 F1
    K_BACKSPACE Backspace K_F2 F2
    K_TAB Tab K_F3 F3
    K_RETURN Return or Enter K_F4 F4
    K_SPACE Space bar K_F5 F5
    K_DELETE Del K_F6 F6
    K_LSHIFT Left Shift K_F7 F7
    K_RSHIFT Right Shift K_F8 F8
    K_LCTRL Left Ctrl K_F9 F9
    K_RCTRL Right Ctrl K_F10 F10
    K_LALT Left Alt K_F11 F11
    K_RALT Right Alt K_F12 F12

    pygame.event
    用于处理事件与事件队列的 Pygame 模块。

    函数
        pygame.event.pump()  —  让 Pygame 内部自动处理事件
        pygame.event.get()  —  从队列中获取事件
        pygame.event.poll()  —  从队列中获取一个事件
        pygame.event.wait()  —  等待并从队列中获取一个事件
        pygame.event.peek()  —  检测某类型事件是否在队列中
        pygame.event.clear()  —  从队列中删除所有的事件
        pygame.event.event_name()  —  通过 id 获得该事件的字符串名字
        pygame.event.set_blocked()  —  控制哪些事件禁止进入队列
        pygame.event.set_allowed()  —  控制哪些事件允许进入队列
        pygame.event.get_blocked()  —  检测某一类型的事件是否被禁止进入队列
        pygame.event.set_grab()  —  控制输入设备与其他应用程序的共享
        pygame.event.get_grab()  —  检测程序是否共享输入设备
        pygame.event.post()  —  放置一个新的事件到队列中
        pygame.event.Event()  —  创建一个新的事件对象
        pygame.event.EventType  —  代表 SDL 事件的 Pygame 对象
    Pygame 通过事件队列控制所有的时间消息。该模块中的程序将帮你管理事件队列。输入队列很大程度依赖于 pygame 的 display 模块。如果 display 没有被初始化,显示模式没有被设置,那么事件队列就还没有开始真正工作。
    常规的队列是由 pygame.event.EventType 定义的事件对象的组成,有多种方法来访问里边的事件对象:从简单的检测事件是否存在,到直接从栈中获取它们。
    为了保持 Pygame 和系统同步,你需要调用 pygame.event.pump() 确保实时更新,你将在游戏的每次循环中调用这个函数。

    在做测试时,你可以输出事件对象以及相应的类型和成员。来自系统的事件都有一个事件类型和对应的成员属性,下边是每个事件类型以及对应的成员属性列表:

    pygame.event.get()
    从队列中获取事件。
    get() -> Eventlist
    get(type) -> Eventlist
    get(typelist) -> Eventlist
    这将获取并从队列中删除事件。如果指定一个或多个 type 参数,那么只获取并删除指定类型的事件。
    请注意,如果你只从队列中获取和删除指定的事件,那么久而久之,队列可能被你不关注的事件所填满。

    pygame.font字体

    1.从系统字体库创建一个 Font 对象
    font = pygame.font.SysFont(None, 48) #不熟悉字体名的就用None
    pygame.font.SysFont(“字体”,字体大小)
    举例
    font = pygame.font.SysFont('Arial', 48)

    2.使用对象里的 render方法渲染文字
    render(text, antialias, color, background=None) -> Surface
    举例
    textobj = font.render(“”hello“”, 1, TEXTCOLOR)

    3.获取字体矩形坐标
    textrect = textobj.get_rect()


    4.字体矩形坐标左上点赋值
    textrect.topleft = (x, y)


    5.字体更新到游戏窗口上
    surface.blit(textobj, textrect)
    drawText('Zombie VS Plants', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 4))

    image图像

    >>> pygame.image.__doc__

    'pygame module for image transfer'
    >>> dir(pygame.image)
    ['__doc__', '__file__', '__name__', '__package__', 'frombuffer', 'fromstring', 'get_extended', 'load', 'load_basic', 'load_extended', 'save', 'save_extended', 'tostring']

    2
    图形尺寸转换的函数:
    >>> pygame.transform.scale.__doc__
    'scale(Surface, (width, height), DestSurface = None) -> Surface resize to new resolution'

    zombieImage=pygame.image.load('zombie.png')
    zombieImageStretchedImage=pygame.transform.scale(zombieImage,(40,40))

    pygame.transform.scale()函数可以放大或缩小精灵。
    第一个参数是pygame.Surface 对象上画的图像。第二个参数是图形新尺寸。
    pygame.transform.scale()函数返回一个pygame.Surface对象,此对象上的图像被赋予新尺寸。我们把原尺寸图像保存在变量playerImage 。但新的图像保存在变量playerStretchedImage。
    playerImage and foodImage中保存的surface对象和用于window的surface对象一样。游戏中,我们把这些图像,字体的surfaces复制到window的surface,这样用户就可以在window窗口一目了然。Font 对象render()方法产生的surface对象也一样,为了显示文字,我们不得不复制surface对象到window surface对象。最后通过update()方法把window surface对象显示到屏幕上。
    当矩形对象代表player的位置和尺寸时,player的图像也被保存在 playerStretchedImage变量中。我们用 pygame.transform.scale()函数改变了图像尺寸。确保传递原surface对象到变量 playerImage ,而不是到变量playerStretchedImage。图像尺寸变化后,图像会有点受损。如果反复变化尺寸,受损会越来越明显。但我们把原图像赋予新尺寸,受损只有小小一次。这就是为什么我们把playerImage变量作为第一个参数传递给pygame.transform.scale()

    3
    图形载入的函数
     >>> pygame.image.load.__doc__
    'pygame module for image transfer'
    pygame.image.load()函数被传递一个图形文件的字符串参数,然后加载。 value of pygame.image.load()返回一个surface对象,这个对象中,图像文件中图像画在它的surface上。我们把这surface对象保存在playerimage内。要确保图像位置和python目录一致。
    sprite精灵代表一个二维图像,并作为屏幕上图形一部分。
     
    这是精灵作为全图的例子
    精灵图像被画在背景顶部。注意我们可以水平翻转精灵图像,这样精灵貌似朝着另一个方向。我们可以在同一个窗口画多个相同精灵。我们也可以重新定义精灵的尺寸,变大或变小。背景图像可以被看做一个大精灵。
     

    精灵图像被画在背景顶部。注意我们可以水平翻转精灵图像,这样精灵貌似朝着另一个方向。我们可以在同一个窗口画多个相同精灵。我们也可以重新定义精灵的尺寸,变大或变小。背景图像可以被看做一个大精灵。
    精灵被保存在电脑图像文件中pygame用的图像格式包括:  BMP, PNG, JPG (and JPEG), and GIF.你也可以从web浏览器下载图像,你也可以用绘图程序制作图像。绘图工具有photoshop,MS Paint or Tux Paint.

    pygame.rect()

    rect = pygame.Rect(300, 100, 40, 40)

    Pygame 通过 Rect 对象存储和操作矩形区域。一个 Rect 对象可以由 left,top,width,height 几个值创建。

     

    rect对象是用来存储矩形对象的,rect对象有一些虚拟属性,

    比如top.left,bottom.right这些是用来固定矩形的位置的,

    还有size,width,height,这些是描述矩形大小,宽高分别是多大,

    center为矩形的中心点,其实就是关于横纵坐标的二元组,因此又有centerx,centery两个属性。此外,还有x,y。

    2.来自Pygame中文文档的解释:

    class pygame.Rect

    Rect是用于存储矩形坐标的pygame对象。

    “构造”方法:

    1).rect = pygame.Rect( left , top, width, height )

    2). rect = pygame.Rect(( left , top),( width, height) )

    3).rect = pygame.Rect(object)

     

    Rect.move_ip
    moves the rectangle, in place
    Rect.move_ip(x, y): return None

    Same as the Rect.move - moves the rectangle method, but operates in place.

    区别在于move_ip改变直接调整对象,move返回一个改变后的对象。

     

    surface.blit VS pygame.display.update()

    surface.blit是在游戏窗口surface上绘制对象

    pygame.display.update()是把游戏窗口surface加载到电脑显示屏幕上

     

     Surface.blit()

    windowSurface.blit(bouncerStretchedImage,rect)

    做出blit这个动作的人是一个Surface类的实例,

    这个人即将在自己身上画图,

    他需要两个参数:要画的图片,和画的位置,即source和rect.

     source的类型是Surface, pygame.image.load(图片路径)返回的就是Surface

    rect需要指定两个值,left和top,Surface类有get_rect()方法,返回Rect

    Rect 是这个样子:

    Rect(left, top, width, height) -> Rect
    (left,top)坐标确定图片所在位置,width和height确定图片宽和高

    冲突检测
    图形化游戏最常见行为就是冲突检测。冲突检测指:屏幕上两个对象是否重叠。如果玩家碰到敌人,则可能损失生命值。在矩形弹动游戏中,冲突检测指两个矩形是否重叠。

    >>> pygame.Rect.colliderect.__doc__
    'colliderect(Rect) -> bool test if two rectangles overlap'
    #测试玩家是否触碰到僵尸
    def playerHasHitZombie(playerRect, zombies):
        for z in zombies:
            #test if two rectangles overlap测试是否触碰到僵尸
            if playerRect.colliderect(z['rect']):
                return True
        return False
    
    #测试子弹是否触碰到僵尸。如果是,就把该僵尸移除
    def bulletHasHitZombie(bullets, zombies):
        for b in bullets:
            if b['rect'].colliderect(z['rect']):
                bullets.remove(b)
                return True
        return False
    
    #测试子弹是否触碰到新僵尸。如果是,就把该僵尸移除
    def bulletHasHitCrawler(bullets, newKindZombies):
        for b in bullets:
            if b['rect'].colliderect(c['rect']):
                bullets.remove(b)
                return True
        return False
    

    创建一个简单的游戏窗口

    首先输入import pygame,sys导入具有所有可用pygame模块的包和系统模块。

    现在游戏窗口还没有任何内容,之后我们可以逐步添加,设计自己的游戏。我已经用pygame完成了贪吃蛇,植物大战僵尸,俄罗斯方块,开心消消乐等知名游戏。

    2.实例:python代码写个植物大战僵尸游戏

    植物大战僵尸

    《植物大战僵尸》是由PopCap Games开发的一款益智策略类单机游戏,发售于2009年5月5日。玩家通过利用多种植,并切换不同的功能,快速有效地把僵尸阻挡在入侵的道路上。

    游戏里有26种僵尸,包括铁桶,报纸,铁门,橄榄球头盔,雪橇车,南瓜头,矿工帽,铁梯僵尸。这些僵尸会入侵我们后花园,我们要用各种植物消灭入侵僵尸。

     

    49种植物每种都有不同的功能,例如樱桃炸弹可以和周围一定范围内的所有僵尸同归于尽,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以针对不同僵尸的弱点来合理地种植植物,这也是胜利的诀窍。

     

    下图是我用pygame编写的简易版植物大战僵尸游戏一个蓝色植物正在吐出圆球攻击僵尸,僵尸数量和移动速度可以自己控制。如果集中一个僵尸,score分数会增加一分,zombies gotten past记录有多少僵尸已经越过植物。当然我还可以设计一些作弊的按键,非常有趣!

     

    不同的敌人,不同的玩法构成五种不同的游戏模式,加之黑夜、浓雾以及泳池之类的障碍增加了游戏挑战性。

    这是房顶上植物们拼命抵抗僵尸入侵场景。

     

    这是在后花园的游泳池里植物们拼命抵抗僵尸入侵场景。

     

    僵尸挺聪明的,如果白天入侵不成功,就晚上搞偷袭。这是在深夜植物们拼命抵抗僵尸入侵场景。

     

    这款python代码当然不是复现原款游戏所有功能,而是简单模拟一下其中乐趣。首先我们准备好以下素材。包括三张僵尸图片:

    BucketheadZombie.gif,ConeheadZombie.gif,zombie.png。

    一张植物图片plant.gif,一张背景图片background.png,一张子弹图片bullet.png

    一首背景音乐background.mp3,一首游戏结束音乐gameover.mp3。由于游戏是之前基于python2.7版本写的,因此建议素材名称使用英文,python2版本对中文支持不太友好。

     

    由于这款游戏代码量太大,这里就不一一展开说明,我建议你们直接去下载源代码和图片,然后根据自己爱好,更改一下背景音乐,图片,和僵尸数量,移动速度等参数设置。我对游戏一些重要语法做一些说明。

    pygame.display.set_caption(words)设置窗口标题

    pygame.display.set_caption(words)方法是设置窗口标题,words参数是窗口标题。我们沿用之前脚本运行下面脚本,我们就生成了一个有Zombie VS Plants标题的窗口。

    pygame.event事件

    常见事件有QUIT,KEYDOWN,KEYUP

    while True:                  #main game loop游戏主循环
        for event in pygame.event.get(): #遍历pygame事件列表
            if event.type==QUIT:        #如果点击关闭按钮(window右上)
                pygame.quit()           #关闭pygame库
                sys.exit()              #系统退出
    

     建立一个简单游戏窗口

    import pygame,sys            #导入pygame和sys模块
    from pygame.locals import*   #导入pygame 局部变量
    pygame.init()                #pygame所有模块初始化
    screen=pygame.display.set_mode((400,300))#设置屏幕长和宽值
    pygame.display.set_caption('Zombie VS Plants')# 设置窗口标题
    while True:                  #main game loop游戏主循环
        for event in pygame.event.get(): #遍历pygame事件列表
            if event.type==QUIT:        #如果点击关闭按钮(window右上)
                pygame.quit()           #关闭pygame库
                sys.exit()              #系统退出
    

     

    pygame.time.Clock

    pygame.time.Clock创建一个新的Clock对象,该对象可用于跟踪时间量。 时钟还提供了多种功能来帮助控制游戏的帧频。

    pygame中的时间以毫秒(1/1000秒)表示。 大多数平台的时间分辨率有限,大约为10毫秒。 该分辨率(以毫秒为单位)在TIMER_RESOLUTION常量中给出。

    pygame.time.Clock.tick()

    tick(framerate=0) -> milliseconds

    每帧应调用一次此方法。 它将计算自上次调用以来经过了多少毫秒。
    如果您传递可选的帧速率参数,该功能将延迟以使游戏的运行速度低于给定的每秒滴答声。 这可以用来帮助限制游戏的运行速度。 通过每帧调用Clock.tick(40)一次,该程序将永远不会以每秒40帧以上的速度运行。一般情况framerate设置为40.

    游戏运行时每秒所运行的帧数(简称FPS,Frames Per Second) 和视频一样,FPS越大,在屏幕上的视频就越来越平滑,直到一个临界点(大约是100FPS),超过这个临界点,再高的FPS都只是一个令人惊奇的数值,400FPS和100FPS在人的视觉中几乎没有差别。
    FPS取决于显卡,其次是内存,CPU,然后是网络(如果是网络游戏的话)与硬盘。
    一般游戏都是40左右fps就可以称之为流畅了。比如策略类(三国志什么的)5fps也是可以接受的。但赛车类 5fps根本玩不下去。
    每款游戏都会有一个官方提供的最低配置要求,尤其是网络游戏,但这个最低配置仅仅适用于将游戏内的所有视频效果全部关闭的状态下使用,而且网络游戏中对于网速的问题是忽略不计的。
    只有提高电脑的显卡、内存才能在网络因素不确定的情况下达到最理想的游戏流畅效果。

    音乐music

    我们曾经玩任何游戏都会伴随动听的背景音乐。pygame.mixer是一个用来处理声音的模块,其含义为“混音器”。因此我们准备用以下方法pygame.mixer.music.load('background.mp3')加载mp3格式背景音乐并准备播放。这样游戏就会深动形象。

    pygame.mixer.music.play(loop, start)方法用于播方音乐,loop表示循环次数,如果loop=1表示音乐播方一次。如果loop=2, 表示音乐播方两次。如果loop=-1,表示音乐不停循环。start 参数控制音乐从哪里开始播放。开始的位置取决于音乐的格式。MP3 和 OGG 使用时间表示播放位置(以秒为单位)。MOD使用模式顺序编号表示播放位置。如果音乐文件无法设置开始位置,则传递了start参数后会产生一个NotImplementedError 错误。

    pygame.mixer.music.stop()方法用于结束音乐播放。如果游戏结束,我们可以加上这句方法,停止播放音乐。

    pygame.mixer.music.load('background.mp3') ##载入一个音乐文件用于播放
    #,如果 loops = -1,则表示无限重复播放。start 参数控制音乐从哪里开始播放。
    pygame.mixer.music.play(-1, 0.0) #开始播放音乐流
    pygame.mixer.music.stop()#停止音乐播放
    

    我们把加载和播方声音的代码加入主程序,这样游戏窗口就有音乐了。

    import pygame,sys            #导入pygame和sys模块
    from pygame.locals import*   #导入pygame 局部变量
    pygame.init()                #pygame所有模块初始化
    screen=pygame.display.set_mode((400,300))#设置屏幕长和宽值
    pygame.display.set_caption('Zombie VS Plants')
    
    pygame.mixer.music.load('background.mp3') ##载入一个音乐文件用于播放
    #,如果 loops = -1,则表示无限重复播放。start 参数控制音乐从哪里开始播放。
    pygame.mixer.music.play(-1, 0.0) #开始播放音乐流
    while True:                  #main game loop游戏主循环
        
        for event in pygame.event.get(): #遍历pygame事件列表
            if event.type==QUIT:        #如果点击关闭按钮(window右上)
                pygame.quit()           #关闭pygame库
                sys.exit()              #系统退出
    pygame.mixer.music.stop()#停止音乐播放
    

    游戏结束时也会有相应音乐,我们文件里游戏结束音乐时wav格式的,和之前mp3格式不一样,我们用gameOverSound = pygame.mixer.Sound('gameover.wav')方法把游戏结束音乐放入gameOverSound变量。gameOverSound.play()方法播放游戏结束音乐。gameOverSound.stop()方法用于停止游戏结束声音播放。

    # set up sounds设置声音
    gameOverSound = pygame.mixer.Sound('gameover.wav')
    gameOverSound.play()  #播放游戏结束时声音
    gameOverSound.stop() #游戏结束声音停止
    

    参数前置

    我们用pygame.display.set_mode((400,300))方法设置屏幕大小时候400,300为屏幕的长和宽。在大型程序设计时,一般不把具体数字放入方法里,而是用变量代替。我们用WINDOWWIDTH表示游戏窗口宽度,用WINDOWHEIGHT 表示游戏窗口高度,WINDOWWIDTH = 1024,WINDOWHEIGHT = 600。我们用以下代码实现游戏窗口大小的参数前置。

    import pygame,sys            #导入pygame和sys模块
    from pygame.locals import*   #导入pygame 局部变量
    #设置变量参数,参数前置
    WINDOWWIDTH = 1024           #游戏窗口宽度
    WINDOWHEIGHT = 600           #游戏窗口高度
    pygame.init()                #pygame所有模块初始化
    screen=pygame.display.set_mode((400,300))#设置屏幕长和宽值
    pygame.display.set_caption('Zombie VS Plants')
    #设置窗口大小
    windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.mixer.music.load('background.mp3') ##载入一个音乐文件用于播放
    #,如果 loops = -1,则表示无限重复播放。start 参数控制音乐从哪里开始播放。
    pygame.mixer.music.play(-1, 0.0) #开始播放音乐流
    while True:                  #main game loop游戏主循环
        for event in pygame.event.get(): #遍历pygame事件列表
            if event.type==QUIT:        #如果点击关闭按钮(window右上)
                pygame.mixer.music.stop()#停止播放音乐
                pygame.quit()           #关闭pygame库
                sys.exit()              #系统退出
    

    如果我们想要让游戏窗口在显示器上全屏展示,我们用pygame.FULLSCREEN对象。

    import pygame,sys            #导入pygame和sys模块
    from pygame.locals import*   #导入pygame 局部变量
    #设置变量参数,参数前置
    WINDOWWIDTH = 1024           #游戏窗口宽度
    WINDOWHEIGHT = 600           #游戏窗口高度
    pygame.init()                #pygame所有模块初始化
    screen=pygame.display.set_mode((400,300))#设置屏幕长和宽值
    pygame.display.set_caption('Zombie VS Plants')
    #设置窗口大小
    windowSurface=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),pygame.FULLSCREEN)
    pygame.mixer.music.load('background.mp3') ##载入一个音乐文件用于播放
    #,如果 loops = -1,则表示无限重复播放。start 参数控制音乐从哪里开始播放。
    pygame.mixer.music.play(-1, 0.0) #开始播放音乐流
    while True:                  #main game loop游戏主循环
        for event in pygame.event.get(): #遍历pygame事件列表
            if event.type==QUIT:        #如果点击关闭按钮(window右上)
                pygame.mixer.music.stop() #停止播放音乐
                pygame.quit()           #关闭pygame库
                sys.exit()              #系统退出
    

    鼠标

    #鼠标设置不可见

    pygame.mouse.set_visible(False)

    键盘设置

     

    while True:
        for event in pygame.event.get():
            if event.type==QUIT:
                terminate()
            if event.type==pygame.locals.KEYDOWN:
                #change the keyboard variables键盘键设置上下左右
                if event.key==pygame.locals.K_LEFT or event.key==ord('a'):
                    moveRight=False
                    moveLeft=True
                if event.key==pygame.locals.K_RIGHT or event.key==ord('d'):
                    moveLeft=False
                    moveRight=True
                if event.key==pygame.locals.K_UP or event.key==ord('w'):
                    moveDown=False
                    moveUp=True
                if event.key==pygame.locals.K_DOWN or event.key==ord('s'):
                    moveDown=True
                    moveUp=False
            #有KEYDOWN就一定有KEYUP,否则游戏对象会持续移动
            if event.type==pygame.locals.KEYUP:
                if event.key==pygame.locals.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                if event.key==pygame.locals.K_LEFT or event.key==ord('a'):
                    moveLeft=False
                if event.key==K_RIGHT or event.key==ord('d'):
                    moveRight=False
                if event.key==K_UP or event.key==ord('w'):
                    moveUp=False
                if event.key==K_DOWN or event.key==ord('s'):
                    moveDown=False
              
        # move the bouncer data structure
        if moveDown and p_destination.bottom<WINDOWHEIGHT:
            p_destination.top+=PLAYERMOVERATE 
        
        if moveUp and p_destination.top>0:
            p_destination.top-=PLAYERMOVERATE 
            
        if moveLeft and p_destination.left>0:
            p_destination.left-=PLAYERMOVERATE 
    
        if moveRight and p_destination.right<WINDOWWIDTH:
            p_destination.right+=PLAYERMOVERATE 
            
        # Draw the game world on the window.
        windowSurface.blit(rescaledBackground, (0, 0))
        windowSurface.blit(zombieStretchedImage,z_destination)
        windowSurface.blit(playerImage,p_destination)
    

      

    发射子弹

    '''
    playerRect = playerImage.get_rect()
    playerRect.topleft = (50, WINDOWHEIGHT /2)
    
    #子弹图像加载
    bulletImage = pygame.image.load('SnowPeashooterBullet.gif')
    bulletRect = bulletImage.get_rect()
    
    #连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然
    BULLETSPEED = 30
    #新增子弹速度,值越小,子弹发射越快
    ADDNEWBULLETRATE = 5
    b['rect'].move_ip(1 * BULLETSPEED, 0)
    #增加子弹计数器
    bulletAddCounter = 0
    '''
    
    import pygame, random, sys, time
    from pygame.locals import *
    
    #set up some variables
    WINDOWWIDTH = 1024
    WINDOWHEIGHT = 600
    #值设置低一些,僵尸移动速度变慢
    FPS = 20
    PLAYERMOVERATE = 15
    #连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然
    BULLETSPEED = 30
    #新增子弹速度,值越小,子弹发射越快
    ADDNEWBULLETRATE = 5
    shoot = False
    #增加子弹计数器
    bulletAddCounter = 0
    RED = (255, 0, 0)
    
    #结束游戏
    def terminate():
        pygame.quit()
        sys.exit()
    
    # set up pygame, the window, and the mouse cursor
    pygame.init()
    #reate an object to help track time
    mainClock = pygame.time.Clock()
    windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))#, pygame.FULLSCREEN)
    #窗口标题
    pygame.display.set_caption('Zombie Defence')
    #鼠标设置不可见
    #pygame.mouse.set_visible(False)
    
    # set up fonts设置字体
    font = pygame.font.SysFont(None, 48)
    
    #加载声音
    pygame.mixer.music.load('grasswalk.mp3')
    
    # set up images
    playerImage = pygame.image.load('SnowPea.gif')
    #get the rectangular area of the Surface
    #Returns a new rectangle covering the entire surface. This rectangle will 
    #always start at (0, 0) with a width and height the same size as the image.
    playerRect = playerImage.get_rect()
    #子弹图像加载
    bulletImage = pygame.image.load('SnowPeashooterBullet.gif')
    bulletRect = bulletImage.get_rect()
    
    zombieImage=pygame.image.load("zombie.png")
    zombieStretchedImage=pygame.transform.scale(zombieImage,(80,80))
    z_destination=pygame.Rect(944, 300, 80, 80)
    #游戏背景图片加载
    backgroundImage = pygame.image.load('background.png')
    #对背景图片尺寸重新调整大小,宽为WINDOWWIDTH,长为WINDOWHEIGHT
    rescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT))
    
    zombies = []
    bullets = []
    playerRect.topleft = (50, WINDOWHEIGHT /2)
    moveLeft = moveRight = False
    moveUp=moveDown = False
    
    pygame.mixer.music.play(-1, 0.0)
    
    #游戏开始循环
    while True: # the game loop runs while the game part is playing
        
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
    
            if event.type == KEYDOWN:
                if event.key == K_UP or event.key == ord('w'):
                    moveDown = False
                    moveUp = True
                if event.key == K_DOWN or event.key == ord('s'):
                    moveUp = False
                    moveDown = True
    
                if event.key == K_SPACE:
                    shoot = True
    
            if event.type == KEYUP:
                if event.key == K_ESCAPE:
                    terminate()
    
                if event.key == K_UP or event.key == ord('w'):
                    moveUp = False
                if event.key == K_DOWN or event.key == ord('s'):
                    moveDown = False
                    
                if event.key == K_SPACE:
                    shoot = False
    
        # add new bullet新增子弹
        #新增子弹计数器
        bulletAddCounter += 1
        print("bulletAddCounter:",bulletAddCounter)
        #当while循环次数大于ADDNEWBULLETRATE时,才能发射子弹
        if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:
            print("shoot")
        #if  shoot == True:  #如果不限制,子弹会连发,没有距离感
            bulletAddCounter = 0
            #playerRect.centery-25是为了让子弹上升一点,与植物炮口平行,centerx+10是为了子弹在前面点出现
            newBullet = {'rect':pygame.Rect(playerRect.centerx+10, playerRect.centery-30, bulletRect.width, bulletRect.height),
    						 'surface':pygame.transform.scale(bulletImage, (bulletRect.width, bulletRect.height)),
    						}
            bullets.append(newBullet)
            
    
        # Move the player around.
        if moveUp and playerRect.top > 30:
            playerRect.move_ip(0,-1 * PLAYERMOVERATE)
        if moveDown and playerRect.bottom < WINDOWHEIGHT-10:
            playerRect.move_ip(0,PLAYERMOVERATE)
            
        # move the bullet移动子弹
        for b in bullets:
            b['rect'].move_ip(1 * BULLETSPEED, 0)
            #print(b['rect'])
            
        # Draw the game world on the window.
        windowSurface.blit(rescaledBackground, (0, 0))
        # Draw the player's rectangle, rails
        windowSurface.blit(playerImage, playerRect)
        windowSurface.blit(zombieStretchedImage,z_destination)
            
        # draw each bullet将所有子弹绘制到游戏界面上
        for b in bullets:
            windowSurface.blit(b['surface'], b['rect'])
           
        # update the display
        pygame.display.update()
        #tick(framerate=0) -> milliseconds
        #帧速率参数,该功能将延迟以使游戏的运行速度低
        mainClock.tick(FPS)
        #print("bullets",bullets)
    

      

     random.randint(a,b)随机生成若干移动僵尸

    在python中的random.randint(a,b)用于生成一bai个指定范围内的整数。du其中参数zhia是下限,参数b是上限,生成的随机dao数n: a <= n <= b。

    '''
    僵尸移动
    '''
    
    import pygame, random, sys, time
    from pygame.locals import *
    
    #set up some variables
    WINDOWWIDTH = 1024
    WINDOWHEIGHT = 600
    #值设置低一些,僵尸移动速度变慢
    FPS = 20
    PLAYERMOVERATE = 15
    #连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然
    BULLETSPEED = 30
    #新增子弹速度,值越小,子弹发射越快
    ADDNEWBULLETRATE = 5
    shoot = False
    #增加子弹计数器
    bulletAddCounter = 0
    #增加僵尸计数器
    zombieAddCounter=0
    
    ZOMBIESIZE = 100 #includes newKindZombies
    #新增丧尸速度,值设置大些,丧失数量少些
    ADDNEWZOMBIERATE = 50
    ADDNEWKINDZOMBIE = ADDNEWZOMBIERATE
    
    NORMALZOMBIESPEED = 2
    NEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2
    
    # set up the colors颜色值设置,可用于背景颜色
    BLACK = (0, 0, 0)
    GREEN = (0, 255, 0)
    WHITE = (255, 255, 255)
    RED=(255, 0, 0)
    #结束游戏
    def terminate():
        pygame.quit()
        sys.exit()
    
    # set up pygame, the window, and the mouse cursor
    pygame.init()
    #reate an object to help track time
    mainClock = pygame.time.Clock()
    windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))#, pygame.FULLSCREEN)
    #窗口标题
    pygame.display.set_caption('Zombie Defence')
    #鼠标设置不可见
    #pygame.mouse.set_visible(False)
    
    # set up fonts设置字体
    font = pygame.font.SysFont(None, 48)
    
    #加载声音
    pygame.mixer.music.load('grasswalk.mp3')
    
    # set up images
    playerImage = pygame.image.load('SnowPea.gif')
    #get the rectangular area of the Surface
    #Returns a new rectangle covering the entire surface. This rectangle will 
    #always start at (0, 0) with a width and height the same size as the image.
    playerRect = playerImage.get_rect()
    #子弹图像加载
    bulletImage = pygame.image.load('SnowPeashooterBullet.gif')
    bulletRect = bulletImage.get_rect()
    
    zombieImage=pygame.image.load("zombie.png")
    zombieStretchedImage=pygame.transform.scale(zombieImage,(80,80))
    z_destination=pygame.Rect(944, 300, 80, 80)
    #游戏背景图片加载
    backgroundImage = pygame.image.load('background.png')
    #对背景图片尺寸重新调整大小,宽为WINDOWWIDTH,长为WINDOWHEIGHT
    rescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT))
    
    zombies = []
    bullets = []
    playerRect.topleft = (50, WINDOWHEIGHT /2)
    moveLeft = moveRight = False
    moveUp=moveDown = False
    
    pygame.mixer.music.play(-1, 0.0)
    
    #游戏开始循环
    while True: # the game loop runs while the game part is playing
        
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
    
            if event.type == KEYDOWN:
                if event.key == K_UP or event.key == ord('w'):
                    moveDown = False
                    moveUp = True
                if event.key == K_DOWN or event.key == ord('s'):
                    moveUp = False
                    moveDown = True
    
                if event.key == K_SPACE:
                    shoot = True
    
            if event.type == KEYUP:
                if event.key == K_ESCAPE:
                    terminate()
    
                if event.key == K_UP or event.key == ord('w'):
                    moveUp = False
                if event.key == K_DOWN or event.key == ord('s'):
                    moveDown = False
                    
                if event.key == K_SPACE:
                    shoot = False
        # Add new zombies at the top of the screen, if needed.增加上市
        zombieAddCounter += 1
        if zombieAddCounter == ADDNEWKINDZOMBIE:
            zombieAddCounter = 0
            zombieSize = ZOMBIESIZE       
            newZombie = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-zombieSize-10), zombieSize, zombieSize),
                            'surface':pygame.transform.scale(zombieImage, (zombieSize, zombieSize)),
                            }
            zombies.append(newZombie)
                
        # add new bullet新增子弹
        #新增子弹计数器
        bulletAddCounter += 1
        print("bulletAddCounter:",bulletAddCounter)
        #当while循环次数大于ADDNEWBULLETRATE时,才能发射子弹
        if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:
            print("shoot")
        #if  shoot == True:  #如果不限制,子弹会连发,没有距离感
            bulletAddCounter = 0
            #playerRect.centery-25是为了让子弹上升一点,与植物炮口平行,centerx+10是为了子弹在前面点出现
            newBullet = {'rect':pygame.Rect(playerRect.centerx+10, playerRect.centery-30, bulletRect.width, bulletRect.height),
    						 'surface':pygame.transform.scale(bulletImage, (bulletRect.width, bulletRect.height)),
    						}
            bullets.append(newBullet)
            
    
        # Move the player around.
        if moveUp and playerRect.top > 30:
            playerRect.move_ip(0,-1 * PLAYERMOVERATE)
        if moveDown and playerRect.bottom < WINDOWHEIGHT-10:
            playerRect.move_ip(0,PLAYERMOVERATE)
            
        # move the bullet移动子弹
        for b in bullets:
            b['rect'].move_ip(1 * BULLETSPEED, 0)
            #print(b['rect'])
            
        # Move the zombies.
        for z in zombies:
            z['rect'].move_ip(-1*NORMALZOMBIESPEED, 0)
            
        # Draw the game world on the window.
        windowSurface.blit(rescaledBackground, (0, 0))
        # Draw the player's rectangle, rails
        windowSurface.blit(playerImage, playerRect)
        windowSurface.blit(zombieStretchedImage,z_destination)
            
        # draw each bullet将所有子弹绘制到游戏界面上
        for b in bullets:
            windowSurface.blit(b['surface'], b['rect'])
        
        # Draw each baddie
        for z in zombies:
            windowSurface.blit(z['surface'], z['rect'])
           
        # update the display
        pygame.display.update()
        #tick(framerate=0) -> milliseconds
        #帧速率参数,该功能将延迟以使游戏的运行速度低
        mainClock.tick(FPS)
        #print("bullets",bullets)
    

      

    完整的植物大战僵尸游戏代码如下。你们可以根据自己偏好来改变人物图片,背景,配音。

    import pygame, random, sys, time
    from pygame.locals import *
    
    #set up some variables
    WINDOWWIDTH = 1024
    WINDOWHEIGHT = 600
    #值设置低一些,僵尸移动速度变慢
    FPS = 20
    MAXGOTTENPASS = 10
    ZOMBIESIZE = 100 #includes newKindZombies
    #新增丧尸速度,值设置大些,丧失数量少些
    ADDNEWZOMBIERATE = 50
    ADDNEWKINDZOMBIE = ADDNEWZOMBIERATE
    NORMALZOMBIESPEED = 2
    NEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2
    PLAYERMOVERATE = 15
    #子弹速度
    BULLETSPEED = 20
    ADDNEWBULLETRATE = 15
    
    TEXTCOLOR = (255, 255, 255)
    RED = (255, 0, 0)
    
    #结束游戏
    def terminate():
        pygame.quit()
        sys.exit()
    #等待玩家按键
    def waitForPlayerToPressKey():
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    terminate()
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE: # pressing escape quits
                        terminate()
                    if event.key == K_RETURN:
                        return
    
    #测试玩家是否触碰到僵尸
    def playerHasHitZombie(playerRect, zombies):
        for z in zombies:
            #test if two rectangles overlap测试是否触碰到僵尸
            if playerRect.colliderect(z['rect']):
                return True
        return False
    
    #测试子弹是否触碰到僵尸。如果是,就把该僵尸移除
    def bulletHasHitZombie(bullets, zombies):
        for b in bullets:
            if b['rect'].colliderect(z['rect']):
                bullets.remove(b)
                return True
        return False
    
    #测试子弹是否触碰到新僵尸。如果是,就把该僵尸移除
    def bulletHasHitCrawler(bullets, newKindZombies):
        for b in bullets:
            if b['rect'].colliderect(c['rect']):
                bullets.remove(b)
                return True
        return False
    
    #输入文字显示
    def drawText(text, font, surface, x, y):
        textobj = font.render(text, 1, TEXTCOLOR)
        textrect = textobj.get_rect()
        textrect.topleft = (x, y)
        #draw one image onto another
        surface.blit(textobj, textrect)
    
    # set up pygame, the window, and the mouse cursor
    pygame.init()
    #reate an object to help track time
    mainClock = pygame.time.Clock()
    windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))#, pygame.FULLSCREEN)
    #窗口标题
    pygame.display.set_caption('Zombie VS Plants')
    #鼠标设置不可见
    pygame.mouse.set_visible(False)
    # set up fonts设置字体
    font = pygame.font.SysFont(None, 48)
    # set up sounds设置声音
    gameOverSound = pygame.mixer.Sound('gameover.wav')
    #加载声音
    pygame.mixer.music.load('background.mp3')
    # set up images
    playerImage = pygame.image.load('plant.gif')
    #get the rectangular area of the Surface
    #Returns a new rectangle covering the entire surface. This rectangle will 
    #always start at (0, 0) with a width and height the same size as the image.
    playerRect = playerImage.get_rect()
    #子弹图像加载
    bulletImage = pygame.image.load('bullet.gif')
    bulletRect = bulletImage.get_rect()
    zombieImage = pygame.image.load('zombie.png')
    newKindZombieImage = pygame.image.load('ConeheadZombie.gif')
    #newKindZombieImage = pygame.image.load('trump31.png')
    #游戏背景图片加载
    backgroundImage = pygame.image.load('background.png')
    #对背景图片尺寸重新调整大小,宽为WINDOWWIDTH,长为WINDOWHEIGHT
    rescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT))
    
    # show the "Start" screen
    windowSurface.blit(rescaledBackground, (0, 0))
    windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))
    drawText('Zombie VS Plants', font, windowSurface, (WINDOWWIDTH / 4), (WINDOWHEIGHT / 4))
    drawText('Press Enter to start', font, windowSurface, (WINDOWWIDTH / 3) - 10, (WINDOWHEIGHT / 3) + 50)
    pygame.display.update()
    waitForPlayerToPressKey()
    #主循环
    while True:
        # set up the start of the game
        zombies = []
        newKindZombies = []
        bullets = []
        zombiesGottenPast = 0
        score = 0
        playerRect.topleft = (50, WINDOWHEIGHT /2)
        moveLeft = moveRight = False
        moveUp=moveDown = False
        shoot = False
        zombieAddCounter = 0
        newKindZombieAddCounter = 0
        bulletAddCounter = 40
        pygame.mixer.music.play(-1, 0.0)
        #游戏开始循环
        while True: # the game loop runs while the game part is playing
            for event in pygame.event.get():
                if event.type == QUIT:
                    terminate()
    
                if event.type == KEYDOWN:
                    if event.key == K_UP or event.key == ord('w'):
                        moveDown = False
                        moveUp = True
                    if event.key == K_DOWN or event.key == ord('s'):
                        moveUp = False
                        moveDown = True
    
                    if event.key == K_SPACE:
                        shoot = True
    
                if event.type == KEYUP:
                    if event.key == K_ESCAPE:
                            terminate()
    
                    if event.key == K_UP or event.key == ord('w'):
                        moveUp = False
                    if event.key == K_DOWN or event.key == ord('s'):
                        moveDown = False
                    
                    if event.key == K_SPACE:
                        shoot = False
    
            # Add new zombies at the top of the screen, if needed.增加上市
            zombieAddCounter += 1
            if zombieAddCounter == ADDNEWKINDZOMBIE:
                zombieAddCounter = 0
                zombieSize = ZOMBIESIZE       
                newZombie = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-zombieSize-10), zombieSize, zombieSize),
                            'surface':pygame.transform.scale(zombieImage, (zombieSize, zombieSize)),
                            }
    
                zombies.append(newZombie)
    
            # Add new newKindZombies at the top of the screen, if needed.
            newKindZombieAddCounter += 1
            if newKindZombieAddCounter == ADDNEWZOMBIERATE:
                newKindZombieAddCounter = 0
                newKindZombiesize = ZOMBIESIZE
                newCrawler = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-newKindZombiesize-10), newKindZombiesize, newKindZombiesize),
                            'surface':pygame.transform.scale(newKindZombieImage, (newKindZombiesize, newKindZombiesize)),
                            }
                newKindZombies.append(newCrawler)
    
            # add new bullet
            bulletAddCounter += 1
            if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:
                bulletAddCounter = 0
                newBullet = {'rect':pygame.Rect(playerRect.centerx+10, playerRect.centery-25, bulletRect.width, bulletRect.height),
    						 'surface':pygame.transform.scale(bulletImage, (bulletRect.width, bulletRect.height)),
    						}
                bullets.append(newBullet)
    
            # Move the player around.
            if moveUp and playerRect.top > 30:
                playerRect.move_ip(0,-1 * PLAYERMOVERATE)
            if moveDown and playerRect.bottom < WINDOWHEIGHT-10:
                playerRect.move_ip(0,PLAYERMOVERATE)
    
            # Move the zombies down.
            for z in zombies:
                z['rect'].move_ip(-1*NORMALZOMBIESPEED, 0)
    
            # Move the newKindZombies down.
            for c in newKindZombies:
                c['rect'].move_ip(-1*NEWKINDZOMBIESPEED,0)
    
            # move the bullet
            for b in bullets:
                b['rect'].move_ip(1 * BULLETSPEED, 0)
    
            # Delete zombies that have fallen past the bottom.
            for z in zombies[:]:
                if z['rect'].left < 0:
                    zombies.remove(z)
                    zombiesGottenPast += 1
    
            # Delete newKindZombies that have fallen past the bottom.
            for c in newKindZombies[:]:
                if c['rect'].left <0:
                    newKindZombies.remove(c)
                    zombiesGottenPast += 1
    		
    		for b in bullets[:]:
    			if b['rect'].right>WINDOWWIDTH:
    				bullets.remove(b)
    				
            # check if the bullet has hit the zombie 检查子弹是否触碰到僵尸
            for z in zombies:
                if bulletHasHitZombie(bullets, zombies):
                    score += 1
                    zombies.remove(z)
            #检查子弹是否触碰到新僵尸
            for c in newKindZombies:
                if bulletHasHitCrawler(bullets, newKindZombies):
                    score += 1
                    newKindZombies.remove(c)      
            # Draw the game world on the window.
            windowSurface.blit(rescaledBackground, (0, 0))
            # Draw the player's rectangle, rails
            windowSurface.blit(playerImage, playerRect)
            # Draw each baddie
            for z in zombies:
                windowSurface.blit(z['surface'], z['rect'])
            for c in newKindZombies:
                windowSurface.blit(c['surface'], c['rect'])
            # draw each bullet
            for b in bullets:
                windowSurface.blit(b['surface'], b['rect'])
            # Draw the score and how many zombies got past
            drawText('zombies gotten past: %s' % (zombiesGottenPast), font, windowSurface, 10, 20)
            drawText('score: %s' % (score), font, windowSurface, 10, 50)
            # update the display
            pygame.display.update()
                
            # Check if any of the zombies has hit the player.
            if playerHasHitZombie(playerRect, zombies):
                break
            if playerHasHitZombie(playerRect, newKindZombies):
               break
            
            # check if score is over MAXGOTTENPASS which means game over
            if zombiesGottenPast >= MAXGOTTENPASS:
                break
            #tick(framerate=0) -> milliseconds
            #帧速率参数,该功能将延迟以使游戏的运行速度低
            mainClock.tick(FPS)
    
        # Stop the game and show the "Game Over" screen.游戏结束执行命令
        pygame.mixer.music.stop()
        gameOverSound.play()  #播放游戏结束时声音
        time.sleep(1)
        if zombiesGottenPast >= MAXGOTTENPASS:
            windowSurface.blit(rescaledBackground, (0, 0))
            windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))
            drawText('score: %s' % (score), font, windowSurface, 10, 30)
            drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
            drawText('YOUR COUNTRY HAS BEEN DESTROIED', font, windowSurface, (WINDOWWIDTH / 4)- 80, (WINDOWHEIGHT / 3) + 100)
            drawText('Press enter to play again or escape to exit', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) + 150)
            pygame.display.update()
            waitForPlayerToPressKey()
        if playerHasHitZombie(playerRect, zombies):
            windowSurface.blit(rescaledBackground, (0, 0))
            windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))
            drawText('score: %s' % (score), font, windowSurface, 10, 30)
            drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
            drawText('YOU HAVE BEEN KISSED BY THE ZOMMBIE', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) +100)
            drawText('Press enter to play again or escape to exit', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) + 150)
            pygame.display.update()
            waitForPlayerToPressKey()
        gameOverSound.stop() #游戏结束声音停止
    

    这一章我们学习了python的pygame模块,了解了pygame模块的基础知识和如何编写植物大战僵尸的DIY游戏。总之pygame在编写视频游戏上方便,高效,且具有高度的可移植性,几乎可以在所有平台和操作系统上运行。不要等了,赶紧去安装pygame模块,开始第一个游戏编程之旅吧。

    https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149(博主视频教学主页)

     

  • 相关阅读:
    20145318 《信息安全系统设计基础》第6.5周学习总结
    20145318 《信息安全系统设计基础》第6周学习总结
    20145318 《信息安全系统设计基础》第5.5周学习总结
    20145318 《信息安全系统设计基础》第5周学习总结
    20145318 《信息安全系统设计基础》第3周学习总结
    20145318 《信息安全系统设计基础》第2周学习总结
    20145318 《信息安全系统设计基础》第1周学习总结
    20145318 《信息安全系统设计基础》第0周学习总结
    20145318赵一Java课程总结
    20145317《信息安全系统设计基础》第10周学习总结2
  • 原文地址:https://www.cnblogs.com/webRobot/p/13052402.html
Copyright © 2011-2022 走看看