Setting properties on a single sprite in a FlxTypedGroup

77 views
Skip to first unread message

Qopzeep

unread,
Apr 7, 2015, 7:46:13 AM4/7/15
to haxef...@googlegroups.com


Hi all,

New to HaxeFlixel and game making in general, although I have coding experience in different fields. I'm really enjoying the experience :)! So far I've been able to figure everything out myself or via an internet search, but now I'm really stumped.

Idea: a player can dig a patch of land in my top-down game. When a player digs a second patch next to the first one, I want to update both patches so their sprites 'add up' neatly (visually, I mean). I've created a spritesheet containing 13 different 32x32 patches of land, like so*:

Everytime a patch is dug, all the existing patches need to be checked, and those bordering other patches need to be adjusted accordingly.

Firstly, I made a new FlxSprite class called DirtPatch that has the loadGraphic and the animations in it. Every tile has it's own 1-frame animation. Probably not the best way to do things, but I'm working with what I know.

In my game, a player can press 'C' dig a patch of land. 'C' calls digPatch(), which pushes a new DirtPatch into a FlxTypedGroup called dirtPatch. At the end of digPatch, a for loop goes through the FlxTypedGroup to determine the position of the new patch relative to the other patches. Then, I need a way to tell each member of the group to update it's animation. I've tried to this by adding a public static var called _dirtPatchTouching:Int; to the DirtPatch class, and varying the animation based on its value. However, when I change the _dirtPatchTouching value to something else, every patch changes into the same one. I guess this isn't surprising, but I can't figure out how to set a value for one specific member of the group, instead of all of them globally. I know I can set stuff like dirtPatch.members[i].x etc., but I can't seem to acces the DirtPatch class from the group. How would I get the animation the be the correct one?

If it helps, I've added the code at the end.

Thanks!
Qopzeep

* As I'm typing this, I realise I need two additional tiles, for long, one tile high patches.

package ;

import flixel.FlxSprite;

/**
 * ...
 * @author ...
 */

class DirtPatch extends FlxSprite
{
   
static public var _dirtPatchTouching:Int;    
   
   
public function new(X:Float=0, Y:Float=0)
   
{
       
super(X, Y);
       
        loadGraphic
("assets/images/Dirt.png", true, 32, 32);
       
        immovable
= true;
       
       
//Each patch has a 1 fram 'animation', e.g. patchRD = a patch with 'open' sides on the right and bottom (=down)
        animation
.add("patch", [0], 1, false);
        animation
.add("patchR", [1], 1, false);
        animation
.add("patchL", [2], 1, false);
        animation
.add("patchD", [3], 1, false);
        animation
.add("patchU", [4], 1, false);
        animation
.add("patchRD", [5], 1, false);
        animation
.add("patchLRD", [6], 1, false);
        animation
.add("patchLD", [7], 1, false);
        animation
.add("patchRUD", [8], 1, false);
        animation
.add("patchALL", [9], 1, false);
        animation
.add("patchLUD", [10], 1, false);
        animation
.add("patchRU", [11], 1, false);
        animation
.add("patchLRU", [12], 1, false);
        animation
.add("patchLU", [13], 1, false);
       
   
}
   
   
override public function update():Void
   
{
       
switch (_dirtPatchTouching) {
           
case 0:    animation.play("patch");
           
case 1:    animation.play("patchR");
           
case 2:    animation.play("patchL");
           
case 3: animation.play("patchD");
           
case 4:    animation.play("patchU");
           
case 5:    animation.play("patchRD");
           
case 6:    animation.play("patchLRD");
           
case 7:    animation.play("patchLD");
           
case 8:    animation.play("patchRUD");
           
case 9:    animation.play("patchALL");
           
case 10: animation.play("patchLUD");
           
case 11: animation.play("patchRU");
           
case 12: animation.play("patchLRU");
           
case 13: animation.play("patchLU");
       
}
       
super.update();
   
}
   
}

Part of Playstate:
public function digPatch()
   
