在网格中自上而下填充开放空间

时间:2012-08-29 22:43:05

标签: actionscript-3 grid match

我正在编写一个匹配三引擎,我成功创建匹配使用巨大的循环来查找匹配的项目。关于如何用项目填充空白空间(下降到空白空间)和创建新项目而没有过多循环和if语句的任何想法?

到目前为止,这是我的相关代码。

public var rows:uint = 8;
public var cols:uint = 7;
public var cell:Array = new Array();
public var plot:Array = new Array();

public var height:int;
public var width:int;

public var relativePositions:Array = [{name:'top', position:-1}, {name:'bottom', position:1}, {name:'left', position:rows*-1}, {name:'right', position:rows*1}];
public var dictionary:Dictionary = new Dictionary();
public var matches:Array = new Array();

public function createGrid(target:*, displayObject:*, spacer:int) : void {

        var iterator:uint = 0;
        for(var c:uint = 0;c<cols;c++){ 
            for(var r:uint = 0;r<rows;r++){                                         
                cell[iterator] = createGamePiece();
                Sprite(cell[iterator]).name = String(iterator);
                Sprite(cell[iterator]).addEventListener(MouseEvent.CLICK, _handleGamePiece_CLICK);
                Sprite(cell[iterator]).addEventListener(MouseEvent.MOUSE_OVER, _handleGamePiece_MOUSE_OVER);
                Sprite(cell[iterator]).addEventListener(MouseEvent.MOUSE_OUT, _handleGamePiece_MOUSE_OUT);
                cell[iterator].y = cell[iterator].height  * r + (spacer*r);
                cell[iterator].x = cell[iterator].width * c + (spacer*c);
                GamePiece(cell[iterator]).positionX = cell[iterator].x;
                GamePiece(cell[iterator]).positionY = cell[iterator].y;
                GamePiece(cell[iterator]).positionRow = r;
                GamePiece(cell[iterator]).positionCol = c;
                target.addChild(cell[iterator]);
                dictionary[String(iterator)] = cell[iterator]
                iterator++
            }
        } 

    }

public function findRelativeMatches(targetSprite:Sprite) : void {

        targetSprite.alpha = .5;
        var rootPosition:Number = Number(targetSprite.name);

        for ( var i:int = 0; i < relativePositions.length; i ++ ) {
            var key:String = String(rootPosition + relativePositions[i].position);
            // to do >> Not hardcoded to 'Pig'
            if (findSprite(key) != null && GamePiece(targetSprite).color == GamePiece(findSprite(key)).color && GamePiece(findSprite(key)).found == false) {
                var sprite:Sprite = findSprite(key);
                sprite.alpha = .5;
                GamePiece(sprite).found = true;
                matches.push(sprite);
                findRelativeMatches(sprite);
            };
        };

        targetSprite.addEventListener(MouseEvent.MOUSE_OUT, function() : void {
            if ( matches.length != 0 ) {
                for ( var j:int = 0 ; j < matches.length ; j++ ) {
                    Sprite(matches[j]).alpha = 1;
                    GamePiece(matches[j]).found = false;
                }
                matches.splice(0);
            }
        });
    }

public function findSprite(key:String) : Sprite {
        var sprite:Sprite;
        dictionary[key] != undefined ? sprite = dictionary[key] : null;
        return sprite;
    }

protected function _handleGamePiece_CLICK(event:MouseEvent):void
    {
        for ( var j:int = 0 ; j < matches.length ; j++ ) {
            var sprite:Sprite = matches[j];
            view.removeChild(matches[j]);

        }

        matches.splice(0);
    }
public function createGamePiece() : Sprite {
        var gamePiece:GamePiece = new GamePiece();
        return gamePiece;
    }

2 个答案:

答案 0 :(得分:0)

你想要向下折叠你的网格,对吧?常见算法从每行的底部向上,找到第一个空白空间的一个索引,另一个用于空白空间上方的第一个占用空间,然后在找到后交换这些值,迭代到顶部。但是你不能以任何可访问的形式存储网格!你应该创建一个网格对象,比如一个精灵向量的向量,并在你移动棋子时在其中指定值。像这样:

var GRID:Vector.<Vector.<Sprite>>; // this should be allocated at createGrid
// populate GRID with your sprites once generated:
// put the following into your inner loop in CreateGrid:
GRID[r][c]=cell[iterator];

// and the following into your removal of matches[] sprites:
GRID[GamePiece(sprite).positionRow][GamePiece(sprite).positionCol]=null; // release link from GRID

// now to move grid objects:
function DropAll():void {
    var i:int;
    var j:int;
    for (i=GRID.length-1;i>=0;i--) {
        var lastEmpty:int=-1;
        for (j=GRID[i].length-1;j>=0;j--) {
            if (GRID[i][j]) {
                if (lastEmpty>0) {
                    GRID[i][lastEmpty--]=GRID[i][j];
                    // relocate your sprite properly here
                    GRID[i][j]=null;
                } // else we're still at full part of grid, continue
            } else if (lastEmpty<0) lastEmpty=j;
        }
    }
}

要正确实例化GRID,您需要分配填充“null”值的所需长度的向量。此外,“GRID”本身是一个Vector,也需要实例化。

GRID=new Vector.<Vector.<Sprite>>();
for (i=0;i<rows;i++) {
    var a:Vector.<Sprite>=new Vector.<Sprite>(cols);
    GRID.push(a);
}

执行此操作后,您可以直接在其中分配链接来填充GRID,例如GRID[r][c]=gameObject;

答案 1 :(得分:0)

这实际上就是我想要的。一种崩溃的方式,无需迭代整个电路板。这样我就可以遍历已删除的项目。

protected function _handleGamePiece_CLICK(event:MouseEvent):void
    {
        for ( var j:int = 0 ; j < matches.length ; j++ ) {
            var oldSprite:Sprite = matches[j];
            moveAllPiecesDown(oldSprite);
            view.removeChild(oldSprite);
            oldSprite = null;
        }
        matches.splice(0);
    }

private function moveAllPiecesDown(oldSprite:Sprite):void
    {
        var piecesAbove:int = GamePiece(oldSprite).positionRow;
        var index:int = int(oldSprite.name);

        for( var i:int = 0; i < piecesAbove; i ++ ) {
            var spriteAbove:Sprite = Sprite(view.getChildByName(String(index-(1+i))));
            if(spriteAbove) {
                spriteAbove.y = spriteAbove.y + spriteAbove.height + 1;
                spriteAbove.name = String(Number(spriteAbove.name)+1);
                GamePiece(spriteAbove).textField.text = spriteAbove.name;
                delete dictionary[spriteAbove.name];
                dictionary[spriteAbove.name] = spriteAbove;
            }
        }
    }