Author Topic: Mass sprite creation  (Read 1560 times)

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Mass sprite creation
« on: Thu, Feb 24, 2011 »
For my platformer game, I have 48x48 pixel animated water blocks that I want to spread around a level, but I don't want to have to revert to doing:
Code: [Select]
_water.add(new Water(x,y))over and over again.

I had made an auto tiler that fills the background with a repeating 64x64 graphic earlier, and I was trying to rework it to easily place water tiles in the right spots.
The original code was this:
Code: [Select]
var finishedBackground:Boolean = new Boolean(false);
var backgroundTileX:uint = new uint(0);
var backgroundTileY:uint = new uint(0);
while (!finishedBackground)
{
background.add(new FlxSprite(backgroundTileX, backgroundTileY, ImgBackground));

backgroundTileX += 64;
if (backgroundTileX > 980)
{
backgroundTileX = 0;
backgroundTileY += 64;
if (backgroundTileY > 1104)
finishedBackground = true;
}
}
which I reworked to make:
Code: [Select]
var finishedWater:Boolean = new Boolean(false);
var waterTileX:uint = new uint(0);
var waterTileY:uint = new uint(0);
var checkSpot:FlxSprite = new FlxSprite(0, 0);
var waterMap:FlxTilemap = new FlxTilemap()
waterMap.auto = FlxTilemap.ALT;
waterMap.loadMap(FlxTilemap.pngToCSV(ImgMapWater, false, 2), ImgWasteTiles);
add(waterMap);


while (!finishedWater)
{
checkSpot.x = waterTileX;
checkSpot.y = waterTileY;
if(checkSpot.collide(waterMap))
{
FlxG.log("Creating at " + waterTileX + "," + waterTileY);
_water.add(new Water(waterTileX, waterTileY));
}

waterTileX += 48;
if (waterTileX > 980) //Max x value needed for area to be filled
{
waterTileX = 0; //Reset x value
waterTileY += 48; //Move y down 48px on the map
if (waterTileY > 1104) //Max y value needed for area to be filled
finishedWater = true;
}
}

The <waterMap> is from a .png for the level with blocks in the top left corners of where each water tile should be, using just some plain white <imgWasteTiles> so I can see that the map is being placed in the right spot. <checkSpot> moves across the map's x by 48 pixels at a time, then repeats over and over again at a 48 higher y value until it has reached the end of the map.

If I just leave out the check for if the blocks are in the right place and just have
Code: [Select]
_water.add(new Water(waterTileX, waterTileY));it all works fine, only there is water filling the entire area.


How can I get this to only place water in the spots needed?


Also, I'm not sure, but I think that since this is in the create() function of PlayState and not in update(), collision is not working, but that's just a thought. Thanks for any help anybody can give. Please let me know if you need any more info about part of this.

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Mass sprite creation
« Reply #1 on: Fri, Feb 25, 2011 »
Is there a reason you need to place the water via code, and not use a map editor like DAME and just draw it?
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Mass sprite creation
« Reply #2 on: Fri, Feb 25, 2011 »
Because I don't know exactly how to use DAME.
Also, the water tiles have their own coding for water physics depending on where the player is in it, and I'm not sure if dame will do that.

I just want to know if there's any easy way of editing my code to quickly create the blocks.

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Mass sprite creation
« Reply #3 on: Fri, Feb 25, 2011 »
Doesn't matter what custom code they need, DAME can handle it.

I don't really get what your code is doing. You are using PNGtoCSV which will create a tilemap fine, that obviously works - but then for some reason you're checking the pixel value and placing water down according to that if it collides with a sprite??? That isn't going to work as the sprite needs to have its update method called for all the collision evaluations to happen. Why not just loop through the tilemap DATA using getTile and check the value of that? Something like:

Code: [Select]
var tilemap:FlxTilemap = Registry.levels.tilemap;

for (var y:int = 0; y < tilemap.heightInTiles; y++)
{
for (var x:int = 0; x < tilemap.widthInTiles; x++)
{
if (tilemap.getTile(x, y) == 1)
{
// add water sprite here at x * tileWidth and  y * tileHeight
}
}
}
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Mass sprite creation
« Reply #4 on: Fri, Feb 25, 2011 »
Wait a second...


FlxTilemap has a getTile() function?! O_o
AArgh!

That's kind of what I was trying to do, only I din't know Flixel had that function there.
Here's the new code:
Code: [Select]
var waterMap:FlxTilemap = new FlxTilemap()
waterMap.auto = FlxTilemap.ALT;
waterMap.loadMap(FlxTilemap.pngToCSV(ImgMapWater, false, 2), ImgWasteTiles);

for (var waterTiley:int = 0; waterTiley < tiles.heightInTiles; waterTiley+=2)
//+=2 because each waterMap tile is 2x2 tiles large
{
for (var waterTilex:int = 0; waterTilex < tiles.widthInTiles; waterTilex+=2)
{
if (waterMap.getTile(waterTilex, waterTiley) != 0)
//activates as long as tile is not blank
                {
_water.add(new Water(waterTilex * 8, waterTiley * 8));
}
}
}
(<tiles> is the main map tilemap)

I guess it would have been a whole lot easier if I had known about that function...
Anyways, you can see it here:
http://www.newgrounds.com/dump/item/051720a5136a54a27e994162aba51217
(thanks also for suggesting a nested <for>. It never crossed my mind as being an option)

So it looks like it works all well for adding main bodies of water. I can add more within the loop for other tiles such as the top of the water or acid to make one big multi-purpose tiler.

One problem I'm seeing though, (might be unrelated to this new method of coding used), but the water seems to be not entirely synchronized, with patches of blocks ahead of or behind others in their animation loop. See any way to fix this?

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Mass sprite creation
« Reply #5 on: Sat, Feb 26, 2011 »
Hmmm it could be there is a delay in starting the animation for them so they fall out of sync. You could try creating the water, and not running an animation. But before the game starts issue a "start anim" to all water blocks at once.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Mass sprite creation
« Reply #6 on: Sun, Feb 27, 2011 »
Well, I finally figured out what the problem was by editing the code so that I could reset the water animation whenever I wanted to.

I remembered that my water tiles have some extra coding so that, like the enemies, they deactivate their motion and collision when off screen.
I removed this part, and the animation is perfectly synchronized, but with all the water on the level constantly updating, its taking a bit of a toll on the framerate. Does anybody know any way to fix this?

ChainedLupine

  • Member
  • **
  • Posts: 91
  • Karma: +0/-0
    • View Profile
    • Dit Dah Games
Re: Mass sprite creation
« Reply #7 on: Thu, Mar 3, 2011 »
There's no real way to fix it, per say.  Tons of FlxSprites all animating at once will cause slowdown, with no way to solve it.

In this case, I would override FlxSprite with a class that had its own update.  Rewrite the animation control logic so that the current frame number is a static on that custom class.  Then, during your main game loop, just update that static frame number at once.  All FlxSprites will then change their frames simultaneously.

I use a similar effect in one of my games to synchronize the animation of individual FlxObjects.

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Mass sprite creation
« Reply #8 on: Sat, Mar 5, 2011 »
So I'm guessing for my <Water> class, I could add a <public static var frameNumber>, and have that update in <PlayState>, and have the water sprite only switch to that if its active.
I won't do that for now, since there's not much of a lag, but I might have to later when I add more objects. Thanks for the help, though.