当前位置:   article > 正文

Python游戏编程_植物大战讲僵尸_贪吃蛇_位置。zombies = [zombie(random.randint(0, screen_widt

位置。zombies = [zombie(random.randint(0, screen_width - 30), random.ran

曾经我也沉迷游戏,连续玩十几个小时竞技游戏可以不吃饭。游戏只是别人写好程序,与其沉迷于他人设计好程序,为何不自己设计游戏,至少学会编程后,我们的月收入上万不是问题。于是便有了录制这部[pygame菜鸟游戏编程教程]动力。不要沉迷于游戏,我们人生还有许多事情要做,旅游,找到另一个伴侣,成立一个家庭,照顾父母。。。。

编程正在逐步改变世界,程序员不是搬砖的。但传统计算教育程面临枯燥乏味课程,让学生感到乏味。
兴趣是学习最好老师!此课程目的是激发大家对编程兴趣,给广大Python入门初学者带来无穷乐趣。
游戏涉及童年玩过经典小游戏,包括贪吃蛇,消消乐,俄罗斯方块,植物大战僵尸,扫雷等等。视频的参考资料可下载脚本。脚本已经编译好,可直接运行!
Have Fun!

欢迎各位同学学习《Python菜鸟快乐游戏编程_pygame

Python菜鸟快乐游戏编程

下图展示视频中几个经典童年游戏,植物大战僵尸

《植物大战僵尸》是由PopCap Games开发的一款益智策略类单机游戏,于2009年5月5日发售。玩家通过武装多种植物切换不同的功能,快速有效地把僵尸阻挡在入侵的道路上。不同的敌人,不同的玩法构成五种不同的游戏模式,加之黑夜、浓雾以及泳池之类的障碍增加了游戏挑战性。

《植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩家防御僵尸的方式就是栽种植物。49种植物每种都有不同的功能,例如樱桃炸弹可以和周围一定范围内的所有僵尸同归于尽,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以针对不同僵尸的弱点来合理地种植植物,这也是胜利的诀窍。游戏根据玩法不同分为五种游戏模式:冒险、生存、花瓶破碎者、小游戏、花园。加之黑夜、屋顶、浓雾以及泳池之类的障碍增加了其挑战性该游戏近乎永无止境。

奥赛罗棋,人工智能AI范畴,英国每年有比赛

黑白棋,又叫反棋(Reversi)、奥赛罗棋(Othello)、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。有一种说法是:只需要几分钟学会它,却需要一生的时间去精通它。黑白棋的棋盘是一个有8*8方格的棋盘。把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的全部翻转会成为自己的棋子。并且,只有在可以翻转棋子的地方才可以下子。黑白棋是19世纪末英国人发明的。直到上个世纪70年代一个日本人将其发展,借用莎士比亚名剧奥赛罗(othello)为这个游戏重新命名,也就是现在大家玩的黑白棋。为何借用莎士比亚名剧呢?是因为奥赛罗是莎士比亚一个名剧的男主角。他是一个黑人,妻子是白人,因受小人挑拨,怀疑妻子不忠一直情海翻波,最终亲手把妻子杀死。后来真相大白,奥赛罗懊悔不已,自杀而死。黑白棋就是借用这个黑人白人斗争的故事而命名。

游戏期间,位置比点数更重要!要着眼于长远利益,因为点数的领先很可能是暂时的。四个角上是必须争取占据的好位置,因为无法移开这些位置上的棋子。 设法使自己走一步时,牵制着对手无法移动任何棋子!这样可以在一排中连续走两步。

当然我们没有必要用一生的时间去精通它。用python程序可以去模拟游戏,找到最佳下棋算法。

开心消消乐,手机玩的很high的爆款游戏

《开心消消乐》是一款乐元素研发的一款三消类休闲游戏。一天晚上,天空中掉下一颗神奇的豌豆种子,正好落在了梦之森林的村长屋附近,种子落地后吸收了池塘的水分,迅速成长,一夜之间变成参天大藤蔓…… 第二天早上,村民们醒来后看到巨大的藤蔓都惊呆了,聚在一起议论纷纷。有人说他似乎看到村长的房子在高耸入云的藤蔓上,房子似乎还在上升,有人号召说应该爬上去救村长,玩家需要爬到藤曼顶部救出村长。

色彩拼图游戏,AI范畴,基于算法,在规定时间内完成色彩统一,这需要一定思考能力哟。

游戏编程模块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_LEFTLeft arrowK_HOMEHome
K_RIGHTRight arrowK_ENDEnd
K_UPUp arrowK_PAGEUPPgUp
K_DOWNDown arrowK_PAGEDOWNPgDn
K_ESCAPEEscK_F1F1
K_BACKSPACEBackspaceK_F2F2
K_TABTabK_F3F3
K_RETURNReturn or EnterK_F4F4
K_SPACESpace barK_F5F5
K_DELETEDelK_F6F6
K_LSHIFTLeft ShiftK_F7F7
K_RSHIFTRight ShiftK_F8F8
K_LCTRLLeft CtrlK_F9F9
K_RCTRLRight CtrlK_F10F10
K_LALTLeft AltK_F11F11
K_RALTRight AltK_F12F12

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\nresize 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\ntest if two rectangles overlap’


def playerHasHitZombie(playerRect, zombies):

        #test if two rectangles overlap测试是否触碰到僵尸

        if playerRect.colliderect(z['rect']):

def bulletHasHitZombie(bullets, zombies):

        if b['rect'].colliderect(z['rect']):

            bullets.remove(b)

#测试子弹是否触碰到新僵尸。如果是,就把该僵尸移除

def bulletHasHitCrawler(bullets, newKindZombies):

        if b['rect'].colliderect(c['rect']):

            bullets.remove(b)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

创建一个简单的游戏窗口

首先输入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()              #系统退出
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

建立一个简单游戏窗口

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()              #系统退出
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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()#停止音乐播放
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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


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()#停止音乐播放
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

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

gameOverSound = pygame.mixer.Sound('gameover.wav')

gameOverSound.play()  #播放游戏结束时声音

gameOverSound.stop() #游戏结束声音停止
  • 1
  • 2
  • 3
  • 4
  • 5
  • 参数前置

我们用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()              #系统退出
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

如果我们想要让游戏窗口在显示器上全屏展示,我们用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()              #系统退出
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 鼠标

#鼠标设置不可见

pygame.mouse.set_visible(False)

  • 键盘设置

#Python菜鸟快乐游戏编程_pygame:https://ke.qq.com/course/3065512

    for event in pygame.event.get():

        if event.type==QUIT:

        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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 发射子弹代码

playerRect = playerImage.get_rect()

playerRect.topleft = (50, WINDOWHEIGHT /2)

bulletImage = pygame.image.load('SnowPeashooterBullet.gif')

bulletRect = bulletImage.get_rect()

#连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然

b['rect'].move_ip(1 * BULLETSPEED, 0)

import pygame, random, sys, time

from pygame.locals import *

#连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然

# set up pygame, the window, and the mouse cursor

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

font = pygame.font.SysFont(None, 48)

pygame.mixer.music.load('grasswalk.mp3')

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

playerRect.topleft = (50, WINDOWHEIGHT /2)

moveLeft = moveRight = 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:

        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

    bulletAddCounter += 1

    print("bulletAddCounter:",bulletAddCounter)

    #当while循环次数大于ADDNEWBULLETRATE时,才能发射子弹

    if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:

    #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移动子弹

        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将所有子弹绘制到游戏界面上

        windowSurface.blit(b['surface'], b['rect'])

    pygame.display.update()

    #tick(framerate=0) -> milliseconds

    #帧速率参数,该功能将延迟以使游戏的运行速度低

    #print("bullets",bullets)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 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 *

#连续发射两个子弹的距离,值越小,子弹距离越近,反之亦然

ZOMBIESIZE = 100 #includes newKindZombies

ADDNEWKINDZOMBIE = ADDNEWZOMBIERATE

NEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2

# set up the colors颜色值设置,可用于背景颜色

# set up pygame, the window, and the mouse cursor

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

font = pygame.font.SysFont(None, 48)

pygame.mixer.music.load('grasswalk.mp3')

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

playerRect.topleft = (50, WINDOWHEIGHT /2)

moveLeft = moveRight = 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:

        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)

    bulletAddCounter += 1

    print("bulletAddCounter:",bulletAddCounter)

    #当while循环次数大于ADDNEWBULLETRATE时,才能发射子弹

    if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:

    #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移动子弹

        b['rect'].move_ip(1 * BULLETSPEED, 0)

        #print(b['rect'])

        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将所有子弹绘制到游戏界面上

        windowSurface.blit(b['surface'], b['rect'])

        windowSurface.blit(z['surface'], z['rect'])

    pygame.display.update()

    #tick(framerate=0) -> milliseconds

    #帧速率参数,该功能将延迟以使游戏的运行速度低

    #print("bullets",bullets)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186

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


import pygame, random, sys, time

from pygame.locals import *

ZOMBIESIZE = 100 #includes newKindZombies

ADDNEWKINDZOMBIE = ADDNEWZOMBIERATE

NEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2

TEXTCOLOR = (255, 255, 255)

def waitForPlayerToPressKey():

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

        #test if two rectangles overlap测试是否触碰到僵尸

        if playerRect.colliderect(z['rect']):

def bulletHasHitZombie(bullets, zombies):

        if b['rect'].colliderect(z['rect']):

            bullets.remove(b)

#测试子弹是否触碰到新僵尸。如果是,就把该僵尸移除

def bulletHasHitCrawler(bullets, newKindZombies):

        if b['rect'].colliderect(c['rect']):

            bullets.remove(b)

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

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

font = pygame.font.SysFont(None, 48)

gameOverSound = pygame.mixer.Sound('gameover.wav')

pygame.mixer.music.load('background.mp3')

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)

waitForPlayerToPressKey()

    # set up the start of the game

    zombiesGottenPast = 0

    playerRect.topleft = (50, WINDOWHEIGHT /2)

    moveLeft = moveRight = False

    moveUp=moveDown = False

    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)

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

        if playerHasHitZombie(playerRect, newKindZombies):

        # check if score is over MAXGOTTENPASS which means game over

        if zombiesGottenPast >= MAXGOTTENPASS:

        #tick(framerate=0) -> milliseconds

        #帧速率参数,该功能将延迟以使游戏的运行速度低

        mainClock.tick(FPS)

    # Stop the game and show the "Game Over" screen.游戏结束执行命令

    pygame.mixer.music.stop()

    gameOverSound.play()  #播放游戏结束时声音

    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() #游戏结束声音停止
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394

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

论文涉及机器学习建模解决方案

版权声明:文章来自公众号(python风控模型),未经许可,不得抄袭。遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/204729
推荐阅读
相关标签
  

闽ICP备14008679号