diff options
| -rw-r--r-- | public/index.html | 15 | ||||
| -rw-r--r-- | public/js/rogue.js | 178 | ||||
| -rw-r--r-- | 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 @@  	  <h1>rogue.js</h1>  	</div>  	<canvas id="gameboard" class="center" width="512" height="416"></canvas> -    <button id="joingame" type="button" title="Join Game">Join Game</button> -    <button id="leavegame" type="button" title="Leave Game">Leave Game</button> -    <button id="wsSendButton" type="button" title="Send WebSocket message"> -      Send WebSocket message -    </button> +	<div class="center"> +	  <table class="center"> +		<tr><td><button id="joingame" type="button" title="Join Game">Join Game</button></td><td></td><td><button id="up">Up</button></td><td></td><td></td> +		</tr> +		<tr><td><button id="leavegame" type="button" title="Leave Game">Leave Game</button></td><td><button id="left">Left</button></td><td><button id="stairs">Stairs</button></td><td><button id="right">Right</button></td><td></td> +		</tr> +		<tr><td></td><td></td><td><button id="down">Down</button></td><td></td><td><button id="drink">Potion</button></td> +		</tr> +	  </table> +	</div>      <pre id="messages" style="height: 400px; overflow: scroll"></pre>      <footer><p>© Matt Kohls, 2019</footer>  	<script src="js/rogue.js"></script> 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); +			} +		}  	});  }); | 
