I've gotten a fair amount of traffic on my first Love2d post comparing it with Unity3d. I've decided to go ahead and write a series of tutorials on Love2d development. This is the first entry in that series.
I've been working in Love2d for awhile now, but I still don't have much to show for it. Game development can be time consuming and technically challenging. This weekend I was thinking about the problem and realized that if I dropped all the planning ahead it might be possible to hammer out a game quickly. So I tried it. This time I set out to create the simplest possible game in the shortest amount of code. The result is on GitHub here. It's about 178 lines of code INCLUDING configuration and comments.
In Love2d you can write a complete game in under 200 lines of code. It'll take the space of an afternoon.
1. Getting Setup
I'm assuming no knowledge of programming or Love. If you're familiar with either or have spent some time in other tutorials feel free to skip to section 2 or even 3.
Love2d is a great, completely free, simple 2D game engine. I cannot recommend it enough for beginners. The community is great and no one is trying to sell you anything (compare that to GameMaker or Unity!) Go ahead and download the proper version of Love for your system. I'll be covering usage in Windows here and I'll link some Mac setup tips. If you're using Linux or if you need more help you can check out the Love wiki page on getting started.
For windows just unzip the Love archive into whichever directory you'd like. I place my in C:\GameDev so that I have a very short path to the file, but you can put it anywhere. I'll also create a folder named "ScrollingShooter" in C:\GameDev. If you prefer to have your Love executable in a different directory you can create a new shortcut in the folder above ScrollingShooter. When we want to launch the game all we do is drag the ScrollingShooter folder onto the Love executable or shortcut.
Inside ScrollingShooter I'm going to create 3 files and 2 folders. The folders are
assets (where we will be storing our graphics) and
bin (for our .love file and executables. Go ahead and create these folders.
For text editing I'm using Atom with language-lua installed. You can use any code editor you'd like. Some good editors include TextMate, Notepad++, and Sublime. Some of these options cost but Atom is completely free.
I'm going to open the ScrollingShooter directory in Atom then create two new files. The first file is
conf.lua. This is a special file. Unlike other source files, the contents of
conf.lua are parsed before Love finishes initializing. This means we can set things like the window size and other variables that may be locked once the game has started.
-- Configuration function love.conf(t) t.title = "Scrolling Shooter Tutorial" -- The title of the window the game is in (string) t.version = "0.9.1" -- The LÖVE version this game was made for (string) t.window.width = 480 -- we want our game to be long and thin. t.window.height = 800 -- For Windows debugging t.console = true end
love.conf(t) is a special function that is executed before any other Love modules are loaded. We're going to keep it simple. It takes a single argument usually called
t. This argument will store the game configuration. We're just going to set the title of our window --
t.title -- and the version of Love we're building this for --
t.version. Then we'll set the window width and height. Finally, we set
true so that we can see errors written in a console window when debugging on Windows. You'll want to change this to false before releasing your game.
A complete list of the attributes you can pass to
t can be found on the Config files wiki.
Next create a file next to
main.lua. This file will store all of our game logic. These are the only two code files we will need. We'll start by filling
main.lua with the basic Love bits. It'll look like this:
debug = true function love.load(arg) end function love.update(dt) end function love.draw(dt) end
The first line just sets a variable called "debug" to true. You'll want to flip this to false before release. I use this variable later for determining whether or not to write things like the frames-per-second to the screen. I'll demonstrate in a little bit.
Next we have three functions. These are called by the Love engine.
love.load is called when the game first starts. We'll load our assets -- images, sounds, etc -- here.
love.draw are called on every frame. Every action here will occur several times a second. Both of these function take
deltaTime as an argument. This is a measure of how much time has passed since the last call. We'll multiply our timers by these values to ensure the game runs the same on your friends old laptop that gets 30 fps or your brand new gaming rig that gets 700 fps.
3. Drawing to the Screen
Before we go any farther, lets just draw something to the screen. I'm not much of an artist, but I know where to find people that are. For this project I'll be using some pixel airplanes created by chabull and distributed for free on OpenGameArt.org. You can download them here.
I'm going to take Airplane_3.png from that graphics kit, drop it in our assets folder, and rename it plane.png. To get this showing up in Love2d we have two steps.
- Load the image into memory
- Draw the image
main.lua. Let's use them.
First, load the image into memory.
playerImg = nil -- this is just for storage function love.load(arg) playerImg = love.graphics.newImage('assets/plane.png') --we now have an asset ready to be used inside Love end
Next we add a draw command inside our draw function. Please note that draw commands must be called inside the draw function. They need to be executed every frame and the draw function is called every frame.
function love.draw(dt) love.graphics.draw(playerImg, 100, 100) end
Our application is ready to run! Just drag the entire ScrollingShooter folder onto love.exe or a shortcut to love.exe and the application will start. The complete source for this example can be found on GitHub.
It doesn't look like much, but it's a start! You'll note that
love.graphics.draw has a second and third argument. For this example I've passed in 100 and 100. These are the x and y coordinates (respectively) where the image will be drawn. We'll talk more about those in part 2.