AS3阵列平铺引擎

时间:2015-05-12 18:43:27

标签: arrays actionscript-3 flash

我一直在处理工作的瓷砖地图,并根据数组中的相关数字在屏幕上显示瓷砖。

Tile 0代表Grass,1代表水,2代表硬币。当用户点击我需要的硬币磁贴时,它会打开一个菜单,用户可以点击按钮来“购买硬币”。来自瓷砖。

    var myMap: Array = [
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
    ];


    for (var i: int = 0; i < mapHeight; i++) {
        for (var u: int = 0; u < mapWidth; u++) {
            var tile: MovieClip = new Tile();
            tile.gotoAndStop(myMap[i][u] + 1);
            tile.x = tileSize * u
            tile.y = tileSize * i
            tile.theIDi = i;
            tile.theIDu = u;
            tile.buttonMode = true;


            addChildAt(tile, 0);
            tile.addEventListener(MouseEvent.CLICK, clickTile);

        }
    }

    function clickTile(event: MouseEvent) {
         positionX = event.currentTarget.theIDu;
         positionY = event.currentTarget.theIDi;

         if(myMap[positionX][positionY] == 2) {
             openGoldMenu(positionX, positionY);                    
         }
    }

    function openGoldMenu() {
         takeCoinsMenu.x = 100;
         takeCoinsMenu.y = 200;
         buttonTake.addEventListener(MouseEvent.CLICK, takeCoins);
    }

    function takeCoins(event: MouseEvent) {
         myStats[0].gold = myStats[0].gold + 10;

         WHAT TO WRITE HERE? HOW CAN I ACCESS THE CURRENT TILE THAT WAS CLICKED WITH THE GOLD COIN ON? URGH CONFUSED!
     }

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点,但最简单的可能是:

  1. 创建一个变量(确保它在任何方法之外声明,因此在你的myMap var旁边会很好)存储最后一个被点击的图块

    var clickedTile:Tile;
    var myMap:Array = [.......
    
  2. clickTile函数中,填充该变量:

    function clickTile(event: MouseEvent) {
        clickedTile = event.currentTarget as Tile;
    
        var positionX:int = clickedTile.theIDu;
        var positionY:int = clickedTile.theIDi;
    
        if(myMap[positionX][positionY] == 2) {
            openGoldMenu(positionX, positionY);                    
        }
    }
    
  3. 现在,在您的takeCoins方法中,您可以引用clickedTile中存储的磁贴。

答案 1 :(得分:0)

noticed your question has already been answered but I wanted to offer an additional tip I wish I had known long ago.

it looks like all your tiles are the same size, if this is the case then don't add a click event to all the individual tiles, just add one to the tile container, which in this case is the clip using this class and then determine which tile you clicked based on the mouse position like so...

=ARRAYFORMULA(IFERROR(REGEXEXTRACT("."&A2:A;
    "^"&REPT("\.[^.]*";COLUMN(OFFSET(A2;;;1;4))-1)&"\.([^.]*)")))

This way you only need to set one event listener and this will be quicker and easier to manager later on when you need to disable it, you can also lose the need to set the theIDi and theIDu variables in the tiles unless you need them later.

Also I would say don't use iId or uId, use xId and yId or xIndex and yIndex, makes more sense when working with a 2d array and is easier to follow later, you can also use something similar as your loop variables just to keep things simple.

addEventListener(MouseEvent.CLICK, clickEventHandler);

private function clickEventHandler(e:MouseEvent):void
{
var uId:int = Math.floor((mouseX - this.x) / tileSize);
var iId:int = Math.floor((mouseY - this.y) / tileSize);

if(myMap[uId][iId] == 2)
{
openGoldMenu(uId,iId);
}
}

Would also be a good idea to store the different tiles in their own 2d array rather then create them and just add them to the stage, this will make it easier to remove/update individual tiles when you come to moving your tiles around because you can just remove a single row or column from the stage because you still have the references rather then looping through all the tiles and checking their ids.

for(var yIndex:int = 0; yIndex < map.length ; xIndex++)
for(var xIndex:int = 0; xIndex < map[yIndex].length ; yIndex++)

then when you want to remove a tile simply call.

var tileArray:Array = new Array();

for(var yIndex:int = 0; yIndex < map.length; yIndex++)
{
if(tileArray[yIndex] == null) tileArray[yIndex] = new Array();
for(var xIndex:int = 0; xIndex < map[yIndex].length; xIndex++)
{
tileArray[yIndex][xIndex] = new Tile();
tileArray[yIndex][xIndex].x = xIndex * tileSize;
tileArray[yIndex][xIndex].y = yIndex * tileSize;
addChild(tileArray[yIndex][xIndex]);
}
}

this also remove the need for the uId and iId because there position in that array is there id.

Hope this helps :)