Skip to content

Commit

Permalink
Text msg + Map change + other stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Chasmiccoder committed Feb 6, 2022
1 parent 99b289e commit cb1ec4b
Show file tree
Hide file tree
Showing 17 changed files with 2,941 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.vs/
.vscode/
.vscode/
todo.txt
Binary file added images/ourMap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/ourMap2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/ourMap3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2,629 changes: 2,629 additions & 0 deletions images/ourMap4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/ourMap5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ACM-VIT Recruitment Portal</title>

<link rel="stylesheet" href="./styles.css" type="text/css">
<link rel="stylesheet" href="./styles/global.css" type="text/css">
<link rel="stylesheet" href="./styles/TextMessage.css" type="text/css">

</head>
<body>
<div class="game-container">
Expand All @@ -22,6 +24,8 @@
<script src="./js/Sprite.js"></script>
<script src="./js/OverworldMap.js"></script>
<script src="./js/OverworldEvent.js"></script>
<script src="./js/TextMessage.js"></script>
<script src="./js/KeyPressListener.js"></script>
<script src="./js/init.js"></script>
</body>
</html>
7 changes: 6 additions & 1 deletion js/GameObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class GameObject {

this.behaviorLoop = config.behaviorLoop || [];
this.behaviorLoopIndex = 0;


this.talking = config.talking || [];

}

mount(map) {
Expand All @@ -31,7 +35,8 @@ class GameObject {
async doBehaviorEvent(map) {

// maybe the game object has no current behaviour or there's a global event (like a cutscene)
if(map.isCutscenePlaying || this.behaviorLoop.length === 0) {
// also return; if the person is currently standing
if(map.isCutscenePlaying || this.behaviorLoop.length === 0 || this.isStanding) {
return;
}

Expand Down
35 changes: 35 additions & 0 deletions js/KeyPressListener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// the way the game works is that if you press a button, to do the same thing, you need to
// lift your finger and press again.
// makes sense in the context of text messages. If you get a text message and press enter,
// and then release enter, then it will resume the original state.

class KeyPressListener {
constructor(keyCode, callback) {
let keySafe = true; // true if a key is not pressed.

this.keydownFunction = function(event) {
if(event.code === keyCode) {
if(keySafe) {
keySafe = false;
callback();
}
}
};

this.keyupFunction = function(event) {
if(event.code === keyCode) {
keySafe = true;
}
};

// binding the event listeners
document.addEventListener("keydown", this.keydownFunction);
document.addEventListener("keyup", this.keyupFunction);
}

// unbind the event listeners
unbind() {
document.removeEventListener("keydown", this.keydownFunction);
document.removeEventListener("keyup", this.keyupFunction);
}
}
51 changes: 42 additions & 9 deletions js/Overworld.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ class Overworld {
}

init() {
this.map = new OverworldMap(window.OverworldMaps.DemoRoom);
this.map.mountObjects();
this.startMap(window.OverworldMaps.DemoRoom);


this.bindActionInput();
this.bindHeroPositionCheck();


this.directionInput = new DirectionInput();
this.directionInput.init();
Expand All @@ -17,17 +21,46 @@ class Overworld {
// game loop fires at 60 fps


this.map.startCutscene([
{who: "hero", type: "walk", direction: "down"},
{who: "hero", type: "walk", direction: "down"},
{who: "npcA", type: "walk", direction: "left"},
{who: "npcA", type: "walk", direction: "left"},
{who: "npcA", type: "stand", direction: "up", time: 800},

])




// this.map.startCutscene([

// {who: "hero", type: "walk", direction: "down"},
// {who: "hero", type: "walk", direction: "down"},
// {who: "npcA", type: "walk", direction: "up"},
// {who: "npcA", type: "walk", direction: "left"},
// {who: "hero", type: "stand", direction: "right", time: 200},
// {type: "textMessage", text: "Why hello there!"},
// ])

}

bindActionInput() {
new KeyPressListener("Enter", () => {
// is there a person to talk to?
this.map.checkForActionCutscene() // check for a cutscene at a specific position

})
}

bindHeroPositionCheck() {
document.addEventListener("PersonWalkingComplete", e => {
if(e.detail.whoId == "hero") {
// hero's position has changed
this.map.checkForFootstepCutscene();
}
});
}

startMap(mapConfig) {
this.map = new OverworldMap(mapConfig);
this.map.overworld = this;
this.map.mountObjects();
}

startGameLoop() {
const step = () => {

Expand Down
20 changes: 20 additions & 0 deletions js/OverworldEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,24 @@ class OverworldEvent {
}
document.addEventListener("PersonWalkingComplete", completeHandler);
}

textMessage(resolve) {

if(this.event.faceHero) { // this.event.faceHero = id of the npc to face that will face the hero
const obj = this.map.gameObjects[this.event.faceHero];
obj.direction = utils.oppositeDirection(this.map.gameObjects['hero'].direction);
}

const message = new TextMessage({
text: this.event.text,
onComplete: () => resolve()
});

message.init(document.querySelector('.game-container'));
}

changeMap(resolve) {
this.map.overworld.startMap(window.OverworldMaps[this.event.map]); // the value this.event.map is referencing {type: "changeMap", map: "Kitchen"} in OverworldMap
resolve();
}
}
132 changes: 109 additions & 23 deletions js/OverworldMap.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
class OverworldMap {
constructor(config) {
// adding a back-reference to the overworld
this.overworld = null;

this.gameObjects = config.gameObjects;
this.cutsceneSpaces = config.cutsceneSpaces || {};

this.walls = config.walls || {};

this.lowerImage = new Image();
Expand All @@ -9,7 +14,7 @@ class OverworldMap {
this.lowerImage.src = config.lowerSrc; // floor
this.upperImage.src = config.upperSrc; // what is rendered above the floor (above the player) like tree tops

this.isCutscenePlaying = true;
this.isCutscenePlaying = false;

}

Expand Down Expand Up @@ -50,8 +55,44 @@ class OverworldMap {
}

this.isCutscenePlaying = false;


// reset npc's to do their normal behaviour
Object.values(this.gameObjects).forEach(object => object.doBehaviorEvent(this))
}

checkForActionCutscene() {
const hero = this.gameObjects['hero']; // can be any of the player controlled objects

// using "" to check whether there is anyone to talk to
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 you press Enter, you'll get the match object depending on your position and direction!
// console.log({match});

if(!this.isCutscenePlaying && match && match.talking.length) {
this.startCutscene(match.talking[0].events)
}
}

// footstep triggered cutscene
checkForFootstepCutscene() {
const hero = this.gameObjects['hero'];
const match = this.cutsceneSpaces[`${hero.x},${hero.y}`];

// is undefined for normal tiles, but displays the object if you step on a tile that triggers a cutscene
// console.log(match);

if(!this.isCutscenePlaying && match) {
this.startCutscene(match[0].events); // right now it's pulling the behavior at the 0th index. Can be changed depending on the current story
}
}



addWall(x,y) {
this.walls[`${x},${y}`] = true;
}
Expand All @@ -71,6 +112,7 @@ class OverworldMap {

window.OverworldMaps = {
DemoRoom: {
// lowerSrc: "./images/DemoLower.png",
lowerSrc: "./images/DemoLower.png",
upperSrc: "./images/DemoUpper.png",
gameObjects: {
Expand All @@ -90,51 +132,95 @@ window.OverworldMaps = {
{type: "stand", direction: "up", time: 800},
{type: "stand", direction: "right", time: 1200},
{type: "stand", direction: "up", time: 300}

],
talking: [
{
// defined this way so that people can say different things, at different points in time
events: [
{type: "textMessage", text: "I'm busy...", faceHero: "npcA"},
{type: "textMessage", text: "Go away!"},
{who: "hero", type: "walk", direction: "left"}
]
},

// saying a different thing later
// {
// events: [
// {type: "textMessage", text: "Congrats on beating that boss!"}
// ]
// }
]
}),

npcB: new Person({
x: utils.withGrid(3),
y: utils.withGrid(7),
x: utils.withGrid(8),
y: utils.withGrid(5),
src: "./images/npc2.png",
behaviorLoop: [
{type: "walk", direction: "left"},
{type: "stand", direction: "left", time: 800},
{type: "walk", direction: "up"},
{type: "walk", direction: "right"},
{type: "walk", direction: "down"}
]
// behaviorLoop: [
// {type: "walk", direction: "left"},
// {type: "stand", direction: "left", time: 800},
// {type: "walk", direction: "up"},
// {type: "walk", direction: "right"},
// {type: "walk", direction: "down"}
// ]
}),
},
walls: {
[utils.asGridCoord(7,6)]: true,
[utils.asGridCoord(8,6)]: true,
[utils.asGridCoord(7,7)]: true,
[utils.asGridCoord(8,7)]: true,
},
cutsceneSpaces: {
[utils.asGridCoord(7,4)]: [
// doing it this way so that for example if you step on a cutscene space
// and if the cutscene gets over, then the same cutscene should not play when you step on the same tile again
{
events: [
{who: "npcB", type: "walk", direction: "left"},
{who: "npcB", type: "stand", direction: "up", time:500},
{type: "textMessage", text: "You can't be in there!"},
{who: "npcB", type: "walk", direction: "right"},
{who: "hero", type: "walk", direction: "down"},
{who: "hero", type: "walk", direction: "left"},
]
}
],
[utils.asGridCoord(5,10)]: [
{
events: [
{type: "changeMap", map: "Kitchen"} // gets referenced in OverworldEvent
]
}
]

}
},

Kitchen: {
lowerSrc: "./images/KitchenLower.png",
upperSrc: "./images/KitchenUpper.png",
gameObjects: {
hero: new GameObject({
x: 3,
y: 5,
hero: new Person({
isPlayerControlled: true,
x: utils.withGrid(5),
y: utils.withGrid(5),
}),

npcA: new GameObject({
x: 9,
y: 6,
src: "./images/npc1.png"
npcB: new Person({
x: utils.withGrid(10),
y: utils.withGrid(8),
src: "./images/npc2.png",
talking: [
{
events: [
{type: "textMessage", text: "You made it!", faceHero: "npcB"}
]
}
]
}),

npcB: new GameObject({
x: 10,
y: 8,
src: "./images/npc2.png"
})

}
},
}
4 changes: 4 additions & 0 deletions js/Person.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Person extends GameObject {
constructor(config) {
super(config);
this.movingProgressRemaining = 0;
this.isStanding = false;

this.isPlayerControlled = config.isPlayerControlled || false;

Expand Down Expand Up @@ -58,10 +59,13 @@ class Person extends GameObject {
}

if(behavior.type === "stand") {
this.isStanding = true;

setTimeout(() => {
utils.emitEvent("PersonStandComplete", {
whoId: this.id
})
this.isStanding = false;
}, behavior.time);
}
}
Expand Down
Loading

0 comments on commit cb1ec4b

Please sign in to comment.