1

I want to create a stacking Game. Where when you tap the screen for instance a block falls down and a new one appears where the other one originally was. Now when the User taps the screen again the same block falls down and if aligned correctly stacks on top of the first one so one and so one. Keep stacking until you miss.

I thought creating an array and pushing each new object to that array would be able to hitTest between each new one etc and have them stack on each other. I realized I don't quite understand how to go about doing this. New instances are created so I got that down. Here is my code so far:

private function engineLogic(e:Event):void 
    {
        stackingHandler();
    }
    
    private function stackingHandler():void 
    {
        for (var i:int = 0; i < aCatArray.length; i++)
        {
            var currentCat:mcCats = aCatArray[i];
            
            //HIT TEST CATS 
            
        }
        trace("NUMBER OF CATS: " + aCatArray.length);
    }
    
    private function onTap(e:MouseEvent):void 
    {
        //Move Down 
        TweenLite.to(cats, 1.0, {y:(stage.stageHeight / 2) + 290, onComplete: addCats}); 
    }
    
    private function addCats():void 
    {
        //Create Instance
        cats = new mcCats();
        //Add Objects
        addChild(cats);
        //Push to Array
        aCatArray.push(cats);
        
    }

I would appreciate any help from you guys. Maybe if you can push me in the right direction. Thank you in advance!

Nathan
  • 536
  • 4
  • 21
  • Why don't you use 2D physics? Like^ http://box2dflash.sourceforge.net/ – Organis Aug 25 '20 at 08:23
  • Hey @Organis I never used 2D Physics. Ill check out it's documentation. However, in this game there wouldn't be any Physics really. Just linear falling that I created using tween to make it smoother. It doesn't matter if the boxes stack and seem like they will lean over because that wouldn't effect the boxes or make them fall. As long as they touch then they will stack. – Nathan Aug 25 '20 at 15:49
  • 1
    @Nathan if still failing to work, you could avoid doing a Hit Test by instead using a `Bitmap` or double `Array`. If Bitmap then you create one with pixel width of total boxes (side by side) and a height from total box stack amount (_eg:_ 10 boxes wide and 7 boxes max height means a 10W _x_ 7H bitmap. The idea is that you mark a taken spot in the bitmap (set pixel color) and avoid hit test by simply checking if pixel has value larger than zero. – VC.One Aug 28 '20 at 21:35
  • Thanks VC I never even thought of doing it that way haha – Nathan Aug 31 '20 at 18:02

2 Answers2

1

It looks like the cats variable holds the object that is currently falling?
In that case you'd do something like this:

private function stackingHandler():void 
{
    for (var i:int = 0; i < aCatArray.length; i++)
    {
        if(cats.hitTestObject(aCatArray[i])) {
            // collision detected!
            // kill the Tween
            // set the y position of the `cats` object 
            // so it appears on top of the object it collided with (`aCatArray[i]`)
            // (it may have moved slightly past the object before doing this check)
        }            
    }
}

So you're looping through the array and hit testing cats against every object in the array one at a time.

It might make more sense to use a basic gravity simulation, or just linearly increasing the y value instead of using a Tween, but you didn't ask about that.

You might also want to set a flag for whether or not an object is currently falling and use that to determine whether or not to run the stackingHandler. Otherwise, you'll just be continually hit testing all the objects when nothing is moving.

Cadin
  • 4,275
  • 1
  • 14
  • 22
  • This actually makes a lot of sense. Ill test it when I get the chance but looks exactly like what I was trying to accomplish. I had semi figured it out earlier I created a double for loop and created two separate variables of the same class. This is much cleaner thanks a lot. Gotcha create a boolean to flag when the hit test occurs correct? – Nathan Aug 27 '20 at 03:07
  • Yeah, a double loop would let you test *every* object against every other object. That's probably what you'd do if you were running a full physics simulation, but in your case where only one object is moving it's overkill. – Cadin Aug 28 '20 at 16:13
  • I tried your method and used a Flag as well but it still seemed to hit test even if only one instance of the object was on the field the only way I got it to work was to create a double for loop. Ill Post how I ended up doing it. – Nathan Aug 29 '20 at 04:27
1

This is how I was able to fix it. Creating a double for loop. Checking if they are equal to each other continue and check for hitTest:

private function stackingHandler():void 
{
    for (var i:int = 0; i < aCatArray.length; i++)
    {
        var currentCat:mcCats = aCatArray[i];
        
        for (var j:int = 0; j < aCatArray.length; j++)
        {
            var newCat:mcCats = aCatArray[j];
            
            if (currentCat == newCat) continue;
            
            //Hit Test between Objects
            if (newCat.hitTestObject(currentCat.mcHit) && newCat.bFlag == false)
            {
                //Stop Moving
                newCat.stopMoving();
                trace("HIT");
                
                if (highScore == 0)
                {
                    addCats();
                    trace("ADD CATS 1");
                }else
                {
                    TweenLite.delayedCall(0.6, addCats);
                    trace("ADD CATS 2");
                }
                
                //Add Points
                highScore ++;
                trace(highScore + " Score");
                //Set Flag boolean
                newCat.bFlag = true
            }
        
        }
        
    }

}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Nathan
  • 536
  • 4
  • 21