-
Notifications
You must be signed in to change notification settings - Fork 0
/
Overworld.js
160 lines (131 loc) · 4.68 KB
/
Overworld.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class Overworld {
constructor(config) {
this.element = config.element;
this.canvas = this.element.querySelector(".game-canvas");
this.ctx = this.canvas.getContext("2d");
this.map = null
}
gameLoopStepWork(delta) {
//Clear off canvas
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)
//Stablish camera
const cameraPerson = this.map.gameObjects.hero
// Update all objects
Object.values(this.map.gameObjects).forEach(object => {
object.update({
delta,
arrow: this.directionInput.direction,
map: this.map,
})
})
//Draw Lower Map
this.map.drawLowerImage(this.ctx, cameraPerson)
//DrawGameObjects
Object.values(this.map.gameObjects).sort((a,b) => {
return a.y - b.y
}).forEach(object => {
object.sprite.draw(this.ctx, cameraPerson)
})
//Draw Upper Map
this.map.drawUpperImage(this.ctx, cameraPerson)
}
startGameLoop() {
let prevMs
const step = 1/60
const stepFn = (timestampMs) => {
if (this.map.isPaused){
return
}
if (prevMs === undefined){
prevMs = timestampMs
}
let delta = (timestampMs - prevMs) / 1000
while(delta >= step){
this.gameLoopStepWork(delta)
delta -= step
}
prevMs = timestampMs - delta * 1000
//Business as usual tick
requestAnimationFrame(stepFn)
}
//First kickoff tick
requestAnimationFrame(stepFn)
}
bindActionInput() {
new KeyPressListener("Enter", () => {
//Is there a person to talk to
this.map.checkForActionCutscene()
})
new KeyPressListener("Escape", () => {
if (!this.map.isCutscenePlaying){
this.map.startCutscene([
{type: "pause"}
])
}
})
}
bindHeroPositionCheck() {
document.addEventListener("PersonWalkingComplete", e => {
if (e.detail.whoId === "hero") {
//Hero position has changed
this.map.checkForFootstepCutscene()
}
})
}
startMap(mapConfig, heroInitState=null) {
this.map = new OverworldMap(mapConfig)
this.map.overworld = this
this.map.mountObjects()
if (heroInitState){
const {hero} = this.map.gameObjects
// this.map.removeWall(hero.x, hero.y)
hero.x = heroInitState.x
hero.y = heroInitState.y
hero.direction = heroInitState.direction
// this.map.addWall(hero.x, hero.y)
}
this.progress.mapId = mapConfig.id
this.progress.startingHeroX = this.map.gameObjects.hero.x
this.progress.startingHeroY = this.map.gameObjects.hero.y
this.progress.startingHeroDirection = this.map.gameObjects.hero.direction
}
async init() {
const container = document.querySelector(".game-container")
//Create the progress file
this.progress = new Progress()
//Show title screen
this.titleScreen = new TitleScreen({
progress: this.progress
})
const usesSaveFile = await this.titleScreen.init(container)
//Potentially load saved data
let initHeroState = null
// const saveFile = this.progress.getSaveFile()
if (usesSaveFile) {
this.progress.load()
initHeroState = {
x: this.progress.startingHeroX,
y: this.progress.startingHeroY,
direction: this.progress.startingHeroDirection,
}
}
//Load hud
this.hud = new Hud()
this.hud.init(document.querySelector(".game-container"))
//Start first map
this.startMap(window.OverworldMaps[this.progress.mapId], initHeroState)
//Create controls
this.bindActionInput()
this.bindHeroPositionCheck()
this.directionInput = new DirectionInput()
this.directionInput.init()
this.directionInput.direction
//Kick off the game
this.startGameLoop()
// this.map.startCutscene([
// {type:"battle", enemyId: "beth"}
// // {type:"changeMap", map:"DemoRoom"}
// // {type:"textMessage", text:"This is the very first message"}
// ])
}
}