仿新仙剑战斗物品指令菜单

遇到的坑

上次做的额外战斗指令菜单和物品战斗指令菜单,突然发现一个大问题,漏风了!!!RPG Maker MV 踩坑八 仿新仙剑战斗物品指令菜单-LMLPHP
其实就是将底部漏出来了,这样整个UI就不完整了,算是出现了BUG。
其实要是直接进行处理也不是没有解决办法,就像主菜单一样,将所以菜单图片均在主菜单的场景中绘制也不是不行,但是会挺麻烦的。

坑一

遇到这个问题首先想到的解决办法是在物品战斗指令菜单的图片绘制中直接绘制背景图片:

Window_ItemCommand.prototype.drawBattleItemCommand=function(){
	var bitmap=this.oldCommand;
	bitmap.blt(this.oldCommand, 0, 0, 128, 224, -55, -64);
	bitmap=this.BattleCommand;
	var sy=0;
	var sw=128;
	var sh=160;
	var dx=0;
	var dy=0;
	this.contents.blt(bitmap, this.drawSx.get(this._index), sy, sw, sh, dx, dy);
}

在需要的UI前绘制背景图片,即将额外战斗指令菜单的图片再绘制一遍,只是在物品指令中绘制。
RPG Maker MV 踩坑八 仿新仙剑战斗物品指令菜单-LMLPHP RPG Maker MV 踩坑八 仿新仙剑战斗物品指令菜单-LMLPHP
这样绘制的弊端很明显绘制好后确实进行了遮挡,但是由于窗口打开时背景是透明的,因此会看到缺了这么一块,这样也算是一个比较明显的穿帮。

坑二

这样不行,那直接在窗口背景上做文章可行吗?

Window.prototype._createAllParts = function() {
    this._windowSpriteContainer = new PIXI.Container();
    this._windowBackSprite = new Sprite();//背景
    this._windowCursorSprite = new Sprite();//光标
    this._windowFrameSprite = new Sprite();//框架
    this._windowContentsSprite = new Sprite();//内容
    this._downArrowSprite = new Sprite();//向下箭头
    this._upArrowSprite = new Sprite();//向上箭头
    this._windowPauseSignSprite = new Sprite();//暂停标志
    this._windowBackSprite.bitmap = new Bitmap(1, 1);
    this._windowBackSprite.alpha = 192 / 255;
    this.addChild(this._windowSpriteContainer);
    this._windowSpriteContainer.addChild(this._windowBackSprite);
    this._windowSpriteContainer.addChild(this._windowFrameSprite);
    this.addChild(this._windowCursorSprite);
    this.addChild(this._windowContentsSprite);
    this.addChild(this._downArrowSprite);
    this.addChild(this._upArrowSprite);
    this.addChild(this._windowPauseSignSprite);
};
Window.prototype._refreshAllParts = function() {
    this._refreshBack();
    this._refreshFrame();
    this._refreshCursor();
    this._refreshContents();
    this._refreshArrows();
    this._refreshPauseSign();
};
Window.prototype._refreshBack = function() {
    var m = this._margin;
    var w = this._width - m * 2;
    var h = this._height - m * 2;
    var bitmap = new Bitmap(w, h);

    this._windowBackSprite.bitmap = bitmap;
    this._windowBackSprite.setFrame(0, 0, w, h);
    this._windowBackSprite.move(m, m);

    if (w > 0 && h > 0 && this._windowskin) {
        var p = 96;
        bitmap.blt(this._windowskin, 0, 0, p, p, 0, 0, w, h);
        for (var y = 0; y < h; y += p) {
            for (var x = 0; x < w; x += p) {
                bitmap.blt(this._windowskin, 0, p, p, p, x, y, p, p);
            }
        }
        var tone = this._colorTone;
        bitmap.adjustTone(tone[0], tone[1], tone[2]);
    }
};

通过这三个方法知道了,窗口在创建时的顺序,并且知道了在_windowSpriteContainer 变量即窗口精灵容器中添加了这么两个精灵,_windowBackSprite _windowFrameSprite 这两个精灵,它们一个是背景精灵,一个框架精灵,而我们需要处理的就行背景精灵了。
但可惜通过直接在背景精灵的操作方法中进行修改代码,并绘制需要的背景这个方法不可行,因为窗口打开后就直接看到后面的场景了。同时为了确保这不是我的操作问题,我在浏览器上重新进行了一遍绘制,却发现可以绘制出来,这是什么原因呢?
这是由于窗口加载时已经将对应的图片操作加载了,因此可以看做是,程序底层运行时只会绘制这对应图片上的内容,若是需要绘制其他的东西,需要我们手动操作。

解决方法

Window_ItemCommand.prototype.initializeBack = function() {
	var bitmap = new Bitmap(128, 160);
	this._windowBackSprite.bitmap = bitmap;
    this._windowBackSprite.setFrame(0, 0, 128, 160);
	this._windowBackSprite.move(0,0);
	this._windowBackSprite.alpha=1;
	if(this.oldCommand){
		bitmap.blt(this.oldCommand, 0, 0, 128, 224, -55, -64);
		bitmap.blt(this.BattleCommand, 0, 0, 128, 160, 0, 0);
	}
};
Window_ItemCommand.prototype._refreshFrame = function() { 
};
//this._itemCommandWindow.changeTransparent();//这是在场景中创建时的,这里需要进行删除或注释掉
Pal_Scene_Battle.prototype.commandItem = function() {
	this._itemCommandWindow.activate();
	this._itemCommandWindow.initializeBack();
	this.selectNextCommand2();
};

通过这几行代码就可以实现想要的效果了。其实这个效果也是有缺陷的,由于窗口是从中间向上下两边展开,因此颜色上就会看到明显的移动痕迹,但是由于展开速度很快,所以大部分人其实是不会看到对应展开的bug的,同时由于这样会出现很明显动画效果,因此我在额外战斗指令的菜单窗口上也添加了这样的代码,这样可以更加的统一一些。

03-24 17:44