Getting somewhere

Published September 03, 2008
Advertisement


Right. Found a working solution to the problem I posted about, after some helpful responses in the thread.

Basically, I am only permitting blocks of the shape A, B and C in the above picture. Obviously the graphics can be anything, but these are the only shapes I can construct a map from. It means that anything you can stand on is always flat but it means that angular ceilings are available to swing from and make the maps a bit more interesting.

So the idea is that to collide with the map, an object calls a function that returns a std::vector of Shapes::Polygons that represent the four cells that the object is (potentially) touching. Like in the N tutorials.

To avoid the edge problems (see the thread I linked to in the last post), I'm sampling the four cells from the map, then using some simple logic to weld shapes together into one shape.

The problem above only happens on vertical edges, since gravity means that the vertical velocity of an object is always greater than its horizontal initial gravity when trying to accelerate from standing into an obstacle.

So I only need to merge the two shapes on the top row and the two shapes on the bottom row.

For the top row, if the configuration is 1, 2 or 3, a polygon based on the two shapes merged together is inserted into the vector. If there is a configuration like 4, or just one shape in the top row, the actual shapes of the blocks are inserted.

For the bottom row it is a bit simpler, since the object must always be moving down onto the bottom row, so the underside of the shapes are irrelevant. So if there is one shape in the bottom row, its shape is inserted. If there are two, a rectangle the shape of item 1 above is inserted.

Works like a charm. I can apply a continuous velocity into a ceiling or floor and still slide along it without catching, and moving against all the slopes works perfectly.

The configurations labelled "Not Permitted" still don't work properly, but they look stupid anyway, so they are not allowed in a map.

It's not an ideal solution as it restricts the shapes I can use on the map a little, but it is working and it is rock solid so I'm going to move on.

I still had this really annoying jitter happening at occasional places on the map. In certain places, the player would jitter up and down by a pixel and jitter when you pushed it against the wall.

I tried everything to fix this - I examined all the interpolation code, I went over and over the SAT code, I tried a million different things in the graphics code (flooring coordinates, rounding coordinates, everything I could think of) and was about to give up when I stumbled across the solution.

Previously my map drawing function looked something like:

void GameMode::RenderBlocks(GraphicsDevice &Graphics){	VertexBuffer V;	int Mx=int(Level.Offset.X)/64,My=int(Level.Offset.Y)/64;	int Dx=int(Level.Offset.X)%64,Dy=int(Level.Offset.Y)%64;	for(int Y=-1;Y<17;++Y)		{		for(int X=-1;X<22;++X)			{			MapCell &M=Level.MapCells[Level.Map(X+Mx,Y+My)];						if(M.ID) AddQuadToBuffer(V,float(X*64-Dx),float(Y*64-Dy),Level.Areas[M.Bank][M.Frame]);			}		}	Graphics.SetTexture(Level.MainTexture);	Graphics.RenderTriangleList(V);}


The problem turned out to be the Dx and Dy variables. Because coordinates can now basically be any float value due to the interpolation, I was losing some precision by converting to int then modulusing. This was never a problem before I started using interpolated rendering but now it was causing the jitter.

The solution was trusty old fmod:

void GameMode::RenderBlocks(GraphicsDevice &Graphics){	VertexBuffer V;	int Mx=int(Level.Offset.X)/64,My=int(Level.Offset.Y)/64;	float Dx=fmod(Level.Offset.X,64);	float Dy=fmod(Level.Offset.Y,64);	for(int Y=-1;Y<17;++Y)		{		for(int X=-1;X<22;++X)			{			MapCell &M=Level.MapCells[Level.Map(X+Mx,Y+My)];						if(M.ID) AddQuadToBuffer(V,float(X*64-Dx),float(Y*64-Dy),Level.Areas[M.Bank][M.Frame]);			}		}	Graphics.SetTexture(Level.MainTexture);	Graphics.RenderTriangleList(V);}


Simple as that. Jitter gone, everything rock solid with a fixed timestep and variable framerate and everything works at any resolution I can crank out of this monitor.

So a pretty good night really.

I've currently got a circular robot (very rough sprite for now) that can move and jump around the level.

Next up is to re-implement the robotic arm that you can swing about on. I already have an old prototype for the actual physics of this working so that shouldn't be a problem. When I've got it working, I just need to play about and find a cool way to render the arm that suggests a rigid arm rather than a flexible rope and we're making some progress.

Google Chrome still very much in favour with me. I hope it is more configurable when it comes out of beta but we all had a good laugh about incognito mode at work today ("What are you doing upstairs, darling?" "Er, er, organising a suprise party." sort of thing).

Got to get an earlier night tonight. Got a bit sucked into the forums last night and didn't go to bed till 2:30am, then up for work at 7:00am. Getting far too old for that sort of thing. I'm afraid all night coding is very much a past-time for the early twenties.
Previous Entry Hello again
Next Entry Robok
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement