needing some help updating to 3.0

Topics: User Forum
Sep 9, 2010 at 9:29 PM

hi everyone.  first off i'll just say that i'm a bit of a noob when it comes to oop and using the farseer physics engine.  I started messing with it about a month ago, and I'm not exactly the sharpest knife in the drawer when it comes to this stuff.  Having said that I did have a pretty good thing going in 2.1, but upgrading to 3.0 has left me scratching my head on how to accomplish the same thing.  I figure the best way to ask how to do this is to explain how it worked in 2.1

I was working on a side scrolling shoot-em-up game with tile based level geometry.  There are two things types of things in the world which have geometry and are controlled by the physics engine.  There are tiles in the world which are static, and there are actors which are basically everything else.  (the player, bad guys, shots fired by the player, debris....)  Starting with actors, there are two lists that hold all the information needed for actors

private List<Actor> actors;

private List<ActorDef> defActors;

Actor is the base class for the active things flying about in the gameWorld.  shots fired by the player, bad guys, the player, and everything are all derived from Actor.  Every Actor has both a Body and Geom.  When an actor dies, such as a badguy getting shot, or a shot flying out of the gamespace the actor gets removed and both the Body and Geom that that actor had get disposed.

 

class Actor
    {
        #region Fields
        protected GameWorld gameWorld;
        protected ActorDef def;
        protected Texture2D image;
        protected Rectangle imageRect;
        protected Vector2 imageCenter;
        //protected Rectangle boundingRect;
        protected Body myBody;
        protected Geom myGeom;
        protected CollisionEvent myCollisionEvent;

        protected bool alive = false;
        protected bool hasGravity = false;
        protected bool hasGeometry = false;
        protected bool collidable = false;
        protected float hp;
        protected float rotation;
        protected CollisionCategory collideMask = CollisionCategory.None;
        protected CollisionCategory damageMask = CollisionCategory.None;
        protected CollisionCategory collideType = CollisionCategory.None;

        protected Vector2 pos;
        protected Vector2 vel;
        protected int actorType = ActorNames.None;
        #endregion

 

(ignore that pos, vel and rotation are separate from the body, those get updated every frame from the body, they're just there to refer to easily)

 

The other thing, the ActorDef class holds what is basically a list of stats for each actor (thats the best way I can describe it) it has a Geom and Body, but those are never added into the simulation.  Its sortof like a blueprint class for each type of actor.  This is the part I can't figure out how to get working in 3.0.  When the gameWorld gets created.  (that's my class that runs all the game part of the game, the physicsSimulator, the actors, the tilemap, etc...) all the defActors get created.  The geometry, of each defActor is created then.  If I want a leg to go flying out of an enemy bug when you blow it up I'd create a defActor for that leg, create the body and geometry for that leg, then pass it into the defActor.  This is never added into the simulation, it just sits there waiting to be used for by an Actor.  Then in the BugActor on death I'd tell it to create a new DebrisActor and pass to the defActor of that bug leg I created.  The new DebrisActor takes the defActor it is given and creates a new Body and new Geom based upon the Body and Geom held by the defActor (that's another thing I can't figure out how to do in 3.0), then adds that into the simulation for itself and is a part of the world.  

class ActorDef
    {
        protected GameWorld gameWorld;
        public Vector2 startVelocity;
        public bool stayUpright;
        public int hp;
        protected int actorDefType;
        protected Body collisionBody;
        protected Geom collisionGeom;
        protected Effect drawEffect = null;
        protected CollisionCategory collideType;
        protected CollisionCategory collideMask;
        protected CollisionCategory damageMask;

So that's what I'm trying to do.  Tiles work the same way as the actors.  There's a list of DefTiles for the different types of tiles and a big 2d array of Tiles that is the map.

Ok, so this is all probably a bit convoluted and maybe a bad way to ask my question.  But trying to get this all working in 3.0 has left me scratching my head.

TLDR: My main question is this, in 3.0 is there some way to create a body, attach a shape as a fixture I guess, (that seems to be how it works from what I can tell), and put it aside as a blueprint.  Not enter it into the world as part of the simulation.  Then, when I need to use it for an actor I'm creating, such as a badguy or the leg of a blown up bug that goes bouncing to a rest, load up that blueprint, make a copy of it, and enter it into the simulation.  It doesn't seem like there's any way to create a body based on another body like you used to be able to, nor any way to add something to the simulation.  everything seems to be part of the simulation.

Also, is there a way to dispose of a body when you want to get rid of it?  It used to be you could call dispose, do you just set active to false now?

 

Sep 9, 2010 at 9:47 PM

I don't have much time to talk, but I'll address a couple things so you can move on if you need to.

To "Dispose" of a body, you can call worldInstance.RemoveBody(bodyToRemove).

You can add fixtures and bodies to a running simulation just fine. You can create the body with

Body bodytocreate = worldInstance.CreateBody(), and you can pass that body as an argument to

the FixtureFactory of choice. You shouldn't have any problems.

The property "Active" as part of Body allows a Body to not be part of the World, and you

can add it back any time you wish.

Hope that helps. 

Sep 9, 2010 at 9:57 PM

Ah ok, so Active = false would be how to make a body into a blueprint like before?  Heh, in retrospect that should have been pretty obvoius :

in the part where you create the body...

Body bodytocreate = worldInstance.CreateBody()

is there any simple way to set all the properties of that body to the properties of my inactive blueprint one?  I assume there's no way to attach fixtures and everthing to the blueprint and then just duplicate it.  (would be nice if there was thou)

Sep 11, 2010 at 8:59 PM

I suppose you could simply make a static function somewhere in a static Helper class

called "CreateBluePrint" that automatically sets all the necessary values.

Just an idea, if I understand your problem. 

Sep 15, 2010 at 9:42 PM

I think I've got this squared away now.  I found the clone feature for shapes and messed around with that for a while until i finally realized you don't even need to clone the shape, you can just use the blueprint one!  all the settings on the fixtures like friction and stuff can be copied over from the blueprint one easily enough.  bodies have a list of their fixtures so getting all that information is no problem, woohoo!

 

There's one thing I'm dealing with right now though... its more of a quick question for anyone who might know how to deal with it...

 

i assume theres a sort of maximum velocity or something now.  can this be increased and is it safe for it to be increased, or is it smarter to rescale everything in the world to a much smaller scale?