AS3跟踪和使用旋转对象的坐标

时间:2014-06-04 20:20:52

标签: actionscript-3 flashdevelop rotatetransform

如何跟踪和使用在初始化时旋转的对象的坐标?

让我们说我有一把剑放在Main init()的舞台上;并旋转(调整),以便它与角色视角一起看起来很好。然而,在另一个班级,我正在使用一个按键计时器事件更多的剑旋转,以创建一个'摇摆'动画。

所有这些都是通过flashdevelop完成的。我只使用CS6来创建符号。而且,随着这种“摇摆”正在发生,我想在剑的尖端添加另一个符号,这是一个碰撞点对象。在挥杆开始时将其添加到舞台上,并在每次挥杆后将其移除。我希望这个物体跟随剑的尖端,但似乎我只能实现它跟随原始剑对象的坐标,就像我最初没有修改过所述剑的旋转一样。我试图实现GlobalToLocal()和LocalToGlobal()方法,但我不认为我完全理解发生了什么。

我希望我能够清楚地知道自己要做的事情。谢谢。这是相关的相关代码。代码就像我尝试上面提到的两种方法之前一样,目前的问题正如之前所描述的那样。我是否想要任何这些方法,或者我只是做错了什么?

主要初始化:

sword = new Sword();

sword.x = 53;
sword.y = 90;
addChild(sword);
sword.rotationZ = -150;
sword.rotationY = 25;
sword.rotationX = -15;

Coll_Point = new coll_point();

处理swing的类有这样的方法:

private function SwingTime(event:Event):void
{
    Main.Coll_Point.x = Main.sword.x + Main.sword.width;
    Main.Coll_Point.y = Main.sword.y + Main.sword.height;
    Main.MazeNr1.addChild(Main.Coll_Point);

    if (Main.sword.rotationZ > -330)
    Main.sword.rotationZ -= 20;

    if (Main.sword.rotationX < 15)
    Main.sword.rotationX += 10;

    if ((Main.sword.rotationZ == -330) && (Main.sword.rotationX == 15))
    {
        SwingTimer.stop();
        SwingBckTimer.start();
    }
}

修改 代码的更全面版本:

public class Main extends MovieClip 
{
    public static var from_point:Point = null;
    public static var to_point:Point = new Point();
    public function Main():void
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    // Puts everything on the stage here.
    private function init(e:Event = null):void
    {
    removeEventListener(Event.ADDED_TO_STAGE, init);
        PlayerInst = new Dorf();
        PlayerInst.x = 45;
        PlayerInst.y = 51;
        addChild(PlayerInst);

        sword = new Sword();
        sword.x = 53;
        sword.y = 90;
        sword.rotationZ = -150;
        sword.rotationY = 25;
        sword.rotationX = -15;
        from_point = new Point (Main.sword.width, Main.sword.height);
        to_point = sword.localToGlobal(from_point);
        addChild(sword);
        swordBD = new BitmapData(32, 32, true, 0x0000000000);
        swordBD.draw(sword);

        Coll_Point = new coll_point();
        Coll_PointBD = new BitmapData(2, 2, true, 0x0000000000);
        Coll_PointBD.draw(Coll_Point);
    }
}

这就是Main的样子,并且每个单独的对象实例化都以这种方式添加到舞台上。包括碰撞点,背景,角色,视线半径的渐变填充等。相关的符号类有点像这样:

public class Creature extends MovieClip 
{
    protected var Swing:Boolean;
    private var SwingTimer:Timer = new Timer (5, 0);
    private var SwingBckTimer:Timer = new Timer (150, 1);
// Constructor.
    public function Creature()
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    // Initializer.
    private function init(event:Event = null):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);

        SwingTimer.addEventListener(TimerEvent.TIMER, SwingTime);
        SwingBckTimer.addEventListener(TimerEvent.TIMER, SwingBack);
    }
private function SwingAction():void
    {
        if (Swing == true)
        {
            SwingTimer.start();
        }
    }

    private function SwingTime(event:Event):void
    {
        Main.Coll_Point.x = Main.sword.localToGlobal(Main.from_point).x;
        Main.Coll_Point.y = Main.sword.localToGlobal(Main.from_point).y;
        Main.sword.addChild(Main.Coll_Point);
        trace(Main.Coll_Point.x);
        trace(Main.Coll_Point.y);

        if (Main.sword.rotationZ > -330)
        Main.sword.rotationZ -= 20;

        if (Main.sword.rotationX < 15)
        Main.sword.rotationX += 10;

        if ((Main.sword.rotationZ == -330) && (Main.sword.rotationX == 15))
        {
            SwingTimer.stop();
            SwingBckTimer.start();
        }
    }

    private function SwingBack(event:Event):void
    {
        Main.sword.rotationZ = -150;
        Main.sword.rotationX = -15;
        //Main.MazeNr1.removeChild(Main.Coll_Point);
    }

还有一个相当长的更新();动画和移动每个需要移动的对象的函数。

2 个答案:

答案 0 :(得分:1)

我认为你的问题可能在

    Main.Coll_Point.x = Main.sword.x + Main.sword.width;
    Main.Coll_Point.y = Main.sword.y + Main.sword.height;

Coll_Point需要全局坐标。

部件+ Main.sword.width+ Main.sword.height仅在未旋转剑的情况下按预期工作,以使高度与y轴对齐,宽度与x轴对齐。

您应该在Main.sword的本地位置使用localToGlobal()Main.sword.width, Main.sword.height)在您将其作为孩子添加之前获取代表剑旋转尖端的全球位置。



有两种方法可以解决这个问题(你似乎有点合并)。你可以


  • 将Coll_Point作为子级添加到层次结构中的剑之上(Stage,MazeNr1,...)并在每个计时器回调时手动更新位置。你必须每次重新计算位置,所以从localToGlobal()从init到你的计时器功能。如果没有被调用,它将不会更新。

为此你应该在计时器回调中使用这种代码:

var local:Point = new Point(Main.sword.width, Main.sword.height);
var global:Point = Main.sword.localToGlobal(local);
Main.Coll_Point.x = global.x;
Main.Coll_Point.y = global.y;



  • 将小点作为小孩添加到剑中。这可能是一种更好的方法,因为这个位置会自动更新。之前我不记得的是你然后在&#34; local&#34;中给出了坐标。表格,所以不要使用localToGlobal()

在创建Collision_Point

的位置运行此操作
Coll_Point.x = <your x offset>;
Coll_Point.y = <your y offset>;
Main.sword.attachChild(Coll_Point);

您可能想要尝试heightwidth之类的内容而不是剑-heightwidth/2



这是一个快速(而不是最漂亮)的图片来演示这个问题。使用对象旋转局部空间:

enter image description here

答案 1 :(得分:1)

我能想象到的唯一可以解决这个问题的方法就是让你的碰撞对象与剑具有相同的注册点。我的意思是定向点应该匹配,并且碰撞图形应该在精灵的里面移动,以便它匹配剑顶部的位置。

这样,您可以将碰撞对象放在剑的同一位置并应用相同的旋转。这样它就会随着剑的顶部一起移动,仍然可以使hitTest正常工作。

我无法想象任何其他方式来解决这个问题,因为任何代码都会得到界限和位置。但真正重要的是注册点和剑的顶部,这是一个图形化的东西,无法处理编码。

我希望你能想象我的意思 - 如果现在,只说,我会为你提供一个图像:)