ツクールMZのフロントビュー戦闘についての質問です。
スクリプトは全く分かりません。
マウス操作で敵ターゲットを選択する時、重なっている敵を思い通りに選択できません。
改善したいのですが私には無理です。お手上げ状態です。
お力添えをお願いします。
---- ---- ---- ---- ---- ---- ---- ----
まず、
しぐれん様の『戦闘時にターゲットのタッチ選択』プラグインを使っています。
http://tm.lucky-duet.com/viewtopic.php?f=5&t=9043
ターゲットを選択する際、敵画像をクリックで選択できる優れものです。感謝です。
ツクールMV用ですが、MZでも正常に動作します。
以下のように敵を配置した戦闘(フロントビュー)で、
重なっている敵をマウス操作で選択するのが非常に難しくなります。
上図の敵画像の透明部分を塗りつぶした状態です。手前は赤色、後は黄色で塗りつぶしています。
敵画像の透明部分も判定されているのが原因で、感覚的に選択できないのだと思います。
---- ---- ---- ---- ---- ---- ---- ----
そこで、画像を2つ用意する方法を考えました。
1枚目はマウス判定用、2枚目が表示用の画像です。
1枚目は何も描かれていない画像にします。大切なのは画像サイズです。
2枚目は敵の姿が描かれた画像です。1枚目の画像の中心と同じ座標に表示します。
z(表示順)を後ろの方にします。
---- ---- ---- ---- ---- ---- ---- ----
プラグインを作ろうと思い、
まず、rmmz_sprites.jsのSprite_Enemyの部分をまるまる抜き出して(コピペ)、
別ファイルにしました。
次に、
Sprite_Enemy.prototype.loadBitmap をコピペして Sprite_Enemy.prototype.loadBitmap2 にしました。
Sprite_Enemy.prototype.updateBitmap
に
const nametest = this._enemy.battlerName()+"-tes"; // ♪追加 2枚目の敵画像のファイル名
と
this.loadBitmap2(nametest); // ♪追加 2枚目の画像を表示
を追記しました。
すると、エラーは出なくなったのですが、2枚目の画像も表示されません。
エラーがないので、どこがダメなのかわかりません。
ここで詰まってしまいました。
一応、コピペしただけのスクリプト全文を載せておきます。
コード: 全て選択
// ※rmmz_sprites.jsよりコピペ
//-----------------------------------------------------------------------------
// Sprite_Enemy
//
// The sprite for displaying an enemy.
// 敵を表示するためのスプライト。
function Sprite_Enemy() {
this.initialize(...arguments);
}
Sprite_Enemy.prototype = Object.create(Sprite_Battler.prototype);
Sprite_Enemy.prototype.constructor = Sprite_Enemy;
Sprite_Enemy.prototype.initialize = function(battler) {
Sprite_Battler.prototype.initialize.call(this, battler);
};
Sprite_Enemy.prototype.initMembers = function() {
Sprite_Battler.prototype.initMembers.call(this); //
this._enemy = null; //
this._appeared = false; //
this._battlerName = ""; //
this._battlerHue = 0; //
this._effectType = null; //
this._effectDuration = 0; //
this._shake = 0; //
this.createStateIconSprite(); //
};
Sprite_Enemy.prototype.createStateIconSprite = function() {
this._stateIconSprite = new Sprite_StateIcon();
this.addChild(this._stateIconSprite);
};
Sprite_Enemy.prototype.setBattler = function(battler) {
Sprite_Battler.prototype.setBattler.call(this, battler);
this._enemy = battler;
this.setHome(battler.screenX(), battler.screenY());
this._stateIconSprite.setup(battler);
};
Sprite_Enemy.prototype.update = function() {
Sprite_Battler.prototype.update.call(this);
if (this._enemy) {
this.updateEffect();
this.updateStateSprite();
}
};
Sprite_Enemy.prototype.updateBitmap = function() {
Sprite_Battler.prototype.updateBitmap.call(this);
const name = this._enemy.battlerName();
const nametest = this._enemy.battlerName()+"-tes"; // ♪追加 2枚目の敵画像のファイル名
const hue = this._enemy.battlerHue();
if (this._battlerName !== name || this._battlerHue !== hue) {
this._battlerName = name;
this._battlerHue = hue;
this.loadBitmap(name);
this.loadBitmap2(nametest); // ♪追加 2枚目の画像を表示
this.setHue(hue);
this.initVisibility();
}
};
Sprite_Enemy.prototype.loadBitmap = function(name) {
if ($gameSystem.isSideView()) {
this.bitmap = ImageManager.loadSvEnemy(name); // サイドビュ
} else {
this.bitmap = ImageManager.loadEnemy(name); // フロントビュ
}
};
Sprite_Enemy.prototype.loadBitmap2 = function(name) { // ♪追加 2枚目の敵画像
if ($gameSystem.isSideView()) {
this.bitmap2 = ImageManager.loadSvEnemy(name); // サイドビュ
} else {
this.bitmap2 = ImageManager.loadEnemy(name); // フロントビュ
}
};
Sprite_Enemy.prototype.updateFrame = function() {
Sprite_Battler.prototype.updateFrame.call(this);
if (this._effectType === "bossCollapse") {
this.setFrame(0, 0, this.bitmap.width, this._effectDuration);
this.setFrame(0, 0, this.bitmap2.width, this._effectDuration);
} else {
this.setFrame(0, 0, this.bitmap.width, this.bitmap.height);
this.setFrame(0, 0, this.bitmap2.width, this.bitmap2.height);
}
};
Sprite_Enemy.prototype.setHue = function(hue) {
Sprite_Battler.prototype.setHue.call(this, hue);
for (const child of this.children) {
if (child.setHue) {
child.setHue(-hue);
}
}
};
Sprite_Enemy.prototype.updatePosition = function() {
Sprite_Battler.prototype.updatePosition.call(this);
this.x += this._shake;
};
Sprite_Enemy.prototype.updateStateSprite = function() {
this._stateIconSprite.y = -Math.round((this.bitmap.height + 40) * 0.9);
if (this._stateIconSprite.y < 20 - this.y) {
this._stateIconSprite.y = 20 - this.y;
}
this._stateIconSprite.y = -Math.round((this.bitmap2.height + 40) * 0.9);
if (this._stateIconSprite.y < 20 - this.y) {
this._stateIconSprite.y = 20 - this.y;
}
};
Sprite_Enemy.prototype.initVisibility = function() {
this._appeared = this._enemy.isAlive();
if (!this._appeared) {
this.opacity = 0;
}
};
Sprite_Enemy.prototype.setupEffect = function() {
if (this._appeared && this._enemy.isEffectRequested()) {
this.startEffect(this._enemy.effectType());
this._enemy.clearEffect();
}
if (!this._appeared && this._enemy.isAlive()) {
this.startEffect("appear");
} else if (this._appeared && this._enemy.isHidden()) {
this.startEffect("disappear");
}
};
//
Sprite_Enemy.prototype.startEffect = function(effectType) {
this._effectType = effectType;
switch (this._effectType) {
case "appear":
this.startAppear();
break;
case "disappear":
this.startDisappear();
break;
case "whiten":
this.startWhiten();
break;
case "blink":
this.startBlink();
break;
case "collapse":
this.startCollapse();
break;
case "bossCollapse":
this.startBossCollapse();
break;
case "instantCollapse":
this.startInstantCollapse();
break;
}
this.revertToNormal();
};
Sprite_Enemy.prototype.startAppear = function() {
this._effectDuration = 16; // たぶん、エフェクトの間隔
this._appeared = true;
};
Sprite_Enemy.prototype.startDisappear = function() {
this._effectDuration = 32; // たぶん、エフェクトの間隔
this._appeared = false;
};
Sprite_Enemy.prototype.startWhiten = function() {
this._effectDuration = 16; // たぶん、エフェクトの間隔
};
Sprite_Enemy.prototype.startBlink = function() {
this._effectDuration = 20; // たぶん、エフェクトの間隔
};
Sprite_Enemy.prototype.startCollapse = function() {
this._effectDuration = 32; // たぶん、エフェクトの間隔
this._appeared = false;
};
Sprite_Enemy.prototype.startBossCollapse = function() {
this._effectDuration = this.bitmap.height;
this._appeared = false;
};
Sprite_Enemy.prototype.startInstantCollapse = function() {
this._effectDuration = 16; // たぶん、エフェクトの間隔
this._appeared = false;
};
//
Sprite_Enemy.prototype.updateEffect = function() {
this.setupEffect();
if (this._effectDuration > 0) {
this._effectDuration--;
switch (this._effectType) {
case "whiten":
this.updateWhiten();
break;
case "blink":
this.updateBlink();
break;
case "appear":
this.updateAppear();
break;
case "disappear":
this.updateDisappear();
break;
case "collapse":
this.updateCollapse();
break;
case "bossCollapse":
this.updateBossCollapse();
break;
case "instantCollapse":
this.updateInstantCollapse();
break;
}
if (this._effectDuration === 0) {
this._effectType = null;
}
}
};
Sprite_Enemy.prototype.isEffecting = function() {
return this._effectType !== null;
};
Sprite_Enemy.prototype.revertToNormal = function() {
this._shake = 0;
this.blendMode = 0;
this.opacity = 255;
this.setBlendColor([0, 0, 0, 0]);
};
Sprite_Enemy.prototype.updateWhiten = function() {
const alpha = 128 - (16 - this._effectDuration) * 8;
this.setBlendColor([255, 255, 255, alpha]);
};
Sprite_Enemy.prototype.updateBlink = function() {
this.opacity = this._effectDuration % 10 < 5 ? 255 : 0;
};
Sprite_Enemy.prototype.updateAppear = function() {
this.opacity = (16 - this._effectDuration) * 16;
};
Sprite_Enemy.prototype.updateDisappear = function() {
this.opacity = 256 - (32 - this._effectDuration) * 10;
};
Sprite_Enemy.prototype.updateCollapse = function() {
this.blendMode = 1;
this.setBlendColor([255, 128, 128, 128]);
this.opacity *= this._effectDuration / (this._effectDuration + 1);
};
Sprite_Enemy.prototype.updateBossCollapse = function() {
this._shake = (this._effectDuration % 2) * 4 - 2;
this.blendMode = 1;
this.opacity *= this._effectDuration / (this._effectDuration + 1);
this.setBlendColor([255, 255, 255, 255 - this.opacity]);
if (this._effectDuration % 20 === 19) {
SoundManager.playBossCollapse2();
}
};
Sprite_Enemy.prototype.updateInstantCollapse = function() {
this.opacity = 0;
};
Sprite_Enemy.prototype.damageOffsetX = function() {
return Sprite_Battler.prototype.damageOffsetX.call(this);
};
Sprite_Enemy.prototype.damageOffsetY = function() {
return Sprite_Battler.prototype.damageOffsetY.call(this) - 8;
};
使いそうなファイルも添付しておきます。
余談になりますが、状態(ステート)によって敵画像を変更したいとも考えていて、
その足がかりになると思い、この方法を選びました。
つまり、2枚目の画像ファイル名を変更すれば、
毒で苦しそうだったり、目をつむって寝てたりできる!
と企んでいます。
よろしくお願いします。