状态菜单功能
状态场景中现在只有一个窗口,即状态窗口里面现在已经实现了的功能有显示人物对应状态背景,人物具体状态,人物信息,初步显示装备简略信息,初步展示人物选中的效果(还没有具体的做人物选中时行走的效果)
具体参照:
人物装备
原版人物装备显示图:
可以看到上面是装备栏,下面是装备的帮助信息(装备的简单展示信息),若是仙剑2,点击F1按键后可以显示具体的装备信息。
装备栏遮挡效果
原版游戏中状态场景中人物装备可以查看该人物是否装备了该件装备及装备名称和图片;现在图中是原游戏选中和未选中对应装备栏的效果。
初步实现了遮挡效果。
var bitmap=ImageManager.loadSystem('EquipmentCover');
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
放在某个方法中的代码,实现了对应图片中头部,手持等装备栏遮挡效果。
踩的坑
初步写好测试好代码后,自然是准备下一步的效果实现了!
需要实现遮挡的选中部分是透明,未选中是半透明效果,毕竟和原版游戏效果一致对应的代入感才强嘛!虽然布局显示等不如现在成熟的游戏那样高效美观!!!
bitmap.opacity=0;
但可惜没有效果(因为bitmap中根本没有这个属性),之后考虑Sprite类,将在场景中的写法放入这里:
var sprite=new Sprite(bitmap);
this.contents.blt(sprite, 0, 0, 48, 48, 422, 2);
得到了这个错误信息,很明显传递的类都不一样!
之后尝试:
this.contents.blt(sprite.bitmap, 0, 0, 48, 48, 422, 2);
没有任何的效果!
重新查看MV手册试试!!!
RPG Maker MV 帮助文档中文汉化版
重新找了下Bitmap的类看到了一丝曙光:
paintOpacity Number
位图对象的不透明度(alpha 值)(0~255)。
不过尝试后还是那样,但突然查看代码时发现了this.contents.outlineWidth = 0;这个语句,之前写过的,文字描边的厚度这个代码,才恍然大悟!虽然在浏览器上调试时内部信息已经修改了,但这只是表面上的修改,并没有修改到实质。
解决方法
var bitmap=ImageManager.loadSystem('EquipmentCover');
this.contents.paintOpacity=0;
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
这是只需要展示部分就行!效果很炸裂!
确实效果很好,刷新一遍后,除了数据还在,其他都没了,懵了好久,才想起该干啥。
var bitmap=ImageManager.loadSystem('EquipmentCover');
this.contents.paintOpacity=155;
...
this.contents.paintOpacity=255;
终于是出来了。
装备栏选中效果
装备栏的选中效果,通过的不断地调试源码和修改代码,现在是想出了三个方法来实现:
- 原状态窗口中直接实现渲染,显示装备
- 状态窗口中添加子窗口实现(由于同级别的窗口在同一个位置上会由于先后顺序而遮挡,因此得使用子窗口)
- 直接在状态场景上绘制
这里面我选择了直接绘制渲染的方式。
踩的坑
由于对源码的不熟悉和帮助手册上对应操作没有类的说明,因此做起来磕磕绊绊的,其中遇到的大坑有不显示光标,获取不到对应数据信息等等。。。
解决方法
Window_EquipSlot.prototype.select = function(index) {
this._index = index;
this.ensureCursorVisible();
this.updateCursor();
this.callUpdateHelp();
};
这段代码时装备栏选择时操作,稍作修改后,变成了状态窗口选择的更新操作显示。
Window_Selectable.prototype.update = function() {
Window_Base.prototype.update.call(this);
this.updateArrows();
this.processCursorMove();
this.processHandling();
this.processWheel();
this.processTouch();
this._stayCount++;
};
这里直接修改成使用它的子类窗口(状态窗口)来操作更新,其中若是不要鼠标操作可以去掉里面 this.processTouch();代码即可。
这四张图就是最终的效果,可以看到右边遮挡部分和右下角的显示都出来了。PS:大家看到的没有背景是为了凸显效果暂时去掉的,可以看到其中还有选中光标的显示,加上背景后就看不到了!!!
展示选中效果和遮挡代码:
Window_Status.prototype.update=function(){
this.processCursorMove();//光标移动
this.processHandling();//命令的处理
this.refresh();//刷新(这个窗口,得先做,不然会有遮挡问题)
this.drawShowCovers();//绘制遮挡
}
Window_Status.prototype.drawShowCovers=function(){
var bitmap=ImageManager.loadSystem('EquipmentCover');
this.contents.paintOpacity=155;//透明度
switch(this._index){//还没有想到更简洁的方式,被选中的不绘制,没选中的绘制,以索引做区分
case 0:
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
break;
case 1:
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
break;
case 2:
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
break;
case 3:
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
break;
case 4:
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 580, 188);
break;
case 5:
this.contents.blt(bitmap, 0, 0, 48, 48, 422, 2);
this.contents.blt(bitmap, 0, 0, 48, 48, 471, 22);
this.contents.blt(bitmap, 0, 0, 48, 48, 513, 55);
this.contents.blt(bitmap, 0, 0, 48, 48, 547, 93);
this.contents.blt(bitmap, 0, 0, 48, 48, 569, 140);
break;
case -1:
break;
}
this.contents.paintOpacity=255;//最后需要不透明,这一步也可以放到刷新中执行
}
绘制右下角帮助信息代码:
Window_Status.prototype.drawEquipments = function() {
var equips = this._actor.equips();//获取角色的装备信息
var equipType=this.equipsArray[this._index];//获取装备类型对应数组的值
var equip=equips[equipType];//确定装备的类型
if(equip!=null){//判断是否有这件装备
this.drawItemName(equip,equipType);
}
};
Window_Status.prototype.drawItemName = function(equip,equipType) {
var sw = 236;var sh = 148;var dx = 448;
var dy = 340;var sx = 0;var sy = 0;var bitmap =null;
if(equipType==0){
bitmap= this.bitmapEquipsWeapons;
sx = equip.iconIndex % 7 * sw;
sy = Math.floor(equip.iconIndex / 7) * sh;
}else{
bitmap= this.bitmapEquipsArmors;
sx = equip.iconIndex % 14 * sw;
sy = Math.floor(equip.iconIndex / 14) * sh;
}
this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);
bitmap =this.bitmapEquipsName;
sw = 168;sh = 40;dx = 472;
dy = 320;sx = 0;sy = 0;
this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);
this.drawText(equip.name, dx, dy+3, 168, 'center');
};
下面这段代码是判断装备类型,由于不同的装备(武器和防具两个种类),对应的精灵图不同,图的每列数据个数也不同,因此前半部分需要通过判断来决定是绘制哪个,绘制多少信息。当然大家要是有好的想法也请提出。
人物选中的行走图
人物选中行走图参考装备栏的操作,确认了选中的是哪个后,进行对应操作。
踩的坑
遇到的坑有计算问题,两个人物重合在一起,虽然确保了只能选中一个操作,但看着确实辣眼以及人物行走过快的问题。
解决方法
两个人重合问题:
最初想到的解决方法是计算两个人物的宽和位置相加,但发现问题太大,都跑到第二个人物的位置上去了,原因是循环判断时第二个人物是操作到的;之后修改后,第二个人物位置加了两次调用了第一个和自己的宽度相加。
解决方法是:
switch (characters){
case 0:
dx+=0;
break;
case 1:
switch(character._characterStatus){
case "赵灵儿初始状态行走":
dx+=this._actor._name==character._name?55:60;
dw+=5;
dh+=this._actor._name==character._name?5:0;
sx-=(sx==0?0:1);
break;
case "赵灵儿变身状态行走":
dx+=this._actor._name==character._name?45:50;
dy+=5;
break;
case "赵灵儿圣灵状态行走":
dx+=this._actor._name==character._name?58:60;
dy-=6;
break;
}
break;
default:
break;
}
确认好基础的数据后,给两个人物将数据定制化处理,这样可以较好的处理好两个 =人物的,虽然应该有更好简洁的方法(想不出来~~~)!!!
处理动画过快问题;
这里使用了 Mandarava(鳗驼螺) 的
【RPG Maker MV插件编程】【实例教程4】玩转标题画面
相关代码,有兴趣的可以看看。
this._elapsedSinceLastUpdate = this._elapsedSinceLastUpdate || 0;
if (this._elapsedSinceLastUpdate >= this._animDelay) {
this.characterIndex++;
this._elapsedSinceLastUpdate = 0;
}
this._elapsedSinceLastUpdate += 1 / Graphics._fpsMeter.fps;
作用是每隔一段时间进行一次绘制人物动作;原版代码颇多,我截取了所需要的部分,替换了原来的操作,最后实现了该效果!!!
下一步计划
下一步计划进一步美化主菜单界面及调整功能,比如无需选中人物即可跳转到状态页面及处理物品使用界面的美化及基础功能的处理!!!