当前位置: 首页 > 科技观察

用Python做游戏有多简单_0

时间:2023-03-20 22:12:33 科技观察

大家好,今天我将用两篇文章来介绍如何使用Python做游戏。本游戏使用PyGame制作,贴图素材来自itch.io[1]。之前没用过PyGame,这次算是学习和使用了。参考教程是PyGame:APrimeronGameProgramminginPython[2]。使用PyGame制作游戏非常简单。在今天的第一篇文章中,我们将让你实现一只可以在地图上移动的猪。基本框架首先,无论您玩什么游戏,只需将以下代码复制并粘贴到您的编辑器中即可。所有游戏都需要这几行代码:importpygamedefmain():pygame.init()pygame.display.set_caption('UnheardofCode:AgamebyQingnan')#Gametitlewin=pygame.display.set_mode((800,600))#窗口大小,width800height600running=Truewhilerunning:foreventinpygame.event.get():ifevent.type==pygame.QUIT:#点击左上角或上角的x右上角关闭窗口当停止程序running=Falsemain()时,运行效果如下图所示:加载素材现在,我们随机找两张图片,一张作为背景,一张作为主角。不用太在意大小,差不多就好了,因为我们可以用代码动态调整。下面两张图是我随便找的资料。请注意图中红框圈出的区域,就是这两张图的大小。我们使用下面的代码加载图片:img_surf=pygame.image.load('imageaddress').convert_alpha()其中.convert_alpha()是为了保持png图片背景透明。如果你加载的图片不是png图片,你可以把convert_alpha()改成convert()。如果要修改图像大小,使用下面的代码:img_surf=pygame.transform.scale(img_surf,(width,height))要在窗口中显示图像,使用下面两行代码:win.blit(材质对象,(左上材质角的横坐标,材质左上角的纵坐标))pygame.display.flip()完整代码如下:importpygamedefmain():pygame.init()pygame.display.set_caption('UnknownCode:MadebyQingnanGame')#游戏标题win=pygame.display.set_mode((800,600))#窗口大小bg_small=pygame.image.load('bg.png').convert_alpha()bg_big=pygame.transform.scale(bg_small,(800,600))pig=pygame.image.load('pig_in_car.png').convert_alpha()running=Truewhilerunning:foreventinpygame.event.get():如果event.type==pygame.QUIT:#当你点击左上角或右上角的x关闭窗口时,停止程序运行=Falsewin.blit(bg_big,(0,0))#先加载背景图,然后坐标为(left,top)win.blit(pig,(200,300))pygame.display.flip()main()运行效果如下图所示:需要注意的是win.blit和pygame.display.flip()必须放在while循环中。win.blit的第一个参数就是我们刚刚加载的材质对象。第二个参数是一个元组,标记了画布上图片左上角的坐标。整个画布的左上角对应坐标(0,0)。由于背景图的大小也是(800,600),所以背景图的左上角放在(0,0)处,刚好可以覆盖整个画布。我在哪里可以找到材料?我们做的是一款像素风格的游戏,你可以在itch.io上找到素材:这个网站改进了很多游戏素材,大部分素材都是免费的,供个人非商业使用。找到喜欢的素材后就可以直接下载,整个过程甚至不需要登录(比国内垃圾素材网站良心多了)。为什么我的材料看起来像这样?下载资料后,您可能会发现一件很奇怪的事情。怎么能把所有的素材都画在一张图上呢?其实,这是行业惯例。制作素材的人会将每一种素材排列在一张图片上。当你想使用它时,你需要自己裁剪它。例如,所有植物都放在一张地图上,所有雕像都放在一张地图上,地基纹理也放在一张地图上。上面我们演示的背景图,乍看之下是一张绿色的图片,但实际上包含了多个基础元素。请注意我用红框框出的部分:在正式游戏中,我们需要将元素拆开重新组装才能使用。重组时,有些元素需要复制多次以便重复使用,有些元素需要旋转和缩放。最终形成如下图这样好看的图:一般来说,像素风格素材的尺寸以16x16、32x32、64x64、128x128居多。剪辑说明通常由材料作者提供。如果没有提供,你也可以亲眼看看,猜一猜。比如我想从雕像材质中裁剪出红框女神雕像:那么,我可以这样写代码:img_surf=pygame.image.load('statuematerial.png').convert_alpha()goddess=img_surf.subsurface((女神像左上角横坐标,女神像左上角纵坐标,女神像宽度,女神像高度))运行效果如图下图中:有同学可能会问:为什么女神的坐标是这样的?只能说这个坐标是我试过很多次的。使用精灵管理物体除了背景图片,我们添加的每一个元素都是一个物体,比如上面的小猪和女神雕像。原则上,上面的代码已经足够你把游戏做的漂亮了。如果要加东西,就不断加载图片素材,然后放到合适的位置。但是我们可以使用面向对象的设计方法,让代码更容易维护,更简单。在PyGame中,有一个名为Sprite的类。我们可以为每个物体实现一个类,继承Sprite,然后将物体的材质设置为.surf属性,将物体的位置设置为.rect属性。例如,我们修改一下上面的代码:.convert_alpha()grass_land=bg_small.subsurface((0,0,128,128))self.surf=pygame.transform.scale(grass_land,(800,600))self.rect=self.surf.get_rect(left=0,top=0)#定位左上角classPig(pygame.sprite.Sprite):def__init__(self):super(Pig,self).__init__()self.surf=pygame.image.load('pig_in_car.png').convert_alpha()self.rect=self.surf.get_rect(center=(400,300))#中心定位类Goddess(pygame.sprite.Sprite):def__init__(self):super(Goddess,self).__init__()building=pygame.image.load('building.png').convert_alpha()self.surf=building.subsurface(((7*64-10,0,50,100)))self.rect=self.surf.get_rect(center=(500,430))#将女神雕像的中心放在canvas(500,430)的位置defmain():pygame.init()pygame.display.set_caption('UnknownCode:庆南Madegame')#游戏标题win=pygame.display.set_mode((800,600))#窗口大小bg=Bg()goddess=Goddess()pig=Pig()all_sprites=[bg,goddess,pig]#Pay注意添加顺序,后面添加的对象层在前面添加的对象层之上running=Truewhilerunning:foreventinpygame.event.get():ifevent.type==pygame.QUIT:#点击在左上角或者当右上角的x关闭窗口时停止程序='__main__':main()runs效果如下图所示:注意代码中的all_sprites=[bg,goddess,pig],这里我在list后面使用了一个更高级的数据结构SpriteGroup来存储它们。今天使用列表就足够了。Material对象.get_rect()会返回一个坐标定位对象,它有多个属性,比如.left,.top,.center,.width,.height。在没有参数的情况下,默认.left=0,.top=0,PyGame会根据这个物体的大小自动计算.width,.height和.center。我们可以通过传入参数来主动设置。当您设置左上角时,它会自动计算中心点的坐标;当你传入中心坐标时,它会自动计算左上角的坐标。从理论上讲,在每个类中,实物可以使用任何名称,不一定是.surf。坐标定位对象不一定要用.rect,只要在win.blit中对应即可。但是,如果你统一使用.surf和.rect,它会给你带来很多好处。下面说说物体碰撞时的这一点。所以我建议你只使用这两个名称。既然是让小猪动起来的游戏,就必须要按下键盘才能让主角动起来。不然跟画有什么区别?请注意main()函数中的whilerunning循环。如果你在循环中加入一行代码:print(111),你会发现运行游戏时111会一直打印出来。本质上,PyGame是通过win.blit不断绘制图片的。由于这个while循环每秒运行很多次,如果每次都运行,我们让win.blit的第二个参数,也就是物体的坐标有细微的差别,那么在人眼中,物质物体在运动。我们的目标是按住键盘上的上、下、左、右方向键,小猪会向4个不同的方向移动。在PyGame中,要获取键盘被按住的键,使用下面的代码来实现:keys=pygame.key.get_pressed()它返回一个看起来像列表(但不是列表)的对象,当我们想要判断某个键按下时,只需要判断ifkeys[你要判断的键]。如果它返回True,则表示它已被按下。基于这个原理,我们来写两段代码。首先修改Pig类,添加一个.update方法:.png').convert_alpha()self.rect=self.surf.get_rect(center=(400,300))#中心定位defupdate(self,keys):ifkeys[pygame.K_LEFT]:self.rect.move_ip((-5,0))#横坐标向左elifkeys[pygame.K_RIGHT]:self.rect.move_ip((5,0))#横坐标向右elifkeys[pygame.K_UP]:self.rect.move_ip((0,-5))#垂直坐标向上elifkeys[pygame.K_DOWN]:self.rect.move_ip((0,5))#垂直坐标向下#ifself.rect防止小猪跑出屏幕。左<0:self.rect.left=0如果self.rect.right>800:self.rect.right=800如果self.rect.top<0:self.rect.top=0如果self.rect.bottom>600:self.rect.bottom=600。update方法接收一个参数keys,就是我们的keys返回的一个看起来像列表的对象。然后判断按下的是哪个方向键。.rect坐标定位对象根据按下的键修改对应方向的值。rect.move_ip中这里的ip是inplace的缩写,就是修改.rect属性本身。它的参数是一个对应横坐标和纵坐标的元组。横纵坐标小于0表示左或上,大于0表示右或下。原来的main()函数只需要在win.blit之前添加两行代码:keys=pygame.key.get_pressed()pig.update(keys)完整代码如下:importpygameclassBg(pygame.sprite.Sprite):def__init__(self):super(Bg,self).__init__()bg_small=pygame.image.load('bg.png').convert_alpha()grass_land=bg_small.subsurface((0,0,128,128))自己。surf=pygame.transform.scale(grass_land,(800,600))self.rect=self.surf.get_rect(left=0,top=0)#定位左上角classPig(pygame.sprite.Sprite):def__init__(self):super(Pig,self).__init__()self.surf=pygame.image.load('pig_in_car.png').convert_alpha()self.rect=self.surf.get_rect(center=(400,300))#中心定位defupdate(self,keys):ifkeys[pygame.K_LEFT]:self.rect.move_ip((-5,0))elifkeys[pygame.K_RIGHT]:self.rect.move_ip((5,0))elifkeys[pygame.K_UP]:self.rect.move_ip((0,-5))elifkeys[pygame.K_DOWN]:self.rect.move_ip((0,5))#防止小如果self.rect.left<0:self.rect.left=0如果self.rect.right>800:self.rect.right=800如果self.rect.top<0:self.rect.top=0如果self.rect.bottom>600:self.rect.bottom=600classGoddess(pygame.sprite.Sprite):def__init__(self):super(Goddess,self).__init__()building=pygame.image.load('building.png').convert_alpha()self.surf=building.subsurface(((7*64-10,0,50,100)))self.rect=self.surf.get_rect(center=(500,430))#将女神雕像的中心点放在画布的位置(500,430)defmain():pygame.init()pygame.display.set_caption('暗黑代码:青南制作的游戏')#游戏标题win=pygame.display.set_mode((800,600))#窗口大小bg=Bg()goddess=Goddess()pig=Pig()all_sprites=[bg,goddess,pig]#注意添加的顺序,对象图在先添加对象的层之上添加后层running=Truewhilerunning:foreventinpygame.event.get():ifevent.type==pygame.QUIT:#当点击在左上角或右上角关闭窗口,停止程序运行=Falsekeys=pygame.key.get_pressed()pig.update(keys)forspriteinall_sprites:win.blit(sprite.surf,sprite.rect)pygame.display.flip()if__name__=='__main__':main()的最终运行效果如下视频所示:总结PyGame制作游戏真的非常简单。只要能加载素材,就能做出一款还能看的游戏。今天我们学习了如何添加素材,如何捕捉键盘事件。PyGame可以读取Gif图片,但是你会发现加载后Gif不动了。下一篇我们会讲到如何让你控制的角色动起来,比如控制一个小人偶,它动的时候脚也跟着动。和物体碰撞检测。