站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2ME 专题手机游戏修改之浅谈

手机游戏修改之浅谈

摘要: 手机游戏修改之浅谈
<tr><td>

[本文章最后由 rocks 在2006-06-16 00:53:49编辑过]

http:///tech/article887.html
手机游戏修改群出品----修改之浅谈(作者:cj20038413)
[]
这次改动,是我们内部讨论的结果,请大家继续支持

初级篇

恩,最近开始修改游戏,有了一点自己的体会和心得,当然要感谢kim,yy,sofy,小召等人的帮助和指点,这篇文章也来之不易,共写了两次,同样的字打了两片……汗……
540) this.width = 540'>

[]看过众多高手的文章,觉得都有点偏向于复杂化和深奥化,这里我尽量写的简单一点,大家也好明白的快一点,好了废话不多说,直奔主题(这么多废话,拖出去砍了)狂汗…………

对于修改来说,首先要备齐工具,这里推荐winhex(16位进制编辑器)ultraedit,Java源代码反编译专家,当然还有你的手机所对应的模拟器,至于java环境一类的你也可以选装,我现在没有装。
首先,我们先来看看一般情况下的全屏解决的问题,对于阿尔卡特ot735i的手机来说,受着黑条的痛苦很久了(什么是黑条??就是游戏时屏幕下方的黑黑的一条,moto c650等一些机子也有这种情况,对此,可以直接用fulljava来处理,735i注意调成128*128的哦^-^
然后,我们再来看看关于中文字体的显示问题,这点在于735i和三星x108/x608中尤为明显,这点winfy和其他高手也都说过了,在这里我简单的说一下就行了(对了,关于字体,主要是游戏调用了小号字体的缘故,而735i和三星用的是中号字体,而且无法和moto一样自动调用中号字体,所以一般的中文游戏都没有任何显示……)

在修改时,一般就针对于getfont(0,0,8)就可以了,那些使用getfont(0,0,16),getfont(32,0,8)一类的游戏大致也差不多主要的差异也就是在16位进制的转换上有所不同……
[]在开始时,打开游戏jar文件,从第一个class文件开始,挨个打开,在里面查找getfont或者getfong(0,0,8),在找到后,看一下getfont的位置,大概记一下,改完后在来看看有些什么变化,注意,多看看程序的习惯要养成!^_^
之后把有getfont的class拉到jar文件之外,用winhex打开,在搜索中点击查找16位进制数……,一般情况下(getfont(o,o,8)时)输入1008(其他的也只是改了最后的数字8,自己也可以推一下),将其改为1000即可,成功后,看一下程序,然后就传回jar文件,之后用模拟器试一下就行了。
这里有史库比2的修改对比图,注意,有些模拟器上可以显示小号字体,但是并不代表手机可以!比如我的就是……汗


之后我们再来看看按键的修改,一般情况下,按键的修改方法都是大同小异的,在我改过的游戏中一般遇到的有if 和 case情况,这两种情况呢,又以if 较为简单,他不用太多的东西就可以轻松实现,所以也是我们最喜欢碰到的情况,呵呵,关于if语句,主要方法和改字体一样,搜索查找,用winhex修改,不过对应的就是faa0和f9a0了,将其修改为所对应的按键就行了,为什么是fa,f9呢?
大家往下看:
阿尔卡特557/556moto c系列 诺基亚: 阿尔卡特ot735i moto v300以后的机型
按键 键值 16进制值 按键 键值 16进制值 按键 键值 16进制值 键名
左软键 -21 EB 左软键 -6 FA 左软键 21 15 soft1
右软键 -22 EA 右软键 -7 F9 右软键 22 16 soft2
上方向键 -1 FF 上方向键 -1 FF 上方向键 1 01 up
[]左方向键 -2 FE 左方向键 -3 FD 左方向键 2 02 left
下方向键 -6 FA 下方向键 -2 FE 下方向键 6 06 down
右方向键 -5 FB 右方向键 -4 FC 右方向键 5 05 right
action(735i)/ok: 20 14 select
其他的数字键手机上都一样,具体如下:
[]按键 键值 16进制值 键名
[]0键 48 30 num0
1键 49 31 num1
2键 50 32 num2
3键 51 33 num3
4键 52 34 num4
5键 53 35 num5
6键 54 36 num6
7键 55 37 num7
8键 56 38 num8
9键 57 39 num9
*键 42 2A star
#键 35 23 pound


大家只需将查到的键改为想要的就行了,而我们一般只要改左右的软键就行了,所以一般都先搜索fa a0 ,这个语句反过来就是表示if i==-6 的意思,大家看程序就是看这个!!当然要s40的游戏才是这样的,如果改其他按键,只要替换相应的代码就行了,比如我要把557游戏的左软键改为735i的,在class中搜-21 或者 keypressed(调用按键的命令),,找到后,用winhex查eba0,然后替换成15ao就行了,关于if的修改kim作了非常详尽的文章在557的帖子里,大家可以参考一下!

此主题相关图片
540) this.width = 540'>

