精靈繪制問題
- 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屬性也是差不多的,導致不能完好的顯示需要的內容,因此換成了普通的精靈。