Sprites (Animated, all of the same size)

Topics: Developer Forum
Oct 8, 2007 at 9:57 PM
Hi, I like this engine and am trying to get started using it for a 2D side scroller. I dont see a way to load in a texture and animate it using a sprite sheet. Am I just missiing it or do I have to write that part myself? If so can someone point me in the write direction?

Thanks
Oct 9, 2007 at 1:18 AM
I'm pretty sure that your question is beyond the scope of this project, although maybe someone here has the answer you need. This site is for a physics engine. It deals with things related to collisions and movement of objects, not really graphical things like animation.
Coordinator
Oct 9, 2007 at 11:34 AM
Yep, this engine doesn't do the graphics stuff. It just tells you where to put the graphics.
Oct 10, 2007 at 12:51 AM
Thanks for the answers. I played around with it and came up with a concept Sprite class that would work with the engine with very few changes. I ran into another problem, in the demos that come with the engine it creates that odd shape thing (im using Demo 3). Well I need to make it into one thing, when I tried on my own, i got it to work except it fell through all the surfaces, what would be the required changes that I would have to make to take that one object to say a square?
Coordinator
Oct 10, 2007 at 11:32 AM
That "odd" thing is a single body with multiple geometries. To make it one thing, just make a rectangleBody and a corresponding rectangleGeometry using the BodyFactory and GeometryFactory.

Oct 10, 2007 at 7:53 PM
Alright thanks, Got it working perfectly. I am getting close to having a fully working Sprite System with movement. Another problem I've run into it Jumping. I have my guy jumping using ApplyImpulse. The only problem im having is finding when he lands. I threw together this code but am having problems with it.

if (agentBody.LinearVelocity.Y < .9 && agentBody.LinearVelocity.Y > -.9)
MySprite.Jumping = false;
else
MySprite.Jumping = true;

The problems are sometimes when the body is on a surface the LinearVelocity goes above .9 or below -.9 making it switch to the jumping texture. Another problem is when the Sprite is in the air a perfectly timed click can make it double jump. Is there a better way to check if the Sprite is on a surface?

Thanks
Coordinator
Oct 10, 2007 at 8:08 PM
Edited Oct 10, 2007 at 8:10 PM
Good question... so good, I'm not sure I have a good answer.

Maybe you could add some lag time in so that if the linear velocity is > .9 for some fraction of a second then you switch to the jump animation. This might get rid of the surface jitter you seem to be experiencing. Not sure it will look right though for normal jumps.

Another possibility is to use the CollisionHandler callback of the geometry object. You could use the "Tag" property to set a label for all your "landscape" geometries then possibly keep track of when you are NOT colliding with a landscape and set the jump sprite accordingly.

Just some ideas that might get you going... not sure either will work. I'll keep thinking on it. Maybe someone else will have an idea.
Oct 10, 2007 at 9:25 PM
Edited Oct 11, 2007 at 2:40 AM
Ok, I am going to try the second method. I have an idea if there is someway to do this. If there is a way to check Collisions between the Sprite geometry and ALL the geometry with the same tag? if not how would I go about doing something like that? Because if there is a way to check collisions with geometry with the tag say "Floor" then it would be very easy to make that way work.

Also, Im have my sprite moving nicely except the jumping and the fact that after you let go of a movement key (left or right) the sprite takes to long to come to a stop, is there a property I can change that would make the body slow down faster?
Oct 11, 2007 at 2:56 AM
I used crashlander's method, but that still made it possible to wall jump and ceiling jump if perfectly timed. So, in addition to what crashlander described, basically I make my character a sphere, and then in the collision handler check the contact list, and if the points are at some range along the bottom portion of the circumference of the sphere, then the character is "standing". The standing state then sticks for a few frames if another "bottom collision". If I don't do the delayed state then the character rapidly switches back and forth between standing and jumping as you "walk" along the surface. It's not perfect but it seems to work ok.

As for getting the character to stop, use friction coefficients, and then make your character rotation static (I do this manually, not sure if there is a way to do it in the engine). Drag coefficients just make your character look like it always has a parachute on. Also, enforce a maximum horizontal velocity and then slightly increase the sideways forces as well as the friction.

Well, that all sounds easy but you really have to tweak it to get it to look just right, or maybe I'm just being picky :P Mine still doesn't look quite right but it's better than it was. I'm thinking of trying a few things, like invisible "bumper" geometries. I'll let you know how it goes.

-Jeremy
Coordinator
Oct 11, 2007 at 10:28 AM
Edited Oct 11, 2007 at 10:30 AM
Physics engines driven games always involve more tweaking then anything else it seems.

@bob, you should be able to create your floor geometries, then give each a Tag = "Floor". Add a callback to your sprite geometry and then in the callback, check for geometries with the "Floor" tag. Here is another post about the callbacks

@JeroMiya, to lock a bodies rotation you could also use an AngleJoint with TargetAngle = 0.
Oct 11, 2007 at 1:25 PM
Edited Oct 11, 2007 at 3:07 PM
Alright, sounds easy enough. I'll try it a little later.

As for the body rotation I used a method I found in another post. Set the bodys moment of inertia to positive infinity, seems to work well for me. Should look like this:

agentBody.MomentofInertia = float.PositiveInfinity;

or something very close, I dont have the code infront of me right now.

I'll post here once I find out if the callback method works. One idea would be to check to see if the colloision happens on top of the object, if not dont set it to standing. I dont know if there is a way to check this, I'm thinking get the X and Y of the object and the sprite and see if the sprite is below the object.

EDIT: I put together this callback that seems to work pretty well: I found one problem, If the player makes the sprite just right up beside the object and runs into it they can double jump off of it

private bool HandleCollision(Geometry g1, Geometry g2, ContactList contactList)
{
if (g2.Tag != null)
{
if (g2.Tag.ToString() == "Floor")
{
if (g1.Position.Y < g2.Position.Y)
Jumping = false;
else
Jumping = true;
}
else
{
Jumping = true;
}
}
return true;
}

Also, JeroMiya, could you post a small example of how you are making the character a sphere and how you are checking only the bottom portion of the cirucumference, Wouldnt it be possible to do something similar with a rectangle?

Ok, I tested the method, it seems like its so close to being able to work. one thing i noticed is when the sprite is going to fall, Is there a way to call the HandleCollision callback without a collision? I am trying to use the LinearVelocity but the problem with that is there is a delay or if you set the number to low you get "jumping gitter" while walking. I am still working with it.

Also how would I enforce a maximum horizontal velocity? and what sideways forces are you refering to JeroMiya. Sorry, I am still learning a lot about Farseer while doing this

Yet another small problem. For jumping im using ApplyImpulse and every once in a while my sprite only jumps a little bit but other times it jumps to the height i want, is there a way to make sure that he jumps the same height all the time?


Sorry if this post seems to be a mess but I've editied like 3 times. If you need me to clarify anything just tell me
Oct 12, 2007 at 1:02 AM
lol using a physics engine to simulate the fake platformer physics can be difficult lol.

I had the same jump problems. One, when you move left or right on a rectangular body, the collision "jitters" (doesn't get called every frame). To solve this, simply set a counter to some set value every time you detect a collision and count down. Until it reaches zero, consider the character to be "collided" with the wall.

The second one was the small jump big jump issue you described. I'm still not really sure why this happens, but as a kludgy workaround I just manually set the Y component of the velocity to my upward jump speed when the user jumps. Conceptually this should be the same thing as applying an impulse force, but it seems to work a little better. It might be something to do with the collision detection system. Maybe the ball is slightly in the platform at certain times, and if you try to apply an upward impulse force at that exact moment, you will collide with the box that you should be on top of and then slow down. Just a theory. Maybe try offsetting your Y position a little bit as well to help avoid collision issues?

As for my code, it is for an competitive assignment for a class I'm taking, so I can't post my code till I'm done and hand it in.

-Jeremy