498 lines
13 KiB
JavaScript
498 lines
13 KiB
JavaScript
class OverworldMap {
|
|
constructor(config) {
|
|
this.overworld = null;
|
|
this.gameObjects = config.gameObjects;
|
|
this.cutsceneSpaces = config.cutsceneSpaces || {};
|
|
this.walls = config.walls || {};
|
|
|
|
this.lowerImage = new Image();
|
|
this.lowerImage.src = config.lowerSrc;
|
|
|
|
this.upperImage = new Image();
|
|
this.upperImage.src = config.upperSrc;
|
|
|
|
this.isCutscenePlaying = false;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
isSpaceTaken(currentX, currentY, direction) {
|
|
const {x, y} = utils.nextPosition(currentX, currentY, direction);
|
|
return this.walls[`${x},${y}`] || false;
|
|
}
|
|
|
|
mountObjects() {
|
|
Object.keys(this.gameObjects).forEach(key => {
|
|
let object = this.gameObjects[key];
|
|
object.id = key;
|
|
|
|
|
|
object.mount(this);
|
|
})
|
|
}
|
|
|
|
async startCutscene(events) {
|
|
this.isCutscenePlaying = true;
|
|
|
|
for (let i = 0; i < events.length; i++) {
|
|
const eventHandler = new OverworldEvent({
|
|
event: events[i],
|
|
map: this,
|
|
})
|
|
await eventHandler.init();
|
|
}
|
|
|
|
this.isCutscenePlaying = false;
|
|
|
|
// reset npcs
|
|
Object.values(this.gameObjects).forEach(object => object.doBehaviorEvent(this))
|
|
}
|
|
|
|
checkForActionCutscene() {
|
|
const hero = this.gameObjects["hero"];
|
|
const nextCoords = utils.nextPosition(hero.x, hero.y, hero.direction);
|
|
const match = Object.values(this.gameObjects).find(object => {
|
|
return `${object.x},${object.y}` === `${nextCoords.x},${nextCoords.y}`
|
|
});
|
|
if (!this.isCutscenePlaying && match && match.talking.length) {
|
|
this.startCutscene(match.talking[0].events);
|
|
}
|
|
}
|
|
|
|
checkForFootstepCutscene() {
|
|
const hero = this.gameObjects["hero"];
|
|
const match = this.cutsceneSpaces[ `${hero.x},${hero.y}`];
|
|
if (!this.isCutscenePlaying && match) {
|
|
this.startCutscene(match[0].events);
|
|
}
|
|
}
|
|
|
|
addWall(x, y) {
|
|
this.walls[`${x},${y}`] = true;
|
|
}
|
|
|
|
removeWall(x, y) {
|
|
delete this.walls[`${x},${y}`];
|
|
}
|
|
|
|
moveWall(wasX, wasY, direction) {
|
|
this.removeWall(wasX, wasY);
|
|
const {x, y} = utils.nextPosition(wasX, wasY, direction);
|
|
this.addWall(x, y);
|
|
}
|
|
}
|
|
|
|
window.OverworldMaps = {
|
|
DemoRoom: {
|
|
lowerSrc: "/images/maps/map-room-entrance.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(8),
|
|
y: utils.withGrid(2),
|
|
}),
|
|
npc1: new Person({
|
|
x: utils.withGrid(6),
|
|
y: utils.withGrid(5),
|
|
behaviorLoop: [
|
|
{ type: "stand", direction: "down", time: 800 },
|
|
{ type: "stand", direction: "right", time: 300 },
|
|
{ type: "stand", direction: "down", time: 400 },
|
|
{ type: "stand", direction: "up", time: 700 },
|
|
],
|
|
talking: [
|
|
{
|
|
events: [
|
|
{ type: "textMessage", text: "Schau dich ruhig um.", faceHero: "npc1" },
|
|
{ type: "textMessage", text: "Vielleicht findest du etwas interessantes ..." },
|
|
]
|
|
}
|
|
]
|
|
}),
|
|
npc2: new Person({
|
|
x: utils.withGrid(2),
|
|
y: utils.withGrid(5),
|
|
behaviorLoop: [
|
|
{ type: "stand", direction: "right", time: 300 },
|
|
// { type: "stand", direction: "down", time: 300 },
|
|
],
|
|
talking: [
|
|
{
|
|
events: [
|
|
{ type: "textMessage", text: "Dieser Raum darf nicht betreten werden.", faceHero: "npc2" },
|
|
{ type: "textMessage", text: "Geh weg!" },
|
|
{ who: "hero", type: "walk", direction: "right" },
|
|
]
|
|
}
|
|
]
|
|
}),
|
|
npc3: new Person({
|
|
x: utils.withGrid(9),
|
|
y: utils.withGrid(3),
|
|
src: "/images/characters/people/hero-test.png",
|
|
behaviorLoop: [
|
|
{ type: "stand", direction: "down", time: 2000 },
|
|
{ type: "stand", direction: "right", time: 2000 },
|
|
{ type: "stand", direction: "up", time: 2000 },
|
|
{ type: "stand", direction: "left", time: 2000 },
|
|
],
|
|
})
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(5,2)] : true,
|
|
[utils.asGridCoord(5,3)] : true,
|
|
[utils.asGridCoord(5,4)] : true,
|
|
[utils.asGridCoord(4,4)] : true,
|
|
[utils.asGridCoord(3,4)] : true,
|
|
[utils.asGridCoord(2,4)] : true,
|
|
[utils.asGridCoord(1,5)] : true,
|
|
[utils.asGridCoord(0,6)] : true,
|
|
[utils.asGridCoord(1,7)] : true,
|
|
[utils.asGridCoord(2,8)] : true,
|
|
[utils.asGridCoord(3,8)] : true,
|
|
[utils.asGridCoord(4,8)] : true,
|
|
[utils.asGridCoord(5,8)] : true,
|
|
[utils.asGridCoord(5,9)] : true,
|
|
[utils.asGridCoord(5,10)] : true,
|
|
[utils.asGridCoord(4,11)] : true,
|
|
[utils.asGridCoord(5,12)] : true,
|
|
[utils.asGridCoord(6,12)] : true,
|
|
[utils.asGridCoord(7,12)] : true,
|
|
[utils.asGridCoord(7,13)] : true,
|
|
[utils.asGridCoord(8,14)] : true,
|
|
[utils.asGridCoord(9,13)] : true,
|
|
[utils.asGridCoord(9,12)] : true,
|
|
[utils.asGridCoord(10,12)] : true,
|
|
[utils.asGridCoord(11,12)] : true,
|
|
[utils.asGridCoord(12,11)] : true,
|
|
[utils.asGridCoord(11,10)] : true,
|
|
[utils.asGridCoord(11,9)] : true,
|
|
[utils.asGridCoord(11,8)] : true,
|
|
[utils.asGridCoord(11,7)] : true,
|
|
[utils.asGridCoord(11,6)] : true,
|
|
[utils.asGridCoord(12,5)] : true,
|
|
[utils.asGridCoord(11,4)] : true,
|
|
[utils.asGridCoord(11,3)] : true,
|
|
[utils.asGridCoord(11,2)] : true,
|
|
[utils.asGridCoord(10,1)] : true,
|
|
[utils.asGridCoord(9,1)] : true,
|
|
[utils.asGridCoord(8,1)] : true,
|
|
[utils.asGridCoord(7,1)] : true,
|
|
[utils.asGridCoord(6,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(1,6)]: [
|
|
{
|
|
events: [
|
|
{ who: "npc2", type: "walk", direction: "down" },
|
|
{ who: "npc2", type: "stand", direction: "left" },
|
|
{ who: "hero", type: "stand", direction: "right", time: 300 },
|
|
{ type: "textMessage", text: "Du kannst hier nicht rein!" },
|
|
{ who: "npc2", type: "walk", direction: "up" },
|
|
{ who: "npc2", type: "stand", direction: "right" },
|
|
{ who: "hero", type: "walk", direction: "right" },
|
|
{ who: "hero", type: "walk", direction: "right" },
|
|
]
|
|
}
|
|
],
|
|
[utils.asGridCoord(11,5)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "Kitchen" }
|
|
]
|
|
}
|
|
],
|
|
[utils.asGridCoord(11,11)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "Bedroom" }
|
|
]
|
|
}
|
|
],
|
|
[utils.asGridCoord(8,13)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "Bathroom" }
|
|
]
|
|
}
|
|
],
|
|
[utils.asGridCoord(5,11)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "Livingroom" }
|
|
]
|
|
}
|
|
],
|
|
[utils.asGridCoord(1,6)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "Office" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
Kitchen: {
|
|
lowerSrc: "/images/maps/map-room-kitchen.png",
|
|
// upperSrc: "/images/maps/room-builder.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(1),
|
|
y: utils.withGrid(4),
|
|
}),
|
|
npc1: new Person({
|
|
x: utils.withGrid(3),
|
|
y: utils.withGrid(6),
|
|
// src: "/images/characters/people/hero-run.png",
|
|
talking: [
|
|
{
|
|
events: [
|
|
{ type: "textMessage", text: "You made it!", faceHero: "npc1" },
|
|
]
|
|
}
|
|
]
|
|
})
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(1,1)] : true,
|
|
[utils.asGridCoord(1,2)] : true,
|
|
[utils.asGridCoord(1,3)] : true,
|
|
[utils.asGridCoord(0,4)] : true,
|
|
[utils.asGridCoord(1,5)] : true,
|
|
[utils.asGridCoord(1,6)] : true,
|
|
[utils.asGridCoord(2,7)] : true,
|
|
[utils.asGridCoord(3,7)] : true,
|
|
[utils.asGridCoord(4,7)] : true,
|
|
[utils.asGridCoord(5,7)] : true,
|
|
[utils.asGridCoord(6,7)] : true,
|
|
[utils.asGridCoord(7,7)] : true,
|
|
[utils.asGridCoord(8,6)] : true,
|
|
[utils.asGridCoord(8,5)] : true,
|
|
[utils.asGridCoord(8,4)] : true,
|
|
[utils.asGridCoord(8,3)] : true,
|
|
[utils.asGridCoord(8,2)] : true,
|
|
[utils.asGridCoord(7,1)] : true,
|
|
[utils.asGridCoord(6,1)] : true,
|
|
[utils.asGridCoord(5,1)] : true,
|
|
[utils.asGridCoord(4,1)] : true,
|
|
[utils.asGridCoord(3,1)] : true,
|
|
[utils.asGridCoord(2,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(1,4)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "DemoRoom" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
Bedroom: {
|
|
lowerSrc: "/images/maps/map-room-bedroom.png",
|
|
// upperSrc: "/images/maps/room-builder.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(1),
|
|
y: utils.withGrid(4),
|
|
}),
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(1,2)] : true,
|
|
[utils.asGridCoord(1,3)] : true,
|
|
[utils.asGridCoord(0,4)] : true,
|
|
[utils.asGridCoord(1,5)] : true,
|
|
[utils.asGridCoord(1,6)] : true,
|
|
[utils.asGridCoord(1,7)] : true,
|
|
[utils.asGridCoord(1,8)] : true,
|
|
[utils.asGridCoord(2,9)] : true,
|
|
[utils.asGridCoord(3,9)] : true,
|
|
[utils.asGridCoord(4,9)] : true,
|
|
[utils.asGridCoord(5,9)] : true,
|
|
[utils.asGridCoord(6,9)] : true,
|
|
[utils.asGridCoord(7,9)] : true,
|
|
[utils.asGridCoord(8,8)] : true,
|
|
[utils.asGridCoord(8,7)] : true,
|
|
[utils.asGridCoord(8,6)] : true,
|
|
[utils.asGridCoord(8,5)] : true,
|
|
[utils.asGridCoord(8,4)] : true,
|
|
[utils.asGridCoord(8,3)] : true,
|
|
[utils.asGridCoord(8,2)] : true,
|
|
[utils.asGridCoord(7,1)] : true,
|
|
[utils.asGridCoord(6,1)] : true,
|
|
[utils.asGridCoord(5,1)] : true,
|
|
[utils.asGridCoord(4,1)] : true,
|
|
[utils.asGridCoord(3,1)] : true,
|
|
[utils.asGridCoord(2,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(1,4)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "DemoRoom" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
Bathroom: {
|
|
lowerSrc: "/images/maps/map-room-bathroom.png",
|
|
// upperSrc: "/images/maps/room-builder.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(3),
|
|
y: utils.withGrid(1),
|
|
}),
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(0,2)] : true,
|
|
[utils.asGridCoord(0,3)] : true,
|
|
[utils.asGridCoord(0,4)] : true,
|
|
[utils.asGridCoord(0,5)] : true,
|
|
[utils.asGridCoord(0,6)] : true,
|
|
[utils.asGridCoord(1,7)] : true,
|
|
[utils.asGridCoord(2,7)] : true,
|
|
[utils.asGridCoord(3,7)] : true,
|
|
[utils.asGridCoord(4,7)] : true,
|
|
[utils.asGridCoord(5,6)] : true,
|
|
[utils.asGridCoord(5,5)] : true,
|
|
[utils.asGridCoord(5,4)] : true,
|
|
[utils.asGridCoord(5,3)] : true,
|
|
[utils.asGridCoord(5,2)] : true,
|
|
[utils.asGridCoord(4,1)] : true,
|
|
[utils.asGridCoord(3,0)] : true,
|
|
[utils.asGridCoord(2,1)] : true,
|
|
[utils.asGridCoord(1,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(3,1)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "DemoRoom" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
Livingroom: {
|
|
lowerSrc: "/images/maps/map-room-livingroom.png",
|
|
// upperSrc: "/images/maps/room-builder.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(11),
|
|
y: utils.withGrid(4),
|
|
}),
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(0,2)] : true,
|
|
[utils.asGridCoord(0,3)] : true,
|
|
[utils.asGridCoord(0,4)] : true,
|
|
[utils.asGridCoord(0,5)] : true,
|
|
[utils.asGridCoord(0,6)] : true,
|
|
[utils.asGridCoord(0,7)] : true,
|
|
[utils.asGridCoord(1,8)] : true,
|
|
[utils.asGridCoord(2,8)] : true,
|
|
[utils.asGridCoord(3,8)] : true,
|
|
[utils.asGridCoord(4,8)] : true,
|
|
[utils.asGridCoord(5,8)] : true,
|
|
[utils.asGridCoord(6,8)] : true,
|
|
[utils.asGridCoord(7,8)] : true,
|
|
[utils.asGridCoord(8,8)] : true,
|
|
[utils.asGridCoord(9,8)] : true,
|
|
[utils.asGridCoord(10,8)] : true,
|
|
[utils.asGridCoord(11,7)] : true,
|
|
[utils.asGridCoord(11,6)] : true,
|
|
[utils.asGridCoord(11,5)] : true,
|
|
[utils.asGridCoord(12,4)] : true,
|
|
[utils.asGridCoord(11,3)] : true,
|
|
[utils.asGridCoord(11,2)] : true,
|
|
[utils.asGridCoord(10,1)] : true,
|
|
[utils.asGridCoord(9,1)] : true,
|
|
[utils.asGridCoord(8,1)] : true,
|
|
[utils.asGridCoord(7,1)] : true,
|
|
[utils.asGridCoord(6,1)] : true,
|
|
[utils.asGridCoord(5,1)] : true,
|
|
[utils.asGridCoord(4,1)] : true,
|
|
[utils.asGridCoord(3,1)] : true,
|
|
[utils.asGridCoord(2,1)] : true,
|
|
[utils.asGridCoord(1,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(11,4)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "DemoRoom" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
Office: {
|
|
lowerSrc: "/images/maps/map-room-office.png",
|
|
// upperSrc: "/images/maps/room-builder.png",
|
|
upperSrc: "",
|
|
gameObjects: {
|
|
hero: new Person({
|
|
isPlayerControlled: true,
|
|
x: utils.withGrid(8),
|
|
y: utils.withGrid(4),
|
|
}),
|
|
},
|
|
walls: {
|
|
// "16,16": true
|
|
[utils.asGridCoord(0,2)] : true,
|
|
[utils.asGridCoord(0,3)] : true,
|
|
[utils.asGridCoord(0,4)] : true,
|
|
[utils.asGridCoord(0,5)] : true,
|
|
[utils.asGridCoord(0,6)] : true,
|
|
[utils.asGridCoord(1,7)] : true,
|
|
[utils.asGridCoord(2,7)] : true,
|
|
[utils.asGridCoord(3,7)] : true,
|
|
[utils.asGridCoord(4,7)] : true,
|
|
[utils.asGridCoord(5,7)] : true,
|
|
[utils.asGridCoord(6,7)] : true,
|
|
[utils.asGridCoord(7,7)] : true,
|
|
[utils.asGridCoord(8,6)] : true,
|
|
[utils.asGridCoord(8,5)] : true,
|
|
[utils.asGridCoord(9,4)] : true,
|
|
[utils.asGridCoord(8,3)] : true,
|
|
[utils.asGridCoord(8,2)] : true,
|
|
[utils.asGridCoord(7,1)] : true,
|
|
[utils.asGridCoord(6,1)] : true,
|
|
[utils.asGridCoord(5,1)] : true,
|
|
[utils.asGridCoord(4,1)] : true,
|
|
[utils.asGridCoord(3,1)] : true,
|
|
[utils.asGridCoord(2,1)] : true,
|
|
[utils.asGridCoord(1,1)] : true,
|
|
},
|
|
cutsceneSpaces: {
|
|
[utils.asGridCoord(8,4)]: [
|
|
{
|
|
events: [
|
|
{ type: "changeMap", map: "DemoRoom" }
|
|
]
|
|
}
|
|
],
|
|
}
|
|
},
|
|
} |