参考]基于j2mejavaplatformmicroedition手机rpg游戏研究内容摘要:

for(int h=0。 h4。 h++){ ms2[h].setPosition(ms2[h].dxsetX,ms2[h].dysetY)。 if(ms2[h].dx(getWidth()+setX) amp。 amp。 ms2[h].dxsetX amp。 amp。 ms2[h].dy(getHeight()+setY)amp。 amp。 ms2[h].dysetY){//只对进入屏幕范围类的精灵才进行描绘 ms2[h].paint(g)。 } }//对精灵类进行描绘 下面介绍下关于在本类中实现的关于 怪物类和英雄类的通信 ,如设计中所述,关于 攻击判断 都是放在怪物类中写的,所以,英雄受到攻击后削减 HP以及打败怪物后所获得的奖励等等都只能依靠类之间的通信来实现,这里我们采用了参数返回和传递的方式,即怪物类返回一些参数,而将这些返回的参数直接传递给英雄类,让英雄类实现各类数据的更新并且在更新后立即将新的数据存入进度。 具体的 实现代码如下: //将怪物类的死亡后的等级以及各方面信息传递到英雄类 private void doMonster(MonsterSprite mSprite,HeroSprite heroSprite,RecordStore rs,int rid){ ((+heroWidth,+heroHeight,getHeight(),getWidth(),heroSprite,),rs,rid)。 } 看起来比较复杂,让我们将他们分解一下,在 MonsterSprite 类中有一个方法 .主要用于描绘和相应的游戏逻辑处理, public int doMovedraw(int heroX,int heroY,int screenHeight,int screenWidth,int heroDir,boolean iisBattle,HeroSprite heroSprite,int heroHp,int herolv,int itemlv),关于该方法的详细解释会在怪物类的代码实现中有解释,它拥有一个 int的返回类型,在该方法中,返回的是英雄的 HP 值,而我们也可以看到传入的参数中也有英雄的 HP值,即这个方法中实现了怪物的描绘和英雄类 HP的变化,同时在怪物类中具有一个属性 deadlv,如果怪物处于生存状态,该值一直为 0,在怪物类的 doMovedraw( „ )方法中如果怪物死亡就立即将该值赋为怪物等级,而相应的英雄类中 处理怪物传来的信息的方法就捕获到该值,然后就对英雄类的属性进行更新,将更新值存入进度 . 接下来再介绍一下如何将进度存入 RMS 中, RMS 即 Record Management System,是由 MIDP提供的数据存储功能,使用这个功能,就可以存储游戏状态,关于 RMS的详细内容请有兴趣的朋友查阅相关资料,这里我们这种讲述如何实现进度的存储,实际上由于 RMS的存储功能远远不如大型的数据库功能完善,所以很多地方需要自行设计许多东西来达到方便的记录管理, RMS的存储是逐条地操作,而一条记录并不存在如大型数据库中的字段类 的概念,所以,为了实现类似的功能,只能在程序中将的所有数据一次操作。 J2ME中提供了对二进制数据进行操作的 DataOutputStream类和 ByteArrayOutputSteam类,通过这两个类可以很方便地把各种类型的数据转换为二进制数据并存储在一行记录中,例如游戏中英雄类的一次记录操作包括记录他的等级,当前的装备,拥有的金钱,物品盒中的物品,经验值等,它们的类型有的是 String,有的是 int,就可以按如下的程序实现二进制数据到真实数据的转化: //对记录中的数据进行转化 public static void chgTogame(byte[] data,HeroSprite heroSprite) throws IOException{ ByteArrayInputStream bais=new ByteArrayInputStream(data)。 DataInputStream dis=new DataInputStream(bais)。 =(())。 =(())。 =(())。 =()。 =(())。 =()*8+30。 =()*10+20。 ()。 =()。 } 为了实现记录读取的效果,在此之前需要从进度中将记录读取出来 而在记录实际使用时: try{//尝试获得记录 rs=(dataname,false)。 //如果不成功则不创建 try{//成功后则尝试获取记录 heroData=(1)。 chgTogame(heroData,heroSprite)。 //将记录转化为实际数据 isData1=true。 }catch(Exception e){(没有获得记录 +e)。 } }catch(RecordStoreNotFoundException e){//如果没有成功获得 try{//关闭记录 (没找到记录 )。 ()。 rs=null。 isData1=false。 }catch(Exception ex){ } }catch(Exception e){} 接下来向大家介绍一下 地图切换 的具体实现,地图切换在这里我专门使用了一个方法来实现,该方法以地图编号为参数,进行实例化以及相关垃圾处理,具体代码如下: public void gotoMap(int mapDir){ if(mapDir==0){ … //图 1的对象撤消 ,具体是将其赋为 NULL try{//描绘新地图 … //图 0要用到的图片加载 }catch(Exception e){} … //实例化地图 0要使用的对象 }else{ … //图 0的对象撤消 ,具体是将其赋为 NULL try{//描绘新地图 … //图 1要用到的图片加载 }catch(Exception e){} … //实例化地图 1要使用的对象 } } 而具体的地图描绘操作则是如下代码 : mapTiled=null。 =null。 //清空地图 1资料 …… mapTiled=new MapTiled(30,30,mapImage,16,16,getWidth(),getHeight())。 // 加载新地图资料 (mapDir,setX,setY)。 ()。 (mapTiled)。 这里的 setX,setY是将相对于地图左上脚的屏幕左上 脚的坐标 : (地图一的情况下 ) setX=()/2+20。 //地图画的位置的左上脚坐标 setY=()/2+20。 if(()/2+20=0){ setX=0。 } if(()/2+20=625getWidth()){ setX=625getWidth()。 } if(()/2+20=0){ setY=0。 } if(()/2+20=625getHeight()){ setY=625getHeight()。 } 而实际上这里的 setX,setY在坐标转化的过程中作用巨大 ,一方面实现了主角走到边角人物移动而地图不移动的效果 ,另一方面也实现了绝对坐标和相对 坐标的转化 ,具体的如精灵类 ,怪物类的坐标如下 : ms2[h].setPosition(ms2[h].dxsetX,ms2[h].dysetY)。 转化方式如下图 : 由此可见 ,相对坐标是 (dxsetX,dysetY)决定的 ,而 dx,dy则是 ASprite类定义的精灵类的公有坐标属性 .由此即可实现相对屏幕左上的坐标和相对地图左上坐标的转化。 HeroSprite 类以及键盘事件,进度更新的实现 HeroSprite 类主要实现英雄的相应处理,包括对英雄的相应记录的更新,以及对事件的处理,另外包括对不能行走地图的检测。 首相,对 记录的更新 ,具体实现如下: public byte[] chgTorms(boolean isFirst) throws IOException{ ByteArrayOutputStream baos=new ByteArrayOutputStream()。 DataOutputStream dos=new DataOutputStream(baos)。 if(itemcode!=null){ MyItem=(itemcode)。 } ((lv))。 //将具体数据写入流 ((itemlv))。 ((gold))。 ((MyItem))。 ((exp))。 if(isFirst==false){//如果不是第一次读入数据则计算攻防 at=itemat[itemlv]+(lv1)*8+30。 df=itemdf[itemlv]+(lv1)*10+20。 } ()。 ()。 numEmpty=0。 if(isFirst==false){//如果不是第一次读入数据则计算空格数 for(int i=0。 i。 i++){ if(itemcode[i]==39。 039。 ){ numEmpty++。 地图 屏幕 setX setY 精灵 dx dy } } } return ()。 } 对怪物的相应处理函数从 SFCanvas中获得数据,这一点在之前的 SFCanvas中已有叙述,具体实现代码如下: public void doMonster(int myhp,int deadlv,RecordStore rs,int recordid){ =myhp。 if(lv=6){ prevexp=lv*lv*60(lv1)*(lv1)*60+150。 //经验值公式 nextexp=prevexp+(lv1)*(lv1)*60(lv2)*(lv2)*60+150。 }else{ prevexp=lv*(lv5)*(lv5)40*(lv4)*(lv4)+150。 nextexp=prevexp+50*(lv+1)*(lv4)*(lv4)40*(lv3)*(lv3)+150。 } if(deadlv!=0){ exp=exp+deadlv*15+()%5。 //怪物死亡时候等级和经验值的换算公式, nextexp下一等级需要的经验, deadlv被杀死怪物的等级 if(exp=nextexp){ if(lv12){//目前设定的最高等级为 11级 lv++。 } at=itemat[itemlv]+(lv1)*8+30。 df=itemdf[itemlv]+(lv1)*10+20。 maxhp=160+(lv1)*40。 hp=maxhp。 } try{ (recordid,chgTorms(false),0,chgTorms(false).length)。 }catch(Exception e){(e)。 } isBattle=false。 } } 关于地图可行与否的判断中会遇到如下问题: 如上图, 英雄贴着墙站着,而且下一步他就会进到墙里面。 我们不会让它发生的。 当然在这里可以设置他即将进入的方块的可行性为 false,在向左行走时进行判断主角下一步即将 进入的方块可行性,如为 FALSE,则不进行坐标和帧变化,实际体现出来的效果就是不能行走,但在实际情况中往往没有这么理想,他可能会产生如下情况: 由图可见,如果仅仅判断精灵类的左上脚,在这样的情况下,显然他的下一步是可行的,但实际上该精灵因为左下脚被挡住,已然无法前进,因此在这样精灵向左走的情况下,实际是要检 查左上和左下两个地方是否都可以行走的,如果其中有一个不满足则不能前进,与此相似,如果在向右走的过程中,则需要同时检查精灵的右上和右下脚,其他的则以此类推,具体实现代码及解释如下(仅解释 UP键): case LISTENER_UP: if(dir!=DIR_UP){//如果按下 UP键时之前的状态不是朝 UP的话,则改变状态 dir=DIR_UP。 (up_seq)。 } if(isWalkable[ldX][ldY1] amp。 amp。 isWalkable[rdX][rdY1]){ //对下一步的判断,如前所述 if(isBattle==true){//按下 UP键时候如果是打斗状态则转化为 UP奔跑帧 (。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。