nancy
版主
积分:1372

openface开发常见问题----开发问题

1)问:为什么我的应用上使用鼠标没有反应?

答:OpenFace的目标环境是手机系统,因此目前没有提供鼠标支持,但是考虑越来越多的手机支持触摸屏,以后OpenFace将会提供鼠标支持。

nancy
版主
积分:1372

2)问:为什么按键盘的方向键,我应用中的焦点无法移动

答:应用的焦点可以分两种:1、对于能得到焦点的元素得到焦点时,系统自动画上焦点边框2、开发人员自行画的焦点边框或者焦点背景。对于第一种,必须使用LzFocus.setFocus(element)才能让焦点落到element所引用的元素上。对于第二种完全由开发人员画出焦点框或者使用图片背景之类。

nancy
版主
积分:1372

3)问:为什么使用LzFocus.setFocus(elementobj)方法没有作用

答:首先要保证该方法确实被调用。其次elementobj对应的元素必须是能得到焦点的(常见默认能得到焦点的元素有inputtext,如果是view则需要在属性中加上focusable=’true’)。最后确定参数elementobj在js中是一个lzx元素对象的引用。通过
canvas.elementname.subelename…方式可以逐级引用到canvas各个设置了name属性的元素。也可以使用id方式直接引用,比如:

<?xml version="1.0" encoding="utf-8"?>
<canvas width="240" height="320">
<view name="v1">
<inputtext name="input1" id="myinput" width="100"/>
</view>
<handler name="oninit">
LzFocus.setFocus(canvas.v1.input1); //正确,通过name方式引用
LzFocus.setFocus(this.v1.input1); //正确,和上面等价,这里this等价canvas
LzFocus.setFocus(myinput); //正确,通过id方式引用
LzFocus.setFocus("canvas.v1.input1"); //错误,参数不应为string
LzFocus.setFocus("myinput"); //错误,参数不应为string
</handler>
</canvas>
注意:直接从本文档中copy源代码示例后如果不能正常编译或者应用不能正常打开,请先检查copy出来的xml代码是否存在中文标点问题(word转换问题),可以直接在IE中看该XML文件,如果IE能正确显示则说明无问题。

nancy
版主
积分:1372

4)问:使用中文后,应用编译后不能运行或者显示乱码

答:OpenFace暂时只支持utf-8编码,所以当您的应用中使用中文字符时,首先应该设置xml文件xml元素标记的encoding=”utf-8”(此步不正确设置应用可能无法运行),并且将该文件保存成utf-8格式(在中文xp系统中默认保存是ACSII格式,此步不正确设置会导致中文乱码),如果应用中有多个文件使用中文,则每个含中文的文件都应该保存成utf-8格式。

nancy
版主
积分:1372

5)问:使用ajax或者dataset请求时,如果参数有中文,为什么在服务器端接受到的是乱码。

答:服务器端处理参数时请使用
new String(request.getParameter(name).getBytes("ISO8859_1"),"utf-8")

nancy
版主
积分:1372

6)问:应用如何响应用户的操作?

答:目前OpenFace只接受用户键盘(PC或手机)的响应。在应用中有两种方式处理按键:1、得到焦点的元素处理按键2、无论是否得到焦点的元素都处理按键。前者只有当该元素得到焦点的情况下用户的按键才被捕捉,而后者无论什么情况下都能捕捉用户的按键。因此应用可以有多处处理用户按键的代码。元素需要处理按键时为该元素添加一个onkeydown的handler即可,如下:
方式1和方式2的区别在于handler中是否设置reference属性,如果不设置则为方式1,否则为方式2。
<handler name="onkeydown" args="key" reference="LzKeys">
var keycode=key.intValue();
switch(keycode){
case LzKeys.VK_LEFT:
//左方向键
break;
case LzKeys.VK_RIGHT:
//右方向键
break;
case LzKeys.VK_UP:
//上方向键
break;
case LzKeys.VK_DOWN:
//下方向键
break;
default:
Debug.write("keycode="+keycode); }
</handler>
具体按键值请见OpenFace 编程参考手册

nancy
版主
积分:1372

