This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
今天我们要在游戏中载入UI和菜单在开始之前我们先调整一下我们之前讲过的游戏代码部分的内容。
首先我们需要更改游戏的背景图片,使之看起来更像是一款打飞机的游戏,而不是最早之前我们随便用的一幅山水图。我们先将游戏背景修改为正常的游戏背景,并且贴上飞机图像。
<img src="https://static001.geekbang.org/resource/image/3c/2c/3cbd72b8968c23eaeb57737a9393072c.jpg" alt="">
这里,我想到一个问题,之前有人留言问我,程序员需不需要有美术功底。我在这里说一下我的看法。如果你只是要做一个程序员,那我可以告诉你,不需要。但是,如果你不是只想做一个“码农”,你想有更多的发展,那各方面的知识,比如策划、美术,你都需要去了解。
## UI的两种呈现形式
言归正传我们需要在这个游戏画面上面加一系列的内容来代表UI的呈现。UI的呈现有两种形式
- 第一种就是美术画好UI图片然后直接贴图用鼠标控制一系列的点击和按下操作
- 另外一种是自己画UI界面比如画一个框并且在框里面写上文字。
这两种方式各有利弊。
如果使用美术UI图贴图的方式**优点**就是可以减少程序员的工作量。这样在版本迭代的时候,美术改一幅图就可以修改界面,方便快捷,你就不需要做多余的工作。但是这样的**缺点**就是增加了游戏安装包的大小毕竟UI是一幅图只要是图就会有一定的体积就会增加安装包的大小。
如果是程序员自己绘制的UI界面**好处**就是主程序体积变得稍大一点,而游戏安装包不会变大。但是这样的**缺点**也很明显就是程序员的工作量会增加很多。而且当游戏需要迭代的时候或者界面需要更新的时候程序员需要重新绘制或者重新编写UI源代码大大增加了工作量。
我们现在是自己来开发那我就讲一讲程序员绘制UI的方法。
我们通过模拟按钮的方式来摆放UI界面。首先我们要在UI界面上摆放一系列字符我们要实现的效果是只要使用鼠标点击到这个字符就会变换字符的内容。这个过程我们会用到鼠标操作、绘制矩形、字体和字符绘制相关的知识下面我就来具体给你讲。
## 鼠标操作
我们先来看一下鼠标操作的知识。在Pygame中鼠标操作用到的模块是pygame.mouse。在这个模块里面点击事件的函数是get_pressed.假如有返回按钮1、按钮2和按钮3等等很多按钮,我们随便选一个点假如说选了按钮1那代码可以这么写
```
pygame.mouse.get_pressed()[0]
```
这条语句不需要在事件语句里面操作,写在别的地方也可以,而且鼠标的操作在循环里一直是实时监测的。
## 绘制矩形
随后,我们要绘制矩形。 **绘制矩形的目的是为了模拟一个按钮。** 矩形绘制的代码是Rect但是我们需要绘制在一个surface上这个surface需要新建然而在pygame中如果使用pygame.surface.surface初始化一个surface的话不能指定位置x值是从0开始的。
所以在屏幕上看到的新建的surface是一个长条状的图层所以我们需要将生成一个图层的子图层并且如果使用这个子图层的话在blit的时候将会提示被锁定所以我们还需要将这个子图层进行拷贝。所以我们的代码看起来是这个样子的。
```
the_rect = Rect(200, 100, 150, 40)
block_surface = screen.subsurface(the_rect).copy()
```
首先第一行代码是建立一个矩形分别是左侧起始值是200顶部从100开始宽度150长度40。随后使用screen这个图层来建立一个子图层子图层的大小按照the_rect这个矩形大小来建立。随后的一个copy函数是将子图层进行拷贝在后续的使用中不会出现锁定图层的情况。
## 绘制字体和字符
之后我们要开始编写文字处理的代码字体我们要用到pygame.font模块我们先初始化一个字体这个字体在安装pygame游戏库的时候就包含在了pygame里面我们直接就可以拿来使用。现在我们初始化字体并且将字体大小调整到25
```
fnt = pygame.font.Font('freesansbold.ttf',25)
```
其中freesansbold.ttf是pygame安装的时候默认存在的ttf字体文件随后我们在第二个参数设置为大小25。
我们拿到了fnt对象然后使用这个对象调用render函数。这其实就是渲染将文字渲染在屏幕并且形成一个文字图层函数原型是这样的
```
Font.render(text, antialias, color, background=None)
```
其中第一个参数text是文字内容第二个参数antialias是抗锯齿第三个内容color是文字颜色最后一个是背景颜色默认可以忽略。
```
tsurf = fnt.render(text, True, (255,255,255))
```
我们将颜色设置为白色所以是255255255
tsurf是render返回的一个文字的图层surface我们之后要按照这个图层来确定它的矩形框。
```
trect = tsurf.get_rect()
```
随后我们需要将文字摆在这个trect矩形框的中央所以我们要进一步将trect确定在中央的位置计算完中央的坐标值并且赋值过去。
```
trect.center = ((block_surface.get_width()/2),(block_surface.get_height()/2))
```
我们将最开始的复制的子图层的宽度和高度除以2就得到了中心点的位置。
最后我们要做的就是在封装的函数内将blit部分包含进去现在我们来看一下完整的包装函数代码。
```
def text_out(text):
fnt = pygame.font.Font('freesansbold.ttf',25)
tsurf = fnt.render(text, True, (255,255,255))
trect = tsurf.get_rect()
trect.center = ((block_surface.get_width()/2),(block_surface.get_height()/2))
block_surface.blit(tsurf, trect)
```
我们看到在函数最后我们blit了block_surface这个被拷贝的图层。
随后我们在游戏的大循环里面,需要判断鼠标的点击事件,我们之前所定义的矩形,代码是这样:
```
the_rect = Rect(200, 100, 150, 40)
```
所以这x的起始位置和结束位置是200和350y轴的起始位置和结束位置是200和240为什么y轴也是200开始呢因为起始点 200既是x轴开始的点也是y轴开始的点。我们在代码里面这么判断鼠标的点
```
txt = &quot;Pause&quot;
x, y = pygame.mouse.get_pos()
if pygame.mouse.get_pressed()[0]:
if x &gt;=200 and x &lt;= 350 and y &gt;= 200 and y &lt;= 240:
txt = &quot;Clicked
```
我们将txt定义为Pause字符串并且判断是不是鼠标左键点击的。如果是的话判断是不是在 x 轴和y轴进行点击如果不是的话就将txt改为Clicked。
随后我们绘制按钮框,并且将按钮框背景设置为绿色,然后输出文字,并且绘制。
```
screen.blit(block_surface, (200, 200))
block_surface.fill([0,20,0])
text_out(txt)
```
将block_surface这个图层绘制在200,200的坐标点并且将之涂为绿色最后调用text_out函数由于text_out里面已经编写了blit函数所以不需要再次blit了。
我们来看一下效果图:
<img src="https://static001.geekbang.org/resource/image/fb/a4/fb4e358092d3ad315e54f61cb984fca4.jpg" alt="">
我们看到了一个绿色的按钮放置在屏幕上并且有一个白色的Pause字样放在按钮上如果是鼠标左键点击在这个按钮上就会变成Clicked字样。
到这里,你可能会问了,为什么没有解释怎么输出中文呢?
在这种情况下,输出中文有两种解决方案。
<li>
第一种是比较底层的方案,就是**根据中文进行点阵绘制**,这需要很底层的代码操作,效率也不太高,所以这种方案我们不作讨论。
</li>
<li>
第二种就是**改变字体**我们可以在初始化字体的时候下载一些网上的中文字体先进行尝试或者我们可以使用系统字体。在使用系统字体的时候我们可以使用SysFont来初始化字体。
</li>
```
fnt = pygame.font.SysFont('微软雅黑',32)
```
另外还需要修改一个地方。我们需要在Python代码最开始的地方添加编码方式并且将中文文字前面添加u字样来告诉解释器是Unicode的。
```
# encoding: utf-8
txt = u&quot;暂停&quot;
```
我们来看一下效果:
<img src="https://static001.geekbang.org/resource/image/bb/d2/bba42a0cb409eedaab6a78f02cc456d2.jpg" alt="">
至此,中文的输出也已经完成了。
到现在为止我们编写完了UI的按钮部分。至于菜单部分我们也可以通过相同的方式来编写菜单效果。
作为菜单这些高级操作,比如点击出现下级菜单、隐藏菜单这些动态效果,可以使用图片的方式来制作菜单,并且进行载入。如果使用程序来编写菜单的效果,工作量就太大了。而如果是图片形式的话,只需要载入并且控制鼠标点击和绘制子菜单就可以了。
## 小结
今天我们学习了UI部分的编写以及文字的输出、鼠标的移动和抓取鼠标按键的实现我来总结一下今天的内容。
<li>
不管何种类型的游戏引擎鼠标的操作基本有3个值需要控制左键、中键和右键。
</li>
<li>
按钮可以用常规的方法来绘制。如果想做出更好的效果,比如画框,可以在框里面再画一个小框,看起来像是有凸出感觉的样子。这就需要你平时多注意观察一些细节,然后去分析如何用我们讲过的简单的操作来实现这些内容。
</li>
<li>
在2D游戏中很多游戏引擎都不支持中文的输出。如果要输出中文假如你的引擎支持那你可以使用系统字体或者其他中文字体如果引擎不支持可以使用一个一个点阵绘制的方式在屏幕上绘制中文。最后一种方式也就是比较极端的方式那就是使用图片来直接贴上中文字符这种方式直接粗暴但是图片资源量太大而且如果你要在游戏中进行网络聊天这里面其实还是没有从根本上解决中文输出的问题。
</li>
现在给你留一个小问题。
如果让你在上述的代码中,将按钮变成菜单,也就是点击按钮,就在下方出下一个下拉框,你会如何实现?
欢迎留言说出你的看法。我在下一节的挑战中等你!

View File

@@ -0,0 +1,185 @@
<audio id="audio" title="第17讲 | 如何用鼠标和键盘来操作游戏?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a2/07/a2860a659da0f8cf1d9a02e777de6f07.mp3"></audio>
**如果一款游戏不能用鼠标和键盘操作,那我们只能当动画来看。**
所以在一款游戏中鼠标和键盘的操作是必不可少的有时候甚至鼠标和键盘都要同时操作比如FPS游戏比如即时战略等等。鼠标和键盘的操作在Pygame中需要进行实时检测这个上一节我有提到过然后我们就可以对游戏画面进行操作。
我们在Pygame中有两种方式可以检测和编写键盘事件一种是使用**event事件**操作,一种是使用**keypressed函数**来进行键盘的判断操作。
我们先来尝试一下使用事件进行操作的键盘事件。我们在之前的代码中,已经使用事件来判断是不是退出,我们来看如下代码:
```
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
```
在这段代码里面event.type的类型如果是QUIT的话就让pygame退出那么举一反三我们也可以在里面写上如下代码
```
if event.type == KEYDOWN:
if event.key == pygame.K_w:
.....
```
在这里我们判断事件的类型是KEYDOWN也就是键盘按下的事件随后我们再在下面的代码里,判断event所返回键盘key值是pygame.K_w这个K_w是pygame里面定义的虚拟键盘的按键代表的是Key值为键盘w的按键所以你只要按下w键就会出现对应的操作。
我们来写下一系列的操作代码,在编写代码之前,我们首先要来定义一下规则。
我们的目的是要让主角的飞机移动起来所谓的飞机的移动我们在前面几篇课程里面都有阐述。如果我们要让飞机在画面上移动起来就需要修正飞机的x轴和y轴。
相应的如果飞机往左侧飞就需要减少飞机的x轴如果飞机往右侧飞就要增加飞机的x轴如果往上面飞就要减少飞机的y轴如果往底下飞就要增加飞机的y轴。我们先理清楚了这些内容之后就可以编写键盘操作代码了。
我们先来修正飞机的x轴和y轴。我们要在游戏的循环之外定义两个变量xx和yy以修正键盘操作后的飞机坐标。
```
xx = 0
yy = 0
```
在定义完了这些内容后,我们再来看看按键的定义。
```
if event.type == KEYDOWN:
if event.key == pygame.K_w:
yy -= 1
if event.key == pygame.K_s:
yy += 1
if event.key == pygame.K_a:
xx -= 1
if event.key == pygame.K_d:
xx += 1
```
首先和普通的游戏一样我们将电脑键盘上的WSAD按键用作上下左右的操作按键所以我们判断了一系列的按键值比如K_wK_s等等然后我们看到xx, yy 的一系列操作,然后我们进行飞机的贴图和操作:
```
screen.blit(pln, (100+xx, 300+yy))
```
我们看到基础坐标值是100300。我们经过键盘操作对xx和yy进行位置的修正。到这里为止我们可以看到只要我们按下WSAD中的任意一个按键飞机就会往指定的位置移动。
所以如果你认为到这里按键的内容就结束了那就错了就像我们今天开头所说的Pygame下的键盘类还有另外一种方式可以检测你可以考虑下面的代码。
```
key = pygame.key.get_pressed()
if key[pygame.K_w]:
yy -= 1
if key[pygame.K_s]:
yy += 1
if key[pygame.K_a]:
xx -= 1
if key[pygame.K_d]:
xx +=
```
是的我们看到了pygame.key.get_pressed(); 函数。这个函数返回一个Key值。和event事件不同的是我们直接可以在每一次循环内进行判断。返回的Key是一个tuple类型在里面存放了各种按键对应的值。如果没有按键所有值都是0如果有按键其中一个值是1。
再来看接下来的代码如果key值的tuple里正好是pygame.K_w的话那么判断结果就是真我们来将这个内容打印出来看一下。
```
print key
```
我们打印了key并且按下w按键随后我们可以在游戏界面命令行看到如下内容输出
<img src="https://static001.geekbang.org/resource/image/48/4a/480b8b53350ddb06e6a70e6987c84a4a.jpg" alt=""><br>
找到那个1没有那个1就是对应的K_w值在key[pygame.K_w]判断的时候返回一个1也就是True那么就产生yy-=1的操作。接下来就是类似的代码了我就不再作重复的阐述了。
看到这里或许你就要问了那有很多的游戏都有组合键比如我按下Ctrl键再按下w键就会出现对应的操作这又该怎么实现呢
你思考一下,我们是不是可以把两个按键写在同一个判断语句下?是的,你没有猜错,确实可以这么写,这就是**组合键**的效果。
```
if key[pygame.K_w] and key[pygame.K_LCTRL]:
yy -= 2
```
在这里我们看到只要同时按下了w和左侧CTRLLCTRL的意思是Left Control就是左侧Control的意思那么yy的坐标值就减去2我们操作一下就知道结果了。所以组合键可以在同一个判断里面使用and连接起来。
然后,事情并没有到这里结束,请你将这些代码写在自己的电脑里,并做一下实验,第一种方式是事件判断,第二种方式是按键判断。这两种方式的区别是什么?
看到区别了吗?如果你按照我说的去做,你会发现,第一种方式,只要按下一个键,飞机就会往指定方向移动一格,然而如果你一直按着这个键,飞机是不会移动的,要等你再按下键盘才行。而第二种方式,只要你一直按着这个键,飞机就会一直不停往指定位置移动。
问题究竟出在哪里呢?
问题在于事件判断首先判断了KEYDOWN当你按下按键的时候KEYDOWN已经被判断了随后我们再进入event的按键类型的判断但是如果你这时候一直按着键盘KEYDOWN事件并没有被唤起所以一直按着按键并没有起到作用所以你要按下键盘松开再按下一次飞机才会移动。
而第二种方式在循环里面只要键盘按下去就会一直返回一个tuple给key然后在继续做判断所以我们只要一直按着键盘一直会做判断直到按下的键盘是WSAD为止。
接下来,我们要做一下鼠标的操作。鼠标的操作我们在前几次的课程中也进行了介绍,我们再来温习一遍,并且添加一些新的内容进去。
我们今天要把一幅图片贴在鼠标的位置,并且随着鼠标的移动而移动,我们先来看下列代码:
```
mouse = 'mouse.png'
mouse_cursor = pygame.image.load(mouse).convert_alpha()
mouse_scale = pygame.transform.scale(mouse_cursor, (40, 40))
While True:
#获取 x, y 值
x-= mouse_scale.get_width() / 2
y-= mouse_scale.get_height() / 2
screen.blit(mouse_scale, (x, y))
...
```
首先我们要定义的一幅图片名叫 mouse.png随后载入图片并且处理alpha混合这在我们先前的课程中都有过阐述。
随后我们看到了一个叫pygame.transform.scale的函数。这个函数的意思是我们要重新将mouse这个surface进行缩放其中缩放的大小长宽是4040并且返回一个新的 surface。
随后在循环里我们获取到这个surface的中心点也就是计算需要绘制鼠标的xy值我们需要得到图片的长宽并且除以2最后blit开始贴图我们看到的效果是这样的。
<img src="https://static001.geekbang.org/resource/image/28/a1/2840dec856ac2ed69eb6d3c8956926a1.jpg" alt="">
那么我们如果要判断鼠标的按键怎么办呢?我们来温习一下上一次所讲的内容,鼠标的按键,也是类似的判断方式:
```
x, y = pygame.mouse.get_pos()
if pygame.mouse.get_pressed()[0]:
....
```
前面那段代码用到的 xy的值在这里进行代码获取。
我们看到pygame.mouse.get_pos() 函数获取两个值x和y坐标后面一段代码就是获取鼠标点击的内容其中 get_pressed函数下标0返回是不是左键点击下标1返回是不是中键点击下标2返回是不是右键点击最后再做出判断。
## 小结
今天的内容基本到这里了,我带你将内容梳理并总结一下。
<li>
首先是键盘事件判断这里会出现按一下键盘做一下操作的情况问题出在KEYDOWN事件判断上。但是如果你需要一直按键的判断可以使用get_pressed函数。
</li>
<li>
组合键可以写在同一个判断下使用and连起来做判断。
</li>
<li>
get_pressed会返回一个tuple里面存放了所有的key值只要判断key值是不是为True就是判断了有没有按键。
</li>
<li>
鼠标操作也可以使用get_pressed函数也是返回tuple其中下标0、1、2分别代表了左、中、右三个按键。
</li>
最后,给你留一个小问题。
如果将组合键写在第一个按键的判断下,会出现什么情况?
```
if key[pygame.K_LCTRL]:
if key[pygame.K_w]:
...
```
欢迎留言说出你的看法,我在下一节的挑战中等你!

View File

@@ -0,0 +1,125 @@
<audio id="audio" title="第18讲 | 如何判断客户端的网络连接?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/21/a4/213efd8525d38e60060de7d47c4d5ea4.mp3"></audio>
由于涉及到网络、脚本语言等等,这一节起,我要开始讲一些基础的、看起来比较枯燥的知识。我会尽力写得有趣生动,但是,知识的获取并不容易,即便我已经在努力去讲解,还是需要你用更多的时间去摸索和学习。
我们在前面说了Pygame的一些客户端知识如果你想让这款游戏能够在网络上传输数据接下来那就需要编写服务器端并且在客户端做客户端连接的准备。
前面我们已经用Pygame讲解了很多内容那我们客户端的网络连接我也继续使用Python来编写当然这已经和Pygame没有关系了。因为网络连接是独立的代码所以只需要直接写在游戏里就可以了。
在开始编写网络部分之前,我们需要整理一下网络的基础知识。如果我们一上来就编写网络代码,对于你来说,可能会有一些概念上的模糊。
对于网络编程或许你已经接触到了或许你只是有点概念或许你一点都没接触过。但是你或许听说过Socket套接字、TCP/IP协议、UDP协议、HTTP、HTTPS协议等等那么这些协议是不是都属于网络编程范畴还是这里面哪些部分是属于网络编程范畴呢
网络,从模型上讲,一共分为七层,从底层到最上层,分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
我来分别解释一下。
<li>
**物理层**:所谓的物理层,你可以理解为我们看到的各种网络线,也就是人肉眼能看到的物理线路,包括光纤、以前连接调制解调器的电话线等等。这些线路就是物理层。物理层有物理层的规范,比如电流、编码、帧、连接头等等。你只需要知道物理层也是存在规范的,就可以了。**物理层最主要的功能就是网络的物理连接**。
</li>
<li>
**数据链路层**所谓的数据链路层就是建立逻辑连接然后进行硬件上的寻址操作、差错的校验然后将二进制的字节进行组合通过MAC地址进行访问比如网卡、交换机等等。你需要记住的是**在这一层要通过MAC地址来进行访问进行硬件寻址操作。**
</li>
<li>
**网络层**网络层进行逻辑地址的寻址操作和数据链路层不同。数据链路是使用硬件寻址操作而网络层是使用逻辑地址寻址比如路由器、防火墙、多层交换机等等。我们最熟悉的IPv4202.101.253.233、IPv6、ARP等等都属于这一层。你在这里需要记住的是**网络层是逻辑寻址操作会用到ARP、IPv4等等协议。**
</li>
<li>
**传输层**在编程中最常用到的TCP、UDP等等协议都在这一层进行操作它首先定义了数据传输的协议端口号以及一些错误的检测。
</li>
<li>
**会话层**:会话层在传输层之上,它就在客户端和服务器端。严谨地说,就是本地机器和远端机器之间的会话,比如要进行断点续传这些操作,就属于会话层的范畴。
</li>
<li>
**表示层**:表示层很容易理解,就是数据的传输,然后展现在电脑上。比如图片的传输和显示、网络地址的加密等等。
</li>
<li>
**应用层**应用层就是提供给电脑用户的各种网络应用比如你自己编写的网络软件、FTP软件、Telnet、浏览器等等。
</li>
以上这些点你要硬性记住的话,会比较困难。我教给你一个方法。
首先,我们想象一段从网线过来一段数据,网线就是“物理层”,那么数据需要找到一个门牌号,这个门牌号是一个硬件地址,可能是你的电脑网卡,也可能是你公司的交换机。这些数据需要把这些门牌地址连接起来,这就是“数据链路层”。
随后这些数据找到门牌号后就需要分发到逻辑地址比如路由器或者你的IP地址这些逻辑地址就是网络地址这就是“网络层”。
经过网络层后就要看这是什么数据是TCP协议的还是UDP协议的。知道了协议后才可以传输数据所以这个是“传输层”。
那么在传输的过程中,可能会中断,所以我们需要登录服务器,断点续传进行重新传输,这些属于机器和机器之间的会话,所以是“会话层”。
传输完数据后,我们就会在电脑里显示这个内容,是一幅图片呢,还是一段电影?这个需要表示出来,所以是“表示层”。
最后,我们将这个一整套的东西,写成了一个应用,这就是“应用层”。
虽然这么表述起来,有许多不精确不严谨的地方,但是通过这段话能让你很快记住这个七层网络模型,对你将来的编程有很大的帮助。
Python支持Socket编程也就是支持TCP、UDP等协议的编程也支持更上层的编程比如HTTP协议等等。在今天的内容中我们要用到TCP编程。至于为什么要使用TCP有这样几个原因
<li>
TCP保证连接的**正确性**。在建立TCP连接的时候需要经过三次握手连接这一方发送SYN协议被连接方返回SYN+ACK协议最后连接方再返回ACK协议
</li>
<li>
TCP保证如果在一定时间内没有收到对方的信息就重发消息保证消息传输的**可靠性**
</li>
<li>
TCP可以进行**流量控制**。它拥有固定大小的缓冲池TCP的接收方只允许另一方发送缓冲池内所接纳的数据大小。
</li>
TCP还有其他更多的保证传输可靠性的内容和标准我在这里不做更多的阐述。另外使用TCP可以进行长时间的连接在客户端和服务器端之间进行不停地交互。在交互过程中服务器端发送数据给客户端客户端就能做出相应的回应。
在Python中编写TCP协议的代码比之使用C/C++更为方便。因为C/C++需要初始化一系列的内容然后进行顺序的流程化绑定设置网络参数最后进行发送和接收操作在结束的时候进行资源的回收。而在Python这里只需要设置协议和IP地址就可以实现TCP协议编程。我们来看一段代码。
```
import socket
class go_sock(object):
ip = &quot;&quot;
port = 0
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def __init__(self):
object.__init__(self)
def connect(self, ip, port):
self.ip = ip
self.port = port
self.sock.connect_ex((ip, port))
def close(self):
self.sock.close()
```
我在这里编写了一个类这个类将TCP的内容封装在了类中这样我们的网络代码能在游戏中方便地初始化使用起来就很方便。
首先我们看到在类里面定义了ip、port、sock这三个变量这三个变量分别是对应IP地址、端口号以及socket句柄。在类里我们直接将sock初始化为socket类其中socket类填写的内容中参数1是服务器之间的网络通信参数2是流Socket这里指的是TCP协议。
在初始化完成了之后我们看到connect函数。在函数里面我们看到参数对变量的初始化其中sock句柄调用了标准socket函数sock.connect_ex这个函数负责与对方进行一个连接。
最后的函数是close关闭操作在任务完成之后你可以调用close函数进行socket句柄的关闭。
我们可以这样使用这个类。
```
_inet = go_sock()
_inet.connect(&quot;115.231.74.62&quot;, 21)
_inet.sock.recv(100)
```
在这里,我们可以简单测试一下某些应用服务器,然后接收返回内容。这个类的封装工作到此就告一个段落,更多的网络服务和交互的编写,我将在下一节阐述。
## 小结
今天我们学习了网络的七层模型结构以及我们将要在游戏中使用的TCP协议的编程。
<li>
我用了一个传输过程介绍了七层每一层做的事情,这个你一定要牢记。
</li>
<li>
我们使用Python封装了Socket库的细节内容只需要直接编写connect代码就可以进行数据的接收和发送操作了。
</li>
<li>
选择TCP协议是因为它安全可靠能保证游戏传输的过程中不出错。
</li>
现在,我给你留一个小问题吧。
如果我们要使用UDP来编写这个网络服务该如何保证数据的准确性呢选择UDP协议的优势在哪里
欢迎留言说出你的看法。我在下一节的挑战中等你!