An update on my game scrolling class

This week I’ve mostly been working on the scrolling part of my game. If you’ve seen the game Trenches on the iphone app store, this is the kind of thing I wanted. Where you can scroll landscape, horizontally by clicking and dragging an area at the base of the screen. I also wanted a nice bounce back when people scroll too far, and also to add velocity for a ‘flick’ scroll. Anyway - here’s the code in case anyone wants to use it…

  1. Save this as gameScroll.lua

[lua]module(…, package.seeall);


– Scrolling

– Set up variables

local previousX = 0;
local leftBoundary = 100;
local rightBoundary = 0;
local scrollVelocity = 0;
local scrollDirection;
local scrollFriction = 5;
local xMove = 0;
– flick scroll function
– used to add on velocity after touch stopped

local function flickScroll()

– make the move

scrollB.x = scrollB.x + scrollVelocity;

– moving left

if(scrollDirection==“left”) then

scrollVelocity = scrollVelocity + scrollFriction;

– past what’s allowed
– do a transition back

if(scrollB.x < ((scrollB.width-480)*-1)) then
print(“PAST”);
Runtime:removeEventListener(“enterFrame”, flickScroll);
scrollVelocity = 0;
moveBack = transition.to(scrollB, {x=((scrollB.width-480)*-1), time=300, transition=easing.outQuad});
movingBack = true;
end

if(scrollVelocity > 0) then
scrollVelocity = 0;
Runtime:removeEventListener(“enterFrame”, flickScroll);
end
end
– moving right

if(scrollDirection==“right”) then

– past what’s allowed
– do a transition back

if(scrollB.x > 0) then
scrollVelocity = 0;
moveBack = transition.to(scrollB, {x=0, time=300, transition=easing.outQuad});
movingBack = true;
end

scrollVelocity = scrollVelocity - scrollFriction;
if(scrollVelocity < 0) then
scrollVelocity = 0;
Runtime:removeEventListener(“enterFrame”, flickScroll);
end
end
end
– main scroll function

local function makeScroll(event)

– if we’re within the bottom scroll box
– used for draging

if(event.y > 270) then

if(event.phase==“began”) then
– lock the focus onto the scrolling
display.getCurrentStage():setFocus(event.target);

– record the start time of this drag
startTime = event.time;
scrollVelocity = 0;

– let us drag scroll even if it’s already trasitioning back
if(movingBack == true) then
transition.cancel(moveBack);
end
end

if(event.phase == “moved”) then
if(previousX == 0) then
previousX = event.x;
end

xMove = event.x - previousX;
previousX = event.x;
if(xMove < 0) then
scrollDirection = “left”;
else
scrollDirection = “right”;
end

–print("xMove: " … xMove);
–print("scrollB.x: " … scrollB.x);

– pulling screen to right -->
– went past elastic (how much allowed to drag over)
– make it drag slower

if(scrollB.x > leftBoundary) then
xMove = xMove / 2;
end

– pulling screen to left – went past elastic (how much allowed to drag over)
– make it drag slower

if(scrollB.x < ((scrollB.width-480)*-1)) then
xMove = xMove / 2;
end

– make the background move

scrollB.x = scrollB.x + xMove;

end
end

if (event.phase==“ended”) then
scrollVelocity = xMove;

– print("scrollVelocity: " … scrollVelocity);

Runtime:addEventListener(“enterFrame”, flickScroll);

xMove = 0;
previousX = 0;

– scrollB currently dragged to the right ->
– past what’s allowed
– do a transition back

if(scrollB.x > 0) then
moveBack = transition.to(scrollB, {x=0, time=300, transition=easing.outQuad});
movingBack = true;
end

– scrollB currently dragged to the left – past what’s allowed
– do a transition back

if(scrollB.x < ((scrollB.width-480)*-1)) then
moveBack = transition.to(scrollB, {x=((scrollB.width-480)*-1), time=300, transition=easing.outQuad});
movingBack = true;
end
end
end
Runtime:addEventListener(“touch”, makeScroll);[/lua]

  1. On the file where you want to run the scrolling, add this code:

[lua]-- create new display group to hold the scrolling
– scrollB = scrolling background

scrollB = display.newGroup();

– Bring in the background images
– And insert them into scrolling group

local insertImage = 240;

bgImages = {‘bg1.png’,‘bg2.png’,‘bg3.png’,‘bg4.png’};

for i,v in pairs(bgImages) do
_G[“bg”…i] = display.newImage(v);
_G[“bg”…i].x = insertImage ;
scrollB:insert(_G[“bg”…i]);
insertImage = insertImage + 480;
end

require(“gameScroll”);

– set up the scroll box
– the bit that people can drag on to scroll

scrollBox = display.newImage(“scroll.png”);
scrollBox.y = 270 + scrollBox.height/2;[/lua]

Notes:

  • scroll.png is an image that the user can click and drag to scroll left and right.
  • Background is made up of any number of bg1.png, bg2.png files
    Call your background files what you want, have as many as you want but insert them into: bgImages = {‘bg1.png’,‘bg2.png’,‘bg3.png’,‘bg4.png’};

The images must be 480 x 320

I’ve tested it on my old ipod 3G and it works great. Hope it helps someone and good luck with your games.

Tom [import]uid: 55068 topic_id: 10829 reply_id: 310829[/import]

Oh and please point out any mistakes, or anything I’ve missed. :wink: [import]uid: 55068 topic_id: 10829 reply_id: 39370[/import]

tomarmstrong1, et al…

Is it possible to integrate a wrapping feature, using two background images, i.e. move bg1 to edge of bg2 as bg2 starts to go out of view? I’ve modified the code to accommodate 1024 x 768 graphics, and killed the bounce back code if dragging beyond current limits. I came up with the following code, and tried a conditional on the “began” then “moved” phases, but nothing appears to happen. I inserted a print statement to display bg1.x and bg2.x, but the positions do not update when the parent display group (scrollB) is dragged about. Guessing I may need a second display group to wrap from side to side, but am lost at this point. Can someone point me in the right direction?

if bg1.x \< 1536 then bg1.x = 512 end  
if bg2.x \< 1536 then bg2.x = 512 end  
if bg1.x \> 1536 then bg1.x = - 512 end  
if bg2.x \> 1536 then bg2.x = - 512 end  

[code]
scrollB = display.newGroup() – scrollB = scrolling background
local insertImage = 512 – half screen width
local bgImages = {‘bg1.png’,‘bg2.png’} – bring in the background images & insert them into scrolling group
for i,v in pairs(bgImages) do
    _G[“bg”…i] = display.newImage(v)
    _G[“bg”…i].x = insertImage 
    scrollB:insert(_G[“bg”…i])
    insertImage = insertImage + 1024
end

– Set up variables
local previousX = 0
local leftBoundary = 0
local rightBoundary = 0
local scrollVelocity = 0
local scrollDirection
local scrollFriction = 5
local xMove = 0
 
local function flickScroll() – used to add on velocity after touch stopped
    scrollB.x = scrollB.x + scrollVelocity – make the move

    – moving left
    if (scrollDirection==“left”) then
        scrollVelocity = scrollVelocity + scrollFriction
        if (scrollVelocity > 0) then
            scrollVelocity = 0
            Runtime:removeEventListener(“enterFrame”, flickScroll)
        end
    end

    – moving right
    if (scrollDirection==“right”) then
        scrollVelocity = scrollVelocity - scrollFriction
        if (scrollVelocity             scrollVelocity = 0
            Runtime:removeEventListener(“enterFrame”, flickScroll)
        end
    end
end

local function makeScroll(event)
    if (event.phase==“began”) then
        display.getCurrentStage():setFocus(event.target) – lock the focus onto the scrolling
        startTime = event.time – record the start time of this drag
        scrollVelocity = 0
    end
    if (event.phase == “moved”) then
        if (previousX == 0) then
            previousX = event.x
        end
        xMove = event.x - previousX
        previousX = event.x
        if (xMove             scrollDirection = “left”
        else
            scrollDirection = “right”
        end 
        print("xMove: " … xMove)
        print("scrollB.x: " … scrollB.x) 
        scrollB.x = scrollB.x + xMove – make the background move
    end
    if (event.phase==“ended”) then
        scrollVelocity = xMove
        – print("scrollVelocity: " … scrollVelocity) 
        Runtime:addEventListener(“enterFrame”, flickScroll)
        xMove = 0
        previousX = 0
    end 
end
Runtime:addEventListener(“touch”, makeScroll)[/code] [import]uid: 12397 topic_id: 10829 reply_id: 43543[/import]