好久没写游戏系列教程了。今天偶然浏览了一下开源跨平台的Python框架Kivy。它可以用来开发多点触控的用户界面程序,允许快速简单的交互设计,非常方便,所以萌生了制作这个教程的想法。本教程将教您如何使用Kivy编写乒乓球游戏。我们将从一个基本应用程序开始,描述创建该游戏的每个步骤。Kivy使用Python和Cython编写,基于OpenGLES2,支持多种输入设备,拥有丰富的widget库。使用相同的代码,您可以直接实现多平台应用程序,包括Windows、macOS、Linux、Android和iOS。所有Kivy小部件都支持多点触控。1.在开始之前,您需要确保您的计算机上已经成功安装了Python和pip。(方案一)如果使用Python进行数据分析,可以直接安装Anaconda,Anaconda内置了Python和pip。(方案二)另外,推荐大家使用VSCode编辑器,优点很多。请选择以下方式之一输入命令安装依赖项:Windows环境打开Cmd(开始-运行-CMD)。MacOS环境打开Terminal(command+空格进入Terminal)。如果您使用的是VSCode编辑器或Pycharm,则可以直接使用界面底部的Terminal。pipinstallkivy[base]kivy_examples2.Kivy的简单使用本节将简单介绍Kivy的基本使用。首先,为我们的游戏创建一个名为main.py的目录和文件:#main.pyfromkivy.appimportAppfromkivy。uix.widgetimportWidgetclassPongGame(Widget):passclassPongApp(App):defbuild(self):returnPongGame()if__name__=='__main__':PongApp().run()在命令行输入pythonmain.py运行应用程序。它应该只显示一个黑色窗口。所以我们所做的就是创建一个非常简单的Kivy应用程序,它创建了一个PongGameWidget类的实例并将它作为应用程序UI的根元素返回。此时你应该把它想象成Widgets的层次结构树。Kivy将这个Widget放在默认窗口中。在下一步中,我们将通过定义PongGame小部件的外观来绘制Pong的背景和游戏分数。3.Kivy-添加简单图形我们将使用.kv文件来定义PongGame类的外观。由于我们的应用程序类称为PongApp,我们可以简单地在同一目录中创建一个名为pong.kv的文件,该文件将在应用程序运行时自动加载。因此,为了定义游戏的外观,我们创建一个名为pong.kv的新文件并添加以下内容:#:kivy1.0.9:canvas:Rectangle:pos:self.center_x-5,0size:10、Self.HeightLabel:FONT_SIZE:70center_x:root.width/4Top:root.top-50Text:"0"Label:FonT_SIZE:70center_x:root.width*3/4TOP:ROOT.TOP-50Text-50Text:"0"注意一个常见的错误:kv文件的名字,比如pong.kv,必须和应用的名字一致,比如PongApp(App结尾前的部分)。如果您现在运行该应用程序,您应该会在中间看到一个垂直条和两个零,其中将显示玩家的分数,如下所示:如您所见,在第一行,我们有:#:kivy1.0。9每个kv文件都需要第一行。它应该以#:kivy开头,后跟一个空格,然后是它将使用的Kivy版本(这样Kivy可以确保你至少拥有你需要的版本,或者稍后处理向后兼容性)。往下看,kv文件中定义了三个元素,一个画布,两个标签。先说两个label,分别代表左右数字,设置font_size(字体大小)、center_x(居中位置)、top(距顶部的距离)、text(文本),可以看到root.width和root.top的使用,这样写的好处是可以跟随窗口宽高的变化。另一个元素canvas在它下面定义了Rectangle参数,也就是我们在画布上添加一个矩形。将矩形的pos设置为小部件水平中心左侧5个像素,并将y设置为0,这定义了矩形将出现的位置。矩形的大小设置为10像素宽和小部件的高度。像这样定义图形的好处是,当值表达式中使用的任何小部件的属性发生变化时,渲染的矩形将自动更新。4.Kivy-添加乒乓球好吧,我们有一个基本的乒乓球场地(虽然是基本的),但我们仍然需要球拍和球来玩。让我们从球开始吧。我们将添加一个新的PongBall类来创建一个小部件,该小部件将成为我们的球并使其反弹。PongBallclass:classPongBall(Widget):#球在x轴和y轴上的速度velocity_x=NumericProperty(0)velocity_y=NumericProperty(0)#referencelist属性,所以我们可以使用ball.velocity作为#简写,g。就像e一样。forw.xandw.yvelocity=ReferenceListProperty(velocity_x,velocity_y)#``move``函数将球移动一步。这个#会等间隔调用来让小球动起来defmove(self):self.pos=Vector(*self.velocity)+self.pos白球的kv配置如下::size:50、50canvas:Ellipse:pos:self.possize:self.size增加使用的Property属性类。以下是此步骤的更新python代码和kv文件。fromkivy.appimportAppfromkivy.uix.widgetimportWidgetfromkivy.propertiesimportNumericProperty,ReferenceListPropertyfromkivy.vectorimportVectorclassPongBall(Widget):velocity_x=NumericProperty(0)velocity_y=NumericProperty(0)locity_velocity=ReferenceListPropertydefmove(self):self.pos=Vector(*self.velocity)+self.posclassPongGame(Widget):passclassPongApp(App):defbuild(self):returnPongGame()if__name__=='__main__':PongApp().run()kv文件如下:#:kivy1.0.9:size:50,50canvas:Ellipse:pos:self.possize:self.size:canvas:Rectangleself.center_x-5,0尺寸:10,self.height标签:font_size:70center_x:root.width/4top:root.top-50text-text:“0”标签:font_size:70center_x:root.width*3*3/4顶部:root.top-50文本:“0”PongBall:中心:self.parent.center5。kivy-增加乒乓球的移动现在我们的目的是让球移动,所以我们必须定期调用move函数让它移动Kivy提供的Clock函数使这很容易:Clock.schedule_interval(game.update,1.0/60.0)将导致游戏对象的更新函数每秒被调用60次。但是我们还有一个问题。我们想确保定期调用PongBall的移动函数,但我们的代码中没有对球对象的任何引用,因为我们只是通过kv文件将它添加到PongGame类的kv规则中。由于我们要做的不仅仅是移动球(例如将球从墙上弹到玩家的球拍上),我们可能需要为PongGame类创建一个更新方法。classPongGame(Widget):defupdate(self,dt):#调用ball.move和其他东西passclassPongApp(App):defbuild(self):game=PongGame()Clock.schedule_interval(game.1.update/6.0.update/)returngame但是,这仍然不能改变我们没有对kv规则创建的PongBall进行操作的事实。为了解决这个问题,我们可以在PongGame类中添加一个ObjectProperty,并将其挂接到kv规则中创建的小部件。完成后,我们可以轻松地在更新方法中引用球的属性,甚至可以让它从边缘反弹。classPongGame(Widget):ball=ObjectProperty(None)defupdate(self,dt):self.ball.move()#如果(self.ball.y<0)or(self.ball.top)从顶部和底部反弹>self.height):self.ball.velocity_y*=-1#左右反弹if(self.ball.x<0)or(self.ball.right>self.width):self.ball.velocity_x*=-1将其映射到kv文件中代码中设置的id:ball::ball:pong_ball#...(canvasandLabels)PongBall:id:pong_ballcenter:self.parent.center6。Kivy-球拍移动事件现在,我们的球开始四处弹跳。唯一缺少的是一个可移动的桨和分数跟踪。我们不会深入讨论创建类和kv规则的所有细节,因为这些概念已经在前面的步骤中介绍过。相反,让我们关注如何移动桨以响应用户输入。可以在Python实战宝典公众号:乒乓球**后台回复获取全部代码和kv规则。在Kivy中,小部件可以通过实现on_touch_down、on_touch_move和on_touch_up方法对输入做出反应。默认情况下,当Widget类实现这些方法时,它只是在其子组件上调用相应的方法来传递事件,直到其中一个子组件返回True。乒乓球很简单。球拍只需要上下移动。事实上,它非常简单,我们甚至不需要让播放器小部件自己处理事件。我们只需要为PongGame类实现on_touch_move函数:defon_touch_move(self,touch):iftouch.xself.width-self.width/3:self.player2.center_y=touch.y我们将把每个玩家的分数保存在一个NumericProperty中。PongGame的分数标签通过更改NumericPropertyscore保持更新,这反过来又更新了PongGame的子标签文本属性。这怎么可能?因为Kivy属性会自动绑定到其对应的kv文件中的任何引用。当球从双方逃逸时,我们会通过PongGame类中的update方法更新比分并再次发球。PongPaddle类还实现了一个bounce_ball方法,这样球会根据击中球拍的位置向不同的方向弹跳,这非常有趣。下面是PongPaddle类的代码:classPongPaddle(Widget):score=NumericProperty(0)defbounce_ball(self,ball):ifself.collide_widget(ball):speedup=1.1。bery0center_*2offset=0.self.center_y)ball.velocity=speedup*(offset-ball.velocity)至此我们基本完成了整个游戏的制作,怎么样,是不是很激动?想要体验这款游戏,可以在Python实战宝典获取所有代码和kv规则公众号后台回复:乒乓球。这是我们文章的结尾。如果觉得文章还不错的话,请关注公众号:Python编程学习圈,或者去编程学习网了解更多编程技术知识,还有海量干货学习资料!