From 445013b6b675c6687af52d184a993c6567ed2975 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Wed, 4 Dec 2019 23:32:06 -0500 Subject: Client renders map, sends commands back to server --- public/index.html | 15 +++-- public/js/rogue.js | 178 +++++++++++++++++++++++++++++++++++++++++++---------- rogue-server.js | 124 ++++++++++++++++++++++++++----------- 3 files changed, 245 insertions(+), 72 deletions(-) diff --git a/public/index.html b/public/index.html index 39f2afc..e8adc13 100644 --- a/public/index.html +++ b/public/index.html @@ -13,11 +13,16 @@

rogue.js

- - - +
+ + + + + + + +
+

     
 	
diff --git a/public/js/rogue.js b/public/js/rogue.js
index c8ca8b9..0b584a7 100644
--- a/public/js/rogue.js
+++ b/public/js/rogue.js
@@ -7,8 +7,23 @@
  * 2019
  */
 
-var gamemap = {};
-var player = {};
+function Player(s, d, c, i , w, lvl, x, y, fl, h, a, p, armor, weapon, staff) {
+	this.strength = s;
+	this.dexterity = d;
+	this.constitution = c;
+	this.intelligence = i;
+	this.wisdom = w;
+	this.level = lvl;
+	this.x = x;
+	this.y = y;
+	this.floor = fl;
+	this.hp = h;
+	this.ac = a;
+	this.potions = p;
+	this.armor = armor;
+	this.weapon = weapon;
+	this.staff = staff;
+}
 
 function Sprite(x, y, width, height) {
 	this.x = x;
@@ -41,7 +56,7 @@ var wall = [
 ];
 
 var stairsdown = new Sprite(12, 26, 16, 16);
-var starisup = new Sprite(13, 26, 16, 16);
+var stairsup = new Sprite(13, 26, 16, 16);
 var tomb = new Sprite(2, 27, 16, 16);
 
 var water = new Sprite(8, 34, 16, 16);
@@ -78,7 +93,7 @@ var heart = new Sprite(7, 55, 16, 16);
 
 /** Mobs **/
 
-var player = [
+var players = [
 	new Sprite(2, 6, 16, 16),
 	new Sprite(2, 7, 16, 16)
 ];
@@ -107,18 +122,27 @@ var space = new Sprite(1, 59, 8, 16);
 const messages = document.querySelector('#messages');
 const joinGame = document.querySelector('#joingame');
 const leaveGame = document.querySelector('#leavegame');
-const wsButton = document.querySelector('#wsButton');
-const wsSendButton = document.querySelector('#wsSendButton');
 let websocket;
 
 /**
- * Show messages from the server
+ * Show messages in message bar
  */
 function showMessage(message) {
     messages.textContent += `\n${message}`;
     messages.scrollTop = messages.scrollHeight;
 }
 
+function parseMessage(message) {
+	var msg = JSON.parse(message);
+	map = msg.map;
+	player = new Player(msg.strength, msg.dexterity, msg.constitution, msg.intelligence, msg.wisdom, msg.level, msg.x, msg.y, msg.floor, msg.hp, msg.ac, msg.potions, msg.armor, msg.weapon, msg.staff);
+	if(msg.msg != "") {
+		showMessage(msg.msg);
+	}
+	drawMap();
+	drawPlayerInfo();
+}
+
 joinGame.onclick = function() {
 	if (!websocket) {
 		websocket = new WebSocket(`ws://localhost:8080`);
@@ -133,7 +157,7 @@ joinGame.onclick = function() {
 			websocket = null;
 		};
 		websocket.onmessage = function(event) {
-			showMessage(event.data);
+			parseMessage(event.data);
 		};
 	}
 };
@@ -147,22 +171,69 @@ leaveGame.onclick = function() {
 	
 };
 
-wsSendButton.onclick = function() {
+stairs.onclick = function() {
     if (!websocket) {
-		showMessage('No WebSocket connection');
+		showMessage('Connection error');
 		return;
     }
 
-    websocket.send('Hello World!');
-    showMessage('Sent "Hello World!"');
+    websocket.send("{\"action\":\"move\", \"message\":\".\"}");
 };
 
+drink.onclick = function() {
+	if (!websocket) {
+		showMessage('Connection error');
+		return;
+    }
+
+    websocket.send("{\"action\":\"drink\", \"message\":\"\"}");
+}
+
+up.onclick = function() {
+	if (!websocket) {
+		showMessage('Connection error');
+		return;
+    }
+
+    websocket.send("{\"action\":\"move\", \"message\":\"w\"}");
+}
+
+down.onclick = function() {
+	if (!websocket) {
+		showMessage('Connection error');
+		return;
+    }
+
+    websocket.send("{\"action\":\"move\", \"message\":\"s\"}");
+}
+
+left.onclick = function() {
+	if (!websocket) {
+		showMessage('Connection error');
+		return;
+    }
+
+    websocket.send("{\"action\":\"move\", \"message\":\"a\"}");
+}
+
+right.onclick = function() {
+	if (!websocket) {
+		showMessage('Connection error');
+		return;
+    }
+
+    websocket.send("{\"action\":\"move\", \"message\":\"d\"}");
+}
+
 const canvas = document.getElementById('gameboard');
 const context = canvas.getContext('2d');
 const spritemap = new Image(320, 1264);
 spritemap.onload = drawInitialBoard;
 spritemap.src = 'scroll-o-sprites-edited.png';
 
+var gamemap;
+var player = new Player(10, 10, 10, 10, 10, 1, 0, 0, 1, 100, 15, 0, "none", "none", "none");
+
 function drawInitialBoard() {
 	for(var i = 0; i < 32; i++) {
 		for(var j = 0; j < 26; j++) {
@@ -186,6 +257,51 @@ function drawInitialBoard() {
 	drawPlayerInfo();
 }
 
+function drawMap() {
+	if(!map || map == "") {
+		return;
+	}
+	var startx = player.x - 11;
+	var starty = player.y - 13;
+	var localX = 0;
+	var localY = 0;
+	for(var i = 0; i < 31; i++) {
+		for(var j = 0; j < 26; j++) {
+			drawSprite(nothing, i, j, false);
+		}
+	}
+	for(var i = startx; i < startx + 22; i++) {
+		for(var j = starty; j < starty + 26; j++) {
+			if(i < 0 || i > 99 || j < 0 || j > 49) {
+				drawSprite(wall[1], localX, localY, false);
+			} else {
+				var symbol = map.charAt(j * 100 + i);
+				switch(symbol) {
+				case '*':
+					drawSprite(wall[0], localX, localY, false);
+					break;
+				case '<':
+					drawSprite(stairsup, localX, localY, false);
+					break;
+				case '>':
+					drawSprite(stairsdown, localX, localY, false);
+					break;
+				case ' ':
+					drawSprite(nothing, localX, localY, false);
+					break;
+				default:
+					break;
+				}
+			}
+			localY++;
+		}
+		localY = 0;
+		localX++;
+	}
+
+	drawSprite(players[0], 10, 13, false);
+}
+
 /**
  * Draws out the player info on the side of the screen
  *
@@ -219,29 +335,27 @@ function drawPlayerInfo() {
 	renderText("Con", 31 - boxWidth + 2, 5);
 	renderText("Wis", 31 - boxWidth + 6, 3);
 	renderText("Int", 31 - boxWidth + 6, 4);
-	renderText("Cha", 31 - boxWidth + 6, 5);
 	renderText("Lvl", 31 - boxWidth + 6, 7);
 	renderText("Flr", 31 - boxWidth + 6, 8);
-	renderText("Equipped", 31 - boxWidth + 2, 10);
-	renderText("Carried", 31 - boxWidth + 2, 15);
-	
-	renderText("100", 31 - boxWidth + 3, 7);
-	renderText("15", 31 - boxWidth + 3, 8);
-	renderText("10", 31 - boxWidth + 4, 3);
-	renderText("10", 31 - boxWidth + 4, 4);
-	renderText("10", 31 - boxWidth + 4, 5);
-	renderText("10", 31 - boxWidth + 8, 3);
-	renderText("10", 31 - boxWidth + 8, 4);
-	renderText("10", 31 - boxWidth + 8, 5);
-	renderText("1", 31 - boxWidth + 8, 7);
-	renderText("2", 31 - boxWidth + 8, 8);
+	renderText("Equipment", 31 - boxWidth + 2, 10);
 	drawSprite(sword, 31 - boxWidth + 3, 12, false);
-	drawSprite(arrow, 31 - boxWidth + 6, 12, false);
-	drawSprite(helmet, 31 - boxWidth + 3, 13, false);
-	drawSprite(armor, 31 - boxWidth + 6, 13, false);
-	drawSprite(potion, 31 - boxWidth + 3, 17, false);
-	drawSprite(scroll, 31 - boxWidth + 6, 17, false);
-	drawSprite(shield, 31 - boxWidth + 3, 18, false);
+	drawSprite(staff, 31 - boxWidth + 3, 13, false);
+	drawSprite(armor, 31 - boxWidth + 3, 14, false);
+	drawSprite(potion, 31 - boxWidth + 3, 15, false);
+	
+	renderText(player.hp.toString(), 31 - boxWidth + 3, 7);
+	renderText(player.ac.toString(), 31 - boxWidth + 3, 8);
+	renderText(player.strength.toString(), 31 - boxWidth + 4, 3);
+	renderText(player.dexterity.toString(), 31 - boxWidth + 4, 4);
+	renderText(player.constitution.toString(), 31 - boxWidth + 4, 5);
+	renderText(player.wisdom.toString(), 31 - boxWidth + 8, 3);
+	renderText(player.intelligence.toString(), 31 - boxWidth + 8, 4);
+	renderText(player.level.toString(), 31 - boxWidth + 8, 7);
+	renderText(player.floor.toString(), 31 - boxWidth + 8, 8);
+	renderText(player.weapon.toString(), 31 - boxWidth + 5, 12);
+	renderText(player.staff.toString(), 31 - boxWidth + 5, 13);
+	renderText(player.armor.toString(), 31 - boxWidth + 5, 14);
+	renderText(player.potions.toString(), 31 - boxWidth + 5, 15);
 }
 
 /**
diff --git a/rogue-server.js b/rogue-server.js
index 91dcb50..62ccbb1 100644
--- a/rogue-server.js
+++ b/rogue-server.js
@@ -20,7 +20,7 @@ function genStat() {
 	for(var i = 0; i < 3; i++) {
 		value += Math.floor(Math.random() * 5) + 1;
 	}
-	return value;
+	return value + 3;
 }
 
 class Location {
@@ -89,7 +89,7 @@ class Mob {
 		this.level = level;
 		this._location = location;
 		this.xp = 0;
-		this._hp = level * getBonus(constitution) + Math.floor(Math.random() * 6) * level;
+		this._hp = level * getBonus(constitution) + (Math.floor(Math.random() * 5) + 1) * level;
 		if(this._hp < 2) {
 			this._hp = 2;
 		}
@@ -102,32 +102,32 @@ class Mob {
 	}
 
 	stats() {
-		var message = "strength:" + this.strength;
-		message = message + ",dexterity:" + this.dexterity;
-		message = message + ",constitution:" + this.constitution;
-		message = message + ",intelligence:" + this.intelligence;
-		message = message + ",wisdom:" + this.wisdom;
-		message = message + ",level:" + this.level;
-		message = message + ",x:" + this._location.x;
-		message = message + ",y:" + this._location.y;
-		message = message + ",floor:" + this._location.floor;
-		message = message + ",hp:" + this._hp;
-		message = message + ",ac:" + this.ac();
-		message = message + ",potions:" + this.potions;
+		var message = "\"strength\":" + this.strength;
+		message = message + ",\"dexterity\":" + this.dexterity;
+		message = message + ",\"constitution\":" + this.constitution;
+		message = message + ",\"intelligence\":" + this.intelligence;
+		message = message + ",\"wisdom\":" + this.wisdom;
+		message = message + ",\"level\":" + this.level;
+		message = message + ",\"x\":" + this._location.x;
+		message = message + ",\"y\":" + this._location.y;
+		message = message + ",\"floor\":" + this._location.floor;
+		message = message + ",\"hp\":" + this._hp;
+		message = message + ",\"ac\":" + this.ac();
+		message = message + ",\"potions\":" + this.potions;
 		if(this.armor == null) {
-			message = message + ",armor: \"none\"";
+			message = message + ",\"armor\": \"none\"";
 		} else {
-			message = message + ",armor:\"" + this.armor.name + "\"";
+			message = message + ",\"armor\":\"" + this.armor.name + "\"";
 		}
 		if(this.weapon == null) {
-			message = message + ",weapon: \"none\"";
+			message = message + ",\"weapon\": \"none\"";
 		} else {
-			message = message + ",weapon:\"" + this.weapon.name + "\"";
+			message = message + ",\"weapon\":\"" + this.weapon.name + "\"";
 		}
 		if(this.staff == null) {
-			message = message + ",staff: \"none\"";
+			message = message + ",\"staff\": \"none\"";
 		} else {
-			message = message + ",staff:\"" + this.staff.name + "\"";
+			message = message + ",\"staff\":\"" + this.staff.name + "\"";
 		}
 		return message;
 	}
@@ -137,7 +137,7 @@ class Mob {
 		if(this.xp >= 100) {
 			this.xp = 0;
 			this.level += 1;
-			var newhp = getBonus(this.constitution) + Math.floor(Math.random() * 6);
+			var newhp = getBonus(this.constitution) + Math.floor(Math.random() * 5) + 1;
 			if(newhp < 1) {
 				newhp = 1;
 			}
@@ -145,10 +145,14 @@ class Mob {
 		}
 	}
 
+	addPotions(value) {
+		this.potions += value;
+	}
+
 	drinkPotion() {
 		if(this.potions > 0) {
 			this.potions -= 1;
-			var gained = Math.floor(Math.random() * 6) * this.level;
+			var gained = (Math.floor(Math.random() * 5) + 1) * this.level;
 			if(this.hp + gained > this.hpMax) {
 				this.hp = this.hpMax;
 				return "You feel brand new";
@@ -208,28 +212,40 @@ class Mob {
 	attack(type) {
 		if(type == "weapon") {
 			if(this.weapon != null) {
-				return getBonus(this.strength) + this.weapon.bonus + Math.floor(Math.random() * 20);
+				return getBonus(this.strength) + this.weapon.bonus + Math.floor(Math.random() * 19) + 1;
 			}
-			return getBonus(this.strength) + Math.floor(Math.random() * 20);
+			return getBonus(this.strength) + Math.floor(Math.random() * 19) + 1;
 		} else if(type == "staff") {
 			if(this.staff != null) {
-				return getBonus(this.intelligence) + this.staff.bonus + Math.floor(Math.random() * 20);
+				return getBonus(this.intelligence) + this.staff.bonus + Math.floor(Math.random() * 19) + 1;
 			}
-			return getBonus(this.intelligence) + Math.floor(Math.random() * 20);
+			return getBonus(this.intelligence) + Math.floor(Math.random() * 19) + 1;
 		}
 	}
 
 	damage(type) {
 		if(type == "weapon") {
+			var value;
 			if(this.weapon != null) {
-				return getBonus(this.strength) + this.weapon.bonus + Math.floor(Math.random() * 6);
+				value = getBonus(this.strength) + this.weapon.bonus + Math.floor(Math.random() * 5) + 1;
+			} else {
+				value = getBonus(this.strength) + Math.floor(Math.random() * 5) + 1;
+			}
+			if(value < 1) {
+				return 1;
 			}
-			return getBonus(this.strength) + Math.floor(Math.random() * 6);
+			return value;
 		} else if(type == "staff") {
+			var value;
 			if(this.staff != null) {
-				return getBonus(this.intelligence) + this.staff.bonus + Math.floor(Math.random() * 6);
+				value = getBonus(this.intelligence) + this.staff.bonus + Math.floor(Math.random() * 5) + 1;
+			} else {
+				value = getBonus(this.intelligence) + Math.floor(Math.random() * 5) + 1;
+			}
+			if(value < 1) {
+				return 1;
 			}
-			return getBonus(this.intelligence) + Math.floor(Math.random() * 6);
+			return value;
 		}
 	}
 
@@ -296,6 +312,9 @@ function getInititive() {
 	return init
 }
 
+/**
+ * Performs an attack by mobA against mobB
+ */
 function attack(mobA, mobB, type) {
 	var attack = mobs[mobA].attack(type);
 	var defence;
@@ -315,6 +334,9 @@ function attack(mobA, mobB, type) {
 	}
 }
 
+/** 
+ * Moves a mob in the direction it wishes to that space if available or starts a fight
+ */
 function move(mob, dir) {
 	var location = mobs[mob].location;
 	switch(dir) {
@@ -368,9 +390,12 @@ function move(mob, dir) {
 }
 
 function cast(mob, dir) {
-
+	// TODO: All that magic jazz
 }
 
+/**
+ * Runs through all the actions each mob wishes to take
+ */
 function performActions(init) {
 	for(var i = init.length - 1; i > -1; i--) {
 		for(var j = 0; j < init[i].length; j++) {
@@ -391,6 +416,7 @@ function performActions(init) {
 					message = mobs[mob].drinkPotion();
 					break;
 				case 'pick':
+					// TODO: Allow for pickups boi
 					//message = mobs[init[i][j]].pickUp();
 					break;
 				case 'drop':
@@ -405,16 +431,26 @@ function performActions(init) {
 	}
 }
 
+/**
+ * Generate a message to be sent to client based on character
+ *
+ * @param character The mob the player is in charge of
+ */
 function buildPlayerMsg(character) {
 	var local = character.location.floor;
-	var message = "{map:\"" + floors[local] + "\",";
+	var message = "{\"map\":\"" + floors[local] + "\",";
 	message = message + character.stats();
 	if(character.action != null) {
-		message = message + "msg:\"" + character.action.message + "\"";
+		message = message + ",\"msg\":" + character.action.message;
+	} else {
+		message = message + ",\"msg\":\"\"";
 	}
 	return message + "}";
 }
 
+/**
+ * Send out action results to all players
+ */
 function sendResults() {
 	for(var i = 0; i < mobs.length; i++) {
 		if(players.has(mobs[i].uuid)) {
@@ -423,14 +459,25 @@ function sendResults() {
 	}
 }
 
+/**
+ * Removes dead mobs from the mob list
+ */
+function cleanDungeon() {
+	for(var i = 0; i < dead.length; i++) {
+		mobs.splice(dead[i], 1); 
+	}
+}
 
+/**
+ * All the steps that need to be taken in a turn
+ */
 function genTurn() {
 	dead = new Array();
 
 	var init = getInititive();
 	performActions(init);
 	sendResults();
-
+	cleanDungeon();
 }
 
 
@@ -453,6 +500,7 @@ wsServer.on('connection', function connection(ws, request) {
 	device.set(ws, id);
 	var local = new Location(78, 5, 0);
 	var character = new Mob(genStat(), genStat(), genStat(), genStat(), genStat(), 1, local, id);
+	character.addPotions(5);
 	ws.send(buildPlayerMsg(character));
 	mobs.push[character];
 	console.log(new Date().toUTCString() + ' | ' + device.get(ws) + ' joins');
@@ -468,8 +516,14 @@ wsServer.on('connection', function connection(ws, request) {
 
 	ws.on('close', function leave() {
 		console.log(new Date().toUTCString() + ' | ' + device.get(ws) + ' leaves');
-		players.delete(device.get(ws));
+		var id = device.get(ws);
+		players.delete(id);
 		device.delete(ws);
+		for(var i = 0; i < mobs.length; i++) {
+			if(mobs[i].uuid = id) {
+				dead.push(i);
+			}
+		}
 	});
 });
 
-- 
cgit v1.2.3