LG KG90n是中国移动游戏基地手机系列中的一款,240x320分辨率的屏幕,不支持蓝牙,下载jar的时候只能使用OTA (Over The Air)下载且下载速度极慢,一般需要五六分钟。不过总体来说性能还可以。做j2me应用时,jar包可以达到600k以上,内存也还算充裕。但是有手机的jvm不是特别完善,开发时如果不注意会出现一些难缠的问题。
以下就是我遇到过的2个问题,试验了多遍得出的结果。
1,屏幕闪动问题
现象:进入游戏后,屏幕总是会闪动,但其实游戏还算流畅。
问题出在屏幕刷新,该手机不允许一帧内对屏幕进行两次刷新。何谓两次刷新?对比一下代码比较好理解一点。
问题代码:
public void paint(Graphics g){
g.setColor(-1);
g.fillRect(0, 0, SCR_W, SCR_H);
Graphics gBuf = imgBuf.getGraphics(); //imgBuf is an Image of screen size as the screen buffer
game.draw(gBuf);
g.draw(imgBuf, 0, 0, 0);
}
修改后无问题的代码:
public void paint(Graphics g){
Graphics gg = g;
if(imgBuf != null)//imgBuf is an Image of screen size as the screen buffer
gg = imgBuf.getGraphics();
gg.setColor(-1);
gg.fillRect(0, 0, SCR_W, SCR_H);
game.draw(gg);
if(imgBuf != null)
g.draw(imgBuf, 0, 0, 0);
}
对比代码可以发现,看问题代码,可以知道前面说的‘两次’是:一次是直接网手机屏幕上画东西,一次是在buffer上画东西,然后再画到屏幕上。而无问题代码的做法是:在画图之前,先看是否有buffer,如果有buffer则把所有东西都画到buffer上,然后再一次性画到手机屏幕上,如果没有buffer,则把所有内容直接画到手机屏幕上——这样就不会出现闪动的问题了。
2,在联网时弹出系统提示窗口问是否允许联网时,也闪动。
现象:正常的情况是弹出一个系统窗口,但是该窗口没有完全遮住屏幕,可以看到j2me应用暂停了,变成了灰色。但是我遇到的问题时,画面不断在我的j2me应用和系统提示窗口之间来回切换闪动,且应用没哟变灰色,还是正常的色彩,提示窗口没有显示出来,只显示出屏幕底部的‘是’和‘否’两个提示按钮。
原因:按键响应的机制有问题。如果直接在按键响应函数中去做逻辑响应——keyPressed()和keyReleased()函数,就会出现这样的问题,如果在这两个函数里只是保存着按键的值,而在线程的run()函数的while循环中去做逻辑处理的话,则能避免改问题(我做的是一个游戏,一般来说游戏都是起一个线程,在run()函数中是否一个while(true)的无限循环不断重画屏幕来实现游戏的运行)。还是对比一下代码:
有问题代码:
public void run(){
while(true){
repaint();
serviceRepaints();
}
}
public void keyPressed(int keycode){
if(keycode == NUM_0){
midlet.platformRequest(url); //此处会出现系统联网提示
}
}
无问题代码:
public void run(){
while(true){
gamelogic();
repaint();
serviceRepaints();
if(keyHold != INVALID_KEY)
keyHold = INVALID_KEY;
}
}
int keyHold;
void gamelogic(){
if(keyHold == NUM_0)
midlet.platformRequest(url);
}
public void keyPressed(int keycode){
keyHold = keycode;
}
对比代码可以发现,后者保证了逻辑处理(gamelogic())在画图之前处理完,逻辑处理和画图不会相互干扰;而前者直接在keyPressed()中处理,则很可能会打断画图的过程——即在画图还未完成的时候,弹出了系统提示框,弹出之后,又要进行剩余的画图过程从而导致了闪屏——似乎也可以这样总结:系统的画图线程和应用的画图线程相互穿插了,导致了闪屏。避免穿插的办法就是在系统画图线程启动的根源处做处理——即按键处理的地方,将逻辑处理和画图过程完全分开。