7)问:通过js或者java给view设置resource,但是图片不能显示

答:在js或者java中设置resource时,图片资源文件不能被编译工具编译到目标文件夹。有两种方式解决:1、手工copy图片文件至目标文件夹。2、在lzx中添加一个Resource,例如:
<resource name="ren" src="yddt-ren.gif"/>
如果出现其他的一些图片不能显示的问题,请先检查编译工具是否将图片文件编译到目标文件夹。

nancy
版主
积分:1372

8)问:我应用中有两个view,但只能看到一个。

答:在OpenFace中,如果不设置元素的x、y值,也没有设置layout,那么默认元素的x和y值均为0,这样两个元素最终显示是重叠在一起使得可能只显示一个,这个同html中元素的显示是有区别的。

nancy
版主
积分:1372

9)问:没有类似Timer这样的类?

想做有动画效果的游戏,不知有没有类似Timer的类可以让我们每隔固定时间间隔就运行一个方法?
目前没有Timer,不过很快就支持,请关注我们的发布更新
答:现在可以用 标签<animator>和<animatorgroup>做动画,
除了使用animate外,熟悉javascript的开发者也可以使用setTimeout函数。该函数提供了定时调用其它函数的方法。

nancy
版主
积分:1372

10)问:事件参数问题

对于某个类,比如View,定义了多种方法,哪里可以找到每种方法的arg和reference参数的定义和用法?
答:wiki上有对应的参考可以查看
这里可以搜索,可以分类察看
http://www.openlaszlo.org/lps/docs/reference/

nancy
版主
积分:1372

11)问:我有一些关于打包的问题,我写好了一个扫雷的游戏,在OpenFace下运行没有问题,完全在预期之中,但是按着方法打包后,也能生产BAT文件,但是双击Openface.exe却打不开,在开始做这个扫雷游戏的时候,做个大概的时候,可以用模拟器打开,但是不能功能和在Openface下不一样,在Openface下能实现的,在模拟器里不能?是不是对一些方法的调用有限制?希望贵公司能解答一下!

答:你所说的Openface下运行没有问题。是否指,下载了SDK包,运行没有问题?
下面是一些解释。但之前也跟你说过,要以模拟器的运行结果为准。
OpenFace(不是他邮件中的OpenFace,他邮件中的OpenFace实际是OpenLaszlo)所支持功能和OpenLaszlo有一些差别。即使有些功能调用的函数名一样,最终表现可能也有差别,也就是说OpenFace和OpenLaszlo不是100%兼容的。
为了减少这种不兼容性对开发带来的影响,实际写应用时,不要在OpenLaszlo上看效果,而是直接在模拟器上看。但是另一方面,可以看OpenLaszlo的develop guide文档来加深对lzx编程思想的理解,注意看OpenLaszlo 的develop guide不是为了里面的代码例子,而是加深对lzx结构体系,编程思想的理解。

nancy
版主
积分:1372

12)问:我下午弄了下,发现一些问题,比如说我写一个二层循环,用new LzText()生成文本标签,但是只能写一个12行12列的,在这个范围内的都可以在模拟器里显示,其他都会发生内存越界,提示不能读取?是不是模拟器的内存大小有限制?在OpenFace.ini中的memory-size = 0xe80000该怎末修改?还有就是在下边这段代码中,我将del[i][j].setVisible(true);设置为true时可以在模拟器里显示,为什么设置为false的时候不能?希望解答一下?
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 12; j++) {
del[i][j]= new LzText(canvas, {text : map[i][j],x : i * 20 + 100,y : j * 20 + 100,fontsize : 14});
del[i][j].setVisible(true);
}}

答:del[i][j].setVisible(true)设置为true可以在模拟器里显示,设置为false时不能显示,这本来就是对的,没有问题,false就是不显示,true才显示。
你提出的内存超界,只能显示12X12的问题,可能是你的JS数组使用时出的问题。
(应该不是模拟器内存的问题)
下面这个例子你参考一下。你可以修改数组长度,可以超多12
<canvas height="400" efcdebug="true">
<text id="tt" text="text"/>
<method event="oninit"><![CDATA[

var map = new Array( 2 );
var del = new Array(2);
for (var i = 0; i < 2; i++) {
map[i] = new Array(2);
del[i] = new Array(2);
for (var j = 0; j < 2; j++) {
map[i][j]=i+j;
del[i][j]= new LzText(canvas, {text : map[i][j],x : i * 20 + 50,y : j * 20 + 50,fontsize : 14});
del[i][j].setVisible(false);
}
}
]]>
</method>
</canvas>

nancy
版主
积分:1372

13)问:OpenfaceSDK生成了一系列的LzInputText,在Openfacex下可以编辑,也可以获得焦点,但是我打包后在模拟器里运行的时候,却不能编辑?而且也没办法聚焦,究竟在Openface中inputtext和LzInputText是怎末运用的?在网站给出的例子中也没有用到这两个标签,在文档也没具体介绍?希望给与解答

答:inputtext 需要在得到焦点的情况才能编辑。在openface上因为不支持鼠标点击,必须要应用设置焦点到相应的inputtext上,使用LzFocus.setFocus()方法。该方法需要提供一个参数,为需要设置的对象引用。关于LzFocus的用法见编程参考手册—class-LzFocus部分。
简单的例子:
<view >
<inputtext name=”myinput”width=”100”/>
<handler name=”oninit”>
LzFocus.setFocus(this.myinput);
</handler>
</view>

nancy
版主
积分:1372

14)问:如何在.lzx中实现两个界面的切换呢?前提是这两个界面不是现成的可
以导入的图片,而是自己编辑的(即自己期望产生的效果),然后可以
在切换的另一个界面中实现相应的功能,这样的话可以用什么函数实现
呢?

答:可以把界面放在view 视图中,用隐藏和显示控制界面切换
如下
<?xml version="1.0" encoding="utf-8"?>
<canvas xmlns:eloo="http://www.monternet.com/2007/components" height="320" width="240">
<text text="按方向左键和右键切换两个界面" fontsize="16" x="20" y="120"/>

<view id="v1" visible="true">
<text text="first interface" fontsize="16" x="20" y="30"/>
</view>

<view id="v2" visible="false">
<view x="10" y="30" width="100" height="50" bgcolor="red"/>
<text text="second interface" fontsize="16" x="10" y="50"/>
</view>

<handler name="onkeydown" reference="LzKeys" args="key">
var keycode = parseInt(key);

switch(keycode){
case 4110: //ok
case 37:
v1.setVisible(false);
v2.setVisible(true);
break;
case 4111: //confirm
case 39:
v1.setVisible(true);
v2.setVisible(false);
break;
}
</handler>
</canvas>

nancy
版主
积分:1372

15)问:我现在想做一个小游戏:迷宫。
每一关单独的都做了出来,但是怎样让每一关联系起来啊(也就是说玩过第一关之后可以继续玩第二关)?
我用的函数是 ...result.setText=LzBrowser.loadURL(' ', ' ');
在openface中我可以实现页面的跳转,但是没法在模拟器中实现。
因为我的每个界面都是用到时自己生成的,而不是提前制作好的,
所以每一关都有 <canvas> </canvas>。
请问我用什么样的函数可以让跳转也在模拟器中实现呢?

答:把每关做成一个独立的应用,然后在两个应用之间进行切换,在目前的openface模拟器上是不能处理的,虽然有办法可以做到这个效果(即使可以进行切换,但是也无法进行数据传递,比如说把第一关的得分带到第二关),因为目前的openface只支持一个应用,没有带上应用管理功能,因此不要在这上面考虑。
LzBrowser对象及相关属性和方法openface并不支持。
所以你必须把这个游戏做在一个应用中,尽管这个游戏的每关之间可能完全没有联系,每关做成独立的有利减少运行时的内存使用以及提高运行速度。而且既然每个界面都是生成的,那么做在一个应用中应该是更容易的。

nancy
版主
积分:1372

16)问:我所说的Openface就是我从你们网站上下载的SDK包,用你们给的tomcat服务器运行,在那里面开发的程序,你说的我明白了,我会注意的,但是每次我改写完了要打包看效果的话,会比较麻烦,我以为在Openface下弄好了直接一次打包就可以,原谅这样是不行的。那我以后会多注意些.

