Setting Camera Focus to Sprite

Hello,

I have an issue that has been bugging me for a while with corona’s camera features.

I have completed the set up for a side scrolling game however, I am unable to have the camera move along with the sprite’s movements. I have used “setCameraFocus(player)” but did not achieve any results. I am totally clueless on how to make the screen move along with the character similar to a traditional NES game. I am familiar with the “endless runner” examples, however, they do not answer the question on the screen moving in reaction to an event and stopping due to an even (button pushes). And since I am not attempting to repeat the same background infinitely, I began thinking that moving the entire “universe” or stage map vs the character sprite was a better option. Can anyone assist.

Below is my source code & my image/sound files are attached:

[lua]
–Hide status bar from the beginning
display.setStatusBar( display.HiddenStatusBar ) display.setStatusBar(display.HiddenStatusBar) _W = display.contentWidth _H = display.contentHeight number = 0

–Start Physics engine
local physics = require (“physics”)
physics.start()
–physics.setDrawMode( “hybrid” )

–Background
local DC_width = display.contentWidth;
local DC_height = display.contentHeight;

motionx = 0; – Variable used to move character along x axis
speed = 9; – Set Walking Speed
score = 0; – Set Score to 0
snd_heart = audio.loadSound(“heart.wav”) – Set heart variable
snd_BGM = audio.loadSound( “DX.mp3”) – Set Background music

– Add Sky to the background
local rect = display.newRect( DC_width/2, DC_height/2 , 1136, 640)
local gradient = {
    type=“gradient”,
    color1={ 1, 1, 1}, color2={ 1, 1, 0, 1 }, direction=“down”
}
rect:setFillColor( gradient )

–Add Grass floor to game
local grass_bottom = display.newImage( “photos/grass_bottom.png”, true )
grass_bottom.x = DC_width/2; grass_bottom.y = DC_height-35;
grass_bottom.anchorX = 0.5 --This is a replacement for set reference point found in v1 versions of a file.
physics.addBody( grass_bottom, “static”,  { friction= 0.5, bounce=0 } )
grass_bottom.myName = “grass”

– Add Grass to the background
local grass_top = display.newImage( “photos/grass_top.png”, true )
grass_top.x = DC_width/2; grass_top.y = DC_height - 95;

local runData = { width=125, height=143, numFrames=32, sheetContentWidth=1024, sheetContentHeight=1024 }
local runSheet = graphics.newImageSheet( “photos/Agares Master Small.png”, runData )
    local runData = {
    { name = “normalRun”, start=25, count=8, time=800},
    { name = “jump”, frames={17,17,17,17,18,18,19,20,20,20,21,21,22,22}, time=2000, loopCount=1},
    { name = “forwardJump”, frames={2,3,4,5,6,7,8,9,10,11,12,13,23}, time=1200, loopCount=1},
    { name = “landing”, frames={16,15}, time=200, loopCount=1},
    { name = “standing”, frames={1}, time=100, loopCount=0},
}
    

local agares = display.newSprite( runSheet, runData )
physics.addBody( agares, “dynamic”, {density = 0.8, friction = 0.5, bounce =0 } )
agares.x = math.random(10, DC_width-10)
agares.myName = “agares”
agares.isFixedRotation = true

local belmont = display.newImage( “photos/simon-belmont.png” )
physics.addBody( belmont, “dynamic”, { density = 0.8, friction = 0.5, bounce = 0 } )
belmont.x = math.random(10, DC_width-10)
belmont.myName = “belmont”
belmont.isFixedRotation = true

– Add left joystick button
 local left = display.newImage (“photos/btn_arrow.png”)
 left.x = 125; left.y = 600;
 left.rotation = 180;

– Add right joystick button
 local right = display.newImage (“photos/btn_arrow.png”)
 right.x = 225; right.y = 600;



 – When left arrow is touched, move character left
 function left:touch()
     if playerInAir == true then
 agares.xScale = -1
 motionx = -speed;
 agares:setSequence(“forwardJump”)
 agares:play()
    else
 agares.xScale = -1
 motionx = -speed;
 agares:setSequence(“normalRun”)
    agares:play()
 end

 end
 left:addEventListener(“touch”,left)



– When right arrow is touched, move character right

 function right:touch()
     if playerInAir == true then
 agares.xScale = 1
 motionx = speed;
 agares:setSequence(“forwardJump”)
 agares:play()
    else
         motionx = speed;
         agares.xScale = 1
        agares:setSequence(“normalRun”)
        agares:play()
 end

 end
 right:addEventListener(“touch”,right)



–Add score to Screen
local playerScore = display.newText( "Score: "…score, DC_width/2, 40, native.systemFont, 16);
playerScore:setFillColor(1, 1, 1);

 – Move character
 local function moveagares (event)
 agares.x = agares.x + motionx;       
       --camera.x = agares.x - DC_width * 0.3
       --camera.y = agares.y - DC_height * 0.3
 end
 Runtime:addEventListener(“enterFrame”, moveagares)

 local function stop(event)
     if (event.phase==“ended” and playerInAir == false) then
     agares:setSequence(“standing”)
    agares:play()
     motionx = 0;
 end
end
timer.performWithDelay( 2800, stop, 0 )
Runtime:addEventListener(“touch”, stop)

– Add Jump button
local up = display.newImage (“photos/btn_arrow.png”)
    up.x = 175; up.y = 560;
    up.rotation = 270;



