Converting a GameMaker project to MonoGame (part 4)

In Part 3 we set up the groundwork for objects. Now let’s get them to do things.

Here a .zip of the project by the end of today:
Tile Based Platformer


Minor Changes
Some quick additions to the code we have already:
The Object constructor should be modified to this:

and the player constructor to:

and finally the object loading code in Room.LoadFromFile:

This is all so that the objects can access information about the room they’re in.

Collision
The collision for the physics (as opposed to interacting with other objects) is all tile based in the project we are converting, and so is very simple. We can do bounding box collisions between objects, but anything more precise such as pixel-perfect collisions would be harder to do in MonoGame. Send me a tweet if you’d like some help setting up more complex collision shapes – it’s just maths.

For now, we just need to convert the script GetCollision from our GameMaker project. It’s pretty simple:

This script wants access to the tiles as well as room size, so it makes sense to add it as a member function of the Room class:

It takes the position as two arguments, and returns an int saying what tile is there.

We need to take a look at the GameMaker script CreateCollisionMap to understand how it works, though it doesn’t need converting itself:

Basically, it looks everywhere in the room, in layer 10, for a tile, and if it finds one writes the tile’s left position to an array, otherwise writing -1.

Our tiles are already stored in an array, so we needn’t bother with this.

So our translated GetCollision should look like this:

Notice just how similar some parts can be.

Player
Let’s go back to the Player class.

The GML Create event calls InitialisePlayer and then some other things we won’t worry about just yet. The InitialisePlayer script looks like this:

We’ve already said we’re ignoring CreateCollisionMap. The rest is just pretty trivial definitions of variables, so let’s write our Create function:

The subtlety here is deciding whether to use int or float for numbers – there is no distinction in GameMaker. If in doubt just use a float, but it’s better to use ints for things you are sure are whole numbers. I’m also using int for positions, because otherwise we’d get some blurring when MonoGame draws a sprite between two pixels.

Ok, we’re now in a position to write the Step function for player. This is jut a conversion of the ProcessPlayer script:

This is basically just a case of translating line by line, but we’ll need to be careful when in comes to input. First let’s add

to the top of the file.

Then just copy and paste the script from GameMaker into our Step function, and go through line by line until it’s valid C#.
Ok, here we go:

Most of that translates directly, even the frankly bizarre bit-hacking of ints. The only major change was the way we check for key presses, but that’s just a case of learning the MonoGame way of doing things.

And it works!

Almost. Firstly, the animation is a bit dodgy because of the way I wrote it before.

More importantly, there is no jumping. In GameMaker this is handled separately with a key press event. We can just put it in the start of the Step function:

And player movement all works, exactly as in the GameMaker version!

Animation bug
The quickest way to fix this is just to move the Step call right to the end of our Object.Update function:

Now we have a fun little game to interact with.
anim
Next time we’ll get the camera to scroll properly, and maybe add enemies.

A quick plug: I just released a game on itch.io, which started as a GameMaker game which I later converted to MonoGame. Why not download it (for free) and see just some of what MonoGame can do.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *