Flash ActionScript 2.0 localToGlobal坐标问题

时间:2018-08-05 19:48:28

标签: actionscript flash-cs6

我不知道这里是否有足够大的人记住ActionScript 2.0,但不幸的是,由于我正在为(天际)编写mod的游戏仍然将AS2用于UI,因此我陷入了困境。

我在动画/补间动画中使用的是Greensock TweenLite / TimeLineLite,但在一些简单的坐标计算上却遇到了困难。

我正在尝试从图标A的起始位置开始对其进行动画处理,将其放大并在x和y中移动,并最终以与图标B相同的位置和大小结束。

图标A和图标B位于同一父剪辑向上两个级别的不同动画片段中,因此我尝试使用localToGlobal来获取每个图标的x / y阶段,然后根据x和y之间的差异进行移动两组舞台坐标。

例如:

Icon A Global x = 95
Icon B Global x = 150
Difference = 55

图标A本地x + 55应该将其放在与图标B相同的x位置上吗?嗯,这远远不及我在屏幕上看到的结果,甚至还没有关闭。

为帮助更好地可视化,这是小部件在游戏中的外观:

Example screenshot

这就是CS6中的样子:

Flash workspace

因此,例如,我尝试将leftPreselectIcon(示例屏幕截图中的“龙骨战斧”)移动/缩放到精确的leftIcon(火力发电厂员工)位置。

以下是相关功能:

public function prepareForPreselectAnimation(): Void
{
    //This function checks if the preselect icons are to the left or right of their main icon and sets the animate out direction to the opposite side. It also stores current main icon x/y as the target values for the preselect icons to animate to. Finally it gets and stores all necessary current scale and alpha values to ensure everything returns to the exact state it was in prior to starting the animation

    var leftIconLTG:Object = {x:(leftIcon._height * 0.5), y:(leftIcon._width * 0.5)};
    var leftPreselectIconLTG:Object = {x:(leftPreselectIcon._height * 0.5), y:(leftPreselectIcon._width * 0.5)};
    var rightIconLTG:Object = {x:(rightIcon._height * 0.5), y:(rightIcon._width * 0.5)};
    var rightPreselectIconLTG:Object = {x:(rightPreselectIcon._height * 0.5), y:(rightPreselectIcon._width * 0.5)};
    var shoutIconLTG:Object = {x:(shoutIcon._height * 0.5), y:(shoutIcon._width * 0.5)};
    var shoutPreselectIconLTG:Object = {x:(shoutPreselectIcon._height * 0.5), y:(shoutPreselectIcon._width * 0.5)};

    leftIcon.localToGlobal(leftIconLTG);
    leftPreselectIcon.localToGlobal(leftPreselectIconLTG);
    rightIcon.localToGlobal(rightIconLTG);
    rightPreselectIcon.localToGlobal(rightPreselectIconLTG);
    shoutIcon.localToGlobal(shoutIconLTG);
    shoutPreselectIcon.localToGlobal(shoutPreselectIconLTG);

    skyui.util.Debug.log("leftIconLTG - x: " + leftIconLTG.x + ", y: " + leftIconLTG.y)
    skyui.util.Debug.log("leftPreselectIconLTG - x: " + leftPreselectIconLTG.x + ", y: " + leftPreselectIconLTG.y)

    if (leftIconLTG.x > leftPreselectIconLTG.x){
        leftTargetX = (leftIcon_mc._width) //If preselect icon is to the left of the main widget animate main widget out to right
        //leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x) + (leftIcon._width / 2)
    } else {
        leftTargetX = -(leftIcon_mc._width) //If preselect icon is to the right of the main widget animate main widget out to left
        //leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x) - (leftIcon._width)
    }
    leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x)
    skyui.util.Debug.log("leftTargetX: " + leftTargetX + ", leftPTargetX: " + leftPTargetX)
    if (rightIconLTG.x > rightPreselectIconLTG.x){
        rightTargetX = (rightIcon_mc._width)
        //rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x) + (rightIcon._width / 2)
    } else {
        rightTargetX = -(rightIcon_mc._width)
        //rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x) - (rightIcon._width)
    }
    rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x)
    if (shoutIconLTG.x > shoutPreselectIconLTG.x){
        shoutTargetX = (shoutIcon_mc._width)
        //shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x) + (shoutIcon._width / 2)
    } else {
        shoutTargetX = -(shoutIcon_mc._width)
        //shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x) - (shoutIcon._width)
    }
    shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x)

    leftPTargetY = leftIconLTG.y - leftPreselectIconLTG.y;
    skyui.util.Debug.log("leftPTargetY: " + leftPTargetY)
    rightPTargetY = rightIconLTG.y - rightPreselectIconLTG.y;
    shoutPTargetY = shoutIconLTG.y - shoutPreselectIconLTG.y;

    //Store current alpha and scale values ready to reapply
    leftIconAlpha = leftIcon_mc._alpha;
    leftTargetScale = ((leftIcon_mc._xscale / leftPreselectIcon_mc._xscale) * 100);
    //leftPTargetX = ((leftIconLTG.x - leftPreselectIconLTG.x) * (leftIcon_mc._xscale / leftPreselectIcon_mc._xscale));
    leftPIconAlpha = leftPreselectIcon_mc._alpha;
    leftPIconScale = leftPreselectIcon._xscale;
    rightIconAlpha = rightIcon_mc._alpha;
    rightTargetScale = ((rightIcon_mc._xscale / rightPreselectIcon_mc._xscale) * 100);
    rightPIconAlpha = rightPreselectIcon_mc._alpha;
    rightPIconScale = rightPreselectIcon._xscale;
    shoutIconAlpha = shoutIcon_mc._alpha;
    shoutTargetScale = ((shoutIcon_mc._xscale / shoutPreselectIcon_mc._xscale) * 100);
    shoutPIconAlpha = shoutPreselectIcon_mc._alpha;
    shoutPIconScale = shoutPreselectIcon._xscale;
    leftNameAlpha = leftName_mc._alpha;
    leftPNameAlpha = leftPreselectName_mc._alpha;
    rightNameAlpha = rightName_mc._alpha;
    rightPNameAlpha = rightPreselectName_mc._alpha;
    shoutNameAlpha = shoutName_mc._alpha;
    shoutPNameAlpha = shoutPreselectName_mc._alpha;

    skse.SendModEvent("iEquip_ReadyForPreselectAnimation", null);

}