此主题相关图片
540) this.width = 540'>

[]此主题相关图片
540) this.width = 540'>

这里,我在说说case的方法,其实我也是刚接触case,开始的时候弄了半天不明白,一头雾水……在那里狂汗不已……还好群里的高手yy他们对我是非常的耐心的解释,才勉强搞定。这里大家要多想想,多思考一下,硬来是没有什么好下场的……我第一次改的case游戏弄了好几个小时还是错误……汗ing……
首先,大家顺被一些第三方的软件比如记事本,word之类的,呆会儿有用,先打开。
当然你的先判断一下是诺机鸭的还是其他的游戏,比如鸭机的就是左软为-6,右软为-7,moto和卡记等的就是-21,-22,这个比较重要,要自己在class中判断方法就是查找……汗(最烦琐却最实用)……
之后要注意你所找到的-6 -7或-21 -22 的位置,记清楚了,改完回来在看看这里的变化!!
[]来不及找个好例子,就这样说好了,因为之前的另一个游戏road to riches还有其他的问题,不便作为范例,我手里有没有多余的游戏……
好,继续,现在我们用winhex打开你所确认的那个class,查找ff ff ff f9或者ff ff ff fa,一般光标会停在你所找到的
第一个fff语句,注意他前面的7个0和数字x,即00 00 00 0x,这里x是多少,表示后面有多少个组,所谓组,是我取的名字,便于理解而已,大家想叫什么都行,而组共有16个代码,一般形式为xx xx xx xx xx xx xx xx,而每8个代码为一个小组,每个小组内的顺序不可以打乱!!注意!!
这里大家看看这就是要找的数据!

00 00 00 02 /ff ff ff fa 00 00 xx xx / xx xx xx xx xx xx xx xx/
分组就是这样分的,前面的0000最好保留一起用!

此主题相关图片
540) this.width = 540'>

好,在winhex里找到后(就是先搜索出来的)用鼠标把你刚才找的16位代码圈出来,现在就点击工具栏的编辑--全部复制--16位进制数值,点了后把winhex最小化,在事先准备好的记事本(word)里粘贴两次,(其中一个作为对照用,另外,此后还要用!小心不要搞混了,放在哪里不管)
好了,现在对照前面的各机型的按键16位数值进行修改了!是在记事本中哦^_^

具体的操作是,比如说这种代码,
00 00 00 02 /ff ff ff fa 00 00 xx xx / xx xx xx xx xx xx xx xx/,直接用00 00 00 xx代替,这里的xx代表你所要改的键值,一般就是你的左右软键的值(16位的哦),记住不要改反了,否则游戏中你的左右键就是反的,记住这里只替换ff ff ff fa或者ff ff ff f9因为只替换左右软键,将这两个替换为00 00 00 xx就行了,之后在为刚替换的数据排序!!!
重要!!比如:
改后:00 00 00 03 / 00 00 00 16/xx xx xx xx /00 00 00 15/yy yy yy yy/zz zz zz zz/zz zz zz zz
这个需要将00 00 00 16/xx xx xx xx与00 00 00 15/ yy yy yy yy
整体对换00 00 00 03 / 00 00 00 15/yy yy yy yy/00 00 00 16/xx xx xx xx /zz zz zz zz/zz zz zz zz即这个样子……后面的xx yy zz一类的东东大家可以看看,不要动啊,还有这里的‘/’符号是为了让大家看的清楚而画的,真正改的时候不能有的啊

好了,第一步完了,

接下来,打开ue即ultraedit,点击 搜索--替换,这是会有一对话框弹出(有点说的多了……不过,这里很容易出错……而且一错就完了),在查找栏把你之前的对照用的数据复制贴上去,记住在数据的最后面不能有空格,仔细检查,替换栏就贴上你改好的数据,注意鼠标此时最好在点一下ue中class文件的左上方,因为ue是从上往下搜的,之后直接点替换,成功后保存,在到winhex里去,之前是最小化,先在会有一对话框提升你更新数据,点‘是’。然后重复操作……这个class里面改完了,就改下一个,知道把你所有确定的有case -6 /-7或者case -21 /-22的class改完……
汗……
[]繁重的体力和脑力还有眼力活……

一般熟练后在10分钟类全部搞定,大家多多努力……

改完后打开改过的class文件看看,顺便还可以查查你该好的数据,一般情况下(好象没有特殊吧),原来的的诸如case-6 -7 都成了你改的 case xx了

呵呵,传回你的jar文件,试着运行一下,应该是ok吧!


最后,在给大家说说游戏的名字修改,这个好象三星的同志说过的,其实我的方法很简单的,注意,不是在游戏中,是在手机上的名字显示,一般都是为英文的吧,呵呵,其实你打开jar里面会有一个meta-inf文件夹,打开,然后把里面的唯一的文件manifest.mf拖到外面,随便你放在哪儿,只要你找的到,我一般就放在桌面,好了,在桌面上打开manifest.mf,有很多的东东,很多都是没有用的,而且里面的有些东西反而阻止了一部分游戏的运行!!我就经常遇到这种情况,具体必要的东西如下
Manifest-Version:
MicroEdition-Configuration:
MicroEdition-Profile:
MIDlet-1:
这些是必须要的,删了好象游戏就不能用了!!(应该是吧,反正我没有试过),还有三个一般也保留

MIDlet-Name:(这个就是手机上的名字显示,你写什么就显示什么)
MIDlet-Version:(版本)
MIDlet-Vendor:(附加信息,你可以写个本人修改之类的东西)
除了name,和vender,其他的最好不改,而剩余的东西一个字:删!

改好后点击:文件--另存为,什么都不变,只是把格式改为utf-8,保存,在传回jar的meta-inf,覆盖原来的manifest.mf
试试,你们的一些以前不能运行的游戏是不是可以了?
呵呵,那些由于机能原因而不能运行的游戏大家就不要在想了,一般这样改了还是不能用的游戏,还有三种途径解决:
一,彻底修改游戏的程序,使之对应自己的手机,一般人……狂汗……,
二,买部新的手机……
三,放弃这个游戏……

(完)
[]
补遗:关于jar的大小
[]复杂的调法这里不作过多说明,因为涉及到修改整个游戏的程序,简单点的就是删掉一些可以不用的东西,比如mid音乐!修改成功的例子有alest
2在按键改后,打上全屏的补丁,有135k左右,偶将mid全删后只有108k。希望这个对
手机内存紧张的朋友有点帮助。
十六进制数的表达方法如果不使用特殊的书写形式,16进制数也会和10进制相混。
随便一个数:9876,就看不出它是16进制或10进制。
Java规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数。而1则表示
一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也也不区分大小写。(注
意:0x中的0是数字0,而不是字母O)
以下是一些用法示例:
int a = 0x100F;
int b = 0x70 + a;10进制数转换成16进制的方法,和转换为2进制的方法类似,
惟一变化:除数由2变成16。
同样是120,转换成16进制则为:
被除数 计算过程 商 余数
120 120/16 7 8
7 7/16 0 7
120转换为16进制,结果为:78。
原码、反码、补码。
我们已经知道计算机中,所有数据最终都是使用二进制数表达。
我们也已经学会如何将一个10进制数如何转换为二进制数。
不过,我们仍然没有学习一个负数如何用二进制表达。
比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:
00000000 00000000 00000000 00000101
5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。
现在想知道,-5在计算机中如何表示?
在计算机中,负数以其正值的补码形式表达。
[] 什么叫补码呢?这得从原码,反码说起。
原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码。
反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
[] 比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 111111
11 11111111 11111010。
称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00
000101 的反码。
反码是相互的,所以也可称:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 000001
01 互为反码。
补码:反码加1称为补码。
[] 也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。
比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11
111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 111
11011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。
再举一例,我们来看整数-1在计算机中如何表示。
假设这也是一个int类型,那么:
1、先取1的原码:00000000 00000000 00000000 00000001
2、得反码: 11111111 11111111 11111111 11111110
3、得补码: 11111111 11111111 11111111 11111111
可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF。
[] 注:这段文字来自sofy,其实16位的东西在c语言上面就详细的很了
这方面的东西大家还嫌不够的话可以找书来仔细研究研究
(偶可省了不少工夫去写了,感谢sofy)

文章来自手机修改群:cj20038413

游戏的减肥法(sofy搜集)
一 减少图片容量

方法1:将多张png图片集成到一张图片上。
[]这是最基本也是最有效的减少png图片容量的办法了。比如你有10张png图片,每张10×15,现在你可以把它集成到一张100×15或者10×150或者X×X的图片上去。这张大png图片的容量比10张png图片的总容量小很多。这是因为省去了9张图片的文件头,文件结束数据块等等,而且合并了调色板(如果10张图片的调色板恰好相同,则省去了9张图片的调色板所占的容量!这是个不小的数字)

方法2:减少图片的颜色数
减少颜色也算是一个方法?我想说的是什么时候减,谁去减。如果游戏完成后发现容量超出,此时在用优化工具减少颜色,虽然能降低图片容量,但图片效果可能就不让你满意了。所以,在美工作图时就要确定使用的颜色数,手机游戏使用的是象素图,即一个象素一个象素点出来的图像,所以预先规定调色板颜色数量是可以办到的。不过,最终使用优化工具也是有用的,有时候相差一两种颜色,但效果差别并不大,容量却可以变小一些。呵呵,减少颜色确实可以算是一种方法。

方法3:尽可能使用旋转和翻转
这点不用解释了

方法4:使用换调色板技术和自定义图片格式
如果前两种方法还不能满足你对容量的要求,而你的游戏中恰好使用了很多仅颜色不同的怪物,那么可以试试换调色板技术。J2ME规范中规定手机至少可以支持png格式的图片,每张png都带有调色板数据,如果两张图片除了颜色不同而其他(包括颜色数)完全相同,则只要保存一张图片和其他图片的调色板,这相对于保存多张图片来说节省了不少容量。不过这个方法挺麻烦,你得了解png文件格式,然后做一个工具提取出调色板数据和调色板数据块在png文件中的偏移。内存中保存图像仍使用Image,如果要换调色板,则将png文件读入到一个字节数组中,根据调色板数据块在png中的偏移,用新的调色板代替原来的调色板数据,然后用这个字节数组创建出换色后的Image。也许你觉得保存一张png和n份调色板数据的方法有点浪费。至少多保存了1份调色板数据啊!如果直接将图像数据提取出来,在加上n份调色板数据,岂不是更节省容量。但是使用上面的方法,我们还可以用drawImage渲染。如果这样自定义了图片格式,那只有自己写个渲染函数了,这倒还可以,只不过put pixel的速度在某些机器上非常慢。或者自己构造png格式数据,再使用Image.如果你真得决定这么做,我还有个小建议,不要对图像数据进行压缩,zip压缩大多数时候比你写得压缩算法好(参见J2ME Game开发笔记-压缩还是不压缩)。论坛上有位朋友提过使用bmp格式代替png格式,jar中图片容量更小,也是一个道理。

二 减少图片所占内存

1 图片所占内存的计算
png图片所占用的内存并不对应于图片容量。图片占用的内存的计算为:width*height*bpp。bpp即为系统内置的颜色位数。以Nokia 6600为例,象素格式为565共16位。所以一张100*100的图片占用100*100*(16/8)=20000字节,约为19.5k的内存。象素格式是固定的无法改变,所以只有减少图片的宽和高才能降低其消耗的内存。

2 减少Image对象数量可节约大量内存
减少Image对象数量不等于减少图片数量。我的意思是说,将一张集成图保存在一个Image对象中,通过setClip的方法从这个Iamge对象中选取你需要的图像渲染。不过这个方法牺牲了一点速度,每帧都从集成图Image中减切图像的速度比无减切的渲染慢。但对于数目不多的渲染,比如精灵,使用这个方法没问题。这个方法还有一个问题就是不能释放集成图中不需要的图片,这就要看你集成的程度了。从图片容量和内存管理的角度综合考虑,我一般使用二次集成的方法。比如有n个精灵,先将各精灵所有的图片集成到一张集成图中,得到n张集成图,然后将这n张集成图再次集成到一张更大的集成图中。这样在jar中只存在一张集成图。使用时,先将大集成图分割载入到n个Image对象中即可。这样各个精灵的图片可以单独管理了。

3 使用旋转和翻转
只保存一个原始的Image,需要时再旋转或翻转
手机修改群

中级篇

按键修改之getGameAction(keyCode)
通过修改游戏键值,我们知道keyPressed(keyCode)是怎么回事。现在,我们来讲讲按键的另一种方式:getGameAction(keyCode)
同样以简单基础为切入点,这里不会讲太复杂的深入研究。

getGameAction(keyCode)
也就是说,这个值是由KEYCODE所得来的,值列表:
键名 KEYCODE GAMEACTION
导航键上: -1 1
导航键下: -6 6
导航键左: -2 2
导航键右: -5 5
中键: -20 8
数字键1: 49 9
[]数字键2: 50 1
数字键3: 51 10
数字键4: 52 2
数字键5: 53 8
数字键6: 54 5
[]数字键7: 55 11
数字键8: 56 6
数字键9: 57 12
[]
由上表可看出,如果一个游戏采用了getGameAction(keyCode)这样的方式,得出的值无论是导航键还是数字键的2、4、6、8,都可以来进行操作,节省了程序员的麻烦及节约了空间。而且getGameAction是标准API,即上表中的值在任何机型上都是相同的,所以也十分方便移植(多用在动作和射击游戏上)。

不过需要值得注意的是,getGameAction对NOKIA的左右软键是有效的(数值暂不明)。但是对于MOTO来说(包括索爱等),getGameAction对左右软键是无效的,具体数值为0。所以如果这个时候仍然修改到左右软键,就可能会出错。另外#*键也都是无效,数字0暂不明。

学会getGameAction,对修改按键来说能够更进一步。getGameAction的值虽然一般不用去修改,但是对阅读代码是有帮助的。而且有的游戏会利用getGameAction来进行判断,这个时候就需要利用到这方面的知识了。
手机修改群 小召


----------------------------------------------------------------------

资料链接:

[]关于ultraedit,详情请点击小海的汉化教程

kim1997修改游戏按键(if)小教程

S40游戏修改和破解浅谈

MOTO JAVA开发相关文档整理

MOTO VXXX/E398游戏的误区

游戏修改之Case特殊情况修改实例详解
[]
修改版游戏下载及详细修改过程

感谢手机修改群里的各位兄弟的支持,特别感谢yy的讲解!!(yy就是yychm——sofy注)
http:///tech/article887.html
</td></tr></table></td> </tr> <tr> <td background="/pic/split.gif" height=1></td> </tr> <tr> <td class="tdMargin1">
↑返回目录
前一篇: J2ME游戏开发笔记(整编版)
后一篇: J2ME潜艇大战游戏设计与实现(有源码)