Camera

See also:

System:

‘Camera Manipulations’

Camera methods:

needs to know:

  • target
    • player
    • npc
    • item
    • nothing (tracks the ‘ground’)
  • viewport x and y
    • this is the dimensions of what the camera ‘sees’
  • bounds x and y
    • these are the levels edges

What is the view point – how does the camera interact (or not) with the player

Most common is: locks onto player – stops at level edges

Centre on player – player is static (apart from animations etc.) and bg scrolls – tops at level edges

Camera box – player moves around screen until they hit a margin/border, then bg scrolls

Factors: where the player is – what happens to the background – what happens at teh edge of the map

Options

Locks to player

Can have it lock to NPCs

Can have it lock to Map

Can have it change mid

Easing – refer to an easing lookup – (see Easing)

Can do any of the following, including one then the other:

  • Follow
  • Track to
  • Static

If tracking, what to do at map or map section edge – know the map size and where we are in 9t – calculate the bounds and gutter ahead of time

The camera has an offset, based upon the viewport being 22 x 16px cells wide and 

10.5 offset x

6 offset y

22 – viewportCells

so, the calculation is:

  • total # of cells width – 1 (for camera position) / 2
  • w – 1 / 2 = offset
  • viewportCells – 1 / 2 = 10.5

In ‘overworld.js

// Establish the camera person
const cameraPerson = this.map.gameObjects.hero;

Or a fixed position:

const cameraPerson = {x: utils.withGrid(7), y: utils.withGrid(6)};
Camera – changing camera person

**** NOTE **** We can change who the camera person is for a cut scene, or other thing if we want, just by changing this value…

Also, might want to consider locking the input controls temporarily while this happens…

Lock input

Look into how the cut scene locks out the input – see: isCutScenePlaying and checkForActionCutscene in OverworldMap.js

Can also use this – will pause everything else tho…

this.map.isPaused = true;

Then sent to the draw map layers and game objects thing:

// Draw Lower layer
this.map.drawLowerImage(this.ctx, cameraPerson);
// Draw Upper layer
this.map.drawUpperImage(this.ctx, cameraPerson);
object.sprite.draw(this.ctx, cameraPerson);

in ‘OverworldMap.js‘:

drawLowerImage(ctx, cameraPerson) {
    ctx.drawImage(
        this.lowerImage,
        utils.withGrid(10.5) - cameraPerson.x,
        utils.withGrid(6) - cameraPerson.y)
}

drawUpperImage(ctx, cameraPerson){
    ctx.drawImage(
        this.upperImage,
        utils.withGrid(10.5) - cameraPerson.x,
        utils.withGrid(6) - cameraPerson.y)
}

then in the ‘sprite.js

const x = this.gameObject.x -8 + utils.withGrid(10.5) - cameraPerson.x;
const y = this.gameObject.y -18 + utils.withGrid(6) - cameraPerson.y;

That’s it!!

Camera person flag

Set the camera person flag in OverworldMap.js

Add this to the constructor:

this.camera = config.camera;
this.cameraOffset = config.cameraOffset;

The data

This will be fixed to a static location on the map – useful for smaller, internal places such as houses etc.

camera: "map", // FIXED POSITION
cameraOffset: {x: utils.withGrid(6), y: utils.withGrid(6)},

Dynamic camera, follows hero (or who ever is added there)

camera: "hero",
     cameraOffset: {},

And, the code to do it – currently there is no internal camera boundary/buffer – that’s next!

In Overworld.js

In gameStepWork:

let cameraPerson = this.map.camera;
let cameraPersonOffset = this.map.cameraOffset;
if(cameraPerson === "hero") {
   cameraPerson = this.map.gameObjects.hero;
}
if(cameraPerson === "map"){
   cameraPerson = cameraPersonOffset;
}

half canvas – 99

Resources

how to make an RPG – p68