Programming Fundamentals  
Lecture 06 Arrays, Matrices, Animations and  
World Representations  
Edirlei Soares de Lima  
<edirlei.lima@universidadeeuropeia.pt>  
Arrays  
Arrays are sequences of items (like variables) of the same  
type.  
Each item is identified by an index (integer).  
With arrays we can store in memory sequences of values  
numbers, text, imagens, etc.), which are all associated with a  
single variable (the array).  
(
Arrays in Lua  
In Lua, are implemented through tables indexed by integer  
numbers.  
Different from many other programming languages, in Lua we  
don't need to define the maximum size of an array.  
Creating a new array:  
my_array = {}  
Arrays in Lua  
Initializing some positions of the array:  
my_array[1] = 5  
my_array[2] = 11  
my_array[5] = 0  
my_array[10] = 3  
Table Functions  
Size of an array:  
arr = {1, 2, 1, 6}  
size = #arr  
Add elements:  
arr = {1, 2, 1, 6}  
table.insert(arr, 8)  
table.insert(arr, 1, 10)  
Remove elements:  
arr = {1, 2, 1, 6}  
table.remove(arr, 4)  
table.remove(arr, 1)  
Example 1: Platforms, Arrays and Camera  
require "vector2"  
world.lua  
function CreateObject(x, y, w, h)  
return {position = vector2.new(x, y), size = vector2.new(w, h)}  
end  
function DrawWorld(world)  
for i = 1, table.getn(world), 1 do  
love.graphics.rectangle("fill", world[i].position.x,  
world[i].position.y, world[i].size.x, world[i].size.y)  
end  
end  
function GetBoxCollisionDirection(x1,y1,w1,h1,x2,y2,w2,h2)  
local xdist = math.abs((x1 + (w1 / 2)) - (x2 + (w2 / 2)))  
local ydist = math.abs((y1 + (h1 / 2)) - (y2 + (h2 / 2)))  
collision.lua  
local combinedwidth = (w1 / 2) + (w2 / 2)  
local combinedheight = (h1 / 2) + (h2 / 2)  
...  
Example 1: Platforms, Arrays and Camera  
if(xdist > combinedwidth) then  
return vector2.new(0, 0)  
end  
collision.lua  
if(ydist > combinedheight) then  
return vector2.new(0, 0)  
end  
local overlapx = math.abs(xdist - combinedwidth)  
local overlapy = math.abs(ydist - combinedheight)  
local playerdir = vector2.normalize(vector2.sub(vector2.new(x1,y1),  
vector2.new(x2,y2)))  
local collisiondir  
if overlapx > overlapy then  
collisiondir = vector2.normalize(vector2.new(0, playerdir.y *  
overlapy))  
elseif overlapx < overlapy then  
collisiondir = vector2.normalize(vector2.new(playerdir.x *  
overlapx, 0))  
else  
collisiondir = vector2.normalize(vector2.new(playerdir.x *  
overlapx, playerdir.y * overlapy))  
end  
return collisiondir  
end  
Example 1: Platforms, Arrays and Camera  
require "vector2"  
require "collision"  
player.lua  
local player = {  
position = vector2.new(400, 100),  
velocity = vector2.new(0, 0),  
size = vector2.new(30, 60),  
maxspeed = 400,  
mass = 1,  
frictioncoefficient = 300,  
onGround = false  
}
function UpdatePlayer(dt, world)  
local acceleration = vector2.new(0, 0)  
local gravity = vector2.new(0, 500)  
acceleration = vector2.applyForce(gravity, player.mass,  
acceleration)  
...  
Example 1: Platforms, Arrays and Camera  
local friction = vector2.mult(player.velocity, -1)  
player.lua  
friction = vector2.normalize(friction)  
friction = vector2.mult(friction, player.frictioncoefficient)  
acceleration = vector2.applyForce(friction, player.mass,  
acceleration)  
local movedirection = vector2.new(0, -1)  
if love.keyboard.isDown("right") then  
local move = vector2.new(500, 0)  
acceleration = vector2.applyForce(move, player.mass, acceleration)  
movedirection.x = 1  
end  
if love.keyboard.isDown("left") then  
local move = vector2.new(-500, 0)  
acceleration = vector2.applyForce(move, player.mass, acceleration)  
movedirection.x = -1  
end  
if love.keyboard.isDown("up") and (player.onGround) then  
player.velocity.y = -450  
movedirection.y = 1  
player.onGround = false  
end  
Example 1: Platforms, Arrays and Camera  
player.lua  
local futurevelocity = vector2.add(player.velocity,  
vector2.mult(acceleration, dt))  
futurevelocity = vector2.limit(futurevelocity, player.maxspeed)  
local futureposition = vector2.add(player.position,  
vector2.mult(futurevelocity, dt))  
acceleration = CheckCollision(world, futureposition,  
movedirection, acceleration)  
player.velocity = vector2.add(player.velocity,  
vector2.mult(acceleration, dt))  
player.velocity = vector2.limit(player.velocity, player.maxspeed)  
player.position = vector2.add(player.position,  
vector2.mult(player.velocity, dt))  
end  
function DrawPlayer()  
love.graphics.setColor(0.2, 0.2, 0.9)  
love.graphics.rectangle("fill", 380, player.position.y,  
player.size.x, player.size.y)  
end  
Example 1: Platforms, Arrays and Camera  
function CheckCollision(world, futureposition, movedirection,  
player.lua  
acceleration)  
for i = 1, table.getn(world), 1 do  
local collisiondir = GetBoxCollisionDirection(futureposition.x,  
futureposition.y, player.size.x, player.size.y,  
world[i].position.x, world[i].position.y,  
world[i].size.x, world[i].size.y)  
if not (collisiondir.x == 0 and collisiondir.y == 0) then  
if collisiondir.y == movedirection.y then --down collision  
player.velocity.y = 0  
acceleration.y = 0  
player.onGround = true  
elseif collisiondir.y == 1 then --up collision  
player.velocity.y = 0  
acceleration.y = 0  
elseif movedirection.x ~= collisiondir.x then --side collision  
player.velocity.x = 0  
acceleration.x = 0  
end  
end  
end  
return acceleration  
end  
Example 1: Platforms, Arrays and Camera  
function GetPlayerPosition()  
return player.position  
end  
player.lua  
require "vector2"  
require "world"  
require "player"  
main.lua  
local world = {}  
function love.load()  
world[1] = CreateObject(50, 550, 1200, 50)  
world[2] = CreateObject(500, 450, 50, 50)  
world[3] = CreateObject(750, 500, 100, 50)  
world[4] = CreateObject(1000, 420, 150, 50)  
end  
function love.update(dt)  
UpdatePlayer(dt, world)  
end  
Example 1: Platforms, Arrays and Camera  
function love.draw()  
love.graphics.setColor(0.2, 0.2, 0.9)  
DrawPlayer()  
main.lua  
love.graphics.setColor(0.2, 0.8, 0.2)  
local playerpos = GetPlayerPosition()  
love.graphics.translate(-(playerpos.x - 380), 0)  
DrawWorld(world)  
end  
Example 2: Arrays and Enemies  
require "vector2"  
enemy.lua  
function CreateEnemy(x, y, r, t)  
local mdir, vdir  
if t == 1 then  
mdir = vector2.new(1, 0)  
vdir = vector2.new(-100, 0)  
elseif t == 2 then  
mdir = vector2.new(0, -1)  
vdir = vector2.new(0, 100)  
end  
return {position = vector2.new(x, y),  
velocity = vdir,  
radius = r,  
etype = t,  
mass = 1,  
movedirection = mdir,  
movechangetime = 2,  
movetimer = 0}  
end  
Example 2: Arrays and Enemies  
function UpdateEnemies(dt, enemies)  
for i = 1, table.getn(enemies), 1 do  
enemy.lua  
local acceleration = vector2.new(0, 0)  
if enemies[i].etype == 1 or enemies[i].etype == 2 then  
local moveForce = vector2.mult(enemies[i].movedirection, 100)  
acceleration = vector2.applyForce(moveForce, enemies[i].mass,  
acceleration)  
enemies[i].velocity = vector2.add(enemies[i].velocity,  
vector2.mult(acceleration, dt))  
enemies[i].velocity = vector2.limit(enemies[i].velocity, 100)  
enemies[i].position = vector2.add(enemies[i].position,  
vector2.mult(enemies[i].velocity, dt))  
enemies[i].movetimer = enemies[i].movetimer + dt  
if enemies[i].movetimer > enemies[i].movechangetime then  
enemies[i].movetimer = 0  
enemies[i].movedirection =  
vector2.mult(enemies[i].movedirection, -1)  
end  
end  
end  
end  
Example 2: Arrays and Enemies  
function DrawEnemies(enemies)  
for i = 1, table.getn(enemies), 1 do  
if enemies[i].etype == 1 then  
enemy.lua  
love.graphics.setColor(0.8, 0.0, 0.0)  
elseif enemies[i].etype == 2 then  
love.graphics.setColor(0.8, 0.8, 0.0)  
end  
love.graphics.circle("fill", enemies[i].position.x,  
enemies[i].position.y, enemies[i].radius, 30)  
end  
end  
require "vector2"  
require "world"  
require "player"  
require "enemy"  
main.lua  
local world = {}  
local enemies = {}  
Example 2: Arrays and Enemies  
function love.load()  
enemy.lua  
world[1] = CreateObject(50, 550, 1200, 50)  
world[2] = CreateObject(500, 450, 50, 50)  
world[3] = CreateObject(750, 500, 100, 50)  
world[4] = CreateObject(1000, 420, 150, 50)  
enemies[1] = CreateEnemy(650, 500, 20, 1)  
enemies[2] = CreateEnemy(1100, 350, 20, 2)  
end  
function love.update(dt)  
UpdatePlayer(dt, world)  
UpdateEnemies(dt, enemies)  
End  
function love.draw()  
love.graphics.setColor(0.2, 0.2, 0.9)  
DrawPlayer()  
love.graphics.setColor(0.2, 0.8, 0.2)  
local playerpos = GetPlayerPosition()  
love.graphics.translate(-(playerpos.x - 380), 0)  
DrawWorld(world)  
DrawEnemies(enemies)  
end  
Arrays and Animations  
Animations are created by sequences of images.  
Example:  
We can store animations as arrays of images!  
require "vector2"  
local hero = {  
walk = {}, -- array of images  
anim_frame = 1,  
position = vector2.new(100, 225),  
velocity = vector2.new(0, 0)  
}
function love.load()  
for i = 1, 4, 1 do -- load the animation frames  
hero.walk[i] = love.graphics.newImage("Hero_Walk_0" .. i .. ".png")  
end  
end  
function love.draw() -- draw the character using the animation index  
love.graphics.draw(hero.walk[hero.anim_frame], hero.position.x,  
hero.position.y)  
end  
...  
...  
function love.update(dt)  
if love.keyboard.isDown("right") then  
hero.velocity = vector2.new(100, 0)  
hero.anim_frame = hero.anim_frame + 1 -- increases the anim. index  
if hero.anim_frame > 4 then  
hero.anim_frame = 1  
end  
-- animation loop  
else  
hero.velocity = vector2.new(0, 0)  
end  
hero.position = vector2.add(hero.position,  
vector2.mult(hero.velocity, dt))  
end  
Example of Animation  
Problem: we did not control the speed of the animation!  
The faster the computer, the faster the animation will be played.  
function love.update(dt)  
if love.keyboard.isDown("right") then  
hero.velocity = vector2.new(100, 0)  
hero.anim_timer = hero.anim_timer + dt -- increases the time with dt  
if hero.anim_timer > 0.1 then  
-- when time gets to 0.1  
hero.anim_frame = hero.anim_frame + 1 -- increases the anim. index  
if hero.anim_frame > 4 then  
hero.anim_frame = 1  
end  
-- animation loop  
hero.anim_timer = 0  
-- reset the time counter  
end  
else  
hero.velocity = vector2.new(0, 0)  
end  
hero.position = vector2.add(hero.position,  
vector2.mult(hero.velocity, dt))  
end  
Exercise 1  
) Continue the implementation of the last exercise by adding the  
animations and movement of the character to all other  
directions. Use the following images:  
1
Texture Atlas  
A texture atlas (also called a  
sprite sheet or an image sprite) is  
an image containing a collection  
of smaller images, usually packed  
together to reduce the atlas size.  
It is often more efficient to store  
the textures in a texture atlas  
which is treated as a single unit  
by the graphics hardware.  
https://edirlei.com/aulas/gameprog/spritesheet_example.png  
require "vector2"  
local hero = {  
position = vector2.new(100, 225),  
velocity = vector2.new(0, 0),  
spritesheet = love.graphics.newImage("spritesheet_example.png"),  
spritesheetQuads = {},  
anim_frame = 1,  
anim_timer = 0  
}
function CreateSpriteSheetQuads(spritesheet, cols, rows, w, h)  
local quads = {}  
local count = 1  
for j = 0, rows - 1, 1 do  
for i = 0, cols - 1, 1 do  
quads[count] = love.graphics.newQuad(i * w , j * h, w, h,  
spritesheet:getWidth(), spritesheet:getHeight())  
count = count + 1  
end  
end  
return quads  
end  
...  
function love.load()  
hero.spritesheetQuads = CreateSpriteSheetQuads(hero.spritesheet, 4, 4,  
6
4, 64)  
end  
function love.draw()  
love.graphics.draw(hero.spritesheet,  
hero.spritesheetQuads[hero.anim_frame],  
hero.position.x, hero.position.y)  
end  
function love.update(dt)  
if love.keyboard.isDown("down") then  
hero.velocity = vector2.new(0, 100)  
hero.anim_timer = hero.anim_timer + dt  
if hero.anim_timer > 0.1 then  
hero.anim_frame = hero.anim_frame + 1  
if hero.anim_frame > 4 then  
hero.anim_frame = 1  
end  
hero.anim_timer = 0  
end  
...  
...  
elseif love.keyboard.isDown("right") then  
hero.velocity = vector2.new(100, 0)  
hero.anim_timer = hero.anim_timer + dt  
if hero.anim_timer > 0.1 then  
if hero.anim_frame < 9 or hero.anim_frame > 12 then  
hero.anim_frame = 9  
end  
hero.anim_frame = hero.anim_frame + 1  
if hero.anim_frame >= 12 then  
hero.anim_frame = 9  
end  
hero.anim_timer = 0  
end  
else  
hero.velocity = vector2.new(0, 0)  
end  
hero.position = vector2.add(hero.position,  
vector2.mult(hero.velocity, dt))  
end  
Matrices  
Matrices are two-dimensional arrays.  
A matrix stores data in an organized form with rows and  
columns.  
3
7
1
5
6
1 8 6 1  
2 5 4 9  
9 3 1 2  
8 6 7 3  
4 9 2 1  
Matrices in Lua  
Declaring and initializing a matrix:  
my_matrix = {}  
-- new matrix  
for i=1, 10, 1 do  
my_matrix[i] = {} -- new row  
for j=1, 10, 1 do  
my_matrix[i][j] = 0  
end  
end  
We are defining and initializing a matrix with 10 columns e 10 rows.  
Matrices in Lua  
We can access the values stored in the matrix using their two-  
dimensional indexes.  
1
2 3  
1
5
? ?1  
?
?
?
? ?  
?8 ?  
2
3
my_matrix[1][1] = 5;  
my_matrix[2][3] = 8;  
my_matrix[3][1] = 1;  
Matrices and Game Worlds  
We can use matrices to represent 2D game worlds.  
Example:  
Matrices and Game Worlds Example 1  
Generating a random matrix and drawing its elements on  
screen using colors.  
local world = {}  
function love.load()  
for i=1, 26, 1 do -- initializes a random matrix (26 x 20)  
world[i] = {}  
for j=1, 20, 1 do  
world[i][j] = love.math.random(0, 3)  
end  
end  
end  
function love.draw()  
for i=1, 26, 1 do -- iterates through the matrix and draw the elements  
for j=1, 20, 1 do  
if (world[i][j] == 0) then  
love.graphics.setColor(1, 0, 0)  
elseif (world[i][j] == 1) then  
love.graphics.setColor(0, 1, 0)  
elseif (world[i][j] == 2) then  
love.graphics.setColor(0, 0, 1)  
elseif (world[i][j] == 3) then  
love.graphics.setColor(1, 1, 0)  
end  
love.graphics.rectangle("fill", (i * 30)-20, (j * 30)-30, 30, 30)  
end  
end  
end  
Matrices and Game Worlds Example 1  
Matrices and Game Worlds Example 2  
Reading a matrix from a file and drawing its elements  
on screen using colors.  
World1.txt  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAAAGGGGG  
GGGGGGGGAGGGGG  
GGGGGGGGAGGGGG  
PPPPPPPPAPPPPP  
AAAAAAAAAAAAAA  
AAAAAAAAAAAAAA  
Matrices and Game Worlds Example 2  
local world = {}  
function LoadMap(filename)  
- reads the content of the file  
local file = io.open(filename)  
local i = 1  
for line in file:lines() do  
world[i] = {}  
for j=1, #line, 1 do  
world[i][j] = line:sub(j,j)  
end  
i = i + 1  
end  
file:close()  
end  
function love.load()  
LoadMap("World1.txt")  
end  
.
.
.
Matrices and Game Worlds Example 2  
.
.
.
function love.draw()  
for i=1, 10, 1 do -- iterates through the matrix and draw the elements  
for j=1, 14, 1 do  
if (world[i][j] == "P") then  
love.graphics.setColor(0.901, 0.921, 0.525)  
elseif (world[i][j] == "G") then  
love.graphics.setColor(0.149, 0.6, 0)  
elseif (world[i][j] == "A") then  
love.graphics.setColor(0.250, 0.490, 0.909)  
end  
love.graphics.rectangle("fill", (j * 50), (i * 50), 50, 50)  
end  
end  
end  
Matrices and Game Worlds Example 2  
Matrices and Game Worlds Example 3  
Reading a matrix from a file and drawing its elements  
on screen using images.  
World1.txt  
Images:  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAGGGGGGG  
GGGGGGAAAGGGGG  
GGGGGGGGAGGGGG  
GGGGGGGGAGGGGG  
PPPPPPPPAPPPPP  
AAAAAAAAAAAAAA  
AAAAAAAAAAAAAA  
Matrices and Game Worlds Example 3  
local world = {}  
local tile_grass  
local tile_water  
local tile_sand  
function LoadMap(filename) - reads the content of the file  
local file = io.open(filename)  
local i = 1  
for line in file:lines() do  
world[i] = {}  
for j=1, #line, 1 do  
world[i][j] = line:sub(j,j)  
end  
i = i + 1  
end  
file:close()  
end  
.
.
.
.
.
.
function love.load()  
LoadMap("World1.txt")  
tile_grass = love.graphics.newImage("grass.png")  
tile_water = love.graphics.newImage("water.png")  
tile_sand = love.graphics.newImage("sand.png")  
end  
function love.draw()  
for i=1, 10, 1 do -- iterates through the matrix and draw the elements  
for j=1, 14, 1 do  
if (world[i][j] == "P") then  
love.graphics.draw(tile_sand, (j * 50), (i * 50))  
elseif (world[i][j] == "G") then  
love.graphics.draw(tile_grass, (j * 50), (i * 50))  
elseif (world[i][j] == "A") then  
love.graphics.draw(tile_water, (j * 50), (i * 50))  
end  
end  
end  
end  
Matrices and Game Worlds Example 3  
Exercise 2  
) Implement a program to display the world of a platform game,  
which is stored in a text file.  
2
Exercise 3  
) Continue the implementation of the last exercise and code a  
virtual camera to allow the player to move and see the entire  
environment.  
3
Important: don’t draw parts of world that are not visible in the screen.  
Texture Atlas  
A texture atlas (also called a  
sprite sheet or an image sprite) is  
an image containing a collection  
of smaller images, usually packed  
together to reduce the atlas size.  
It is often more efficient to store  
the textures in a texture atlas  
which is treated as a single unit  
by the graphics hardware.  
Texture Atlas Example  
World  
Tileset  
XXXXXXXXXXXXXX  
XXXXXXXXXXXXXX  
XXXXXXXXXXXXXX  
XXXXXXXXXXXXXX  
XXXXXXXXXXXXXX  
XXXBXXXXXXXXXX  
XXBBBXXXXXXXXX  
GGGGGGGAAGGGGG  
TTTTTTTPPTTTTT  
TTTTTTTPPTTTTT  
http://www.inf.puc-rio.br/~elima/intro-eng/plataform_map1.zip  
Texture Atlas Example  
local world = {}  
local tilesetImage  
local tileQuads = {}  
local tileSize = 64  
function LoadTiles(filename, nx, ny)  
tilesetImage = love.graphics.newImage(filename)  
local count = 1  
for i = 0, nx, 1 do  
for j = 0, ny, 1 do  
tileQuads[count] = love.graphics.newQuad(i * tileSize ,  
j * tileSize, tileSize, tileSize,  
tilesetImage:getWidth(),  
tilesetImage:getHeight())  
count = count + 1  
end  
end  
end  
.
.
.
.
.
.
function LoadMap(filename)  
local file = io.open(filename)  
local i = 1  
for line in file:lines() do  
world[i] = {}  
for j=1, #line, 1 do  
world[i][j] = line:sub(j,j)  
end  
i = i + 1  
end  
file:close()  
end  
function love.load()  
LoadMap("plataform_map.txt")  
LoadTiles("plataform_tileset.png", 2, 2)  
love.graphics.setBackgroundColor(0.6, 0.819, 0.980)  
end  
.
.
.
.
.
.
function love.draw()  
for i=1, 10, 1 do  
for j=1, 14, 1 do  
if (world[i][j] == "G") then  
love.graphics.draw(tilesetImage, tileQuads[1],  
(j * tileSize) - tileSize, (i * tileSize) - tileSize)  
elseif (world[i][j] == "T") then  
love.graphics.draw(tilesetImage, tileQuads[4],  
(j * tileSize) - tileSize, (i * tileSize) - tileSize)  
elseif (world[i][j] == "A") then  
love.graphics.draw(tilesetImage, tileQuads[7],  
(j * tileSize) - tileSize, (i * tileSize) - tileSize)  
elseif (world[i][j] == "P") then  
love.graphics.draw(tilesetImage, tileQuads[8],  
(j * tileSize) - tileSize, (i * tileSize) - tileSize)  
elseif (world[i][j] == "B") then  
love.graphics.draw(tilesetImage, tileQuads[6],  
(j * tileSize) - tileSize, (i * tileSize) - tileSize)  
end  
end  
end  
end  
Texture Atlas Example  
Tile-Based Scrolling Example  
XXXXXXXXXXXXXXXXXXXXXXXXXXXX  
XXXXXXXXXXXXXXXXXXXXXXXXXXXX  
XXXXXXXXXXXXXXXXXXXXXXXXXXXX  
XXXXXXXXXXXXXXXXXXXXXXXXXXXX  
XXXXXXXXXXXXXXXXXXXXXXXXXXXX  
XXXBXXXXXXXXXXXXXBXXXXXXXXXX  
XXBBBXXXXXXXXXXXBBBXXXXXXXXX  
GGGGGGGAAGGGGGGGGGGGGAAGGGGG  
TTTTTTTPPTTTTTTTTTTTTPPTTTTT  
TTTTTTTPPTTTTTTTTTTTTPPTTTTT  
http://www.inf.puc-rio.br/~elima/intro-eng/plataform_map2.zip  
Tile-Based Scrolling Example  
local world = {}  
local tilesetImage  
local tileQuads = {}  
local tileSize = 64  
local world_config = {  
worldSize_x = 28,  
worldSize_y = 10,  
worldDisplay_x = 14,  
worldDisplay_y = 10  
}
local camera = {  
pos_x = 1,  
pos_y = 1,  
speed = 120  
}
function LoadTiles(filename, nx, ny)  
tilesetImage = love.graphics.newImage(filename)  
local count = 1  
for i = 0, nx, 1 do  
for j = 0, ny, 1 do  
tileQuads[count] = love.graphics.newQuad(i * tileSize, j *  
tileSize, tileSize, tileSize,  
tilesetImage:getWidth(),  
tilesetImage:getHeight())  
count = count + 1  
end  
end  
end  
function LoadMap(filename)  
local file = io.open(filename)  
local i = 1  
for line in file:lines() do  
world[i] = {}  
for j=1, #line, 1 do  
world[i][j] = line:sub(j,j)  
end  
i = i + 1  
end  
file:close()  
end  
function love.load()  
LoadMap("plataform_map.txt")  
LoadTiles("plataform_tileset.png", 2, 2)  
love.graphics.setBackgroundColor(0.6, 0.819, 0.980)  
end  
function love.update(dt)  
if love.keyboard.isDown("right") then  
camera.pos_x = camera.pos_x + (camera.speed * dt)  
elseif love.keyboard.isDown("left") then  
camera.pos_x = camera.pos_x - (camera.speed * dt)  
end  
if camera.pos_x < 0 then  
camera.pos_x = 0  
elseif camera.pos_x > world_config.worldSize_x * tileSize -  
world_config.worldDisplay_x * tileSize - 1 then  
camera.pos_x = world_config.worldSize_x * tileSize -  
world_config.worldDisplay_x * tileSize - 1  
end  
end  
function love.draw()  
offset_x = math.floor(camera.pos_x % tileSize)  
first_tile_x = math.floor(camera.pos_x / tileSize)  
for y=1, world_config.worldDisplay_y, 1 do  
for x=1, world_config.worldDisplay_x, 1 do  
if (world[y][first_tile_x + x] == "G") then  
love.graphics.draw(tilesetImage, tileQuads[1],  
((x -1)*tileSize) - offset_x ,((y-1)*tileSize))  
elseif (world[y][first_tile_x + x] == "T") then  
love.graphics.draw(tilesetImage, tileQuads[4],  
((x-1)*tileSize) - offset_x ,((y-1)*tileSize))  
elseif (world[y][first_tile_x + x] == "A") then  
love.graphics.draw(tilesetImage, tileQuads[7],  
((x-1)*tileSize) - offset_x ,((y-1)*tileSize))  
elseif (world[y][first_tile_x + x] == "P") then  
love.graphics.draw(tilesetImage, tileQuads[8],  
((x-1)*tileSize) - offset_x ,((y-1)*tileSize))  
elseif (world[y][first_tile_x + x] == "B") then  
love.graphics.draw(tilesetImage, tileQuads[6],  
((x-1)*tileSize) - offset_x ,((y-1)*tileSize))  
end  
end  
end  
end  
Tile-Based Scrolling Example