{                
       
var _dX:Int = 0;
       
var _dY:Int = 0;
       
var _upCheck:Bool = false;
       
var _rightCheck:Bool = false;
       
var _downCheck:Bool = false;
       
var _leftCheck:Bool = false;
       
       
//The player can dig a new patch to the left, right, up or down. The placing is calculated for 32x32 tiles. Feetlocation are the coords of the player's feet, instead of the top left corner of the sprite. This makes playing more intuitive.
       
if (player.facing == FlxObject.LEFT) {
            dirtPatch
.add(new DirtPatch(Math.floor((feetLocation.x - 32) / TILE_WIDTH) * TILE_WIDTH, Math.floor((feetLocation.y) / TILE_HEIGHT) * TILE_HEIGHT));
            _dX
= Math.floor((feetLocation.x - 32) / TILE_WIDTH) * TILE_WIDTH;
            _dY
= Math.floor((feetLocation.y) / TILE_HEIGHT) * TILE_HEIGHT;
       
} else if (player.facing == FlxObject.RIGHT) {
            dirtPatch
.add(new DirtPatch(Math.floor((feetLocation.x + 32) / TILE_WIDTH) * TILE_WIDTH, Math.floor((feetLocation.y) / TILE_HEIGHT) * TILE_HEIGHT));
            _dX
= Math.floor((feetLocation.x + 32) / TILE_WIDTH) * TILE_WIDTH;
            _dY
= Math.floor((feetLocation.y) / TILE_HEIGHT) * TILE_HEIGHT;
       
} else if (player.facing == FlxObject.UP) {
            dirtPatch
.add(new DirtPatch(Math.floor((feetLocation.x) / TILE_WIDTH) * TILE_WIDTH, Math.floor((feetLocation.y - 32) / TILE_HEIGHT) * TILE_HEIGHT));
            _dX
= Math.floor((feetLocation.x) / TILE_WIDTH) * TILE_WIDTH;
            _dY
= Math.floor((feetLocation.y - 32) / TILE_HEIGHT) * TILE_HEIGHT;
       
} else if (player.facing == FlxObject.DOWN) {
            dirtPatch
.add(new DirtPatch(Math.floor((feetLocation.x) / TILE_WIDTH) * TILE_WIDTH, Math.floor((feetLocation.y + 32) / TILE_HEIGHT) * TILE_HEIGHT));
            _dX
= Math.floor((feetLocation.x) / TILE_WIDTH) * TILE_WIDTH;
            _dY
= Math.floor((feetLocation.y + 32) / TILE_HEIGHT) * TILE_HEIGHT;
       
}

       
//  Outside the function there is a bar that counts the time until the patch is dug. It disappears when finished.    
        digBar
.kill();

     
       
var count:Int = 0;
       
for (count in 0...dirtPatch.members.length) {
           
if (dirtPatch.members[count].exists && dirtPatch.members[count].active) {
               
if (_dX == dirtPatch.members[count].x && _dY == (dirtPatch.members[count].y + TILE_HEIGHT)) {
                    _upCheck
= true;
               
} else if (_dX == (dirtPatch.members[count].x - 32) && _dY == dirtPatch.members[count].y) {
                    _rightCheck
= true;
               
} else if (_dX == dirtPatch.members[count].x && _dY == (dirtPatch.members[count].y - 32)) {
                    _downCheck
= true;
               
} else if (_dX == (dirtPatch.members[count].x + 32) && _dY == dirtPatch.members[count].y) {
                    _leftCheck
= true;
               
}
           
}    
       
}
       
       
if (_upCheck == false && _rightCheck == false && _downCheck == false && _leftCheck == false) { DirtPatch._dirtPatchTouching = 0; }
       
if (_upCheck == true && _rightCheck ==  true && _downCheck ==  true && _leftCheck == true) { DirtPatch._dirtPatchTouching = 12; }
       
       
if (_upCheck == false && _rightCheck == true && _downCheck == false && _leftCheck == false) { DirtPatch._dirtPatchTouching = 1; }
       
if (_upCheck == false && _rightCheck == false && _downCheck == false && _leftCheck == true) { DirtPatch._dirtPatchTouching = 2; }
       
if (_upCheck == false && _rightCheck == false && _downCheck == true && _leftCheck == false) { DirtPatch._dirtPatchTouching = 3; }
       
if (_upCheck == true && _rightCheck == false && _downCheck == false && _leftCheck == false) { DirtPatch._dirtPatchTouching = 4; }
       
if (_upCheck == false && _rightCheck == true && _downCheck == true && _leftCheck == false) { DirtPatch._dirtPatchTouching = 5; }
       
if (_upCheck == false && _rightCheck == true && _downCheck == true && _leftCheck == true) { DirtPatch._dirtPatchTouching = 6; }
       
if (_upCheck == false && _rightCheck == false && _downCheck == true && _leftCheck == true) { DirtPatch._dirtPatchTouching = 7; }
       
if (_upCheck == true && _rightCheck == true && _downCheck == true && _leftCheck == false) { DirtPatch._dirtPatchTouching = 11; }
       
if (_upCheck == true && _rightCheck == false && _downCheck == true && _leftCheck == true) { DirtPatch._dirtPatchTouching = 13; }
       
if (_upCheck == true && _rightCheck == true && _downCheck == false && _leftCheck == false) { DirtPatch._dirtPatchTouching = 8; }
       
if (_upCheck == true && _rightCheck == true && _downCheck == false && _leftCheck == true) { DirtPatch._dirtPatchTouching = 9; }
       
if (_upCheck == true && _rightCheck == false && _downCheck == false && _leftCheck == true) { DirtPatch._dirtPatchTouching = 10; }
       
     

   
}


Gama11

unread,
Apr 8, 2015, 3:14:57 AM4/8/15
to haxef...@googlegroups.com
You definitely don't need an animation for a single frame, just set sprite.animation.frameIndex directly.

Have you considered using a FlxTilemap instead of a group of sprites? The auto-tiling there might help (see in this demo), though maybe it not's flexible enough for what you want to do.

Btw, since in Haxe everything is an expression, meaning everything, including a switch-case, has a return-value, your DirtPatch::update() can be written a lot more nicely / with less redundancy:

animation.play(switch (type) {
    case 0: "patch";
    case 1: "patchR";
    case 2: "patchL";
    case 3: "patchD";
    case 4: "patchU";
    case 5: "patchRD";
    case 6: "patchLRD";
    case 7: "patchLD";
    case 8: "patchRUD";
    case 9: "patchALL";
    case 10: "patchLUD";
    case 11: "patchRU";
    case 12: "patchLRU";
    case 13: "patchLU";
    default: "patch";
});

Qopzeep

unread,
Apr 10, 2015, 12:42:36 PM4/10/15
to haxef...@googlegroups.com
Hi Gama11,

Thanks for your help, this was *exactly* what I was looking for :). I glanced over that demo's code before, but I recall being a stubborn dick and trying it "my way". After 20 minutes of tweaking, it's working like a charm.

Also thanks for the feedback on code optimisation. I haven't given that much attention yet, but these tips are very welcome.

Learning something new about haxeflixel every day!

Qopzeep
...
Reply all
Reply to author
Forward
0 new messages