Page 1 of 1

Horizontal scrolling background

Posted: Mon Feb 05, 2018 7:50 pm
by benbooth493
Hi.

I'm new to Love2d and I'm playing around and learning as I go....maybe write a game at some point!
I'm trying to implement a scrolling background, where when my character sprite is walking right or left the sprite stays stationary, but the background scrolls infinitely.

I just can't figure out how to do this! Help please! :)

Here's what I have so far:

Code: Select all

require('camera')

local anim8 = require('lib/anim8/anim8')
local shine = require('lib/shine')
local player
local vignette
local viewport = {}
local background = {}

function love.load()
    -- post-processing
    local grain = shine.filmgrain()
    grain.opacity = 0.2

    vignette = shine.vignette()
    vignette.parameters = { radius = 1.0, opacity = 0.7 }

    post_effect = vignette:chain(grain)

    -- set up some variables
    viewport.width = love.graphics.getWidth()
    viewport.height = love.graphics.getHeight()
    speed = 150

    -- set default graphics filter to nearest-neighbour
    love.graphics.setDefaultFilter('nearest', 'nearest')

    -- background
    background.image = love.graphics.newImage('assets/background-1.jpg')
    background.x = 0
    background.speed = speed

    -- define spritesheet
    local spritesheet = love.graphics.newImage('assets/sprites/morris-spritesheet.png')
    local g = anim8.newGrid(18, 32, spritesheet:getWidth(), spritesheet:getHeight())

    -- player object
    player = {
        spritesheet = spritesheet,
            x = viewport.width / 3,
            y = 500,
            speed = speed,
            animations = {
                idle_right = anim8.newAnimation(g(1, 1), 0.1),
                idle_left = anim8.newAnimation(g(1, 1), 0.1):flipH(dt),
                run_right = anim8.newAnimation(g('2-5', 1), 0.1),
                run_left = anim8.newAnimation(g('2-5', 1), 0.1):flipH(dt)
            },
            last_direction = nil,
        width = 18 * 5,
        height = 32 * 5
    }
    -- player defaults
    player.animation = player.animations.idle_right
    player.last_direction = 'right'
end

function love.update(dt)
    if love.keyboard.isDown('q') then
        love.event.push('quit')
    end

    if love.keyboard.isDown('left') then
        if player.x > 0 then
            player.animation = player.animations.run_left
            -- cause player to move across viewport
            -- player.x = player.x - (player.speed*dt)
            player.last_direction = 'left'

            -- scroll the background
            background.x = background.x + background.speed * dt
            if background.x < viewport.width then
               background.x = background.x + viewport.width
               -- background.x = background.x - viewport.width
            end
        end

    elseif love.keyboard.isDown('right') then
        if player.x < (viewport.width - player.width) then
            player.animation = player.animations.run_right
            -- cause player to move across viewport
            -- player.x = player.x + (player.speed*dt)
            player.last_direction = 'right'

            -- scroll the background
            background.x = background.x - background.speed * dt
            if background.x > viewport.width then
                background.x = background.x - viewport.width
            end
        end

--[[     elseif love.keyboard.isDown('up') the
   [             player.animation = player.animations.run_right
   [             player.y = player.y - (player.speed*dt)
   [             player.last_direction = 'right'
   [
   [     elseif love.keyboard.isDown('down') then
   [             player.animation = player.animations.run_right
   [             player.y = player.y + (player.speed*dt)
   [             player.last_direction = 'right' ]]

    elseif player.last_direction == 'right' then
        player.animation = player.animations.idle_right

    elseif player.last_direction == 'left' then
        player.animation = player.animations.idle_left
    end

    player.animation:update(dt)
end

function love.draw(dt)
    -- post_effect:draw(function()

    local sx = love.graphics:getWidth() / background.image:getWidth()       -- scale background
    local sy = love.graphics:getHeight() / background.image:getHeight()     -- scale background

    love.graphics.draw(background.image, 0, 0, 0, sx, sy)
    -- love.graphics.draw(background.image, background.x + background.image:getWidth(), 0, 0, 10, 10)

    love.graphics.print("x: "..tostring(player.x), 5, 5)
    love.graphics.print("y: "..tostring(player.y), 5, 20)
    love.graphics.print("player.width: "..tostring(player.width), 5, 35)
    love.graphics.print("background.x: "..tostring(background.x), 5, 55)
    love.graphics.print("viewport.width: "..tostring(viewport.width), 5, 70 )
    love.graphics.print(tostring(love.graphics:getWidth()), 5, 85)
    love.graphics.print(tostring(love.graphics:getHeight()), 5, 100)

    player.animation:draw(player.spritesheet, player.x, player.y, 0, 5, 5)

    -- end)
end

Re: Horizontal scrolling background

Posted: Mon Feb 05, 2018 11:01 pm
by jojomickymack
if you just want to scroll a static image forever, this thread might help.

viewtopic.php?f=4&t=83763&p=211275&hili ... ge#p211275

As a mental note for myself, I want to see if this image wrapping function works.

http://www.love2d.org/wiki/%28Image%29:setWrap

Maybe that helps?

Re: Horizontal scrolling background

Posted: Mon Feb 05, 2018 11:07 pm
by zorg
If you wanted to go the "background isn't affected by camera position but still scrolls" way, you could use a mesh the size of the window (or screen if fullscreen), use the background image as texture, and by having the wrapping mode set to the repeating one, as jojmickymack linked, messing with the UV coordinates of the mesh will do the infinitely moving background trick; downside is, (mostly) only works for a static image.

Otherwise, You could have the camera affect everything, then just make sure to draw the background as many times on a grid the size of the background image, as it's needed to fill the current screen, although only draw those that are actually on-screen.

Re: Horizontal scrolling background

Posted: Tue Feb 06, 2018 8:33 am
by benbooth493
Excellent!
I know have this working although I need to scale the Quad/QuadTexture to fit the viewport.
When I try to add the scale factor for x,y it just appears to move the texture rather than scale it:

Code: Select all

local sx, sy = background.quad:getTextureDimensions()
sx = love.graphics:getWidth() / sx
sy = love.graphics:getHeight() / sy

love.graphics.draw(background.image, background.quad, 0, 0, 0, sx, sy)
Any ideas?

Re: Horizontal scrolling background

Posted: Tue Feb 06, 2018 6:03 pm
by jojomickymack
see if you can incorporate this into your project - use the Image:setWrap('repeat') for the background and draw it using a quad. The quad's x position (first param) is what scrolls the image.

note - setting setWrap('repeat', 'clampzero') is what's needed for this - 'repeat', 'repeat' would wrap both horizontally and vertically, maybe better for a top down adventure game or something.

Re: Horizontal scrolling background

Posted: Tue Feb 06, 2018 7:37 pm
by benbooth493
That kind of works but I need it to scroll based on character walking direction.
I have the scrolling working nicely, it's just that the image is larger than the screen dimensions, and I need to scale the image to fit a quad that has the same dimensions as the screen.

Re: Horizontal scrolling background

Posted: Wed Feb 07, 2018 2:38 am
by jojomickymack
I'm not sure why the scaling isn't working for you there, I updated my love file in the last post using scaling.

note - you probably don't want to scale according to width if you're doing a long horizontal strip.

let me know if we're getting closer to the desired effect. :megagrin:

Re: Horizontal scrolling background

Posted: Wed Feb 07, 2018 7:55 am
by benbooth493
Ok got it working....even built a player and background class.
Code much tidier. :)

Re: Horizontal scrolling background

Posted: Thu Feb 08, 2018 2:54 am
by jojomickymack
Sweet! I hadn't thought of setting up a game in this way until now - I can imaging with some obstacles in the way and some other gameplay mechanics this could really be a simple way to make a side scroller.

One idea I was thinking about is a 2 layered background - maybe a bright sunny day background and a spooky stormy background at alpha 0 - maybe it could be a dr jeyckl/mr hyde type of thing - as you walk along, the 2nd background gets a higher alpha and the things get creepier....

That would be pretty easy and would probably be kinda interesting for the player. Maybe the music could fade in some more hardcore elements as the background got darker?

I think the filmgrain thing you're doing there made me think about that - getting scarier as you play...