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); + } + } }); }); |