public function equipPreselectedItem(iSlot: Number, currIcon: String, newIcon: String, newName: String, currPIcon: String, newPIcon: String, newPName: String): Void
{

    var iconClip: MovieClip;
    var iconClip_mc: MovieClip;
    var currIcon: String;
    var pIconClip: MovieClip;
    var pIconClip_mc: MovieClip;
    var currPIcon: String;
    var itemName_mc: MovieClip;
    var preselectName_mc: MovieClip;
    var targetX: Number;
    var pTargetX: Number;
    var pTargetY: Number;
    var pIconAlpha: Number;
    var pIconScale: Number;
    var pIconTargetScale: Number
    var iconAlpha: Number;
    var itemNameAlpha: Number;
    var preselectNameAlpha: Number;

    switch(iSlot) {
        case 0:
            iconClip = leftIcon;
            iconClip_mc = leftIcon_mc;
            pIconClip = leftPreselectIcon;
            pIconClip_mc = leftPreselectIcon_mc;
            itemName_mc = leftName_mc;
            preselectName_mc = leftPreselectName_mc;
            targetX = leftTargetX;
            pTargetX = leftPTargetX;
            pTargetY = leftPTargetY;
            pIconAlpha = leftPIconAlpha;
            pIconScale = leftPIconScale;
            iconAlpha = leftIconAlpha;
            pIconTargetScale = leftTargetScale;
            itemNameAlpha = leftNameAlpha;
            preselectNameAlpha = leftPNameAlpha;
            break
        case 1:
            iconClip = rightIcon;
            iconClip_mc = rightIcon_mc;
            pIconClip = rightPreselectIcon;
            pIconClip_mc = rightPreselectIcon_mc;
            itemName_mc = rightName_mc;
            preselectName_mc = rightPreselectName_mc;
            targetX = rightTargetX;
            pTargetX = rightPTargetX;
            pTargetY = rightPTargetY;
            pIconAlpha = rightPIconAlpha;
            pIconScale = rightPIconScale;
            iconAlpha = rightIconAlpha;
            pIconTargetScale = rightTargetScale;
            itemNameAlpha = rightNameAlpha;
            preselectNameAlpha = rightPNameAlpha;
            break
        case 2:
            iconClip = shoutIcon;
            iconClip_mc = shoutIcon_mc;
            pIconClip = shoutPreselectIcon;
            pIconClip_mc = shoutPreselectIcon_mc;
            itemName_mc = shoutName_mc;
            preselectName_mc = shoutPreselectName_mc;
            targetX = shoutTargetX;
            pTargetX = shoutPTargetX;
            pTargetY = shoutPTargetY;
            pIconAlpha = shoutPIconAlpha;
            pIconScale = shoutPIconScale;
            iconAlpha = shoutIconAlpha;
            pIconTargetScale = shoutTargetScale;
            itemNameAlpha = shoutNameAlpha;
            preselectNameAlpha = shoutPNameAlpha;
            break
        }

    var tempIcon: MovieClip = iconClip.duplicateMovieClip("tempIcon", this.getNextHighestDepth());
    tempIcon.gotoAndStop(currIcon);
    iconClip._alpha = 0;
    iconClip.gotoAndStop(newIcon);
    var tempPIcon: MovieClip = pIconClip.duplicateMovieClip("tempPIcon", this.getNextHighestDepth());
    //var iconLTG: Object = {x:(iconClip._width * 0.5), y:(iconClip._height * 0.5)}
    //iconClip.localToGlobal(iconLTG);
    //var tempPIconLTG: Object = {x:(tempPIcon._width * 0.5), y:(tempPIcon._height * 0.5)}
    //tempPIcon.localToGlobal(tempPIconLTG);
    //pTargetX = ((iconLTG.x - tempPIconLTG.x) * (iconClip_mc._xscale / pIconClip_mc._xscale));

    //skyui.util.Debug.log("iconLTG.x: " + iconLTG.x + ", iconLTG.y: " + iconLTG.y + "tempPIconLTG.x: " + tempPIconLTG.x + ", tempPIconLTG.y: " + tempPIconLTG.y + ", pTargetX: " + pTargetX)

    tempPIcon._xscale = pIconClip_mc._xscale;
    tempPIcon._yscale = pIconClip_mc._yscale;
    tempPIcon.gotoAndStop(currPIcon);
    pIconClip._alpha = 0;
    pIconClip._xscale = 25;
    pIconClip._yscale = 25;
    pIconClip.gotoAndStop(newPIcon);
    var tl = new TimelineLite({paused:true, autoRemoveChildren:true, onComplete:equipPreselectedItemComplete});
    tl.to(itemName_mc, 0.3, {_alpha:0, ease:Quad.easeOut}, 0)
    .to(preselectName_mc, 0.3, {_alpha:0, ease:Quad.easeOut}, 0)
    .call(updateNamesForEquipPreselect, [iSlot, newName, newPName, this])
    .to(tempIcon, 0.6, {_x:targetX, _y:((tempIcon._height) / 2), _rotation:"+=90", _alpha:0, _xscale:25, _yscale:25, ease:Quad.easeOut}, 0);
    .to(tempPIcon, 0.6, {_x:pTargetX, _y:pTargetY, _alpha:iconAlpha, _xscale:pIconTargetScale, _yscale:pIconTargetScale, ease:Quad.easeOut}, 0)
    .to(iconClip, 0, {_alpha:iconAlpha, ease:Linear.easeNone})
    .to(tempPIcon, 0, {_alpha:0, ease:Linear.easeNone})
    .to(pIconClip, 0.4, {_alpha:pIconAlpha, _xscale:pIconScale, _yscale:pIconScale, ease:Elastic.easeOut}, 0.5)
    .to(itemName_mc, 0.3, {_alpha:itemNameAlpha, ease:Quad.easeOut}, 0.6)
    .to(preselectName_mc, 0.3, {_alpha:preselectNameAlpha, ease:Quad.easeOut}, 0.6)

    tl.play();
}

