RPG Maker MV 主菜单及物品栏效果展示二 (仙剑物品场景效果)

文章讲述了在RMMV版本的仙剑游戏中,人物选择菜单UI存在bug,导致原本正常显示的菜单失效。开发者需对主菜单人物状态栏和UI进行调整,包括间距修改、图片加载优化以及光标显示等问题,以修复这一显示问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

仙剑物品场景人物选择菜单效果

游戏原版
游戏中原版的效果可以看到人物在没有选中时没有那一圈颜色的,选中后会上浮到最上层,并出现选择框。

RMMV中展示

由于物品场景的人物选择菜单继承于主菜单中的人物菜单因此正常来说是轻而易举就处理好的,但是很遗憾,出现了一个BUG导致这里面的不显示了!
主菜单人物状态窗口
主菜单中的显示看着还是挺好的,至少没有看到什么错误!
物品人物状态栏
现在露馅了,由于开发过程中经常的调整调动,很明显原来基础的已经不适用了,因此需要重新进行定位开发。这也是一个纠错的环节。

RMMV——仙剑人物菜单UI制作

现在需要进行UI的调整了!!!

主菜单人物状态栏调整

代码部分调整了部分的间隔。

Window_MenuStatus.prototype.initialize = function(x, y) {
	Window_Selectable.prototype.initialize.call(this, x, y, 610, 116);
	this.characterStateFrame=ImageManager.loadMenu('CharacterStateFrame');
    this.refresh();
};

多了个characterStateFrame属性,用于加载显示光标的图片。

Window_MenuStatus.prototype.standardPadding = function() {
    return 0;
};
Window_Selectable.prototype.spacing = function() {
    return 6;
};

内边距修改为0,两个队伍中每个人物间距修改为6。

Window_MenuStatus.prototype.drawItemImage = function(index) {
	var actors = $gameParty.members(); var actor=actors[index];
	var rect = this.itemRect(index);
	this.changePaintOpacity(actor.isBattleMember());
	this.drawActorFace(actor, rect.x + 2, rect.y + 1, rect.width, rect.height,index);
	this.changePaintOpacity(true);
};
Window_MenuStatus.prototype.drawActorFace = function(actor, x, y, width, height,index) {
    this.drawFace(actor.faceName(), actor.faceIndex(), x, y, width, height,index);
};
Window_MenuStatus.prototype.drawFace = function(faceName, faceIndex, x, y, width, height,index) {
	var actors=$gameParty.members(); var wx=0;
	switch(actors.length){
		case 1: wx=154*3; break;
		case 2: wx=154*2; break;
		default: break;
	}
    width = width || Window_MenuStatus._faceWidth;
    height = height || Window_MenuStatus._faceHeight;
    var bitmap = ImageManager.loadFace(faceName);
    var pw = Window_MenuStatus._faceWidth;
    var ph = Window_MenuStatus._faceHeight;
    var sw = Math.min(width, pw);
    var sh = Math.min(height, ph);
	//可能需要修改
    var sx = faceIndex % 6 * pw + (pw - sw) / 2;
    var sy = Math.floor(faceIndex / 6) * ph + (ph - sh) / 2;
   if(!bitmap.isReady()){
	   setTimeout(()=>{ this.contents.blt(bitmap, sx, sy, sw, sh, x+wx, y); this.drawItemStatus(index); },0.25);
   }else{
	    this.contents.blt(bitmap, sx, sy, sw, sh, x+wx, y);
   }
};

这里面绘制人物头像部分修改了对应的间隔,内容容器的大小重新布局计算了图片间的间隔,去掉了一些不必要的参数,新增了index参数,由于在物品场景中Window_MenuActor继承了Window_MenuStatus类,因此可以都显示出来,但是代价也是有的,由于不断添加了新的图片,因此加载效率低下,需要判断头像绘制,中图片的加载是否完成,并重新绘制,但这样一来,由于是后绘制的头像,因此人物的状态和文字就会被覆盖!,因此需要index重新获取到人物在队列中的索引,并手动调用绘制状态的函数,在0.25秒后执行这些。

Window_MenuStatus.prototype.drawItemStatus = function(index) {
	var actor = $gameParty.members()[index];var rect = this.itemRect(index);
	this.drawActorSimpleStatus(actor, rect.x,  rect.y, rect.width,rect.height);
};
Window_MenuStatus.prototype.drawActorSimpleStatus = function(actor, x, y, width,height) {
    this.drawActorIcons(actor, x+73, y+36,width,height);
    this.drawActorHp(actor, x, y, width);
	this.drawActorMp(actor, x, y, width);
};

这部分是绘制人物状态代码,简化了获取绘制矩形区域的操作,对于部分方法是采用直接写死值的方式,这样会更好。

Window_MenuStatus.prototype.drawIcon = function(iconIndex, x, y) {
	var actors=$gameParty.members();var wx=0;
	switch(actors.length){
		case 1: wx=154*3; break;
		case 2: wx=154*2; break;
		default: break;
	} x=x+wx;
    var bitmap = ImageManager.loadSystem('CharacterStatus');
    var pw = 24; var sx = iconIndex % 5 * pw;  var sy = 0;
	if(!bitmap.isReady()){
		   setTimeout(()=>{this.contents.blt(bitmap, sx, sy, pw, 26, x, y);},0.25);
	}else{
		    this.contents.blt(bitmap, sx, sy, pw, 26, x, y);
	}
};

绘制人物状态,drawActorIcons方法没有变动因此没有将代码贴出来,在物品场景中家长问题,因此这里也是使用了延迟加载,不然第一个人物的显示不出来。

Window_MenuStatus.prototype.drawActorHp = function(actor, x, y, width) {
    width = width || 144;
	var color1 = this.textColor(10);
    var color2 = this.textColor(15);
    this.drawCurrentAndMax(actor.hp, actor.mhp, x-2, y+56, width,color1, color2);
};
Window_MenuStatus.prototype.drawActorMp = function(actor, x, y, width) {
    width = width || 144;
    var color1 = this.textColor(9);
    var color2 = this.textColor(15);
    this.drawCurrentAndMax(actor.mp, actor.mmp, x-10, y+74, width,color1, color2);
};
Window_MenuStatus.prototype.drawCurrentAndMax = function(current, max, x, y,
                                                   width, color1, color2) {
   var actors=$gameParty.members(); var wx=0;
   switch(actors.length){
	case 1: wx=154*3; break;
	case 2: wx=154*2; break;
	default: break; }  x=x+wx;
	this.contents.fontSize=14;//设置字体大小
    var labelWidth = this.textWidth('HP');//28
    var valueWidth = this.textWidth('0000');//56
    var slashWidth = this.textWidth('/');//14
    var x1 = x + width - valueWidth;
    var x2 = x1 - slashWidth;
    var x3 = x2 - valueWidth;
    if (x3 >= x + labelWidth) {
        this.changeTextColor(color1);
		this.contents.outlineColor=color1;
		this.contents.outlineWidth = 0;
        this.drawText(current, x3, y, valueWidth, 'right');
        this.changeTextColor(color2);
		this.contents.outlineColor=color2;
		this.contents.outlineWidth = 0;
        this.drawText('/', x2, y, slashWidth, 'center');
		this.changeTextColor(color1);
		this.contents.outlineColor=color1;
		this.contents.outlineWidth = 0;
        this.drawText(max, x1, y, valueWidth, 'left');
    } else {
		this.contents.outlineColor=color1;
		this.contents.outlineWidth = 0;
        this.changeTextColor(color1);
        this.drawText(current, x1, y, valueWidth, 'left');
    }
};

这是绘制人物Hp和Mp的方法,drawCurrentAndMax 方法中字体大小的属性,调整到了前面,避免有时,显示错误的问题;Hp和Mp的绘制方法均进行了操作的简化。

Window_MenuStatus.prototype._refreshCursor = function() {
	var pad = this._padding;
	var x = this._cursorRect.x;
	var y = this._cursorRect.y;
	var w = this._cursorRect.width;
	var h = this._cursorRect.height;
    var bitmap = new Bitmap(w, h);
    this._windowCursorSprite.bitmap = bitmap;
    this._windowCursorSprite.setFrame(0, 0, w, h);
	var actors=$gameParty.members();
	var wx=0;
	switch(actors.length){
		case 1:
			wx=154*3;
			break;
		case 2:
			wx=154*2;
			break;
		default:
			break;
	}
    this._windowCursorSprite.move(wx+x, y);
    if (w > 0 && h > 0&&this.characterStateFrame) {
		var csf=this.characterStateFrame;
		this._windowCursorSprite.bitmap.blt(csf,0,0,164,96,0-3,0+20,164,96);
    }
};
Window_MenuStatus.prototype._updateCursor = function() {
	this._windowCursorSprite.bitmap.clear();
	var blinkCount = this._animationCount % 50;
	var characterStateSpriteY=0;
    if (this.active) {
		switch(Math.floor(blinkCount/10)){
			case 0:
				characterStateSpriteY=0;
			break;
			case 1:
				characterStateSpriteY=96;
			break;
			case 2:
				characterStateSpriteY=192;
			break;
			case 3:
				characterStateSpriteY=288;
			break;
			case 4:
				characterStateSpriteY=384;
			break;
			default:
			break;
		}
    }
	this._windowCursorSprite.bitmap.blt(this.characterStateFrame,0,characterStateSpriteY,164,96,0-3,0+20,164,96);
	this._windowCursorSprite.visible = this.isOpen();
};

进行光标的绘制及更新,由于重新规划了人物状态的菜单的的宽高,因此光标的适配非常合适,当然期间遇到的计算问题确实让人头疼。
在这里插入图片描述

物品场景人物状态栏

Window_MenuActor.prototype.initialize = function(x,y) {
    Window_MenuStatus.prototype.initialize.call(this, x, y);
	//this.hide();
};
Pal_Scene_Item.prototype.showSubWindow = function(window) {
    window.x = 15;
    //window.show();
    window.activate();
};

这里可以看到物品场景中的人物栏隐藏和显示注释掉了,这是因为会影响到人物栏的显示效果。

Pal_Scene_Item.prototype.onItemOk = function() {
	var s=this.children[3];
	this.children[3]=this.children[4];
	this.children[4]=s;
    $gameParty.setLastItem(this.item());
    this.determineItem();
};
Pal_Scene_Item.prototype.hideSubWindow = function(window) {
	this._actorWindow.deselect();
	var s=this.children[3];
	this.children[3]=this.children[4];
	this.children[4]=s;
    window.deactivate();
    this.activateItemWindow();
};

this._actorWindow.deselect();方法的调用,可以使取消人物状态栏后人物状态栏的光标不再显示,s的变量是交换物品场景中物品背景图片和人物栏的前后位置,这样遮挡关系就确定了。不同精灵之间是可以修改前后的遮挡关系的,若是某个精灵的位图上不断绘制图案是直接覆盖的。就像油画绘画一样。
在这里插入图片描述在这里插入图片描述
由于文字颜色不一样,因此可以很好的区分原游戏和我这边的效果。

下一篇会进行法术场景的制作,不知道会不会有坑或是直接完成效果,大家拭目以待吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值