4.13 角色
角色自身的状态比较复杂,而且几乎与游戏场景的所有对象都有交互,是本游戏的一大核心。
游戏场景并不关心角色的内部实现,它只关心角色的创建、更新、移动、放置炸弹这几个功能,下面将逐一介绍。
4.13.1 创建
目前角色有主角和NPC两种,角色类里定义了一个静态方法Character createCharacter(int characterType, int row, int col)来创建不同的角色。这里应用了一个工厂方法模式,使得Game场景不用对角色的创建担负责任,只须通知角色类我需要使用谁就可以,这种模式在本游戏里有多处被使用到。
实际上主角和NPC的创建只有精灵源图片不相同,其它的参数是一样的。
/**
* 创建精灵
* @param characterType 精灵类型
* @param row 精灵出生时所在行
* @param col 精灵出生时所在列
* @return 精灵对象
*/
public static Character createCharacter(int characterType, int row, int col)
{
Image imgCharacter = null;
try
{
switch(characterType)
{
case Character.HERO:
imgCharacter = Image.createImage(PopTang.IMAGE_SRC_HERO);
break;
case Character.ENEMY:
imgCharacter = Image.createImage(PopTang.IMAGE_SRC_ENEMY);
break;
default:
break;
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
return new Character(imgCharacter, row, col);
}
4.13.2 更新
在角色更新状态之前,它需要先对自己类型进行判断,当发现自己是NPC的时候,让自身先通过AI流程产生动作,再返回来继续更新。由于时间问题,本游戏AI只是产生一个简单的随机动作,就不详细介绍了。
if(type == Character.ENEMY)
{
aiAction();
}
如果角色状态为生存的话,接下来将对自身所处的环境进行检查。先检查所处单元格是否存在道具,是的话则附加该道具属性并将地面清空。
// 拾获道具
int tool = map.getBombsAndToolsLayer().getCell(col, row);
if (tool >= Map.TOOL_BOMB)
{
pickUpTool(tool);
map.getBombsAndToolsLayer().setCell(col, row, 0);
}
然后检测所处单元格是否致命,是的话立刻转入死亡状态,并返回等待下一次更新。
// 检测所在单元格是否致命
if(map.hasFeature(row, col, Map.DEADLY))
{
isAlive = false;
return;
}
剩下的事情就是对角色状态的绘制与更新了。
角色一开始被创建的时候是处于出生状态,这段时间内角色在原地做旋转动作。旋转动画为角色资源图片的1-5帧,每2个时间周期切换一次。当发现角色年龄大于出生期PopTang.BORN_TIME时,角色转入静止状态,朝南站立。
// 由出生状态转静止状态
if(status == Character.BORN && age > PopTang.BORN_TIME)
{
status = Character.FACE_SOUTH;
setFrame(Character.FACE_SOUTH * 5);
return;
}
角色进入静止状态后计时器stayTime开始累加,当超过阀值PopTang.REST_WAITTIME时角色进入休息状态。休息状态的角色有一个眨眼睛的动画,为了让角色眨眼睛的频率显得更加自然,眨眼动画帧的切换时机由stayTime计时器多次取余产生。
// 休息状态
if (status == Character.REST)
{
if((stayTime/5) % 15 == 0 || (stayTime/5) % 20 == 0)// 眨完眼睛后停一会
setFrame(Character.REST * 5 + (getFrame() + 1) % 5);
}
下面处理角色的死亡状态,与休息状态转换一样同样有一个deadTime计时器用来累加角色的已死亡时间。在deadTime小于阀值PopTang.DEAD_WAITTIME的期间角色将播放死亡动画,并每隔4个周期将自身的isVisible属性取反,造成闪烁效果。
// 是否超过死亡时间,人物失效
if (deadTime < PopTang.DEAD_WAITTIME)
{
deadTime++;
}
else
{
isEnabled = false;
setVisible(false);
return;
}
// 正在死亡
if (age % 2 == 0)
{
// 修改姿态
int preFrame = getFrame();
int nextFrame = 0;
if(preFrame < Character.DEAD * 5 || preFrame >= (Character.DEAD + 1) * 5)
{
nextFrame = Character.DEAD * 5;
}// 转换姿态
else
{
if(preFrame != ((Character.DEAD + 1) * 5) - 1)
nextFrame = Character.DEAD * 5 + preFrame % 5 + 1;
else
{
nextFrame = preFrame;
if (age % 4 == 0)
setVisible(false);
else
setVisible(true);
}
}// 继续前一姿态
setFrame(nextFrame);
}
return;
死亡时间超过阀值后角色将转入不可用状态,isEnabled属性被改为false,状态机将会定时检查该属性,以对角色进行重生或回收。
4.13.3 移动
角色的移动指令来源于键盘的输入或者AI指令,为了让游戏操作更加的流畅,角色移动还应该具有模糊对齐的特性。总之,此处要解决的最大问题是与地图的碰撞。
角色大小是16×24像素,但它的有效碰撞区域为16×16像素,与地图单元格大小一样,这须要在计算碰撞的时候进行适当的转换。下面用图例逐一介绍碰撞的几种情况,在图中我们以黑色方格表示障碍,红绿方格表示角色,其中红色方格表示角色的有效区域:
? 前方无障碍,直接通行
角色向某个方向移动前先要判断当移动后该方向上的两个顶点是否会落在障碍区域内,如果不会的话则向该方向移动speed个像素。
图 4.13 3 向前移动speed像素
? 前方近距离有障碍,贴近障碍物
当检测前方有障碍并且与障碍的距离小于speed时则贴近障碍单元格。
图 4.13 4 贴近障碍单元格
? 前方有障碍,但只有小部分碰撞,绕开障碍物
当检测到前方有障碍,但障碍只与角色的一小部分发生碰撞时,角色将绕开障碍单元格,这种模糊对齐的特性使得角色操作变得更加流畅。
图 4.13 5 绕开障碍,模糊对齐
角色移动与碰撞的代码篇幅较长,此处不再贴出,可参看附录源码。
进行完角色移动后需要更新角色动画帧,该帧由角色前一帧与当前方向换算得出。
// 修改姿态
int nextFrame = 0;
if(preFrame < direction * 5 || preFrame >= (direction + 1) * 5)
{
nextFrame = direction * 5 + 1;
}// 转向
else
{
nextFrame = direction * 5 + 1 + (preFrame - direction) % 4;
}// 继续前一姿态
setFrame(nextFrame);
4.13.4 设置炸弹
角色的最后一个方法是放置炸弹,其基本流程已在第4.11.1节介绍过,不再累述,这里要注意判断当前单元格及当前角色是否允许放置。
/**
* 放置炸弹
*/
public void setBomb()
{
// 检查单元格中是否已放置炸弹
if(!map.hasFeature(getRow(), getCol(), Map.BOMB))
{
// 当角色为生存状态且携弹量大于0时才可放置
if(isAlive && bombsNum > 0)
{
String key = "" + (getCol() * 10 + getRow());
Game.bombs.put(key, new Bomb(this));
bombsNum --;
}
}
}
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
so cool~
好详尽的注释
我上次做项目的时候,开始没写注释
结果后来交的时候要求30%的注释量
从头注释那一堆代码的时候
那个晕啊!
确实很酷!
这样一来我都觉得自己做的设计根本没有任何意义。
很不错,谢谢你的分享了!!
谢谢啊
老大,没有下载版吗?
我也是在做毕业设计,感觉j2me同j2ee实在差别太大了。快崩溃了。
还有,你的画面很漂亮呀。
下载版?
不是有源程序嘛,deployed目录下的PopTang.jar和PopTang.jad就可以直接传到手机里用了。
呵呵,记得我当时实习手机开发上美工课画像素画....
手那是发麻啊~~~
不错啊,非常感谢!!!
赞一个
你的作品和论文写得很好,觉得你做东西真的很认真,佩服
记得我一年多前做毕业设计,很多都是应付式的,现在觉得真是有点后悔。
最近想学学j2me,主要是搞个超级玛丽,谢谢你的作品了,有很好的参考价值。
很好呀!要象你多学点。
真是太伟大了
你怎么不搞个大屏的啊
?
因为我自己用的N6070就这么大,方便测试
非常感谢
正打算做手机游戏的毕业设计,没有头绪一定好好参考.
就不客气的收下了
感激不尽!(一百遍) 楼主太好了! 我都不知道用语言了! 总之一句感激不尽! 279636240是我的QQ希望高手们多多指点!
楼主很不错啊,向你学习钻研和贡献精神
lz强人!张某佩服。小弟现在国外工作,实不如意,打算明年年底回国工作,打算从事J2ME手机游戏的开发工作。因为我喜欢玩游戏,一直都想自己做个游戏,可惜,雷声大,雨点小。
我的毕业设计是JPG和BMP图片的相互转换,用TurboC2谢谢,最后实现了,可是,程序写得很烂,跟Lz比简直是相差十万八千里啊,一句话,还是佩服!
昨晚配置J2ME的环境,搞到凌晨3点,没有成功,装好EclipseME后,首选项中的J2me选项出来了,但是Platform Components这个选项始终没有。不知Lz能否指导小弟一下?小弟感激不尽!
我大半年没写过程序了,刚打开Eclipse看了下,也没找到你说的Platform Components.
不知道你要做何用?
哦,这个问题已经解决了,Eclipe版本不同,3.2好像没有这个选项,不过系统已经配置好了,helloworld已经运行成功,不过还是谢谢你,呵呵~~
我今年大四了,我跟导师说明年毕业设计换你的这个题目,因为我可能明年会进一家手机游戏公司,打算也做个泡泡堂,不知道你介不介意让我使用你的部分代码和论文,可能还需要你稍微指点一下,谢谢了
QQ:376773982
可以,有疑问请联系我QQ,只是代码方面我已经忘得差不多了。。。
哥们 你真伟大啊 收藏了
老大,你什么时候上QQ啊,给你留言也没用,有没有开题报告之类的资料可以给我参考一下啊?论文有没有DOC版的,我还有几个代码的问题想请教你一下,谢谢了
QQ:376773982
不好意思,平时工作非常忙,加我QQ的时请注明身份,否则一般是不通过的。
9931817到底是不是你QQ啊,我用google搜到的
根本就没有身份验证啊。
不好意思, 我的QQ是7405440...我也忘了我有没有在Blog上公布过QQ了.
我想玩这款游戏,能告诉我在哪下载吗,我在你的blos里找不到,有源码我也不会用
马上要毕业了,课题就是基于J2EE的手机游戏的编程,因为我是学通信的对软件的开发不是很了解,准备毕业论文就这么混过去,看到LZ和各位师哥师姐的留言我决定认真的做玩,要让以后没有遗憾。
我也是万老师的学生,他是一个很好的老师,不过我不是一个跟你一样的好学生,呵呵,是他推荐我来的,他说你做的毕业设计是代表了大学生本科的最高水平,佩服。。。师哥~~~
做的不错哦..如果是大屏幕的,在模拟器上玩的会更爽的,一个字,强!还有个问题,看了下高手的论文,地图是三维的,那么,这也算一款三维游戏了吧..
你好!冒昧打扰了。我现在在做j2me的手机游戏。我是个新手。看了你的程序。我有点搞不懂。关于那个“保存关卡配置”具体是怎么做的啊。是怎么生成的十六进制配置文件的?如果你有空的话,麻烦回答下。谢谢哈!
用你目录做参考写另一个游戏的论文,谢谢了
你好,我现在是个大四的毕业生,由于Java根基浅薄,看了你的毕业设计关于那个关卡类的设计是怎么完成的?还望指教阿!QQ:61508486
bbbbbb
你好,我也是软件学院的学生,万老师上课的时候提过你,在这看到你的东西,很荣幸,呵呵!你的程序做的真的很好,向你学习,也请教下,你的泡泡堂在Jbuilder X里面应该如何运行,我其他的配置应该都没问题,就是运行不了,
java.io.IOException: CreateProcess: C:\Nokia\Devices\S40_SDK_3rd_Edition_Feature_Pack_2\bin\javaw -classpath D:\ppt\classes;C:\Nokia\Devices\S40_SDK_3rd_Edition_Feature_Pack_2\lib\classes.zip ppt.PopTang error=2
还望指教,谢谢!
我读书那会老师用JBuilder教学, 但我还是坚持用自己的Eclipse, 不熟悉JBuilder的配置, 帮不上你了.
我也向你推荐Eclipse或NetBean.开发工具的选择上大可不必跟着老师走, 想当年我们学C语言时还用Turbo C, 打击了多少人...还不如用Ultra Edit + cl呢!
确实不错,比我那时做的强多了!!记得我做手游毕设的时候好像还从没人做过手游毕设~~呵呵
万老师确实是好老师,如果没有他的指导的话就无法完成游戏了!
伟大啊
很强大,谢谢分享,希望能向你请教!谢谢
very good
谢谢分享,希望以后能向你请教!
大虾,请较一下,请问你知道J2ME游戏的脚本是怎么写的吗?地图工具用的是什么呢?有没有相关的教程啊?网上关于脚本的东西很少,地图工具也没有教程,自己摸索蛮耗时间的说~~
借鉴了下你的这个项目,论文还有部分代码(主要是整体的框架),不知道可行否?谢谢先~
@jerry_zihuai
无所谓~
我喜欢玩这个游戏,嘿嘿 !
Find Canon IR2830 Sharp AR-208s
Buy Sharp MX-M200D
Canon Image Runner
Image Runner 2018
Buy Canon IR-2020
Review Canon IR-1025IF
High-Performance Laser All-in-One for your Business or Small Workgroup
Buy Panasonic
Panafax UF-7200
Sharp FO-DC535 REFURB
Find Brother8480DN
Canon Canon IR-1025IF
Sharp FO-2080