Verticle game scrolling

Thanks for your help Caleb!

The max texture size is 8192. My background is now 320 x 2048. It still doesn’t fill the screen. If I use multiple backgrounds, will it fill the screen? Also, how do you use multiple wallpapers?

Thanks again! [import]uid: 188277 topic_id: 35062 reply_id: 139913[/import]

lilgreen,

Go get Caleb’s “Perspective” from the Community Code section.

If you study it, you’ll see exactly what needs to be done from a working solution.

It will do everything you need to do and then some most likely.

Not only will it scroll, it’s got integrated parallax scrolling (8 layers supported)

IMO, it’s more than cool, it’s “Frosty”!

I haven’t had time to post a video example of the parallax integration, but I’ve got one posted in the comments thread showing the vertical scrolling using ver 1.0, it’s now 1.2 I think.

“Perspective” Linkl

Hope this helps,

Nail [import]uid: 106779 topic_id: 35062 reply_id: 139438[/import]

That’s exactly what I want. I’ll try it, and get back to you soon. Thanks! [import]uid: 188277 topic_id: 35062 reply_id: 139519[/import]

[Double post] [import]uid: 188277 topic_id: 35062 reply_id: 139520[/import]

Hmm… nothing seems to be working. Physics stopped working, and The camera doesn’t work. Here’s my code:

[code]
– Create player and set location
local player = display.newImage(“images/player.png”)
player.x = display.contentWidth / 2
player.y = display.contentHeight / 3

– Turn player into physics body
physics.addBody(player, { radius = 30 } );

– perspective
local perspective = require(“perspective”)
local camera = perspective.createView()
camera.x, camera.y = 100, 100
camera:add(player, 1, true)
camera:setFocus(player)
camera.offsetX, camera.offsetY = 150, 150
camera:setBounds(_W, 0, _H, 0)
camera:track()

– Create walls on the left and right
local leftWall = display.newRect (0, 0, 1, display.contentHeight);
local rightWall = display.newRect (display.contentWidth, 0, 1, display.contentHeight);

– Add physics to the walls. They will not move so they will be static
physics.addBody (leftWall, “static”, { bounce = 0.1 } );
physics.addBody (rightWall, “static”, { bounce = 0.1 } ); [import]uid: 188277 topic_id: 35062 reply_id: 139536[/import]

I tried using Caleb’s perspective, but it doesn’t seem to work. The camera doesn’t work, and collisions are completely off.

-- Create player and set location  
local player = display.newImage("images/fred.png")  
player.x = display.contentWidth / 2  
player.y = display.contentHeight / 3  
  
-- Turn player into physics body  
physics.addBody(player, { radius = 30 } );  
  
-- Create walls on the left and right  
local leftWall = display.newRect (0, 0, 1, display.contentHeight);  
local rightWall = display.newRect (display.contentWidth, 0, 1, display.contentHeight);  
  
-- Add physics to the walls. They will not move so they will be static  
physics.addBody (leftWall, "static", { bounce = 0.1 } );  
physics.addBody (rightWall, "static", { bounce = 0.1 } );  
  
-- perspective  
  
local perspective = require("perspective")  
local camera = perspective.createView()  
camera.x, camera.y = 100, 100  
camera:add(player, 1, true)  
camera:add(lines, 1, true)  
camera:add(rightWall, 1, true)  
camera:add(leftWall, 1, true)  
camera:setFocus(player)  
camera.offsetX, camera.offsetY = 150, 150  
camera:setBounds(\_W, 0, \_H, 0)  
camera:track()  

That’s all I need to put in there. I also got this error message in Lua Gllider:

...n\code\corona projects\game\perspective.lua:48: bad argument #-2 to 'insert' (Proxy expected, got nil)  
message  
stack traceback:  
 [C]: ?  
 [C]: in function 'insert'  
 ...n\code\corona projects\game\perspective.lua:48: in function 'add'  
 ...s\jordan\code\corona projects\game\main.lua:141: in main chunk  

Here’s what it looks like:

http://imgur.com/9GqamCS [import]uid: 188277 topic_id: 35062 reply_id: 139564[/import]

@lil,

Is this you entire main.lua?

I’m thinking the “insert” error has to do with line 23 ,

I don’t see where “lines” has been declared.

I’d also play around with the setBounds parameters.

Nail [import]uid: 106779 topic_id: 35062 reply_id: 139566[/import]

Thanks for your help!
I also have this, but I didn’t think it mattered:

local lineLengthConstraint = 128  
local lines = {}  
  
local function getLength(x1, x2, y1, y2)  
 local x = x1 - x2  
 local y = y1 - y2  
 local length = math.sqrt(x\*x + y\*y)  
 return length  
end  
  
local function drawLine(event)  
  
 if event.phase == "began" then  
  
 -- inTouch state.  
  
 inTouch = true  
  
 -- X/Y Coordinates of initial touch.  
  
 initialX = event.x  
 initialY = event.y  
  
 -- Create our line.  
  
 ourLine = display.newLine(initialX, initialY, initialX, initialY+getLength(initialX, event.x, initialY, event.y))  
 ourLine:setColor(0,255,0)  
 ourLine.width = 8  
 ourLine.rotation = math.deg(math.atan2(event.y - initialY, event.x - initialX)) - 90  
  
 elseif event.phase == "moved" and inTouch then  
  
 -- Recreate our line, in the case that it is shorter than the length constraint.  
  
 if getLength(initialX, event.x, initialY, event.y) \<= lineLengthConstraint then  
  
 -- Remove old version of our line.  
  
 display.remove(ourLine)  
 ourLine = nil  
  
 -- Create new version of our line.  
  
 ourLine = display.newLine(initialX, initialY, initialX, initialY+getLength(initialX, event.x, initialY, event.y))  
 ourLine:setColor(0,255,0)  
 ourLine.width = 8  
  
 -- Store limited line length.  
  
 limitedLineLength = getLength(initialX, event.x, initialY, event.y)  
  
 -- Physics  
  
 --local physShape = { (ourLine.width/2),0, (ourLine.width/2),limitedLineLength, -(ourLine.width/2),limitedLineLength, -(ourLine.width/2),0 }  
 --physics.addBody(ourLine, "static", {bounce=1.0, shape=physShape})  
  
 end  
  
 -- Set rotation of our line.  
  
 ourLine.rotation = math.deg(math.atan2(event.y - initialY, event.x - initialX)) - 90  
  
 elseif event.phase == "ended" and inTouch then  
  
 -- inTouch state.  
  
 inTouch = false  
  
 -- Physics  
  
 local physShape = { (ourLine.width/2),0, (ourLine.width/2),limitedLineLength, -(ourLine.width/2),limitedLineLength, -(ourLine.width/2),0 }  
 physics.addBody(ourLine, "static", {bounce=1.0, shape=physShape})  
  
 -- Remove line from the screen when there's one or more stored in the table.  
 if #lines \>= 1 then  
 for i=1,#lines do  
 display.remove(lines[i])  
 lines[i] = nil  
 end  
 end  
  
 -- Store our line in a table, just in case we need to reference or remove it later.  
  
 lines[#lines+1] = ourLine  
  
 end  
  
end  

also, I don’t really understand the setBounds params. What can I do so that it only scrolls vertically? [import]uid: 188277 topic_id: 35062 reply_id: 139652[/import]

Using multiple backgrounds would simply be a matter of creating separate images and using them together instead of one image and using it as the only image.

Caleb [import]uid: 147322 topic_id: 35062 reply_id: 140250[/import]

Lil,

Interesting project you are working on.

On line 23 you are adding “lines” to the camera view before “lines” are created, this is causing the “insert” error.

You need to add the “lines” to the camera view after you create the line.

 -- Store our line in a table, just in case we need to reference or remove it later.  
  
 i = #lines+1  
 lines[i] = ourLine  
 camera:add(lines[i], 1, false)  
  

notice how I changed the line[index] declaration also.
camera:add(lines[#index+1], 1, false) doesn’t work, the camera view wants a clean lines[i] value it seems.

I’d probably just comment out the camera:offset declarations and also comment out your camera.x, camera.y = 100, 100 declaration, at least until you get a feeling how the camera view works and the values it returns.

You can also remove the previously created “lines” at the “began” phase if you want it to disappear on the “touch” as you drag a new line.

I added a floor to your project to stop the player from continuously falling to get a feel for what it happening when you draw the lines.

I also changed the setBounds to just scroll in the vertical.

camera:setBounds(x1, x2, y1, y2)
the x1 is the x value the camera starts to track the focus, the x2 value is the x value the camera stops tracking the focus.

To only scroll in the vertical, start the camera tracking at x1 = 0 and stop the camera tracking at x2 = 0.

camera:setBounds(0, 0, 0, 10000)  
  
 local bottomFloor = display.newRect(0, 500, display.contentWidth, 20)  
 physics.addBody(bottomFloor, "static", { bounce = 0.1, } )  
  

Hope this helps and doesn’t cause more confusion,

Nail [import]uid: 106779 topic_id: 35062 reply_id: 139676[/import]

Thanks for all your help, nail!

I put the code in my project. Here is what it looks like:

local physShape = { (ourLine.width/2),0, (ourLine.width/2),limitedLineLength, -(ourLine.width/2),limitedLineLength, -(ourLine.width/2),0 }  
 physics.addBody(ourLine, "static", {bounce=1.5, shape=physShape})  
  
 -- Remove line from the screen when there's one or more stored in the table.  
 if #lines \>= 1 then  
 for i=1,#lines do  
 display.remove(lines[i])  
 lines[i] = nil  
 end  
 end  
  
 -- Store our line in a table, just in case we need to reference or remove it later.  
  
 i = #lines+1  
 lines[i] = ourLine  
 camera:add(lines[i], 1, false)  
  
 end  
  
end  
  
Runtime:addEventListener("touch", drawLine)  
  
local perspective = require("perspective")  
local camera = perspective.createView()  
camera.x, camera.y = 100, 100  
camera:add(player, 1, true)  
camera:add(rightWall, 1, true)  
camera:add(leftWall, 1, true)  
camera:setFocus(player)  
-- camera.offsetX, camera.offsetY = 150, 150  
camera:setBounds(0, 0, 0, 1000000000)  
camera:track()  
  
-- Floor with physics. Since the camera changes the location of objects, it will be placed after the camera.  
local bottomFloor = display.newRect(0, 500, display.contentWidth, 20)  
 physics.addBody(bottomFloor, "static", { bounce = 0.1, }   

I still have problems, though. First off, the player no longer moves. Second I get this white line that moves vertically on the screen:
http://imgur.com/Rc5yain

Once again, thanks for all your help. I really appreciate it! [import]uid: 188277 topic_id: 35062 reply_id: 139677[/import]

I also got this error message:

...s\jordan\code\corona projects\bungee bounce\main.lua:131: attempt to index global 'camera' (a nil value) message stack traceback: [C]: ? ...s\jordan\code\corona projects\bungee bounce\main.lua:131: in function <...s projects bounce><br> ?: in function <?:229><br> [import]uid: 188277 topic_id: 35062 reply_id: 139678[/import] </…s>

I also got this error message:

...s\jordan\code\corona projects\bungee bounce\main.lua:131: attempt to index global 'camera' (a nil value) message stack traceback: [C]: ? ...s\jordan\code\corona projects\bungee bounce\main.lua:131: in function <...s projects bounce><br> ?: in function <?:229><br> [import]uid: 188277 topic_id: 35062 reply_id: 139679[/import] </…s>

lilGreen,

Now you are adding “lines” to the “camera” after the lines are created, this is correct, but the “camera” itself isn’t created yet.

This is throwing the error that ‘attempt to index “camera” is nil’, because you are trying to add an object to the camera, before the camera itself is created, it has a nil value.

Move these 2 lines toward the top of the main.lua so whenever you call “camera”, it can be referenced and modified by what ever you are trying to add to it.

local perspective = require(“perspective”)
local camera = perspective.createView()

Realize, once an error gets kicked, all kinds of strange behavior follows. The “bottomFloor” should be a horizontal line for instance, yet you are seeing it as a vertical line.

You’ve got to usually fix the first error you see in order to continue debugging, the following errors are usually noise caused by the first error.

I’d also add the “bottomFloor” to the camera and increase it’s bounce to 1 so you can see some physics interaction.

You’ve got to realize the “player” is the camera’s focus and will appear to not move, while in reality it is moving. The other objects on the screen, the “bottomFloor” for instance will move in relationship to the camera view creating the illusion.

If you want to see the “player” move a little, not locked into position, play with the “damping” value in perspective.lua and set it to 20 or more and you’ll see the difference.

This is tricky stuff and a little hard to comprehend. Keep playing with it, spawn your player from higher up maybe to see it drop onto the floor possibly.

player.y = display.contentHeight / 6 instead of /3.

Nail
[import]uid: 106779 topic_id: 35062 reply_id: 139702[/import]

Thanks for you help, Nail!

I have changed the code to this, but now all I get is a wallpaper and nothing else… it’s kinda strange:

[code]
local perspective = require(“perspective”)
local camera = perspective.createView()

– physics.setDrawMode(“hybrid”)

local physics = require(“physics”)

physics.start()

physics.setScale( 60 )

physics.setGravity(0, 10)

display.setStatusBar( display.HiddenStatusBar )

local background = display.newImage( “images/clouds.png”, true )

– Create player and set location
local player = display.newImage(“images/fred.png”)
player.x = display.contentWidth / 2
player.y = display.contentHeight / 6

– Turn player into physics body
physics.addBody(player, { radius = 30 } );

– Create walls on the left and right
local leftWall = display.newRect (0, 0, 1, display.contentHeight);
local rightWall = display.newRect (display.contentWidth, 0, 1, display.contentHeight);

– Add physics to the walls. They will not move so they will be static
physics.addBody (leftWall, “static”, { bounce = 0.1 } );
physics.addBody (rightWall, “static”, { bounce = 0.1 } );

– Floor with physics
local bottomFloor = display.newRect(0, 500, display.contentWidth, 20)
physics.addBody(bottomFloor, “static”, { bounce = 1.0, } )

_W = display.contentWidth;
_H = display.contentHeight;

local lineLengthConstraint = 128
local lines = {}

local function getLength(x1, x2, y1, y2)
local x = x1 - x2
local y = y1 - y2
local length = math.sqrt(x*x + y*y)
return length
end

local function drawLine(event)

if event.phase == “began” then

– inTouch state.

inTouch = true

– X/Y Coordinates of initial touch.

initialX = event.x
initialY = event.y

– Create our line.

ourLine = display.newLine(initialX, initialY, initialX, initialY+getLength(initialX, event.x, initialY, event.y))
ourLine:setColor(0,255,0)
ourLine.width = 8
ourLine.rotation = math.deg(math.atan2(event.y - initialY, event.x - initialX)) - 90

elseif event.phase == “moved” and inTouch then

– Recreate our line, in the case that it is shorter than the length constraint.

if getLength(initialX, event.x, initialY, event.y) <= lineLengthConstraint then

– Remove old version of our line.

display.remove(ourLine)
ourLine = nil

– Create new version of our line.

ourLine = display.newLine(initialX, initialY, initialX, initialY+getLength(initialX, event.x, initialY, event.y))
ourLine:setColor(0,255,0)
ourLine.width = 8

– Store limited line length.

limitedLineLength = getLength(initialX, event.x, initialY, event.y)

– Physics

–local physShape = { (ourLine.width/2),0, (ourLine.width/2),limitedLineLength, -(ourLine.width/2),limitedLineLength, -(ourLine.width/2),0 }
–physics.addBody(ourLine, “static”, {bounce=1.0, shape=physShape})

end

– Set rotation of our line.

ourLine.rotation = math.deg(math.atan2(event.y - initialY, event.x - initialX)) - 90

elseif event.phase == “ended” and inTouch then

– inTouch state.

inTouch = false

– Physics

local physShape = { (ourLine.width/2),0, (ourLine.width/2),limitedLineLength, -(ourLine.width/2),limitedLineLength, -(ourLine.width/2),0 }
physics.addBody(ourLine, “static”, {bounce=1.5, shape=physShape})

– Remove line from the screen when there’s one or more stored in the table.
if #lines >= 1 then
for i=1,#lines do
display.remove(lines[i])
lines[i] = nil
end
end

– Store our line in a table, just in case we need to reference or remove it later.

i = #lines+1
lines[i] = ourLine
camera:add(lines[i], 1, false)

end

end

Runtime:addEventListener(“touch”, drawLine)

camera.x, camera.y = 100, 100
camera:add(player, 1, false)
camera:add(rightWall, 1, true)
camera:add(leftWall, 1, true)
camera:add(bottomFloor, 1, true)
camera:setFocus(player)
– camera.offsetX, camera.offsetY = 150, 150
camera:setBounds(0, 0, 0, 1000000000)
camera.damping = 20
camera:track()
[/code] [import]uid: 188277 topic_id: 35062 reply_id: 139742[/import]

[double post] [import]uid: 188277 topic_id: 35062 reply_id: 139563[/import]

Hey lilGreen,

Try adding adding the background to the camera to create the vertical scrolling illusion.

local background = display.newImage( “images/clouds.png” )
camera:add(background, 2, false)

You are going to see if you drag and spawn a “lines” at the center of the screen, it is going to actually be placed near the bottomFloor because the camera is focusing on the “player” which it is keeping near the center of the screen.

Reduce damping to 10 maybe and change the setBounds to

camera:setBounds(0, 0, -1000, 1000000000)

Setting y1 to -1000 will keep the camera tracking the “player” as he moves above the top of your current background into negative y values.

You’ll see your background.png is going to have to be a lot taller as the "player’ moves above or below it, but your current size will give you a visual idea of what is going on.

Nail

[import]uid: 106779 topic_id: 35062 reply_id: 139760[/import]

It works! Thanks!

I have one more thing, though. How can I make it so that the background isn’t like this, and actually fills up the entire screen?

http://imgur.com/Zn23C1n [import]uid: 188277 topic_id: 35062 reply_id: 139764[/import]

Hey there!

Sorry you’re having some trouble with Perspective. I didn’t see this post before now, or I’d have helped earlier.

Making the background fill the screen would simply be an issue of drawing the background larger when you create it.

And I also noticed when you add your objects to the Perspective view, you always add “true” to the end. Keep in mind that this is simply a shortcut - this:

[lua]camera:add(player, 1)
camera:add(rightWall, 1)
camera:add(leftWall, 1)
camera:add(bottomFloor, 1)
camera:setFocus(player)[/lua]
(or with all of the trues in there)
Can be written as this:
[lua]camera:add(player, 1, true)
camera:add(rightWall, 1)
camera:add(leftWall, 1)
camera:add(bottomFloor, 1)[/lua]
Not to mention you’ll probably want to add your objects other than your character to a lower layer (the higher the number, the lower the layer) - that’s probably why you were just seeing a big background. The layer is the second argument.

Caleb [import]uid: 147322 topic_id: 35062 reply_id: 139786[/import]

Thanks Caleb! I can see the player again!

I had the background size at 1280 x 2048 when I created it. I can see the background goes down lower than the screen. How can I get the bottom of the background to be at the bottom of the screen? Also, The background still doesn’t fill the screen. Can you please help me with that?

Thank you! [import]uid: 188277 topic_id: 35062 reply_id: 139789[/import]