精灵绘制问题
- RPG Maker MV战斗问题
- 入场飞身
- 战斗背景绘制
- 精灵集及精灵
RPG Maker MV战斗问题
在RMMV中战斗是在场景中调用战斗管理器,通过管理器去操作角色对象行动及精灵的绘制的。
入场飞身
在其中就发现一个问题加载图片进场时,会偏高,且显示的不是需要的那个需要绘制的区域。
从这可以看到人物进场时脚下的影子位置和飞身进场的位置差距挺大的且看到,不是我所理想的进场的姿势,那这发生了什么呢?
当时想到了是不是无意中调用了这里面的的偷窃的动画呢?
不过注释了 steal 后发现不是,那可能是什么问题呢?
在看到了控制台的打印后想到了是不是这个位置的出现了问题:
Sprite_Actor.prototype.refreshMotion = function() {var actor = this._actor;var motionGuard = Sprite_Actor.MOTIONS['guard'];if (actor) {if (this._motion === motionGuard && !BattleManager.isInputting()) {return;}var stateMotion = actor.stateMotionIndex();if (actor.isInputting() || actor.isActing()) {this.startMotion('wait');console.log("待机")} else if (stateMotion === 3) {this.startMotion('dead');} else if (stateMotion === 2) {this.startMotion('sleep');console.log("睡眠")} else if (actor.isChanting()) {this.startMotion('chant');console.log("魔法等待")} else if (actor.isGuard() || actor.isGuardWaiting()) {this.startMotion('guard');console.log("保护等待")} else if (stateMotion === 1) {this.startMotion('abnormal');console.log("异常状态")} else if (actor.isDying()) {this.startMotion('dying');console.log("重伤")} else if (actor.isUndecided()) {//是否犹豫(等待)this.startMotion('wait');console.log("是否犹豫")} else {this.startMotion('wait');console.log("后退")}}
};
通过打印看到刚进来时角色是执行了待机的操作的,那会不会是这个地方出现了问题。
可通过浏览器的调试发现也不是,查看了精灵的大小后,发现精灵一开始是宽高都是0,后面突然变成了精灵图片的宽高,但通过直接修改宽高为固定值却没有任何效果,就在一筹莫展的时候,突然想起了更新帧的代码中是这样写的:
Sprite_Actor.prototype.updateFrame = function() {Sprite_Battler.prototype.updateFrame.call(this);var bitmap = this._mainSprite.bitmap;if (bitmap) {var motionIndex = this._motion ? this._motion.index : 0;var pattern = this._pattern < 3 ? this._pattern : 1;var cw = bitmap.width / 9;var ch = bitmap.height / 6;var cx = Math.floor(motionIndex / 6) * 3 + pattern;var cy = motionIndex % 6;this._mainSprite.setFrame(cx * cw, cy * ch, cw, ch);}
};
这里面除了调用父类的方法没有用(因为是空的方法,可以看作是接口的抽象方法),往下依次是将精灵获取的图片赋值给一个变量中,然后判断位图是不是空的,不是才执 IF 中的语句,其中获取运动索引的是一个三元运算符,是判断运动的值存在就直接将其索引给变量,否则将0给变量。
if(this._motion){var name=this._actor.battlerName();var motionIndex=this._motion[name].index;this._motionIndexCount = motionIndex.length;var pattern = this._pattern < this._motionIndexCount ? this._pattern : 0;var cw = bitmap.width;var ch = bitmap.height / 12;var cx = 0;var cy = motionIndex[pattern];this._mainSprite.setFrame(cx * cw, cy * ch, cw, ch);}
而我的位图判断后是这样的,这就有个问题,没有运动就不会执行相应的绘制,这意味着初始的绘制是一整个图片,那为什么看到会高呢?那是因为组成的图片中最下面是一个完全透明的图片,所以看到最后可以看到的精灵图时是看着飞过来的。
这个经历告诉了我什么呢?不要进行盲目的优化代码,因为优化过后,很可能变得糟糕或更糟糕,需要进行详细的测试每次修改后都得测试对应修改过后的位置是不是会有问题,不然这修改就是无效的。
战斗背景绘制
刚开始尝试战斗背景时发现了背景位置不对,因此尝试进行了调整。
Spriteset_Battle.prototype.createBattleback = function() {var margin = 32;var x = -this._battleField.x - margin;var y = -this._battleField.y - margin;var width = Graphics.width + margin * 2;var height = Graphics.height + margin * 2;this._back1Sprite = new TilingSprite();this._back2Sprite = new TilingSprite();this._back1Sprite.bitmap = this.battleback1Bitmap();this._back2Sprite.bitmap = this.battleback2Bitmap();this._back1Sprite.move(x, y, width, height);this._back2Sprite.move(x, y, width, height);this._battleField.addChild(this._back1Sprite);this._battleField.addChild(this._back2Sprite);
};
Spriteset_Battle.prototype.locateBattleback = function() {var width = this._battleField.width;var height = this._battleField.height;var sprite1 = this._back1Sprite;var sprite2 = this._back2Sprite;sprite1.origin.x = sprite1.x + (sprite1.bitmap.width - width) / 2;sprite2.origin.x = sprite1.y + (sprite2.bitmap.width - width) / 2;if ($gameSystem.isSideView()) {sprite1.origin.y = sprite1.x + sprite1.bitmap.height - height;sprite2.origin.y = sprite1.y + sprite2.bitmap.height - height;}
};
createBattleback 中margin是用于给背景图片留出边缘空间的常数,计算 **x **和 y 使得背景图片的左上角比战斗场的左上角再向左和上移动margin的距离,计算 width 和 height 用游戏画面大小加上两边的margin。然后创建背景1和背景2的平铺精灵,再将对应的背景位图给到两个精灵,并移动其位置和加入精灵集的子集中。
locateBattleback 获取前景图片的宽高,并计算背景图片的原点坐标。
很明显这样是不符合我的要求的,那该怎么办呢?
Spriteset_Battle.prototype.updateBattleback = function() {if (!this._battlebackLocated) {//this.locateBattleback();this._battlebackLocated = true;}
};
在更新战斗背景中注释掉locateBattleback 方法,这样就不会触发原点计算的操作,然后修改创建背景的方法:
Spriteset_Battle.prototype.createBattleback = function() {//var margin = 32;var x = -80;var y = -60;var width = 640;var height = 480;this._back1Sprite = new Sprite();this._back2Sprite = new Sprite();this._back1Sprite.bitmap = this.battleback1Bitmap();this._back2Sprite.bitmap = this.battleback2Bitmap();this._back1Sprite.move(x, y, width, height);this._back2Sprite.move(x, y, width, height);this._battleField.addChild(this._back1Sprite);this._battleField.addChild(this._back2Sprite);
};
这样就可以实现对应的操作了!
这样内容是不是太少了,踩得坑呢?
精灵集及精灵
精灵集有如下的方法:
- move ( x , y , width , height ):直接设置 TilingSprite(平铺精灵) 的 X 坐标、Y 坐标、宽度和高度。
- setFrame ( x , y , width , height ):设置 TilingSprite(平铺精灵) 所显示 bitmap(位图) 的矩形区域。
- update ():在每一帧中刷新 TilingSprite(平铺精灵) 。
属性:
- bitmap Bitmap:TilingSprite(平铺精灵) 所显示的图片。
- opacity Number:TilingSprite(平铺精灵) 的不透明度(0 ~ 255)。
- origin Point:滚动显示效果中 TilingSprite(平铺精灵) 的原点。
- visible Boolean:TilingSprite(平铺精灵) 的可见性。
- x和y坐标了
这里面我操作了move、setFrame、origin这几项,但发现不能解决问题。
SceneManager._scene.children[0]._back1Sprite.move(-80,-60,640,480)
计划是调整图片现在在这里面的坐标和大小的,但这样显示却不行。
SceneManager._scene.children[0]._back1Sprite.setFrame(-80,-60,640,480)
由于平铺的关系导致了图片的不正常拼接,及像素拉伸。
origin属性也是差不多的,导致不能完好的显示需要的内容,因此换成了普通的精灵。