Skip to content

162. 2D platform game #7 – Extras

September 16, 2014

In this post I’ll look at extra features such as messaging the player, creating backgrounds, and creating an inventory.

First, you can see all of those things in this one image (the background range of mountains is a little faint).
 photo photo7_zps2373176a.png

Messaging

Most games teach the player the game by messaging when a new challenge or object appears, and messaging can also be used to interact with the player in various ways.

I started by setting up a message queue, and only showing one message at a time, in the middle of the screen. This didn’t work well if the player moved quickly, because the messages would stack up and then show when the player was well past the place where the message originated. Also, the middle of the screen wasn’t always noticeable.

So I changed things so that multiple messages could show above each other, fading out at the end, and so that the messages appear above the player.

I could have used a message class, but I didn’t think the messages really needed that. Instead, I set up a table to hold the message functions and data (as before, using a table keeps everything together and minimises the chances of the user duplicating any of the function or variable names).

Here is the function that adds a new message to the table (along with the first two lines that set up the table).

SS_Message={}
SS_Message.text={}

function SS_Message.Add(txt,t) --txt is message, t is time
    t= (t or 2) + ElapsedTime --time when message ends
    --add message text to existing list
    SS_Message.text[#SS_Message.text+1]={txt,t}
end

After that, I have a draw function that positions the messages above the player’s head (but checking they don’t go off the screen), and draws each one above the other. It also checks if any messages have expired, and removes them from the message table if they have. There is nothing fancy about this code, so I haven’t included it here.

Backgrounds

Side scrollers need backgrounds to make them visually interesting. I wanted two types of background – one for landscapes, above the ground, and the other for the walls of rooms.

1. Landscapes

For landscapes, I want rolling hills. They may need to continue for several screens, and I want them to be created randomly so they are different each time you play.

The noise function built into Codea is very useful for this kind of thing. You give it x (and optionally y, and z) values, and it gives you back a value between -0.5 and +0.5. Depending on how fast you change the x (and y,z if you are using them) values, you can get very smooth or very bumpy results.

How do you get mountains from a series of numbers between -0.5 and +0.5? You can simply use the formula b + h * noise(v) , where b is the base (minimum) height, h is the maximum additional height, and v is the x value given to the noise function. You should vary v to give the right shape. In the code below, I’ve set v equal to 1/200 of the x axis position (so if x=300, v = 1.5).

This is not the same as random numbers, where each number is completely independent of the previous number. They would give you very jagged landscape. Noise smooths it out nicely.

I had to play around to get the effect I wanted (see the background in the image at the top of the post), but in the end here is the code I used.

--x,y is start tile; ww,hh are width and height of landscape
--in tiles; c is colour, rr is roughness of landscape (I used rr=2)
function SS_CreateLandscape(x,y,ww,hh,c,rr)
    --convert to pixels
    local w,h,r=ww*SS_w,hh*SS_h,rr*SS_h 
    --create blank image and draw landscape
    local i=image(w,h)
    setContext(i)
    strokeWidth(1)
    stroke(c)
    --use a random number to make the results slightly different 
    --each time, by adding it to the x value we provide
    local z=math.random()
    --draw a series of vertical lines. pixel by pixel
    for c=1,w do
        local a=h-r+r*noise(z+c/200)
        line(c,1,c,a)
    end
    setContext()
    --add the image to our table of images
    SS_AddImage(i,x-1+ww/2,y-1+hh/2)
    --or you could just return the image
    return i
end

2. Walls of rooms

Ideally, I want to provide an image and draw it over a set of tiles, to show the wall of a room. There is the usual problem that images are very rarely the right size to do this. You can do some image editing to get the exact image you want, but you can also do some editing in Codea itself.

Drawing part of an image

If you just want to draw part of an image (because it is too big), you can use the copy function to make a copy of the part you want, and use that.

Scaling an image

When you sprite an image, you can specify the size, allowing you to shrink (or expand) the image.

Tiling an image

Sometimes you may want to tile an image. For example, you may have the image of a box, and want to draw a wall lined with boxes. You can simply draw all the boxes one by one, but this may slow down your program.

Better may be to create an image the size you want, then draw all the boxes onto it (using setContext to draw to the image rather than the screen). Then you can draw this single image from then on.

I have another way of doing this, using a shader (if you don’t know, a shader is some C code that can produce nice effects – shaders look much harder than they are, and I have an ebook about them). This shader can tile an image over a large area. However, creating an image at the beginning with everything on it (the previous option above) is probably the most efficient.

Inventory

The inventory is pretty simple, just drawing some boxes at upper right of the screen, and putting inventory items in them with a counter for each.

Advertisement

From → Games, Programming

3 Comments
  1. Hello

    First of all thank you for doing this blog, it’s an invaluable resource that I’ve learned masses from.

    About the messaging system.

    Can you explain how the table set up works? Why do you need

    SS_Message={}

    and

    SS_Message.text={}

    is the .text an arbitrary variable you’ve come up with, or does it have meaning in Lua/ Codea? Does the .suffix naming convention next the table inside the first one? Why couldn’t you just use SS_Message for storing the messages?

    Sorry for all the questions. Clearly I need to read more about tables….

  2. Emil permalink

    Hi, I wonder where the full code is for this project? 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: