Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    298
  • comments
    1135
  • views
    232592

And Newton thought HE had it hard!

Sign in to follow this  
HopeDagger

105 views

Player Physics

That's right, kiddies. Gather around old grandpa Steve and listen to his recounted tales of the implementation of player physics.

Today was another marvellous day for productivity and progress. Note that I've had this whole week off of work so far (until Thursday), so the majority of my free time is going into Skirmish Online's development.

Each game instance now has a Player associated with it, which the main camera is fondly centered on. This player can be controlled by the user (via customizable keys (lacking a customization interface :P)), and features the standard fare player physics: velocity, friction, 360-degree rotation, and all of that fun stuff. The movement animation cycles relative to the magnitude of the player's velocity, so it's neat to give him a high TopSpeed and have him zip around like he's Bicycle Repair Man or something.


Whack! Watch out for that crate!

After the player was politely waltzing around my screen, it was then time to tackle collisions. Skirmish requires two flavours: map collisions (with wall tiles), and sprite collisions (with map objects, bullets, cheese-burgers, etc).

This required a rewrite of how I was previously handling the sprite lists (full list, and a list of collidable sprites). I was using std::vector originally, which was as slow as beans in terms of sequential access. std::list was a bit faster, but my framerate was still plummetting. Now I beefed it up to a quasi-dynamic array which zips along with sufficient speed, all contained within a SpriteArray class that manages addition, removal, sequential access, and data-clearing.

Map collisions were a cinch. Since tiles are arranged evenly in 32x32 blocks, it's just a matter of dividing the points on the player's hitbox by 32, and checking the hit-type of that tile. I devised both CanWalkOver() and CanShootOver() helper functions to ease the (likely) future pains of managing the collision possibilities between the various sprite types and tiles.


Pixels, my friend?

Sprite->Sprite collisions are a huge pain. Mainly because I insist upon having pixel-perfect collision detection. [smile] Stubborn me. For those of you just tuning in, I'm using OpenGL, which means that direct pixel access -- in terms of speed -- is a lot like cutting the front lawn with a frog. Not very fast. So how am I to get this working without killing my performance?

At first the plan was to render just the sprite in question, and then read just one pixel (at the player's centre) to determine if it's a hit or not (!black). I couldn't get any logical results from glReadPixels(), so a few tutorials off Google later, some milling around on GD.NET, and I canned it. That approach would just plain take too long.

The other resort was to bite the bullet and do it how I did in the previous writing of Skirmish: access the surface pixel data and check from there. That's as easy as locking a surface to a texture and reading it in Direct3D, but I'm in OpenGL-land now, and it doesn't seem that simple. So I had to settle for storing the pixel data into each created Texture object when I loaded the data in initially at startup-time. This means a bit of a bigger memory footprint, but the tradeoff is that I get direct pixel-reading access (virtually) for free. Woot.

So I implemented this, and got the player bouncing off of non-rotated objects. Those crates and chairs didn't even know what hit them. Next up was to get rotated map objects colliding properly too. This sounds simple, but you must remember that the pixel data is stored in a manner equivalent to Rotation=0. Luckily I had faced this exact problem with the previous Skirmish, and solved it by instead inversely rotating the point on the bitmap I was checking. I doubt I'm sounding too clear, but a long story short: it worked. There was a big bug that took me about 2 hours to figure out, but this is getting pretty nitty-gritty. I don't think most readers really care about that. [smile]

After that, I finished by checking the X and Y directions seperately, allowing the player to 'slide' across the edges of most objects, rather than bumping off or getting stuck. It'll need some tweaking down the line, but the game -- yes, I called it a game now :P -- is starting to feel stable and closer to being playable!

Oh, and I tossed in a few more little things, like a gfx_utils.cpp/h file-set to handle quickly drawing rectangles, lines, and that sort of jargon. Mainly so I could enable/disable drawing sprite hitboxes for easier debugging. Also implemented sprite layering via the ever-handy z-buffer. Now you can officially hide under trees again! [grin]



(Er, how do I show a screenshot of collision detection?)




Tomorrow will hopefully see the final tweaking of the player physics, and then the beginnings of networking. And I've got to say that I'm thrilled at how fast things are coming together. I can only hope that this time it sees success! [smile]
Sign in to follow this  


6 Comments


Recommended Comments

You know, I was going to gripe about you bashing STL (like, how std::vector is defined in the standard to be _at least_ as fast as std::list with regards to sequential access, and that the slowdown you were seeing was probably from insertion/removal penalties with the vector) but then I realized: hey. You got it working before, and got it working now.

So who am I to complain about your coding habits? :D

Looking forward to getting knife-ownt some more! Any thoughts on a release timeframe yet?

Share this comment


Link to comment
Beware the z-buffer, it will turn on you when you least expect it.......

Looks great though, looking forward to a demo....

Share this comment


Link to comment
Quote:
Original post by HopeDagger
(Er, how do I show a screenshot of collision detection?)


Draw the contact points and collision normals [grin].

Share this comment


Link to comment
Quote:
Any thoughts on a release timeframe yet?


Last time it took 5 months, going from scratch. This time I have all (well, most) of the graphics done, just about all of the editors done, knowledge of what I need to do, a killer networking library, and an equal amount of dedication.

I'm estimating perhaps by the beginning of November I'll be at least where I was before. It depends how hard University life hits me. [smile] Fingers crossed!


@Duke: Gah, no way. :P In that time I could write something useful, like, uh.. collision points and nor-- damn! [grin]

Share this comment


Link to comment
Good to see you are doing progress [smile]. I can't wait for the first playable demo!

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!