-
Notifications
You must be signed in to change notification settings - Fork 0
/
room.js
168 lines (168 loc) · 6.46 KB
/
room.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
161
162
163
164
165
166
167
168
import fs from 'fs';
let wordArr = [];
fs.readFile('static/words.txt', (err, data) => {
if (err)
throw err;
wordArr = data.toString().split(/[\r\n]+/);
//console.log(data.toString().split(/[\r\n]+/));
});
class Room {
static MAX_TIME = 10;
static MAX_ROUNDS = 3;
static MIN_PLAYERS = 1; // Need 3 players to start the game
static BETWEEN_ROUNDS_MS = 5000;
currentRound = 0;
activeUser = null;
activeWord = "";
users = new Map(); // Maps user ids to {"id":user id, "username":username, "profilePicture":{}, "score":score}
canvasEvents = [];
timer;
time = Room.MAX_TIME;
roomName;
gameStarted = false;
io; // socketio Server object
constructor(roomName, io) {
this.roomName = roomName;
this.io = io;
/*
setInterval(()=>{
if (this.time == 0) {
this.time = Room.MAX_TIME;
this.nextUser();
}
this.io.to(this.roomName).emit("timer change",this.time);
this.time--;
},1000)
*/
}
addUser(userId, userData) {
userData.score = 0; // Add score field once user has joined a game
console.log("user data being emitted is: " + Object.keys(userData.profilePicture));
this.io.to(this.roomName).emit("new user", userData);
//console.log(username);
this.users.set(userId, userData);
if (this.activeUser == null) {
this.setActiveUser(userId);
}
if (!this.gameStarted && this.users.size >= Room.MIN_PLAYERS) {
this.startGame();
}
// Check if there are now enough users to start the game
}
removeUser(userId) {
this.users.delete(userId);
this.io.to(this.roomName).emit("remove user", userId);
if (userId == this.activeUser) {
// Choose a new user
if (this.users.size == 0) {
this.activeUser = null;
}
else {
const [first] = this.users; // This gets the first element of the map as an array of key + value
if (first != null) {
this.setActiveUser(first[0]); // Set active user to id of first user
console.log("new user is: " + this.activeUser);
}
}
}
}
setActiveUser(userId) {
const getWord = () => {
let val = Math.floor(Math.random() * wordArr.length);
return wordArr[val]; // Exclamation mark tells typescript that there is definitely a value
};
const previousUser = this.activeUser;
this.activeUser = userId;
console.log("user id " + userId + " is the active user");
this.io.to(userId).emit("chat message", "You are the active user!");
this.io.to(userId).emit("drawing information request"); // Get line width and line color
this.activeWord = getWord(); // Choose a new word for the active user
this.io.to(userId).emit("chat message", "Your word is: " + this.activeWord);
this.io.to(this.roomName).emit("new active user", { prevUser: previousUser, newUser: this.activeUser });
this.io.to(this.roomName).emit("new word", this.activeWord.length);
this.clearCanvas();
}
clearCanvas() {
this.io.to(this.roomName).emit("clear canvas");
this.canvasEvents = [{ "action": "clear canvas" }];
}
nextUser() {
const iter = this.users.entries();
for (const [username, _] of iter) {
if (username == this.activeUser) {
const iterNext = iter.next().value;
if (iterNext) { // Check if there is a next user (otherwise loop back to start)
this.setActiveUser(iterNext[0]);
}
else {
const [first] = this.users; // This gets the first element of the map as an array of key + value
if (first != undefined) {
this.setActiveUser(first[0]);
this.nextRound();
}
else {
console.log("First user is undefined");
}
}
}
}
// If reaching the end of the player list, advance to the next round
// If final round, do something
}
runTimer() {
this.timer = setInterval(() => {
this.io.to(this.roomName).emit("timer change", this.time);
if (this.time == 0) {
this.time = Room.MAX_TIME;
// Display the scores of the users
for (const [_, userData] of this.users) {
this.io.to(this.roomName).emit("display scores", { userData: userData, BETWEEN_ROUNDS_MS: Room.BETWEEN_ROUNDS_MS });
}
this.resetTimer();
}
this.time--;
}, 1000);
}
resetTimer() {
clearTimeout(this.timer);
setTimeout(() => {
this.runTimer();
this.nextUser();
}, Room.BETWEEN_ROUNDS_MS);
}
startGame() {
console.log("Game started!");
this.gameStarted = true;
this.nextRound();
this.runTimer();
}
nextRound() {
this.currentRound++;
if (this.currentRound > Room.MAX_ROUNDS) {
console.log("Game over!");
}
}
wordGuessed(userId) {
if (this.gameStarted) {
// Player who guessed the word gets points
// Pass active player to the next person
console.log('time guessed: ' + this.time);
this.addScore(userId);
// this.nextUser();
// this.time = Room.MAX_TIME;
}
}
addScore(userId) {
let points = 500 - (Room.MAX_TIME - this.time) * 5;
// Gain 500 points for guessing instantly and -5 points for every extra second it takes to guess
// Drawer gains a quarter of the number of points the guesser gained
// this.users.get(userId).score += points
// this.io.to(userId).emit('update points', points);
// this.io.to(this.activeUser).emit('update points', points);
this.users.get(userId).score += points;
this.users.get(this.activeUser).score += Math.floor(points / 4);
this.io.to(this.roomName).emit("score change", { "userId": userId, "score": this.users.get(userId).score });
this.io.to(this.roomName).emit("score change", { "userId": this.activeUser, "score": this.users.get(this.activeUser).score });
}
}
export { Room };