spacer

Programming Löve and Lua - Asteroids

Asteroids game animated gifA few months ago my 12 year old niece asked my if I could help her learn how to program. An interesting question. I've been programming for more than 30 years so the answer should be yes. But what to teach her?

Ideally she should be able to create something fun with relatively modest effort. And so I started striking candidates off the list. Eventually the page was empty so I knew I'd have to look further afield.

In my wanderings I was at one time looking at writing an Android app. I'd come across some cross-platform game development environments like Unity 3D. These looked promising but complicated for a novice. After more searching I stumbled across Löve 2D which is an engine that can be scripted using Lua. I'd heard of Lua before in the context of Unity 3D. Since then I've found .lua files lurking all over the place. It's a lot more popular than I'd initially thought.

The Löve 2D environment provides support for drawing graphics both vector and bitmap. It plays audio files either by streaming or straight from memory. It can query all the usual input devices so your program can be controlled by keyboard, mouse, joystick, etc. At first glance things look fine but simple, but as you look further you find many deep features that you can tap. Things like distance attenuation for sounds, font support, timers, events, some sort of shader effects and even a physics engine.

The Lua language is straightforward and is familiar enough that if you've done C or Pascal or even Visual Basic, it's easy to pickup. For a novice it seems a fun way to start. The tables (arrays on steroids) are particularly powerful; a cross between normal arrays and dictionaries.

Learning Löve and Lua may be the spark that leads to a passion for programming.

Proof of Concept

I started preparing some tutorials for my niece to ease her into programming. In about the fourth tutorial I started to develop a simple game based on the old arcade classic "Asteroids". Before going too far I wanted to prove to myself that Löve was capable of powering such a modest game. This write up briefly describes my experiences and will also list all the tutorials for my niece so anyone interested can follow along.

Love/Lua Source Code and All Media Files

Asteroids like game written in Löve - screen shot

Installing Löve and Notepad++

Löve is a 2D game engine with a Lua interpreter built in. It can be found here and is available for Windows, Mac OSX and Ubuntu. Under Windows, at least, it installs easily. I also added the love folder to the system path to simplify a later step. If you run love.exe by itself it runs a built-in program called 'Rubber Piggy'. Cute.

Löve has no IDE so the first thing to do is find an editor and ideally one that understands Lua and can link to Löve. Notepad++ fills the bill reasonably well. There are others but the ones I tried disappointed. You can download a lua.xml file for Notepad++ to add syntax highlighting and limited auto completion.

Use Windows to set Notepad++ as the default editor for .lua files.

It's nice to have a hot key to launch your Löve programs. You can edit shortcuts.xml that appears in the Notepad++ program folder and in your appdata/roaming/notepad++ directory and add one. I duplicated the line for FireFox.

I changed "Launch in Firefox" to "Launch in Love"

and I changed

firefox "$(FULL_CURRENT_PATH)"

to

love "$(CURRENT_DIRECTORY)"

If you didn't add love to the system path you may need to specify the full directory to the love.exe in the line above.

Once you've done these steps you can edit the shortcut keys within Notepad++ using the menu option "Run, Modify Shortcut".

The Anatomy of a Löve Program

The Löve engine functions by making callbacks to a few standard functions whose contents we specify. These are

love.load()
love.draw()
love.update()

First, Löve calls love.load() once. In here you'll initialize everything, load resources such as graphics and sounds, and do any other one-time activities.

Next, Löve goes into a loop alternately calling love.draw() followed by love.update().

The first function, love.draw(), is responsible for drawing the current frame.

The second function, love.update(dt), checks for user inputs if any, updates variables, plays sounds, etc. It has an optional argument, dt, that tells how many seconds have elapsed since the last frame. This allows us to compensate for changes in the frame rate and produce something that runs at a constant speed.

Löve and Lua Lessons

My niece has no programming experience. As a typical near-teen she is familiar with smart phones, game consoles, and the like. She has a Windows 7 PC that she is learning to use. This is where I'm starting from.

Tutorial 1 - Löve and Lua

This explains the mechanics of creating and running your first Löve program. It tries to explain the basic idea of a function without going too deep. At the end, one will have created the equivalent of a hello world program.

Tutorial 2 - Variables and Simple Flow Control

This lesson introduces the idea of variables and why they're useful. It gives the basics of naming variables and case sensitivity. Lua variables are great because they can store anything, even a function or Lua code. Finally it introduces IF THEN END to control the flow of execution.

Start Creating an Asteroids Game

Tutorial 3 - Tables and Animation

This lesson introduces tables. Tables are like arrays but can use either numeric or text keys rather than simple numeric indeces. Using tables you can create classic arrays as well as structures.

testTable = {"apple",4,"sixteen")

testTable[1] contains "apple"
testTable[2] contains 4
testTable[3] contains "sixteen"

testTable = {fruit="apple",plates=4,age="sixteen")

testTable["fruit"] or testTable.fruit contains "apple"
testTable["plates"] or testTable.plates contains 4
testTable["age"] or testTable.age contains "sixteen"

Cool!

Also a simple spaceship engine animation is created by alternating between two pictures. The spaceship comes alive as it boosts it's away around the screen.

Tutorial 4 - Fixing Time (associated files)

As the programs get more complicated, the frame rate will vary and uneven. Without some compensation, animations will speed up and slow down as the frame rate varies. This short lesson shows how to use dt (deltaTime) to constant motion regardless of the current frame rate.

Tutorial 5 - Sound (associated files)

Here we start to jazz up the program. We add some atmospheric background music by StellarDrone and some egine sound to our rocket flying around the screen. It shows the difference between streaming and playing samples loaded in memory.

Tutorial 6 - Using Functions (associated files)

Here we'll begin moving code into functions in anticipation of adding more space junk. Developing a few thought out functions will make finishing the game much easier.

The remaining tutorials are not done BUT the code that these would develop is in the complete source code linked near the start of this page. Your understanding is appreciated.

Tutorial 7 - Collisions

Now that we have our spaceship, asteroids and bullets flying about, we tackle collisions. This leads to table.insert and table.remove to manage our menagery of space objects.

Tutorial 8 - Creating a simple UI

Finally the finishing touches. We add a pregame UI to begin a game, and some end conditions to signal when the game is over. We take a quick peak at love.filesystem to see how we can maintain a high-score file.

 

And that's it. Nothing terribly fancy but a functional Asteroids type game. Enjoy.

--- end ---