Mobile.Python第四章.doc_第1页
Mobile.Python第四章.doc_第2页
Mobile.Python第四章.doc_第3页
Mobile.Python第四章.doc_第4页
Mobile.Python第四章.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章 应用程序的构建与SMS收件箱PyS60使你简单的在S60平台上访问用户接构建口框架。感谢PyS60提供如此简单的处理方法,使得你可以学习怎样构建一个有标题栏、菜单和一些对话框的真正的应用程序,这只需要15行左右的代码。我们从怎样在Python中定义函数开始。在4.2部分中我们构建了一个应用程序,它呈现了一个典型的S60应用程序的全部结构。另外,这一部分介绍了PyS60中的一个最重要的概念,回调函数,它让你可以将任意的动作与各种事件进行绑定。当我向你展示怎样在应用程序中添加菜单时这个概念将会很有用。你或许已经迫不及待的想要开始做真正的应用程序了。在4.3部分,我将介绍怎样处理字符串。这个将在4.4部分的访问SMS收件箱时会很有用。例如,我将构建一个功能齐全的应用程序,让你方便的搜索和排序你的SMS消息。最后,在4.5部分,我展示了一个SMS游戏服务,让你和你的朋友用文本消息玩刽子手游戏。4.1 函数在前面章节中你尝试的Python脚本是一行一行执行的。每一行代码执行一个动作,并且直到动作结束,才会转到下一行执行。对于从头到尾直接处理的任务,这是简单且健壮的方法。但是,如果我们想要用户来决定做什么,而不是让程序用相同的顺序执行相同的操作,那么我们的代码必须按不同的方式来组织。典型的,有图形用户界面的应用程序是一种情况,这使得用户通过UI元素的交互来执行不同的动作。当使用S60的框架来构建用户界面时,执行进程不是按照代码一行一行来进行的。相反,用户或许通过按、说手机键盘的指定键来启动专门的任务。在这种情况下,你作为一名应用程序开发者的工作就是绑定指定任务到指定的按键事件上。当用户选择一个菜单项或者退出时,你的应用程序应该执行这个事件的相关任务。出于这个目的,你需要创造自己的函数。在例1中(在这里作为例9再一次出现),我们有三行代码按顺序执行。第二行触发了一个文本输入域,第三行触发了一个弹出通知框。例9:第一个PyS60程序import appuifwword = appuifw.query(uType your name, text)appuifw.note(uGreetings from + str(word)我们可以定义一个函数,将那两行代码放到函数里。这是我们在例10中所做的,函数名为askword()。在函数内部,像以往一样执行进程是按顺序进行。函数只是一种给定名字,用来分隔和将代码组织成小块的方法例10:第一个函数import appuifwdef askword():word = appuifw.query(uType a word, text)appuifw.note(uThe word was: + str(word)任何时候我们想要执行这个任务,就是想要执行这两行代码,我们只需要调用函数askword():askword()askword()在这种情况下,它两次询问一个字。在前一个章节中,你已经一直在调用函数了。例如:messaging.sms_send(+358., uGreetings from PyS60)appuifw.note(uI love MobileArt)这些是较早前例子的代码,调用的是messaging模块的sms_send函数和appuifw模块的note函数。Python语言课程:函数函数是将你的代码分割成具有独立功能的方法。函数有名字和函数体,并且可以被调用。函数具有可选的输入变量,叫做参数,同时它可以返回一个值。这里有一个例子:def add values(x, y):print Values are, x, yreturn x + y关键词def开始函数的定义。关键词def后跟函数名,这里是add_values。括号里是函数的参数,用逗号分开。括号后是冒号。函数头后的缩进行组成了函数体,当函数被调用时将会一行接一行的执行。在Python中,缩进产生不同,所有确保函数体的代码行正确对齐。函数体和if子句以及循环语句一样要遵循同样的缩进风格。函数体或许会包含一个跟有值的return语句,它将返回给调用行。return语句是可选的。调用函数是函数名和其后小括号内的输入值:z = 3new sum = add values(z, 5)print Their sum is, new sum如果没有给定输入值,在括号中就没有任何东西。返回值可以赋值给变量,如new sum = add values(z, 5),或者函数调用包含了更复杂的表达式。例如,上面例子中最后一行代码可以写作:print Their sum is, add values(z, 5)这种情况下,你不需要new_sum变量。正如你猜测的,例子产生如下输出:Value are 3 5Their sum is 8Python的口号是“包含电池”。意思是Python附带了广泛的预定义函数库,使得在完成许多复杂任务完全不费力。4.2 应用程序结构许多S60应用程序共享同样的用户界面布局。看看图4.1,几乎任何S60移动电话应用程序,包括PyS60解释器,你将会注意到同样的用户界面结构。(b)(a)对话框appuifw.query()appuifw.note()etc.程序体 appuifw.app.body导航标签标题 appuifw.app.title图4.1 一个典型的用户界面(a)结构 (b)基于该结构的截图图4.1(a)显示了S60用户界面的结构。对比图4.1(b)中显示的典型用户界面,其为用S60UI框架构建,可以看出图表与实际情况的对应关系。在下面的叙述中,括号中的文本参照截图中的文本。在屏幕的顶部,你可以看到程序的标题(Tabs)。在标题的下方,可以看到一行导航标签(One 和Two)程序体中间的大块区域可以用来放置一系列不同的UI元素(列表:red,green,blue,brown)。各种对话框,如弹出通知框,会出现在应用程序体,就像我们在第三章中看到的。在底部,可以看到两个需专用键激活的项目,是手机键盘的左右软键。如果没有对话框被激活,左软件将激活应用程序菜单(Options),右软键退出正在运行的应用程序(Exit)。如果有对话框显示,左软键对应于接受,右软键对应于取消。在PyS60中,你可以通过appuifw模块的app对象访问UI元素。在4.2部分谈论了更多有关对象的内容。更改UI元素是简单的,每一个元素(title,body,menu和exit_key_handler)是appuifw.app对象的内部变量,你可以像别的变量那样给它们赋值。只需要记住用全名,如appuifw.app.title。无论什么时候你改变了这些变量中的任何一个,相关的UI元素就有相应的改变。第一个应用程序是使用appuifw模块提供的UI框架的最基本的应用程序。它不做任何有用的事情,但是它说明了一个可工作应用程序的最小需求。它将一直运行,直到用户选择退出应用程序,这与以前的例子恰恰相反,以前都是从头到尾执行。图4.2显示了它正在运行。图4.2 第一个应用程序这部分包含了两个与应用程序构建相关的语言课程,分别是回调函数和对象。如果你一次掌握不了也不用担心。随着后面越来越多的例子,它们将会越来越清晰。例11:第一个应用程序import appuifw, e32def quit():print Exit key pressed!app_lock.signal()appuifw.app.exit_key_handler = quitappuifw.app.title = uFirst App!appuifw.note(uApplication is now running)app_lock = e32.Ao_lock()app_lock.wait()print Application exits在导入常见的appuifw模块的旁边,我们也需要一个叫e32的模块。这个模块提供了许多有用的低级对象和塞班OS相关功能的函数。这里我们需要对象e32.Ao_lock()。我定义了一个新函数quit(),当用户按下退出键时,它用来处理应用程序的关闭事件。当我们有许多函数来完成各种任务的时候,我们需要告诉Python那个函数专门用来处理退出事件。这是通过将函数名赋值给特定变量appuifw.app.exit_key_handler来实现的。当用户按下退出键,该变量指向的函数将会被UI框架调用。在许多情况下,当一些事件发生时,Python期望你提供相关函数的函数名以供调用。这种函数就叫做回调函数。关于回调函数的语言课程将会讲清楚这个概念。Python语言课程:回调函数回调函数就是一个普通的函数,和别的函数定义类似,但是它被用于特殊的目的。在回调函数和普通函数间没有什么技术上的不同。典型的,回调函数被PyS60的关联到特定事件的函数调用,例如当用户选择一个菜单项或决定退出应用程序。相对而言,原始的函数被你的应用程序代码调用是用来处理应用程序的特定任务。但是,有些情况下,回调函数有可能被你的应用程序直接调用。将一个函数和一个事件缔合叫做绑定。一些PyS60对象如Canvas和Inbox,都包含一个函数bind(),用来将一个函数绑定到相关对象的一些事件。无论什么时候,当PyS60 API文档或本书让你提供一个回调函数,都不要再函数名后加上小括号,因为回调函数只在事件发生后被调用。如果你对C或C+比较熟悉的话,你或许注意到在这些语言中和函数指针的传递类似。在例11中,我们将应用程序名赋给标题变量appuifw.app.title。当程序运行时该字符串显示在屏幕的顶部。像本章开头谈论的那样,目前为止我们看到的PyS60程序是一行接一行执行的,当最后一行执行完后程序退出。但是,例11不会退出直到用户决定这么做。因此我们的应用程序在执行完最后一行后不应该退出,应该等待用户的动作。这可以用模块e32中的一个叫做Ao_lock对象来实现。该对象包含一个wait()函数,使得应用程序进入等待状态直到函数signal()明确的释放了这个锁。函数signal()必须在你想要终止应用程序的时候调用,所以我们在函数quit内部调用它。要看看为什么在应用程序代码的底部建立一个锁很重要,从你的代码中省略app_lock.wait(),运行应用程序。一个对话框弹出来了,但是应用程序没有进入等待状态,它立即就结束了。当你运行例11时,你将会在屏幕的顶部看到“First App!”标题(见图4.2),和一个弹出对话框。直到你按下退出键(右软键)退出程序外什么都不会发生。之后,你将在PyS60控制台看到文本“Exit key pressed!”和“Application exits”。很难注意到应用程序正在运行。这是因为PyS60解释器是用同样的应用程序框架构建的,所以它看起来和任何别的PyS60应用程序一样。Python语言课程:对象对象将变量和函数组织起来进行操作。在许多情况下,函数和变量彼此之间相互关联,如果它们被分开处理显得很没有意义。对象在大型的复杂的应用程序中相当有用,如果大型应用程序没有被分成小的单元在实际中很难理解。Python已经为你做了许多这样的工作,所以你可以用Python已经准备好的对象愉快的编码。用面向对象的方法开发大型的复杂的应用程序已经超出了本书的范围。在别的书籍和网络上有许多关于面向对象的编程信息。你会惊奇的发现用Python编写的用来教授面向对象编程的例子一点也不复杂,并且不要求你继承自己的对象。我们的目的只是让你知道一些函数可以创建对象。例11中,一个Ao_lock对象被赋值给变量app_lock。app lock = e32.Ao lock()对象自己包含的变量和函数可以用点操作符进行访问,如:app_lock.wait()调用该对象的wait()函数。同样:appuifw.app.title=u”Hello world”给appuifw模块的app对象的title变量赋值。实际上,你可以将对象看做它们模块的内部模块,是点操作符的延伸。本章中,你能够发现有许多使用对象的例子。你已经见过处理标准用户接口的app对象,以及用来等待用户操作的Ao_lock对象。实际上,Python中的所有东西都是对象,包括strings、lists和tuples,也包括更多专用结构如Inbox对象,其用来访问SMS消息。在Python中对象无所不在,你一直在使用它们甚至都没注意到。4.2.1 应用程序菜单应用程序菜单提供了简单亲切的方式给用户程序了一个可操作的列表。阅读本部分后,你能够用应用程序菜单构建有用的工具,用来响应用户的请求。Python语言课程:元组元组是一个不可变列表。在创建之后你不能添加、删除或更改它的值。元组通常用来组织有关系的值,如坐标、地址线或者配方的组成部分。元组的定义方式与列表一样,但是取代方括号,值用小括号括起来:red = (255, 0, 0)weekdays = (Mon, Tue, Wed, Thu, Fri, Sat, Sun)family = (Mary, 38), (John, 35), (Josephine, 12)第一行和第二行定义了简单的序列。最后一行是一个元组的元组。元组的内部包含了不同类型的值:字符串和整型。你可以很容易的将元组的值分拆成单独的值。这里我们用上面创建的元组red和family:r, g, b = redmom, dad, child = family这种情况下,变量r、g和b是整型,而mom、dad和child是两项目元组。注意在拆分时你不得不定义和相关元组项目一样多的变量。你可以像列表一样用索引来引用元组中单独的项目。相比于列表,如下的赋值操作family1=(“Jack”,25)是不可能的,因为这将改变元组。在一些情况下,你需要将列表转成元组或将元组转成列表。前者用函数tuple()实现,后者用list()。例如:print list(red)在你的屏幕上产生如下输出:255,0,0注意方括号表示是一个列表。例12对例11进行了扩展,它包含一个应用程序菜单(见图4.3)。图4.3 应用程序菜单例12:应用程序菜单import appuifw, e32def photo():appuifw.note(uCheese!)def darken():appuifw.note(uI cant see a thing!)def lighten():appuifw.note(uMy eyes are burning!)def quit():print WANNABE PHOTOEDITOR EXITSapp_lock.signal()appuifw.app.exit_key_handler = quitappuifw.app.title = uPhotoEditorappuifw.app.menu = (uTake Photo, photo), (uEdit photo,(uDarken, darken), (uLighten, lighten)print WANNABE PHOTOEDITOR STARTEDapp_lock = e32.Ao_lock()app_lock.wait()应用程序菜单appuifw.app.menu被定义成一个由元组组成的列表。列表中的每一项都有格式(u”Item name”,item_handler),第一个元素定义在应用程序菜单中显示的文本,第二个是当项目被选中时调用的回调函数。对比图4.3和appuifw.app.menu列表将会更加的简单。菜单可能有等级,意思是一个菜单项可能会包含一个子菜单。子菜单的定义与主菜单的元组的列表类似。例12中,第二个菜单项“Edit photo”打开了一个两项目的子菜单“Darken”和“Lighten”。在图4.3中,“Take Photo”和“Edit Photo”作为主菜单显示,“Darken”和“Lighten”作为“Edit photo”的子菜单显示。三个函数photo()、darken()和lighten(),是绑定到菜单项的回调函数。本例中,每一个被选中的项目打开一个弹出通知框。和以前一样,你可以用右软键关闭应用程序。现在你应该尝试构建菜单和简单的应用程序!实际上构建应用程序是简单的事。4.2.2 应用程序体有几个对象可以赋值给应用程序体:l canvas用来处理屏幕上的图形(参见第五章)l form用来构建复杂的组合了各种输入域如文本、数字和列表的结构(参见第九章)l listbox用来显示列表项(参见第九章)l text对象用来处理自由格式的文本输入(关于该对象的更多信息参见PyS60文档)你可以用appuifw.app.screen变量增加应用程序预留的区域。有三个不同尺寸可以用(见图4.4):appuifw.app.screen = fullappuifw.app.screen = largeappuifw.app.screen = normal(c)(b)(a) 图4.4 应用程序屏幕尺寸:(a)全屏,(b)大屏,(c)一般4.2.3 标签页在PyS60文档中,你可以找到函数appuifw.app.set_tabs()的描述,它是用来定义导航栏标签页的。标签页是用字符串和回调函数定义的,与应用程序菜单类似。4.2.4 内容处理器专用对象Content_handler,是appuifw模块的一部分,可用来打开各种类型的文件,如图像、照片和web页面,使用标准S60平台浏览器应用程序。第九章将使用该对象。4.3字符串处理只有很少的应用程序一点也不处理文本数据。有些情况下,你对这样的文本不感兴趣,但是你需要将文本转换成其他格式如列表或者整型,用程序处理将会很简单。最终,当你的应用程序已经处理完数据并想要以文本格式打印输出时,应用程序必须将内部数据结构转换回文本。幸运的是在Python中这个是简单明了的。本部分中我将介绍字符串的基本操作,本书中许多例子都将用到。4.4部分介绍SMS收件箱时,需要一些处理字符串的功能强大的工具。在Python中字符串也是对象。实际上这意味着所有的字符串相关的函数将自动可用而不用任何的导入操作,但是你需要记住在调用字符串函数时要使用点操作符,例如txt.find(“is”)。记住在创建一个字符串后是不可能更改它的。所有的字符串操作将返回一个新的字符串,而原来的字符串不受影响。4.3.1 定义字符串有许多方法定义新的字符串:txt = Episode XXXIVtxt = Bart said: Eat my shortstxt = Homers face turned red. He replied: Why you little!第一行用双引号括起来一个字符串。这是定义字符串最经常用的方法。第二行用单引号。如果你的字符串中包含有双引号,它迟早会用到。最后一行是最后一招,如果字符串既包含双引号又包含单引号以及断行,你可以使用三对双引号将其括起来。4.3.2 访问字符串的一部分你可以用方括号括起来的索引访问单独的字符,这和列表类似。如果你想要找出指定子串的起始索引,用find()函数。例如,下面的代码中第一行输出“h”,第二行输出“i”:txt = python is greatprint txt3print txttxt.find(is)上面txt.find(“is”)返回值为7,并且索引7所在字符为“i”。你可以用start:end符号访问子串:txt = python is greatprint txt:6print txt7:9print txt10:以上打印语句输出子串为“python”,“is”和“great”。4.3.3 使用字符串做选择你经常需要使用字符串来做选择。你可以测试一个字符串是否非空,例如:txt = if txt:print Many characters!else:print No characters这个例子打印输出“No characters”。你可以用函数len()获得字符串的长度。下面的例子输出“password too short”。Passwd=”secret”If len(passwd)= 0:appuifw.note(box.content(idsindex)首先,要搜索的字符串存储在变量query中。和前一个例子一样,我们用Inbox对象的函数sms_message()获取所有消息ID的列表。程序循环遍历所有的消息,用content()函数获取每一个消息的内容并尝试在每一个消息中查找query字符串。如果find()函数报告了query()在消息中出现,我们将该消息ID添加到列表ids以便于以后查找。我们也添加了消息内容的摘要(前25个字符)到列表hits中,以便于我们将其展示给用户。当我们处理完所有的消息,我将以消息摘要作为列表项,用选择列表框显示hits列表。当用户选择了一项,列表对话框返回该项在列表中的索引。用这个索引我们可以找到在ids中相关消息ID,完整消息内容就可以从手机SMS收件箱中提取出来并显示给用户。4.4.3 SMS排序器除了消息内容,也可以提取消息时间戳、发送者电话号码(地址)和该消息是否被Inbox对象读取的信息。为了展示如何使用这些函数,我制作了一个包含有退出键处理器、应用程序标题和菜单的程序。这个应用程序可以用来对你的SMS收件箱进行排序,排序依据文本消息的各种属性。你可以通过菜单进行选择,是用时间、发件人还是未读标记进行排序。例16:收件箱排序器import inbox, appuifw, e32def show_list(msgs):msgs.sort()items = for msg in msgs:items.append(msg1:15)appuifw.selection_list(items)def sort_time():msgs = for sms_id in box.sms_messages():msgs.append(-box.time(sms_id), box.content(sms_id)show_list(msgs)def sort_sender():msgs = for sms_id in box.sms_messages():msgs.append(box.address(sms_id), box.content(sms_id)show_list(msgs)def sort_unread():msgs = for sms_id in box.sms_messages():msgs.append(-box.unread(sms_id), box.content(sms_id)show_list(msgs)def quit():print INBOX SORTER EXITSapp_lock.signal()box = inbox.Inbox()appuifw.app.exit_key_handler = quitappuifw.app.title = uInbox Sorterappuifw.app.menu = (uSort by time, sort_time),(uSort by sender, sort_sender),(uUnread first, sort_unread)print INBOX SORTER STARTEDapp_lock = e32.Ao_lock()app_lock.wait()代码看起来似乎很长,但是要注意函数sort_time()、sort_sender()和sort_unread()几乎一样。每一个函数创建了列表msgs。对于每一种情况,列表中的元组的第一项是键,是消息排序的依据,第二项是消息的内容。我们用列表的sort()函数对列表进行排序。在Python中,列表的排序如下:如果列表只包含字符串,按照字母顺序排序;如果列表只包含整型,按照升序排序;如果列表包含元组或列表,列表或元组的第一项被用作排序键;如果列表包含不同的类型,同一种类型的项目被组织在一起,每一种类型被分开排序。本例中,排序键依赖于用户的选择:l 当消息被接受,sort_time()函数用Inbox对象的time()函数提取时间。返回的时间是以1970年1月1日为起点到当前时间的秒数,这是许多操作系统的时间度量。l sort_sender()函数用address()函数返回的发送者的电话号码作为排序键。l sort_unread()函数用unread()函数的返回值作为排序键,如果消息未读返回1否则返回0。因为Python的sort()函数将整型按照升序排序,我们不得不将时间戳和未读标记置为负值,-box.time(sms_id)和-box.unread(sms_id),因为我想要最新的和未读的消息显示在列表的顶部。三个函数都准备了一个列表msgs,是为了按期望的方式进行排序。这些情况中,实际上排序和结果列表的显示是一样的,所以这些任务被分成它自己的一个函数show_list()。在msgs列表被排序以后,我们就可以丢掉排序键,只用元组中的第二项即消息内容,用其构造一个包含消息摘要的新的列表,就像前面的例子一样。做完这些后,已经排序的消息就可以显示了。你可以将例15和例16整合成一个收件箱搜索和排序的应用程序,一个完整的个人消息助手就完成了。有一个关系较大的函数delete(),Inbox对象可用。其和content()、address()以及time()函数很像。它被用来删除一个消息,但是在尝试前要确保你已经备份了你的SMS收件箱。4.4.4 接收消息如果你想要构建一个被SMS消息控制的服务,你的程序必须能够对接收到的消息作出响应。理论上你可以在一定时间间隔调用函数sms_messages(),检查自从上一次调用后列表是否有变化来完成这个任务。这种方法很可能做了许多不必要的工作。幸运的是,PyS60提供了一个选择:无论什么时候,当收到一个新消息时,回调函数将被调用。例17:SMS接收器import inbox, appuifw, e32def message_received(msg_id):box = inbox.Inbox()appuifw.note(uNew message: %s % box.content(msg_id)app_lock.signal()box = inbox.Inbox()box.bind(message_received)print Waiting for new SMS messages.app_lock = e32.Ao_lock()app_lock.wait()print Message handled!Inbox对象的bind()函数绑定了一个回调函数到收到新消息的事件上。本例中,函数message_received()在新消息到达时被调用。回调函数带有一个参数,收到消息的ID即msg_id。基于这个ID,消息的内容和任何别的属性都可以从SMS收件箱提取,就像上面那样。程序不会从开始到结束只执行一次。相反,它等待一个事件的发生。这次事件不是被用户直接触发,而是一个新进的SMS消息触发。等待是用相似的方式处理的,使用Ao_lock对象。当新消息到达,函数message_received()将被调用。它打开一个弹出通知框用来显示新到消息的内容。然后Ao_lock被释放,程序随着信息“Message handled!”而结束。唯一的适当的终止该程序的方法就是发送SMS消息到你的手机。4.4.5 转发消息从每天使用手机中你知道,当新的文本消息到达时会触发声音提醒,同时一个弹出通知说收到一个新的消息。但是如果你制作一个自动处理消息的程序,是不希望有提醒的。幸运的是,当新消息到达时用回调函数立即删除消息,提醒是可以避免的。在例18中,我们用一个过滤SMS网关验证了这一特征。该网关接收一个新消息,删除里面所有的脏词,并且转发以审查的消息到另一个手机。例18:过滤SMS网关import messaging, inbox, e32PHONE_NUMBER = asty_words = Java, C+, Perldef message_received(msg_id):box = inbox.Inbox()msg = box.content(msg_id)sender = box.address(msg_id)box.delete(msg_id)for word in nasty_words:msg = msg.replace(word, XXX)messaging.sms_send(PHONE_NUMBER, msg)print Message from %s forwarded to %s %(sender, PHONE_NUMBER)box = inbox.Inbox()box.bind(message_received)print Gateway activatedapp_lock = e32.Ao_这个脚本将会使由收到SMS消息引发的提醒全部失效。与前一个例子一样,函数message_received()在新消息到达时被调用。函数message_received()提取新消息的内容并且立即从收件箱中删除。脏字被“XXX”代替,清理后的消息被转发到另外一个指定在PHONE_NUMBER的手机。对于每一个转发的消息都打印了一个日志信息,显示了发送者和接收者的电话号码。注意你不要指定你自己的电话号码给PHONE_NUMBER。这将使得程序转发消息给它自己,导致一个死循环。4.5 SMS游戏服务器本章我们已经谈了许多新的概念。我们已经学习了如何使用标准用户接口框架,怎样操作字符串和怎样读取和接收SMS消息。在最终例子中,所有的特征将被放到一起运用。该应用程序是一个有用户界面的SMS游戏服务器。它实现了典型的刽子手游戏,维基百科是这样描述它的:一个玩家想出一个词,另外一个通过列举字母尝试将其猜出来。用一行短破折号将要猜的词呈现出来,为了给出字母的数量。如果猜字的玩家提出了一个单词中有的字母,另一个玩家将其写到所有正确的位置上。当猜字的玩家完成了单词或者正确的猜出了整个单词,游戏结束。注意我们的游戏省略了游戏的图画部分。在你阅读了第五章后,添加图像到游戏将是一个有趣的练习,该章介绍了所需的函数。你是游戏的管理者,并运行着服务器。你可以输入要猜的单词通过用户界面。另外一个玩家发送文本消息到你的手机,猜测单独的字符(如“GUESS a”),或者猜测整个单词(如“WORD cat”)。每猜一次后,一条包含有当前单词状态的应答消息将会发送给猜测者。这没有玩家数量限制。程序的实现包含有一些以前没有介绍的特征,但是它们将在后面的讨论中出现。因为代码不能在一页列出来,所以我将其分成三部分。你应该将这些部分合并成一个完整的应用程序。例19:刽子手游戏服务程序(1/3)import inbox, messaging, appuifw, e32, contactscurrent_word = Noneguessed = Nonenum_guesses = 0def new_game():global current_word, guessed, num_guessesword = appuifw.query(uWord to guess, text)if word:current_word = word.lower()guessed = list(_ * len(current_word)num_guesses = 0print New game started. Waiting for messages.def game_status():if current_word:appuifw.note(uWord to guess: %sn % current_word +Current guess: %sn % .join(guessed) +Number of gusses: %d % num_guesses)else:appuifw.note(uGame has not been star

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论