モーショングラフィックスで学ぶActionScript − Flash MX −

7.4 ドロップ先条件を追加する

ID: FB0206002 Page: 212/Line: Last


[p.212のスクリプト]

// ドラッグもとのMovieClip: myMovieClip_mc
// 第1フレームアクション
// 初期値の設定
nOriginalX = _x;
nOriginalY = _y;
// マウスボタンを押したとき
this.onPress = function() {
  this.startDrag();
};
// マウスボタンを離したとき
this.onRelease = function() {
  this.stopDrag();
  this.xSetPosition();
};
// マウスボタンを領域外で離したとき
this.onReleaseOutside = this.onRelease;
// 位置設定のユーザー定義関数
function xSetPosition() {
  var oTarget = eval(_droptarget);
  if (oTarget != undefined) {
    var oInfo = oTarget.xGetInfo();
    var sTargetType = oInfo.sType;
    if (sType == undefined || sType == sTargetType) {
      _x = oInfo.x;
      _y = oInfo.y;
    } else {
      _x = nOriginalX;
      _y = nOriginalY;
    }
  } else {
    _x = nOriginalX;
    _y = nOriginalY;
  }
}


補足

このフレームアクションは、ステージ上のMoveClipがドラッグ元を除いてすべてドロップ先であれば、正しく動作します。また、ドラッグ元MovieClipに変数sTypeが設定してあれば、とくに問題はありません。けれど、sTypeの設定されていないドラッグ元を、ドロップ対象でないMovieClipに重ねてマウスボタンを放すと、スナップはしないもののその位置に止まってしまい、元の位置に戻りません。

これは、ドロップ先でないMovieClipも、「_droptarget」としてストリングのパスを返すからです。「_droptarget」が値を返せば、そのターゲットパスは取得できます。つまり、ターゲットパスoTargetは、未定義値(undefined)にはなりません。ですから、位置設定をするユーザー定義関数の最初の「if」条件は、「true」と評価されます。

そして、ドラッグ元MovieClipに変数sTypeが設定されていなければ、第2の「if」条件も「true」になります。したがって、ドラッグ元MovieClipは、元の位置には戻りません。しかし、ドロップ対象でないMovieClipには、位置情報をObjectで返すユーザー定義関数xGetInfoがありません。ユーザー定義関数がなければ値は返されず、変数oInfoには未定義値(undefined)が代入されます。当然、「x」や「y」のプロパティなど取出せませんから、oInfo.xとoInfo.yも未定義値(undefined)になります。

MovieClipの「_x」「_y」プロパティに未定義値「undefined」を設定した場合、座標は変更されません。それで、ドラッグ元MovieClipは、ドロップした位置に止まってしまうことになります。

この場合を処理するには、「if」アクションをさらに加えて、変数oInfoが未定義値「undefined」かどうかを評価すればよいでしょう。「if」アクションはすでに練習してきましたので、とくに補足すべき説明はありません。ただ、「if」条件が3重になりますので、よく評価の構造を考えてスクリプトを組み立てましょう。確認のために、まず「if」条件の部分だけ取出してみることにします。

if (oTarget != undefined) {
  // ドロップ先MovieClipからObjectを受取って変数oInfoに代入
  if (oInfo == undefined) {
    // 元の位置に戻す
  } else {
    // ObjectからsTypeの値を取出す
    if (sType == undefined || sType == sTargetType) {
      // Objectからxy座標値を取出して設定
    } else {
      // 元の位置に戻す
    }
  } else {
    // 元の位置に戻す
  }
}

第1の「if」条件では、ターゲットパスが取得できたかどうかを調べて、ドロップ先がMovieClipであることを確認しています。第2に加えたのが、ドロップ先MovieClipがObjectを返したかどうかを評価する「if」条件です。Objectが返されれば、ドロップ対象のMovieClipであることがわかります。第3の「if」条件は、sTypeの合致を評価するものです。

ひとつ気づくことは、元の位置に戻す処理が3箇所にあることです。このように何度も出てくる処理は、ユーザー定義関数にした方がすっきりします。これらを書替えたMovieClipのフレームアクションは、以下のようになります。

// ドラッグもとのMovieClip: myMovieClip_mc
// 第1フレームアクション
// 初期値の設定
nOriginalX = _x;
nOriginalY = _y;
// マウスボタンを押したとき
this.onPress = function() {
  this.startDrag();
};
// マウスボタンを離したとき
this.onRelease = function() {
  this.stopDrag();
  this.xSetPosition();
};
// マウスボタンを領域外で離したとき
this.onReleaseOutside = this.onRelease;
// 位置設定のユーザー定義関数
function xSetPosition() {
  var oTarget = eval(_droptarget);
  if (oTarget != undefined) {
    var oInfo = oTarget.xGetInfo();
    if (oInfo == undefined) {
      this.xSetBack();
    } else {
      var sTargetType = oInfo.sType;
      if (sType == undefined || sType == sTargetType) {
        _x = oInfo.x;
        _y = oInfo.y;
      } else {
        this.xSetBack();
      }
    }
  } else {
    this.xSetBack();
  }
}
// 元の位置に戻すユーザー定義関数
function xSetBack() {
  _x = nOriginalX;
  _y = nOriginalY;
}

_____

作成者: 野中文雄
作成日: 2002年6月29日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.