Tiled Map Generation and Texturing

Topics: Developer Forum
Jul 19, 2011 at 10:01 AM

Hi Guys,

I am playing with Farseer Engine looking at creating large tile based map.

Currently i have a array thats storing vector locations and then creating bodys at the locations, its working wellish on small maps, but if i make a 500 by 500 tiles its extremly slow to load if at all... Is this the type of thing Farseer should be used for? should i be creating hundreds and thousands of bodys??

Secondly, is there a way to apply a texture directly to the newly created body, currently i have to use the vector points above to draw a texture where the body is, but for debugging it would be great if there was some way to turn like a overlay or borders only view on so it shows allt he bodys... can you advise if this is already a feature?

Cheers,

Mal

Jul 19, 2011 at 10:14 AM

The best method is to create a body which surrounds several tiles. For example, if you have a ground, the best is to meka a line or a rectangle which is the same size as the ground, and not having lots of rectangles.

 

Also yes, there is a way of apply textures directly to bodys, take a look at the Farseer Physics Engine Samples XNA. In this way, moving bodies will move automatically the texture.

 

And the overlay you say, do you mean a way to see the shape of the bodies? You can activate the debug modes. In the Physics Engine Samples XNA, for example, if you press F1it shows the shapes of the bodies, is you press F3 the contact, the points, etc..

Jul 19, 2011 at 10:27 AM
Edited Jul 19, 2011 at 10:37 AM

Thanks for the reply Victorspain, the issue with the first problem is that the user is going to want to add or remove more squares to the ground... If you have seen or played Terraria or minecraft ... kinda like that.

the ability to remove square / bodys to allow the player to "dig"...

Ill take a look at the samples files, i have already but i didnt see anything that looked like what i was wanting... ill try again.

 

I was also thinking about only creating the bodys that are in the view of the character... but that didnt work. I use this technique for limiting the drawing / viewing of the textures and it works really well, just not with physics bodys because you need to "update" and it seems to kill the game.

 

Edit... Maybe it is worth firstly creating the array and then only loading "chunks" of the array when the character goes towards them... yea that makes sense...

Jul 19, 2011 at 11:34 AM
Edited Jul 19, 2011 at 11:35 AM

Here if a example whic creates a square and sets a texture for it which can be drawn outside the shape. I recommend you to make the shape alike the texture, if not the collisions looks wreid.

 

Vertices yourbodyvertices = new Vertices(4);
            yourbodyvertices.Add(new Vector2(0.0f, 0.0f));
            yourbodyvertices.Add(new Vector2(-1.0f, 0.0f));
            yourbodyvertices.Add(new Vector2(-1.0f, -1.0f));
            yourbodyvertices.Add(new Vector2(0.0f, -1.0f));

PolygonShape yourbodyshape = new PolygonShape(yourbodyvertices, 2f);

            yourbody = new Body(World);
            yourbody.BodyType = BodyType.Dynamic;;
            yourbody.Position = new Vector2(0.0f, -1.0f);
            yourbody.CreateFixture(yourbodyshape, "yourbody");

Sprite yourbodytexture = new Sprite(ScreenManager.Content.Load<Texture2D>("Materials/yourbodytexturefile"), AssetCreator.CalculateOrigin(yourbody)/_scale);

 

Then, in the draw method

 

ScreenManager.SpriteBatch.Draw(yourbodytexture.Texture, ConvertUnits.ToDisplayUnits(yourbody.Position), null,
                                           Color.White, yourbody.Rotation, yourbodytexture.Origin, _scale, SpriteEffects.None, 0f);

 

 

Also, for the game you want, I recommend you a tilebassed engine. If you don't need advanced collisions, moving bodies, fluids simulations, etc, a tile engine would fit perfetly in your needs.

Simply chech in the array if the tile is enmty or not, and then simulate a collision manually with it. If's more simple and faster.

Jul 19, 2011 at 11:54 AM

Victorspain thanks for your reply, ill give that a go now and see how i go, also concerning your last statement i believe at this stage i will require moving bodies, and advances physics movements so i will try to persist with this engine.

I started with a very basic tile engine and found that the collision detection was terrible! and had so many issues with it... if i could find better collision detection math then i might re-look my previous work, but i am really liking the possibilitys with a proper physics engine.

Again thanks for your help.

Jul 19, 2011 at 12:25 PM

Actually Victorspain, you might also be able to help me with another small thing...

With .Dispose, is this what you use to delete a body?

Jul 19, 2011 at 12:27 PM
Edited Jul 19, 2011 at 2:04 PM

