正确地悬停在等距瓷砖精灵上

时间:2015-07-06 14:28:12

标签: actionscript-3 events isometric

我有四个课程:Room,TileGrid,HoverTile和Tile。

房间由墙壁和TileGrid组成。 TileGrid由Tile制成。目前,我使用此代码从Tiles生成TileGrid:

    this.mapArray = [[1,1,1,1,1,1,1],
                         [1,1,1,1,1,1,1],
                         [1,1,1,1,1,1,1],
                         [1,1,1,1,1,1,1],
                         [1,1,1,1,1,1,1],
                         [1,1,1,1,1,1,1],
                         [1, 1, 1, 1, 1, 1, 1]];

        this._mapHeight = this.mapArray.length;
        this._mapWidth = this.mapArray[0].length;
        this._tileHeight = 23;
        this._tileWidth = 46;

        var initialX:Number = 260;
        var initialY:Number = 150;

        for (var isoY:int = 0; isoY < mapArray.length; isoY++)
        {
            for (var isoX:int = 0; isoX < mapArray[isoY].length; isoX++)
            {
                if (isoX == 0 && isoY == 0)
                {
                    var _tile:Tile = new Tile();
                    _tile.x = initialX;
                    _tile.y = initialY;
                    this.addChild(_tile);
                }

                if (this.mapArray[isoY][isoX] == 1)
                {
                    var _tile:Tile = new Tile();
                    _tile.x = initialX - (isoX * 20) - (isoY * 20);
                    _tile.y = initialY - (isoX * 10) + (isoY * 10);
                    addChild(_tile);

                    _tile.addEventListener(MouseEvent.MOUSE_OVER, updateHover);
                }
            }
        }

我目前的问题是,我想在鼠标悬停在其上的瓷砖周围添加一个白色方块。我以前使用的代码是不够的,因为Tile sprite的透明部分仍被计为其中的一部分。因此,即使我指向另一个Tile2(它位于Tile1旁边),例如,如果我对Tile2还不够远,它会突出显示Tile1。

所以,这是我正在使用的当前代码:

    public function updateHover(e:MouseEvent):void
    {
        var mX:int = e.stageX - (_tileWidth / 2);
        var tPoint:Point = pointToXY(mX, e.stageY);

        var isoX = tPoint.x;
        var isoY = tPoint.y;

        if (isoX >= 0 && isoY >= 0)
        {
            if (isoY < mapArray.length)
            {
                if (isoX < mapArray[0].length)
                {
                    tPoint = xyToPoint(isoX, isoY);
                    _tileHover.x = tPoint.x;
                    _tileHover.y = tPoint.y;
                    _tileHover.visible = true;
                    return;
                }
            }
        }

        _tileHover.visible = false;
    }

    public function pointToXY(x:int, y:int):Point
    {
        x -= 260;
        y -= 150;

        var pRatio:int = (_tileWidth / 2) / (_tileHeight / 2);
        var tX:int = (y + x / pRatio) * (pRatio / 2) / (_tileWidth / 2);
        var tY:int = (y - x / pRatio) * (pRatio / 2) / (_tileWidth / 2);

        return new Point(tX, tY);
    }

    public function xyToPoint(x:int, y:int):Point
    {
        x -= 1;

        var worldPoint:Point = new Point(0, 0);
        worldPoint.x = (x * (_tileWidth / 2)) - (y * (_tileWidth / 2));
        worldPoint.y = (x * (_tileHeight / 2)) + (y * (_tileHeight / 2));
        worldPoint.x = worldPoint.x + (_tileWidth / 2);
        worldPoint.y = worldPoint.y + (_tileHeight / 2);
        worldPoint.x += 260;
        worldPoint.y += 150;

        return worldPoint;
    }

抱歉,我必须发布这么多代码块。现在,260和150是整个房间的默认起点。也就是说,我真的很困惑如何让最后两个功能特别有效,以便他们给我正确的答案。这是我使用此代码所期望的:

enter image description here

那将是完美的。但是,我不知道为什么代码不起作用。尺寸都是正确的,我相信偏移量也是正确的。所以,我是

1 个答案:

答案 0 :(得分:1)

首先,你应该将监听器添加到this,而不是_tile,因为那时你被锁定到舞台坐标以确定所选的磁贴,这是不好的。其次,你的听众应该反对MouseEvent.MOUSE_MOVE事件,而不是结束,这样你就会不断获得更新的鼠标坐标,以便将你的矩形正确移动到瓷砖上。你有一个小错误,你有一个(0,0)瓷砖创建两次,一个是不活动的。

    for (var isoY:int = 0; isoY < mapArray.length; isoY++)
    {
        for (var isoX:int = 0; isoX < mapArray[isoY].length; isoX++)
        {
            if (this.mapArray[isoY][isoX] == 1)
            {
                var _tile:Tile = new Tile();
                _tile.x = initialX - (isoX * 20) - (isoY * 20);
                _tile.y = initialY - (isoX * 10) + (isoY * 10);
                addChild(_tile);
            }
        }
    }
    this.addEventListener(MouseEvent.MOUSE_MOVE, updateHover);

此外,你最好在数组上存储(x,y)对(最有可能是tile),这样你的初始0和1数组就会转换为{{1对象。要做到这一点,首先要这样做:

Tile

这将创建一个与您的this.tileArray=[]; for (var i:int=0;i<this.mapArray.length;i++) this.tileArray.push(new Array(this.mapArray[i].length)); 维度相匹配的空数组,这些空格将用作已创建的mapArray对象的占位符。执行此操作后,您可以调用Tile将新创建的磁贴放置到其位置。之后,您可以将您的监听器重写为:

this.tileArray[isoY][isoX]=_tile;