–Make character jump
function up:touch(event)
if(event.phase == “began” and playerInAir == false) then
agares:setLinearVelocity( 0, -270 )
agares:setSequence(“jump”)
    agares:play()
playerInAir = true
print(playerInAir)
end
end
up:addEventListener(“touch”,up)



–Create hearts
function createHeart()
local heart = display.newImage( “photos/heart.png” )
    physics.addBody( heart, “dynamic”, {density=0.1, bounce=0.5})
    heart.x = math.random(20, 620); heart.y = 0;
    heart.myName = “heart”
end
timer.performWithDelay( 2800, createHeart, 0 )

 
–Detect whether the player is in the air or not
function onCollision( event )

   if(event.object1.myName == “grass” and event.object2.myName == “agares”) then
      playerInAir = false;
      agares:setSequence(“landing”)
       agares:play()
       motionx = 0;
       --performWithDelay 600;

    end

    --If guy collides with coin, remove coin
    if(event.object1.myName == “agares” and event.object2.myName == “heart”) then
        audio.play(snd_heart);
        score = score + 1;
        playerScore.text = "Score: "…score
        event.object2:removeSelf();
    end

     --Remove coin when it reaches the ground
    if(event.object1.myName == “grass” and event.object2.myName == “heart”) then
        event.object2:removeSelf();
    end
end

Runtime:addEventListener( “collision”, onCollision )

[/lua]

Hi Andy,

Corona doesn’t have the traditional “camera” built in, meaning, there’s not a specific “camera object” which you move around. Instead, Corona works on the concept of display groups which move in relation to the device’s view, thus giving the impression that the screen itself is the “camera” (that may not be a great description but it’s a brief summary).

Of course, you want to have a NES-style camera, and there is a popular 3rd-party library for that called “perspective”. Here is a link to the page. It’s very easy to implement and many developers use it:

http://code.coronalabs.com/code/perspective-virtual-camera-system

Also, if you’re building a more complex scrolling-world type of game, and that game uses tiles to construct its world, you may want to consider using something like the Dusk engine or MTE, which are other 3rd-party libraries which use Tiled data and handle all sorts of other world building and scrolling functionality:

http://gymbyl.com/programming/dusk.html

http://forums.coronalabs.com/topic/33119-million-tile-engine-beta-release/

Take care,

Brent

Also, this isn’t terribly difficult to implement without 3rd party libraries. The below is the code I use in my gameloop that allows the view to orient to the player:

 if (playerfile.herohitBox.x \> 500 and playerfile.herohitBox.x \< 4400) then GameSettings.game.x = -playerfile.herohitBox.x + display.contentWidth/2 end if (playerfile.herohitBox.y \> -150 and playerfile.herohitBox.y \< 160) then GameSettings.game.y = -playerfile.herohitBox.y + 255 end

Not rocket science by any means. I have a platformer tutorial project up on github that you can take a look at, which, I think, achieves what you’re looking for.

Brent,

I implemented the perspective code solution and it worked better than I imagined. The beginning lessons I have used did not sufficiently go over layers in corona and how to “simulate” movement on the screen. I am not going to pretend and say I understand all the inner workings of the library but I know it works.

Alex,

I never got a chance to implement your code but I will also work a version that implements this as well. I still want to understand the final product and I think your method achieves that also.

Thanks for the help

Thanks for sharing.

Hi Andy,

Corona doesn’t have the traditional “camera” built in, meaning, there’s not a specific “camera object” which you move around. Instead, Corona works on the concept of display groups which move in relation to the device’s view, thus giving the impression that the screen itself is the “camera” (that may not be a great description but it’s a brief summary).

Of course, you want to have a NES-style camera, and there is a popular 3rd-party library for that called “perspective”. Here is a link to the page. It’s very easy to implement and many developers use it:

http://code.coronalabs.com/code/perspective-virtual-camera-system

Also, if you’re building a more complex scrolling-world type of game, and that game uses tiles to construct its world, you may want to consider using something like the Dusk engine or MTE, which are other 3rd-party libraries which use Tiled data and handle all sorts of other world building and scrolling functionality:

http://gymbyl.com/programming/dusk.html

http://forums.coronalabs.com/topic/33119-million-tile-engine-beta-release/

Take care,

Brent

Also, this isn’t terribly difficult to implement without 3rd party libraries. The below is the code I use in my gameloop that allows the view to orient to the player:

 if (playerfile.herohitBox.x \> 500 and playerfile.herohitBox.x \< 4400) then GameSettings.game.x = -playerfile.herohitBox.x + display.contentWidth/2 end if (playerfile.herohitBox.y \> -150 and playerfile.herohitBox.y \< 160) then GameSettings.game.y = -playerfile.herohitBox.y + 255 end

Not rocket science by any means. I have a platformer tutorial project up on github that you can take a look at, which, I think, achieves what you’re looking for.

Brent,

I implemented the perspective code solution and it worked better than I imagined. The beginning lessons I have used did not sufficiently go over layers in corona and how to “simulate” movement on the screen. I am not going to pretend and say I understand all the inner workings of the library but I know it works.

Alex,

I never got a chance to implement your code but I will also work a version that implements this as well. I still want to understand the final product and I think your method achieves that also.

Thanks for the help

Thanks for sharing.