One last advice, kynematic and static bodies do NOT collide. If you want a moving plattaform to collide with the static tiles you have to manage it by youself. I lost lots of time thinking it was a problem with my bodies until I read that these bdies never collide each other.

I haven't needed to delete a body yet, so don't know about the .Dispose. I'll take a look today.

Jul 19, 2011 at 3:13 PM
Edited Jul 19, 2011 at 3:38 PM

FYI, i am trying to use this as well...

_world.RemoveBody(Body);

getting more errors... googleing now :P




This is so silly... i didn't think it would be so flippen hard just to remove / delete a body once its created!

Can anyone assist here?
Jul 19, 2011 at 3:41 PM
Edited Jul 19, 2011 at 3:45 PM

You made me look at it xD

I've tried using  fix1.Body.Dispose(); but it leaves the texture, only removes the body.

 

Tried also deleting the texture, but it gives me an error in the draw method. I think that I have to chech every time if the texture exist before drawing it. Expensive method. Any better?

Jul 19, 2011 at 3:46 PM
Edited Jul 19, 2011 at 3:49 PM

lol thanks for your time, but i would love to know how you got rid of the body... i can get rid of a texture fairly easy :P

public void timedPhysicsBlockDestroySingle()
        {
            //Game1._world.RemoveBody(chuckTile);
            chuckTile.Dispose();
        }

I was trying to use this method to dispose or remove the newly created body, doesn't work... what am i doing wrong here?

edit: i separated the drawing of the textures to the creation of the bodys, to allow me to swap out textures at will, thats how i deleted the texture...

Edit 2:

this is how i create the bodys:

chuckTile = BodyFactory.CreateRectangle(Game1._world, 0.25f, 0.25f, 1f, groundPosition, Color.CornflowerBlue);
chuckTile.Restitution = restitution;
chuckTile.Friction = friction;
chuckTile.IgnoreGravity = true;
chuckTile.IgnoreCCD = true;
chuckTile.SleepingAllowed = true;
Jul 19, 2011 at 3:55 PM

I think i might understand what i am doing wrong... i think that i have mis-understood the difference between a body and a fixture.

I need to remove both or just the fixture... Now how do i remove the fixture lol google...

Jul 19, 2011 at 3:59 PM

I've managed to delete the boy and the texture.

I've used this code:

fix1.Body.Dispose();
_cubesprite.Texture.Dispose();
l = 1;

where fix1 is the first fixture in the collision(i delete it when it collides another body), cubesprite is the sprite of the body, ald l is the parameter i use in the draw method to prevent it from triying to draw an unexisting texture. 

if (l == 0)

{

ScreenManager.SpriteBatch.Draw(_cubesprite.Texture [MORE THINGS...];

}

Also, I create bodies with this:

Vertices yourbodyvertices = new Vertices(4);
            yourbodyvertices.Add(new Vector2(0.0f, 0.0f));
            yourbodyvertices.Add(new Vector2(-1.0f, 0.0f));
            yourbodyvertices.Add(new Vector2(-1.0f, -1.0f));
            yourbodyvertices.Add(new Vector2(0.0f, -1.0f));

PolygonShape yourbodyshape = new PolygonShape(yourbodyvertices, 2f);

            yourbody = new Body(World);
            yourbody.BodyType = BodyType.Dynamic;;
            yourbody.Position = new Vector2(0.0f, -1.0f);
            yourbody.CreateFixture(yourbodyshape, "yourbody");

Sprite yourbodytexture = new Sprite(ScreenManager.Content.Load<Texture2D>("Materials/yourbodytexturefile"), AssetCreator.CalculateOrigin(yourbody)/_scale);

Jul 20, 2011 at 6:07 AM

Ok a bit of success here :)

I copied what you were doing above.

Firstly adding a trigger that stopped the drawing of the body, which was a simple and good idea thank you.

Then i tried to remove the body with both:

Game1._world.RemoveBody(chuckTile);
chuckTile.Dispose();

this does not work, it give you:

The body is already marked for removal. You are removing the body more than once.

which i guess is complely obvious lol

i just use:

Game1._world.RemoveBody(chuckTile);

Looks like the Dispose method is really just for removing other fixtures attached to a main body ie. fixture.chuckTile.Dispose();

and it "seems" to remove the body... seems... <.<   >.>   i need to find a way to make 100% sure its removing it and not just the texture hehe, i think i know how i can do this.

Again thanks for your assistance VictorSpain

Jul 20, 2011 at 8:18 AM
Edited Jul 20, 2011 at 8:51 AM

After all that i figured out how to create and remove bodys easily! woot!