我也已将其上传到Pastebin HERE

应该起作用的直接图标A X值+全局X值差导致:

Screenshot 2

两个图标之间的距离越大,问题就越严重。如果我将图标A的起始位置编辑得更远,则结果如下:

Screenshot 3

从这两个示例中,记录的值和计算为:

[20:12:47.970] leftIconLTG - x: 149.49916992187, y: 581.28598632812
[20:12:47.970] leftPreselectIconLTG - x: 94.587438964844, y: 577.68461914063
[20:12:47.970] leftTargetX: 39.15, leftPTargetX: 54.911730957031
[20:12:47.970] leftPTargetY: 3.6013671874999

[20:13:18.510] leftIconLTG - x: 149.49916992187, y: 581.28598632812
[20:13:18.510] leftPreselectIconLTG - x: 594.56030273438, y: 577.68461914063
[20:13:18.510] leftTargetX: -58.55, leftPTargetX: -445.0611328125
[20:13:18.510] leftPTargetY: 3.6013671874999

因此您可以看到目标leftIcon全局(LTG)x为149.5,在第一个屏幕截图中,leftPreselectIcon从94.6的全局x开始。 leftPTargetX包含正确计算为54.9的差异。因此,从理论上将leftPreselectIcon从0的本地起始x移至54.9应该在理论上将其移至正确的位置。

那么我在这里做错了什么?从注释的代码中可以看到,我还进行了其他几次尝试,包括将半/全图标宽度添加到计算中,甚至通过将全局x差异值乘以比例来测试比例差异是否与它有关。使用屏幕上的高度从图标A缩放到图标B缩放的系数。但是没有一个让我靠近。


已解决

解决方案是为每组图标创建“存储”对象,然后在目标图标上调用localToGlobal,然后在要移动的图标上调用globalToLocal,两个调用相同的对象:

var leftPIconTarget:Object = {x:0, y:0};

    leftIcon.localToGlobal(leftPIconTarget);

    leftPreselectIcon.globalToLocal(leftPIconTarget);

leftPIconTarget现在在leftPreselectIcon上包含补间的目标x和y坐标,并且无论我将起始位置移动到屏幕上的哪个位置,它都可以继续工作。唯一的困扰是我必须将右边的x设为负数,否则会朝错误的方向前进,这根本没有意义,因为如果我将左边的图标移到右边,那么它就必须从右到左进行动画处理,不必使其负面。去搞清楚!无论如何,它有效,而这就是我所困扰的一切!

0 个答案:

没有答案