The making of - Wheelchair Stunts

Been thinking about a new game idea and have this thing in my mind. As Angry Nerds was inspired from Angry Birds, this one is partly inspired from Bad Piggies. I liked the whole vehicle momentum and the ramp jumping stuff using the physics engine and I also remember way back, some motor bike jumping game on the C64 where you had to jump increasingly bigger jumps each time.

 

I'm thinking something along these lines except it won't be a motor bike but a non powered vehicle that relies on gravity to get up the speed needed to make the jump. Then it would all be about working out how far up the ramp to start your run to get enough speed and momentum to get you across the jump and land safely on the ramp on the other side.



This will do for a start, so first up I need to look into creating some complex objects with wheels and joints to form some sort of vehicle. Farseer physics allows all this but I've not done joints or joined bodies before so some R&D required.

Getting Started

Iv'e built a framework, skeleton project from my Angry Nerds project and am reusing my object factory as a basis for this. I have a bunch of basic objects, rectangle, circle and triangle but I need to create something more complex. I certainly need to look at joints and wheels. 

 

Not a great deal of documentation for this really but managed to get something after a fair bit of 'just trying it' and some trial and error but essentially came down to just this.

 

public static BaseObject Chair(Canvas canvas, World world, int x, int y, float scale)
{
    BaseObject body = ChairChasis(canvas, world, x, y, scale);

    BaseObject w1 = LargeChairWheel(canvas, world, x - 20, y+12, scale);
    BaseObject w2 = SmallChairWheel(canvas, world, x + 20, y+20, scale);
                        
    RevoluteJoint r1 = JointFactory.CreateRevoluteJoint(world, body.ObjectBody, w1.ObjectBody, new Vector2(0, 0));
    RevoluteJoint r2 = JointFactory.CreateRevoluteJoint(world, body.ObjectBody, w2.ObjectBody, new Vector2(0, 0));
            
    body.Angle = 45;
    return body;
}

ChairChasis is basically a block and LargeChairWheel and SmallChairWheel are both circle objects. The CreateRevoluteJoint does all the work and now we have a basic 2 wheeled vehicle.

I can really start moving now, as I pretty much have all the mechanics I need

The Jump Ramp

To prove my vehicle was working correctly I quickly stuck a square rock and long flat rock from my object factory on the screen in a ramp formation and dropped my vehicle onto it. It worked! It rolled down the ramp nicely and came to rest. This is what's nice about using a physics engine, in that you can just chuck stuff in there and watch it work.

 

 

Next up was to create a proper ramp. Initially I played about with a ramp shaped polygon object but this was the crapest thing I had ever seen. I managed to use the farseer lines and arc methods to get something that worked but it was too inflexible. What I really needed was some sort of calculated bezier line ramp with a smooth upward curve.

 

If I can develop some sort of Ramp Object that takes a containing rectangle and an angle for the down ramp and up ramp as parameters then this would allow me to create any ramp and jump I wanted. However, the maths involved for this were beyond me, sin and cos waves are not my thing.

Inspiration

Been stuck on the ramp thing for ages but I've had a great idea! I can draw out a generic ramp in photoshop and plot a set of points along it as an Array. About 10 points will do it then I just join them up with lines, however, if I add a X and Y scaling factor I can bend the steepness or length of the ramp any way I wish. 2 of these, one reversed for the up ramp will form the complete jump. It can't fail!

Implementing Ramp.cs

I've added a new object to my library that creates a body from a series of lines from an array of points with a horizontal and vertical scaling. The points array plots a 45 degree line downwards from top left to bottom right then curving off to the ground.

Increasing the yscale will give me a steeper curve while decreasing it a shallower one. I'm returned a rectangle containing the ramp which I can place where I like. I can mirror the ramp to provide take off and landing ramps. I was pretty confident this would work and it did, first time. I bolted everything together and before you know it, had this.

 

Scaling

Something I never took too seriously but is in fact quite important. Farseer works in a world of MKS (Meter-Kilogram-Second) and so a 32x32 pixel object created in Farseer will be 32 metres square! so you have to scale it down.

Easy enough, in fact my objects do this for me already, however, I was just scaling down by a handy amount, 100.

This worked in Angry Nerds, working with 32cm blocks was ok but I wasn't getting very good results here. Just not getting enough momentum. So, I thought about it and a better scale would be 32px per metre, so my 64x32px chariot would be a realistic 2m x 1m.

The difference this made is amazing. The movement is a whole lot more natural now and some decent momentum is gained from my 'vehicle' as I watch it shoot off the end of the ramp and fly off the edge of the screen.

I need to get more familiar with the physics of this thing.

The coefficient of restitution

Not doing much coding at the moment. Now I have some basics working, I'm taking a proper look at the physics of this thing, I am using a physics engine after all. There are a bunch of things that I need to understand a bit better, such as density, friction, damping and restitution to name but a few.

I also want to redo the scrolling and zooming that I started with Angry Nerds and set about defining the scale of the game area.

Refactoring

Not had much time to work on WS lately. Have been doing some website work and the cab upgrade has distracted me a little. 

I did manage to texture my ramps and create a proper Ramp object and add it to my Object factory. Now at least it knows some things about itself like its calculated dimensions and also its ramp angle.

 

Iv'e also been reworking my scrolling and zooming, not particularly succesfully however. Im thinking I might have to rethink how I do this, if at all.

Pan and zoom

This has been doing my head in for a few weeks. Ive added the neccesary mouse events to the canvas and now I can drag the map around within the window and I can zoom in and out with the mousewheel. 

However! trying to limit the drag so you cant drag it too far off the screen has been a massive headache. It should be straight forward.

The map is 3 times the visible window size, so I can restrict its movement by checking that

Map.Left <= 0 and Map.Left >= -(Map.Width - Window.Width)

 

Works, however I can also zoom. Silverlight makes this quite easy by applying a transform to the canvas, so I can zoom by 80% by setting applying a zoom transform to 0.8.

Ok, so when zoomed the map sould be 80% smaller but no matter the maths still is the same, however although the map has been scaled down, when I get the canvas properies it still gives me the unscaled values!

 

Anyway, I eventually got it and it came down to this.

Map.Left <= 0 and Map.Left >= -(((Map.Width * Zoom) - Window.Width) / Zoom)

Go figure?

Proving the mechanics

Now I have the scrolling and dragging of the map working and my ramp and wheelchair objects working, I really need to make the game out of all this. I quickly added the mouse control from Angry Nerds to the wheelchair base to make it draggable and gave it a quick test.

Sort of works, not great but proves the mechanics of it all is working. I can drag my chair and drop him on the ramp and off it goes. Zooms down and flies through the air lovely.

 

Not pretty, Im using an abstract texture that shows me that its mapping to the physical object correctly

 

 

There it goes, the game mechanics in action

continued..