Here's a flappy bird game in one file, although it sounds like you guys are just interested in the scrolling.
Code: Select all
function love.load()
player = {
width = 10,
height = 10,
x = 70,
y = 70,
vy = 0,
vx = 0
}
timer = 0
gravity = 1300
max_upwards_velocity = -gravity/2
pipes = {}
gap_size = 100
pipe_width = 40
pipe_timer = 1.8
speed = 300
time_between_pipes = speed/250
window_height = love.graphics.getHeight()
window_width = love.graphics.getWidth()
gameover = false
score = 0
end
function make_pipes()
-- Let's think about where the gaps in the pipes go
-- Obviously they can't go off the screen so let's limit them to the window
-- height
gap_area = window_height
-- But if we draw them with the top at the bottom of the screen, the bottom
-- will be too low and we'll have a smaller gap.
-- Let's ensure this never happens by not putting the top of the gap closer
-- to the bottom than its own width.
gap_area = gap_area - gap_size
-- And let's ensure that there always appear to be 2 pipes instead of one
-- by never moving the gap far enough away from the center to hit the edge
-- In this case, let's keep the pipe in the middle 80% of the screen
-- We'll have to remember to offset the gap downwards by 10% the area we
-- were considering before.
vertical_offset = gap_area * 0.1
gap_area = gap_area * 0.8
-- Now we're ready to work out what the co-ordinates of our pipes should be
-- First, put the gap in randomly by generating an integer value up to
-- "gap_area"'s size
gap_position = math.random(gap_area)
--Now the first pipe
pipe1 = {
x = window_width, -- start all pipes offscreen to the right
y = 0, -- stop player from cheating by making top pipe really high
width = pipe_width,
height = vertical_offset + gap_position
}
-- Work out the second pipe based on the gap size and the first pipe
pipe2 = {
x = window_width,
y = pipe1.height + gap_size,
width = pipe_width
}
pipe2.height = window_height - pipe2.width
-- return the pipes
return {pipe1, pipe2, scored = false}
end
--BoundingBox.lua stolen straight from the love wiki
function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end
function love.update(dt)
-- UPDATE PLAYER
-- Downwards velocity is affected by gravity
player.vy = player.vy + gravity * dt
-- and velocity changes position
player.y = player.y + player.vy * dt
if player.vx > 0 then
print("Um guys vx is " .. player.vx)
end
player.x = player.x + player.vx * dt
-- lose if you fall off the screen
if player.y > window_height then
gameover = true
end
-- UPDATE PIPES
-- for each pipe
for number, pipe in ipairs(pipes) do
-- Move pipes left
pipe[1].x = pipe[1].x - speed * dt
pipe[2].x = pipe[2].x - speed * dt
-- Lose when a pipe collides with player
-- Notice we extend the rectangle of the upper pipe by 10000 pixels upwards
-- so that the player can't jump over pipes
if CheckCollision(player.x, player.y, player.width, player.height,
pipe[1].x, pipe[1].y - 100000, pipe[1].width, pipe[1].height + 100000)
or CheckCollision(player.x, player.y, player.width, player.height,
pipe[2].x, pipe[2].y, pipe[2].width, pipe[2].height ) then
gameover = true
end
-- Also check collision with the gap, and add one to the score when
-- we collide with it. Mark the pipes' scored attribute as true
-- so that we don't keep adding to the score every time we run
-- love.update whilst we're between 2 pipes
if CheckCollision(player.x, player.y, player.width, player.height,
pipe[1].x, pipe[1].y + pipe[1].height, pipe[1].width, gap_size)
and not pipe.scored and not gameover then -- don't let corpses score either
score = score + 1
pipe.scored = true
end
-- remove pipes when they're off the screen to the left
if pipe[1].x < 0 - pipe_width then
-- this only works because we insert pipes into the front of the
-- pipes table instead of the back, and we remove them in the same
-- order we add them.
pipes[number] = nil
end
end
-- ADD PIPES PERIODICALLY
pipe_timer = pipe_timer - dt --decrease pipe timer
if pipe_timer < 0 then -- when timer runs out
pipe_timer = time_between_pipes -- reset timer
table.insert(pipes, 1, make_pipes()) -- and add pipes
end
end
function love.draw()
-- make sure that the color is set to white (important after dying)
love.graphics.setColor(255,255,255)
-- Make everything a different color on gameover
if gameover then
love.graphics.setColor(0, 70, 140)
end
-- Draw player
love.graphics.rectangle("fill", player.x, player.y, player.width, player.height)
-- For each pipe
for number, pipe in ipairs(pipes) do
-- draw the top pipe
love.graphics.rectangle("fill", pipe[1].x, pipe[1].y, pipe[1].width, pipe[1].height)
-- and the bottom pipe
love.graphics.rectangle("fill", pipe[2].x, pipe[2].y, pipe[2].width, pipe[2].height)
end
if gameover then
love.graphics.setColor(255,255,255)
love.graphics.rectangle("fill", 0, window_height/2 - 35, window_width, 70)
love.graphics.setColor(0,0,0)
love.graphics.print("Score: " .. score .. ". Press ESC to restart", window_width/2 - 80, window_height/2 - 10)
end
end
function love.keypressed(key, isRepeat)
if key == "return" then
if player.vy < 0 then
player.vy = player.vy - gravity/3
else
player.vy = -gravity/3
end
if player.vy < max_upwards_velocity then
player.vy = max_upwards_velocity
end
end
-- escape restarts game
if key == "escape" then
love.load()
end
end
In order to do scrolling like in the "No Game!" screen for love, you need to modify the position of your images by a velocity * dt every update.
In the case of the "No Game!" screen, there are two layers doing this, one on top of the other, with different velocities.