答:实际上每次修改了应用后不需要使用打包的dat文件,在编译源文件时,除了生成dat文件外,还会直接生成目标代码(exmc、jsbc等文件)到desktop目录,这样每次修改代码后,编译一下,然后直接运行模拟器就是跑修改后的应用。

nancy
版主
积分:1372

17)问:有几个关于OpenFace的问题想向您请教一下。
(1)<text>标签内的引号“”显示问题。如果直接在<text>标签内写引号的话,在模拟器上显示的不是引号而是&quot:,如果要在<text>标签内显示引号,有什么直接的方法么?
(2)请问模拟器是否可以直接调用一个手机浏览器或者将一个浏览器嵌在<canvas>内部,一个简单的例子就是在<canvas>内直接显示一个html格式的网页。
打扰了。
谢谢

答: 问题1: text.setText("\"abc\""); 这样可以输出“abc”
问题2:暂时还不支持。

nancy
版主
积分:1372

18)问:我在openface的开发中碰到了两个问题:
1. 如何实现文本的输入并显示。我想定义一个视图输入框,然后从手机上输入字母或汉字并在输入框中显示,请问如何实现输入,输入法是不是和手机的输入法相关联的。
2. 如何实现文本的分页显示。有些文本内容比较长,即使设置的multiline="true",也无法在一个视图内显示完毕,请问如何才能分页显示,通过键盘按向下的方向键实现新一行内容的显现。
答:1输入框可以使用inputbox 标签,获得焦点后在模拟器通过F5切换输入法,手机上可能是#号键
2由于目前没有滚动条,但是可以实现相同的功能:multiline="true"设置为true, 宽度和高度也要作相应的设置,然后可以通过函数getTextHeight()和getTextWidth()
等获得文本高度和宽度,然后计算文本的本身的高度和文本框的高度确定目前显示的到第几页、共几页这些信息,再用一个组建画一个滚轴,这样就可实现所述功能

nancy
版主
积分:1372

19)问:我们需要以下文档:
音频和视频开发文档
文件操作(后台服务接口等)
按键映射表

答: 相关文档请在网上查找。
音频与视频,文件操作目前支持不全
对于按键的定义,请参考:http://www.openface.org.cn/wiki/index.php/LzKeys

nancy
版主
积分:1372

20)问:我现在要做一个推箱子的游戏。但是遇到很多的问题:
第一,怎么让每一关链接起来呢?
第二,每一关的图片能不能利用一个函数,让他自己生成,还是必须自己导入图片呢?
第三,如果让一个小人推着箱子移动,用什么函数呢?
我看了文档,然后翻阅了资料,一些用vc++或者Java写成的推箱子游戏的一切都是可以用函数算法解决的,但是我不知道
如何利用咱们的.lzx语言实现呢?

答:1必须把这个游戏做在一个应用中,尽管这个游戏的每关之间可能完全没有联系,需要通过界面的显示与隐藏切换实现。
2 可以使用产生随机数的方法实现,但是算法要考虑游戏是否能顺利过关。
3 可以通过设置这两个节点(小人图片和箱子图片)的x,y位置来实现。这些完全可以通过函数(javascript中的function ()或者lzx中的method)实现 。
<handler name=”onkeydown” reference=”LzKeys” args=”key”>
fundtion func1 (a,b){
….
}
<method name=”func2” args=”a,b”>
</method>
</handler>

nancy
版主
积分:1372

21)问:就是我在学习查看图片这个项目时,有个地方我看不明白,代码是这样的:
<view name="container" datapath="photoData:/path" focusable="true" id="container" bgcolor="black" stretches="none" width="${Math.min(parent.width,240)}" height="${Math.max(parent.height,320)}" clip="true" oninit="init()">

<view id="v1" focusable="true" name="v1" y="${Math.max(parent.height,320)-50}" width="${parent.width/4}" height="50" stretches="both" resource="a1" clip="true" onfocus="parent.focus()" onblur="parent.blur()">
</view>
<view id="v2" focusable="true" name="v2" x="xoffset" y="${Math.max(parent.height,320)-50}" width="${parent.width/4}" height="50" stretches="both" resource="a2" clip="true" onfocus="parent.focus()" onblur="parent.blur()">

</view>
<view id="v3" name="v3" focusable="true" x="2*xoffset" y="${Math.max(parent.height,320)-50}" width="${parent.width/4}" height="50" stretches="both" resource="a3" clip="true" onfocus="parent.focus()" onblur="parent.blur()">
</view>
<view id="v4" name="v4" focusable="true" x="3*xoffset" y="${Math.max(parent.height,320)-50}" width="${parent.width/4}" height="50" stretches="both" resource="a4" clip="true" onfocus="parent.focus()" onblur="parent.blur()">
</view>
<view id="v5" name="v5" focusable="false" x="0" y="0" width="${parent.width/4}" height="0" stretches="both" clip="true" resource="a1" onload="loadAinmate()">
<animator name="top" attribute="y" from="0" to="0" duration="1000" start="false" onstop="parent.parent.updateq()" onstart="parent.parent.startmove()"/>
<animator name="left" attribute="x" from="0" to="0" duration="1000" start="false" onstop="parent.parent.updateq()"/>
<animator name="wid" attribute="width" from="0" to="0" duration="1000" start="false" onstop="parent.parent.updateq()"/>
<animator name="hei" attribute="height" from="0" to="0" duration="1000" start="false" onstop="parent.parent.updateq()"/>
在这段代码里面,我始终没有搞明白 onfocus="parent.focus()" onblur="parent.blur()"这句代码中onfocus、onblur的用法,类似的还有oninit、onload这几个属性究竟有什么用?

答:这几个属性都是在事件触发的时候产生响应。
比如onfocus="parent.focus()" ,在view 获得焦点的时候(获得焦点事件)就会响应(调用父视图的focus()方法)
同理 onblur 就是失去焦点时响应事件。 Oninit 在初始化时被触发,onload 在下载数据完成时被触发。
多参考下面两个文档:
OpenFace 应用开发指南
OpenFace 编程参考手册

nancy
版主
积分:1372

22)问:我在项目中导入了一个文件大小约为10M的XML类型的数据文件,直接导致OpenFace.exe无法启动,请问,在OpenFace中,在数据量较大的时候,通常会如何处理!对于数据量较大的数据的处理,通常采用什么方式?能否举例说明?

答:由于内存问题,我们无法处理。
从应用角度来说,对于大的xml的文档应该换成小的xml文档,然后多次读取的方式解决。

nancy
版主
积分:1372

23)问:数据分割成若干个小的xml文档是可以的,但是如何进行多次读取?如果是datapointer的话,是否先将datapointer指向第一个文件,等第一个文件遍历完之后再将其指向下一个文件,以此类推?这样如何保证内存的使用不会过大,在datapointer指向下一个文件之前是否需要将原来加载的数据清除,如何清除?或者是否有更好的方法实现多个数据文件多次读取。望能举例说明。

答:在OpenFace应用程序中,<dataset>就提供了一种封装XML数据的方法。取决于数据源的种类,数据集可以使动态的也可以是静态的。当数据集通过”type=http”显式地声明时,src属性的值就解译为一个URL,此时数据集在运行时装载数据。如果src数据缺省,那么它表达的数据就应该包含在<dataset>标签内,于是数据直接编译进应用程序。
当我们说HTTP数据集是动态的时,即意味着我们可以使用程序方式来重新装载数据。具体方法是:调用数据集对象的doRequest()方法;或如果request属性被设置为true,通过通过调用setSrc(),setQueryString(),或setQueryParam()来改变数据集的URL及请求的参数(如果是一个静态的XML是不需要请求参数的)。

通过改变数据集URL就达到了一个dataset指向多个xml文档,这样避免了一次一下子载入很大的一个文档。上面几个函数具体请见编程参考手册dataset部分。
下面的例子,按数字键1请求data1.xml,按数字键2请求data2.xml。
<canvas width="240" height="320" >
<dataset name="mydata" type="http">
</dataset>

