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