Home > Flixel, Programming, Weekend Tower Defense > Moving Groups of FlxSprites

Moving Groups of FlxSprites

Now we’re getting somewhere. I’ve got enemy and tower status menus working. This is about as much as I had before switching to Flixel, so from here on out it’s real progress again. Here’s a video of the current game.

The status menus were a real challenge. In regular AS3, I would just add bunch of different objects to a sprite, and those objects would all move with the sprite. You can’t add objects onto a FlxSprite like a regular AS3 sprite. I thought that maybe I could create a FlxGroup and add all my objects to that and they would all move together, but I was wrong.

Fortunately, FlxGroups were the right way to head. You can iterate over all objects added to a FlxGroup. If you create a baseline FlxSprite that will function as your upper-left corner, you can move that object and then move all the objects in your FlxGroup in relation to that sprite. Here’s the code I used to move my StatusWindow group around:

public function move(point:FlxPoint):void {
    var startPointX:int = this.bgSprite.x;
    var startPointY:int = this.bgSprite.y;

    for (var i:int = 0; i < this.length; i++) {
        this.members[i].x = point.x - startPointX + this.members[i].x;
        this.members[i].y = point.y - startPointY + this.members[i].y;
    }

    this.upgradeButton.label.x = this.upgradeButton.x;
    this.upgradeButton.label.y = this.upgradeButton.y + 3;
}

Interesting note about that, FlxButtons can be moved using their x and y, but for some reason, the labels don’t move with them and have to be moved separately.

This worked perfectly to move the window to based on a FlxPoint. In order to get the window to follow an enemy as it moves, I had to add a target variable within the StatusWindow class. This tells the window which object to follow around the screen. Unfortunately, x and y coordinates are Numbers (AS3 version of a Float) and they get rounded to an int before being drawn. For some reason, this can cause stuttering when you’re telling one object to follow another. To fix this, I round the x and y coordinates of the followed object before telling StatusWindow to follow it. Here’s the code for that:

public function findBestLocation():FlxPoint {
    return new FlxPoint(Math.round(this.target.x - 50), Math.round(this.target.y - 70));
}

This function will later be used to keep the window on the screen, without flowing onto the menus or off the edge of the screen. For now, it just offsets the location of the target object.

Oh, and I almost forgot that I added win and loss conditions to the level. You can see at the end of the video that a little text appears. It says, “You win!!! Press enter to return to menu.” That’ll have to get changed at some point, but it works. There’s also a loss condition when your invisible health drops to 0 that also directs you to return to the menu. They both switch a gameIsOver Bool to true in my PlayState. This causes the game to skip the update loop and instead checks to see if the user is pressing enter to return to the menu. Here’s the top of the PlayState’s update code now:

override public function update():void
{
    if (gameIsOver) {
        if (FlxG.keys.justPressed("ENTER") ||
                FlxG.keys.justPressed("P")) {
            FlxG.switchState(new MenuState());
        }
    }
    else {
        for (var i:int = 0; i < gameSpeed; i++) {
            super.update();
        }
	
        this.runNonGameUpdates();

I’ll be adding the rest of the stats to the bottom menu, along with actual buttons to press to change game speed. Then I think I’ll export my tower stats to a csv file or something and make the game import the stats. That will make it easier to balance the game later. While setting that up, I’m going to add an ability to declare several levels for each tower so they can be upgraded.

  1. No comments yet.
  1. No trackbacks yet.