GameDev with Love (2D)
Tue Jul 23 2024
Start your Love2d journey!!! I'll get over libreries and programming technices to get a finel game.
Love2d is a great framework for getting into game development because many engines work with quite complex concepts behind the scenes. For this reason, I started using Love2d for personal basic projects, and I’m here to explain how to get started in this way.
Installing Love2d
To run Love2d, you first need to install Lua, which is a powerful programming language used in many modern projects like Neovim, web apps, and Roblox map-making.
On Windows (Chocolatey):
choco install lua53
On Ubuntu:
sudo apt install lua5.3 # or other versions
On other systems:
#------- Brew -------
brew install lua
#------- Arch-based (pacman) -------
sudo pacman -S lua
#------- On RHEL, CentOS, Rocky, and AlmaLinux -------
yum install epel-release
yum install lua
#------- On Fedora Linux -------
dnf install lua
Once you have installed Lua, Love2d will be available. I recommend visiting the official website and following the instructions depending on your system.
Game Structure
Love2d works with 3 basic functions: load()
, update()
, draw()
. Each of these functions must be declared in the main file named main.lua, which is essential for running Love2d (where all the physics, classes, objects, and other game elements are handled).
main.lua
Here, we are going to write our first Love2d game! So let’s get started. First, we need to put the functions into the main.lua
file.
function love.load() end
function love.update(dt) end
function love.draw() end
Now, let’s discuss them.
love.load()
Inside this function, we are going to load all the necessary resources for the game; we can also create bodies, load images, set timers, define variables, etc. This is because some things don’t need to be loaded every frame, and here we can call them for later use.
love.update(dt)
Here, the game is updated every frame. This includes calculating math, angles, algorithms, and everything needed to draw the game. In this function, we’ll bind all the keys to wait for input and trigger actions.
love.draw()
Every character needs a sprite or a figure (at minimum), and inside this function, we declare this using love.graphics
functions, giving us access to all the geometric functions to draw and paint sprites.
Libraries
In this course, we can use the built-in functions of Love2d, but I think it’s unnecessary since many people on the internet have created a whole set of libraries ready to use. That’s why I’ve decided to present the libraries I use in my projects. I’m grateful to a327ex for creating a Love2d blog where I learned a lot, and for making many libraries for Love2d.
I highly recommend checking out the documentation for each library. You can also check out this repo where there are more libraries for Love2d.
Object-Oriented Programming
When we are developing a game is necesary to generate objects to control each character, npc or item in the game. Love2d doesn’t includes an OOP handler or manager, that’s why I like to use Classic, because this librarie manage tipical functions of Objects like extend()
or self.super:func()
to call functions of parent objects.
I like to create one file for each character. For example, on a Player.lua
:
Object = require("path/to/Object")
Player = Object:extend()
function Player:new(area,x,y,opts)
self.super:new(area,x,y,opts)
end
function Player:update(dt)
self.super:update(dt)
--update body physics
--update controls
end
function Player:draw()
self.super:draw()
end
On this way we call the object Player on the main.lua
by :
Physics
This library is pretty easy to use because it sets up all the necessary components to handle a body. I like this because we don’t want problems while coding the game.
Windfield works like this: first, you create a world, then you can create bodies, joints, and apply physics.
Here’s an example:
Physics = require("path/to/windfield")
function love.load()
-- create a world with no gravity
world = Physics.newWorld(0,0)
-- create a rectangle at (0,0) with dimensions 10x30
body = world:newRectangleCollider(0,0,10,30)
-- we can modify every attribute of the body
body:setRestitution(0.1)
end
function love.update(dt)
-- update the world physics
world:update(dt)
end
function love.draw()
-- draw the world (only body borders)
world:draw()
end
Inputs
Every game needs an input flux to work, and this librarie will help us to manage that input signs.
function love.load()
IN = Input()
IN:bind("up","jump")
IN:bind("left","move_left")
IN:bind("right","move_right")
end
function love.update(dt)
if IN:pressed"jump") then
--calculate the jump - pressed only evaluate when the key goes down.
end
if IN:down("move_left") then
--calculate move to left - down evaluate every cycle while the key is down.
end
end
Camera
The camera is pretty important to get a inmersive game, that’s why I love to use this lib, because is simple and ready to use.
function love.load()
camera = Camera()
end
function love.update(dt)
camera:update(dt)
end
function love.draw()
camera:attach()
-- Draw your game here
camera:detach()
camera:draw() -- Call this here if you're using camera:fade, camera:flash or debug drawing the deadzone
end
Timers
When and enemy or item is alive, the most of the time they internally have a timer with a predefined or random lifetime (miliseconds ,seconds or minutes).
function love.keypressed(key)
if key == ' ' then
Timer.after(1, function() print("Hello, world!") end)
end
end
function love.update(dt)
Timer.update(dt)
end
UI
Buttons, input text or modals are essential to interact with the game interface, maybe on a main menu or settings menu.
local yui = require 'lib.yui'
function love.load()
local w, h = 300, 80
local x = math.floor((love.graphics.getWidth() - w) / 2)
local y = math.floor((love.graphics.getHeight() - h) / 2)
ui = yui.Ui:new {
x = x, y = y,
yui.Rows {
yui.Label {
w = w, h = h / 2,
text = "Hello, World!"
},
yui.Button {
text = "Close",
onHit = function() love.event.quit() end
}
}
}
end
function love.update(dt)
ui:update(dt)
end
function love.draw()
ui:draw()
end
https://gitea.it/1414codeforge/yui