Make a Shooter in Lua/Love2D - Setup and Player Movement

Published August 09, 2017 by jeansberg
Do you see issues with this article? Let us know.
Advertisement

Hello! This will be the first in a series of posts on developing a simple shoot 'em up game using the Lua programming language and the Love2D framework. I decided to make this game as a bit of a break from another game project that I've been working on for a while. I chose Lua and Love2D due to their focus on simplicity and efficiency. I will be writing these posts as I learn.

Getting started

In order to run the game we are making, you need to install the Love2D framework from https://love2d.org. You might also want to use an IDE or a plugin for your favorite text editor to get things such as autocomplete and syntax checking. Here is a list of such [tools](http://www.gamefromscratch.com/post/2016/01/25/Editors-and-IDEs-for-Lua-and-Love-Development.aspx). Personally I went with the Atom Editor plugin, since Atom is currently my favorite text editor.

Let's write some code!

After we have our tools set up, the first thing we'll do is simply create a folder containing a file named main.lua. This is where the Love2D executable will look for the game code's entry point. This is where we will put all our code for now.

We will start by writing three very important functions:

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

These functions are called by the Love2D engine and are required to get any of our code to run at all. The load() function is called exactly once, when the game is started. The draw() function is called continuously once the game is running and is where any graphics code should be placed. The update() function is also called continuously and is where the state of the game should be updated.

love.load()


function love.load()
  xPos = 0
  yPos = 0
  playerWidth = 64
  playerHeight = 64
  playerSpeed = 200
  submarineImage = love.graphics.newImage("resources/images/submarine.png")
end

The load() function is the perfect place for all kinds of initialization code. We start by defining some integer values for the position, size and speed of the player. We then load an image located on the hard drive - I'm using [this little pixel art submarine I drew](https://github.com/jeansberg/GreatDeep/blob/master/resources/images/submarine.png). This image will represent the player in our game. Note that Lua is a dynamically typed language so we don't need to declare any types for these variables. 

love.draw()


function love.draw()
  love.graphics.draw(submarineImage, xPos, yPos, 0, 2, 2)
end

For now, our draw() function will contain a single line of code to draw the image at the player's current position. Normally you would only need the image, x-position and y-position parameters. The three last parameters are there because I wanted to make my tiny 32x32 pixel image a little bit bigger. The 0 means that the image will not be rotated and the 2s mean that the image's width and height are doubled.

love.update()


function love.update(dt)
  downUp = love.keyboard.isDown("down") or love.keyboard.isDown("up")
  leftRight = love.keyboard.isDown("left") or love.keyboard.isDown("right")

  speed = playerSpeed
  if(downUp and leftRight) then
    speed = speed / math.sqrt(2)
  end

  if love.keyboard.isDown("down") and yPos<love.graphics.getHeight()-playerHeight then
    yPos = yPos + dt * speed
  elseif love.keyboard.isDown("up") and yPos>0 then
    yPos = yPos - dt * speed
  end

  if love.keyboard.isDown("right") and xPos<love.graphics.getWidth()-playerWidth then
    xPos = xPos + dt * speed
  elseif love.keyboard.isDown("left") and xPos>0 then
    xPos = xPos - dt * speed
  end
end

The update() function will contain code for listening to keyboard input and moving the player around. You probably noticed that this function takes a parameter called dt. This is passed to the function by the Love2D engine and indicates how much time has passed since the last update() call. This is used as a multiplier to determine how much our variables should change. Without this adjustment, the speed of our game would directly depend on the speed of the computer running it!

Input handling

We begin by using the built in keyboard.isDown() function to check if any arrow keys are currently being pressed. We store this information in two variables. One will indicate whether the down or up key is being pressed. The other one will do the same for the left and right keys. If both of these values are true, it means the player will be moving diagonally. In that case we need to divide the speed value with the square root of two before we apply it to the x- and y-positions. Otherwise diagonal movement would be much faster than horizontal or vertical movement.

Movement constraints

We then check whether the down or up key is being pressed again (not the most optimal code, but sufficient for a tutorial!). If the down key is being pressed, we increment the y-position, since the y-coordinates start at 0 at the top of the screen. We use dt as a multiplier as mentioned above. It's not enough to merely check the player input however. We don't want the submarine to disappear below the screen, so we make sure the yPos variable is never greater than the height of the screen minus the height of the player (the player width and height are 64 pixels since I doubled the width and height of the image when drawing it). Similarly, we want to make sure that the submarine doesn't go above the screen so we check that yPos is greater than zero. The code for horizontal movement is very similar. 

Conclusion

You can now use love.exe which comes with the Love2D install to run the game! Just make sure you give it the path to the folder containing your main.lua file as a parameter. You should be able to control the submarine with the arrow keys on your keyboard. If you're on a laptop without arrow keys, simply change the "down", "up", "left" and "right" parameters to some letter keys.

In the following post we will take a look at some shooting, so stay tuned!

owpawi4rta5pnmnypqao.gif.ae79405b2cb16ea9e352c85b24fd6b80.gif

Links

Source code for this part
Finished source code

Cancel Save
0 Likes 5 Comments

Comments

Ivan Zherdev

Looks jerky. Not polished. Not good enough for modern game industry.

December 26, 2018 07:42 AM
fleabay
12 minutes ago, Ivan Zherdev said:

Looks jerky.

You do know that's a GIF and not the "game", right?

December 26, 2018 07:58 AM
Ivan Zherdev
24 minutes ago, fleabay said:

...that's a GIF...

Are GIF's limited to 12 FPS?

December 26, 2018 08:24 AM
fleabay

This is his final GIF. Somewhat less jerky.

tkyaysrbzx050gehju4m.gif

For anyone interested, the complete 5 part tutorial is at

https://dev.to/jeansberg/make-a-shooter-in-lualove2d---part-1

December 26, 2018 10:34 AM
jeansberg

Whoa, blast from the past. :)

I did have a hard time exporting good GIFs for some reason.

If it doesn't meet the quality standards, no hard feelings.

December 27, 2018 07:40 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement