2012-08-29 85 views
0

我正在编写一个匹配三引擎,并且我成功地使用巨大的循环来创建匹配以查找匹配的项目。有关如何用物品填充空白空间(放入空白空间)并创建新项目而没有过多循环和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; 
    } 

回答

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; 
      } 
     } 
    } 
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您需要分配填充有“空”值所需长度的载体。另外,“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[r][c]=gameObject;

+0

hm - 我想唯一的问题是如何实例化:var GRID:Vector。>; –

+0

我假设它会是这样的:public var GRID:Vector。> =新的Vector。>(rows * cols);但这似乎并不奏效。 –

+0

好吧,我正在写答案的实例代码,假设你知道它在运行时的行和列号。 – Vesper