<simplelayout axis="y" spacing="5"/>
<text y="10" fontsize="20" resize="true" datapath="mydata:/myXML/text()"/>

<text id="tmp" fontsize="20" resize="true" text="hello"/>
<handler name="onkeydown" reference="LzKeys" args="key">
switch(key){
case 49:
mydata.setSrc("http://222.128.6.118/test/data1.xml");
mydata.doRequest();

break;
case 50:
mydata.setSrc("http://222.128.6.118/test/data2.xml");
mydata.doRequest();

break;

}
tmp.setText(""+key);

</handler>
</canvas>

nian508
游民
积分:31

如果想动态加载本地的多个xml 怎么办 ?mydata.setSrc("http://222.128.6.118/test/data2.xml"); src不是网上的 我试了下好像不行

openface
技术支持
积分:420

设置了src后还要调用doRequest方法,详细见编程参考手册,dataset部分。

nian508
游民
积分:31

还是不行 我把那两个xml下载到本地
代码改成





switch(key){
case 49:
mydata.setSrc("test.xml");
mydata.doRequest();

break;
case 50:
mydata.setSrc("test2.xml");
mydata.doRequest();

break;

}
tmp.setText(""+key);


xhm1027
游民
积分:112

运行doRequest()方法时能在界面上显示诸如“数据采集中,请等待.....”的效果吗?
我看了,用ajax可以做到,但是直接用数据集的doRequest方法能实现吗?

openface
技术支持
积分:420

其实,使用数据集和ajax的背后的原理都差不多,数据集相当于再封装了一层。
“数据采集中”这句话是在请求开始时到请求结束时显示的,ajax是根据它请求的4个状态来判断请求开始和请求结束的。

数据集是否能做到这点呢?实际就变成你能否判断数据请求开始和结束。结论是可以的。很明显,当你调用doRequest时就是请求开始的时候,而当数据集的内容变化时就是请求结束的时候(通过ondata事件)。

也许你还会碰到一些问题,我觉得这样的问题最好是自己多去体会、思考解决,所谓知其然还要知其所以然,我直接告诉你方法也许对你解决这个问题很有帮助,但是不利于你自行解决问题。

xhm1027
游民
积分:112

使用了这个方法,发现一个问题: 加载第一个src(data1.xml) 的时候在模拟器中正常,当用函数mydata.setSrc("data2.xml");mydata.doRequest(); 时模拟器就死掉了。
而第一次加载data2.xml时正常,而第二次用函数加载data1.xml模拟器也死掉了。
log文件的错误提示应该是“WARNING!!! vm->heap uses much memory!!! request bytes 120 ”,应该是内存溢出。
请问如何处理?

nancy
版主
积分:1372

两个xml文档分别有多大?
一种可能是两个XML比较大,导致内存不够。比如说在载入第二XML时,第一个XML产生的数据还在使用,相关的一些内存没有或者部分没有被释放。
应用能够载入多大的XML取决于应用其它部分消耗的内存。一般来说如果怀疑XML过大导致内存不够,可以把XML文件弄小看看。

另外如果觉得不是XML文件大小导致的内存不够死机,可以只把XML载入进行,但是不把dataset绑定到任何对象之上(包括不要用datapointer指向它),看看是否还会因内存不足死机。

这种问题凭描述一般很难判别是什么问题,如何解决,如果自己解决不成功的话可以把代码发出来看看。

zs
游民
积分:1

24)问:我想做一个贪食蛇的游戏,想问一下怎样在游戏执行过程中判断键盘的输入呢?例如再一个无限循环中是否可以添加判断是否有按键按下,并能返回键值的函数呢?谢了

openface
技术支持
积分:420

Lzx应用中,任何时候都可以接受按键。
上面提到的已经不是Lzx语法或者OpenFace使用的问题,而是编程思路问题。

我觉得上面的问题更应该是当执行一个无限循环时如果有按键动作,那么是否可以中断这个无限循环。
答案是肯定的,具体看这个无限循环是个什么样的结构。这样的问题,自己多想想比较好,如果一条路行不通时,考虑另外的思路也是不错的。

另外,若有任何问题,请单独开贴