# A Löve2D Tutorial — Part 05 Animate!

This is the fith part of a Löve2D tutorial. This is part is based heavely (HEAVELY) in the tutorial available at the Löve2D Wiki. Take a look!

Given all that we have seen so far, this might be a good moment to get into the animation topic. In most games, the characters, enemies and scenario have some kind of movement that makes the gaming experience so much more enjoyable. It might look very simple at first, but it actually involves a lot of theory and techniques in art, math and computer science which cannot be covered here, but we can touch the surface of it and explain how to create simple animations with love2d.

So, let’s create an animated “hero” and explain some key points about it:

`local elapsed = 0local scale = 4  -- scale works better as a global variable-- This function loads an sprite sheet (coff coff, a image -- composed of smaller images) and maps quadrants (coff coff -- the position of each smaller image)-- for each individual sprite (coff coff the smaller image), -- so we can show little bits of the image individually.-- -- path: image file path-- width: width of each sprite in the image-- height: height of each sprite in the image-- duration: total duration of the animation; NOT individual sprite changelocal function sprite_animation (path, width, height, duration, pos_x)  local image = love.graphics.newImage(path)  local quads = {}  -- if not specified, the animation will take 1s  duration = duration or 1    -- map quadrants; we have 1 row of sprites, each with   -- 16px width and 18px height  for y=0, image:getHeight()-height, height do    for x=0, image:getWidth()-width, width do      table.insert(quads, love.graphics.newQuad(x, y, width, height, image:getDimensions()))    end  end    return {    x = pos_x or 0,    y = 0,    width = width,    height = height,    speed = 120,    quads = quads,    sprite_sheet = image,    duration = duration,    time = 0,    -- using a function makes it easier to debug    get_sprite_num = function (self)      return math.floor(self.time / self.duration * #self.quads) + 1    end,    -- returns the quadrant, which tells which part of the image    -- to draw    get_quad = function (self)      return self.quads[self:get_sprite_num()]    end,    update_time = function (self, dt)      -- update time so we can change the showing sprite      -- as time goes by      self.time = self.time + dt            -- make sure our time doesn't go too high      if self.time >= self.duration then        -- if duration is smaller than dt, we could        -- have issues, but that is unlikely        self.time = self.time - self.duration      end    end,    draw = function (self)      -- draws our hero based on its current state            -- if hero is going left, we mirror the image      -- note: a better approach would "remember" the direction      -- the hero is moving, and not flip it back to the right      -- by default      if love.keyboard.isDown('left') then        love.graphics.draw(          self.sprite_sheet, self:get_quad(),           self.x+self.width*scale, self.y, -- correct position after rotation          math.pi,  -- rotate           scale, -scale  -- negative scale flips the image        )      else        love.graphics.draw(          self.sprite_sheet, self:get_quad(),           self.x, self.y,           0,           scale, scale        )      end    end  }endlocal function make_hero ()  -- loads the hero sprite sheet as an animation  return sprite_animation('hero.png', math.floor(96/6), 18)endfunction love.load ()  -- loads hero animation into a global variable  hero = make_hero()endfunction love.update (dt)  -- keep track of time  elapsed = elapsed + dt  -- update our hero internal time  hero:update_time(dt)    -- I think our hero should be able to move. Don't you?  if love.keyboard.isDown('left') then    hero.x = math.max(hero.x - hero.speed * dt, 0)  end  if love.keyboard.isDown('right') then    hero.x = math.min(hero.x + hero.speed * dt, 400 - 16 * scale)  endendfunction love.draw()  -- draws our hero in position (0, 0), without an angle and scaled by 4  hero:draw()  -- here you could use print with a mono spaced font to avoid this  -- weird string spacing  love.graphics.printf('      elapsed: ' .. string.format('%.2f', elapsed), 10, 100, 300)  love.graphics.printf(' sprite time: ' .. string.format('%.2f', hero.time), 10, 80, 300)  love.graphics.printf(' sprite num: ' .. hero:get_sprite_num(), 10, 120, 200)end`

So, what is the big idea here? To create a animated character in most game engines, you basically loads a big image (sprite sheet) composed of smaller images (sprites), maps the position of each sprite and shows them sequentially, changing them during the duration of the animation. Of course there are other techniques that can be used, but this one is quite resource aware and easy to implement. Therefore, we use it in our example.

Basically we create an animation loading function that loads our sprite sheet into a hero variable. The loaded animation knows how to draw itself and rotate between the available squads (objects that map where each sprite is in the sprite sheet).

As we know the size of each square where the sprite is contained (16, 18), we iterate over the total image size mapping each sprite to a squad. Then we define how long should it take to go over every mapped squad (the duration) and change the sprite that is showed on each fraction of the duration as time goes by.

I also thought it would be a good idea to make our hero look left when it is walking left. That is done using negative scale technique and rotation. You can see the final result by pressing left and right arrow keys with the example running, which should look like this: