分类:
2006-11-19 12:17:53
基于Palm操作系统的地图搜索引擎
此文档记录解决在Palm机上显示地图以及在地图上映射坐标的过程
开发工具:Metrowerks CodeWarrior IDE version 5.2.1283
因为在Palm机上建立一个资源图片需要用Bmp格式,而Bmp格式的图片很大,Palm又有一个限制,资源文件不能大于64kb,这样就必须对地图进行合理分割,既要让几张地图在浏览过程中可以连续显示,又要避免坐标系统的混乱。
首先解决单张图片在屏幕上移动的问题
手机屏幕的分辨率为320*320(像素),经过多次试验,发现当资源图片的设置满足下面设置时,图片的大小以及显示的清晰度都是最好的。
大小为(160*160),图像高密度(Double)显示,色深为8-bit,使用Palm OS5的最新压缩方法。这样图片在屏幕上显示的实际大小为320*320。
系统提供WinDrawBitmap函数实现图片的显示,它会自动切除超出屏幕显示区域的部分,我们只需要改变图片的显示位置就可以实现图片的移动了。
后来发现,当多次调用绘图函数时,会导致屏幕更新明显缓慢。
比如:当我们在一个屏幕上画两张图片,每张只显示一部分时,就可以发现显示更新缓慢的现象,当图片再多时就更明显了。
我们可以用双缓冲技术来解决这个问题,我们可以向系统申请一块缓冲区,在其内进行画图操作,之后将缓冲区内的内容一次复制到屏幕上。
用了双缓冲技术后发现显示速度明显提高了,因为系统不用每次调用绘图函数之后都执行同样的相关操作。(在操作系统内部如何实现画图没有研究过,这只是试验的结果)
解决图片分割问题
将图片分割成35张,每行7个,共5行,编号为1000-1034,每张图片正好占满整个屏幕。
用originalScreen存储屏幕句柄,mapOffscreen来存储图像缓冲句柄。
每次当图片移动时,都要载入相邻的相关图片,这样会导致一个问题,当需要移动图片时,都要从资源库中一个一个地调入,即使是小规模的移动也是如此,为了解决这个问题,我们可以同时载入与那张图片相邻的八张图片,形成一个9图矩阵,其编号为:0-8。
0 1 2
3 4 5
6 7 8
并用bitmapH[9]和bitmapP[9] 内存句柄数组和图片类型指针数组存储该9图矩阵。
我们始终将9图矩阵中中间的那张图片称为currentMap。9张图片就像在屏幕上运动,当屏幕到达左边界时,currentMap变成3号图片,当到上边界时1为currentMap,依次类推。当currentMap变化时,同时载入其他8张图片,这样就减少了从资源库中载入图片的频度。
用vX,vY代表中间那张图片在屏幕中显示的位置,cX,cY代表屏幕的左上角在整个地图中的坐标。则vX,vY用来显示图像,cX,cY用来准确定位某点在整个地图中的坐标,同时判断地图在屏幕上显示是否溢出。
计算每张图片左上角的坐标公式为:
cX = 160*((MapID%100)%7)
cY = 160*((MapID%100-(currentMap%100)%7)/7)
右上角的摇杆解决方案
图片大小为55*55,同时也用高密度显示,所以实际大小为110*110,称其为stick
整体效果如下:
在右上角图片的中间画上一个摇杆。
屏幕的坐标为160*160
因为要用触摸笔对中间的那个摇杆控制,使其跟随触摸笔运动,这样就需要判断触摸笔点击屏幕时点击的是否是遥感可以移动的那块区域。stick2可以移动的区域为:以(118,15)为端点,以25为长宽的矩形区域,这个区域用RectangleType这个结构存储,命名为stick2Rct。
用penDownX和penDownY来存储触摸笔刚接触屏幕时的坐标。
当触摸笔在屏幕上移动时,stick2也随着移动相应的坐标增量。用changeX和changeY来记录增量。
触摸笔移动的区域为 以(131,27)为圆心,以15为半径的圆。
提笔的响应区域为整个区域。sick2UpRct
用bool变量gPenDown来记录当前触摸笔的状态。
整个遥感的响应过程:
当接触屏幕时:记录当前的坐标值,赋给penDownX和penDownY
stick2的中心移动到点击的位置。
记录gPenDown为true;
当触摸笔在屏幕上移动时:计算坐标的增量:
changeX = eventP->screenX-penDownX;
changeY = eventP->screenY-penDownY;
cX+changeX>=0 && cX+changeX<=879 && cY+changeY>=0 && cY+changeY<=528
判断显示的图片是否越界。
if (vY >= 160 && changeY<0 && currentMap >1014)
{
CurrentMap(currentMap-7, APEEK);
}
if (vY <= -160 && changeY>0 && currentMap <1021)
{
CurrentMap(currentMap+7, APEEK);
}
if (vX >= 160 && changeX<0 &&(currentMap%100)%7!=1)
{
CurrentMap(currentMap-1, LEVEL);
}
if (vX <= -160 && changeX>0 &&(currentMap%100)%7!=5)
{
CurrentMap(currentMap+1, LEVEL);
}
之后根据增量移动图片和stick2
当触摸笔提起时:stick2复位,gPenDown为true
遥杆测试
2006.11.17 21:00
遥杆制作完成,进行测试。
在测试过程中,我们发现,类似于google的遥杆不适合在小型的屏幕上使用,因为笔尖的移动面积过于狭小,所以现决定把整个遥杆控制界面放到屏幕的正中间,当不需要使用遥杆时,在屏幕的右上角显示一个小图标(),当点击该区域后,遥杆控制界面出现在屏幕正中心,与以前的制作相似。
.......
具体实现方法请看源代码