DIR_NORTH = 0; DIR_EAST = 1; DIR_SOUTH = 2; DIR_WEST = 3; WORLD_HEIGHT = WORLD_WIDTH = 16; var colorScheme = { tileTint: 0xFFFFFF, wallTint: 0xDDDDDD, cubotHoverTint: 0x00FF00, cubotTint: 0xFFFFFF, textFill: "#FFFFFF", textStroke: "#9298a8", biomassTint: 0x63B85F, biomassHoverTint: 0x00FF00, tileHoverTint: 0x00FF00, itemIron: 0x434341, itemCopper: 0xC87D38, hologramFill: "#0aced6", hologramStroke: "#12FFB0", hologramAlpha: 0.9 }; var mar = {}; mar.kbBuffer = []; mar.kbBufferText = ""; mar.animationFrames = {}; mar.controlledUnitVisible = false; mar.lastLines = ""; mar.bigMessage = ""; CUBOT_WALK_FRAMES = { south: 240, north: 194, west: 254, east: 164 }; HARVESTER_WALK_FRAMES = { south: 347, north: 317, west: 377, east: 287 }; LOW_ENERGY = 100; if (fullscreen) { RENDERER_WIDTH = window.innerWidth* window.devicePixelRatio - 4; RENDERER_HEIGHT = window.innerHeight* window.devicePixelRatio - 4; } else { RENDERER_WIDTH = document.getElementById("game").clientWidth * window.devicePixelRatio; RENDERER_HEIGHT = (window.innerHeight / 1.40) * window.devicePixelRatio; } var game = new Phaser.Game(RENDERER_WIDTH, RENDERER_HEIGHT, Phaser.AUTO, 'game', null, true, false); function dispatchTileLeave(x, y) { for (var i = 0; i < mar.world.tiles.length; i++) { var tX = mar.world.tiles[i].tileX; var tY = mar.world.tiles[i].tileY; if (mar.world.tiles[i].isWall && ((tX === x && tY - 1 === y ) || (tX - 1 === x && tY - 1 === y) || (tX - 1 === x && tY === y )) && mar.world.tiles[i].alpha !== 1) { game.add.tween(mar.world.tiles[i]).to({alpha: 1}, 175, Phaser.Easing.Quadratic.In, true); } } } function dispatchTileEnter(x, y) { /* * X X X * X C T * X T T * * Transparent, X: Normal, C: Cubot */ for (var i = 0; i < mar.world.tiles.length; i++) { var tX = mar.world.tiles[i].tileX; var tY = mar.world.tiles[i].tileY; if (mar.world.tiles[i].isWall && ((tX === x && tY - 1 === y ) || (tX - 1 === x && tY - 1 === y) || (tX - 1 === x && tY === y ))) { game.add.tween(mar.world.tiles[i]).to({alpha: 0.6}, 300, Phaser.Easing.Quadratic.In, true); } } } function Word(terrain) { var self = this; self.tiles = []; self.objects = []; setupWorldArrows(); this.setTerrain = function (terrain) { for (var x = 0; x < WORLD_HEIGHT; x++) { for (var y = 0; y < WORLD_HEIGHT; y++) { var terrainType = terrain[y * WORLD_WIDTH + x]; if (terrainType === 1) { var tile = game.add.isoSprite(getIsoX(x), getIsoY(y), 0, 'sheet', "tiles/bigTile", isoGroup); tile.baseZ = 0; tile.baseTint = colorScheme.wallTint; tile.anchor.set(0.5, 0.2); tile.isWall = true; } else if (terrainType === 2) { tile = game.add.isoSprite(getIsoX(x), getIsoY(y), 0, 'sheet', "tiles/tile", isoGroup); text = game.make.text(0, 16, "Iron", { fontSize: 22, fill: "#434341", stroke: "#FFFFFF", strokeThickness: 1, font: "fixedsys" }); text.alpha = 0.6; text.anchor.set(0.5, 0); tile.addChild(text); tile.baseZ = 0; // tile.baseTint = 0x434341; tile.baseTint = 0xF3F3F3; tile.anchor.set(0.5, 0); } else if (terrainType === 3) { tile = game.add.isoSprite(getIsoX(x), getIsoY(y), 0, 'sheet', "tiles/tile", isoGroup); var text = game.make.text(0, 16, "Copper", { fontSize: 22, fill: "#C87D38", stroke: "#FFFFFF", strokeThickness: 1, font: "fixedsys" }); text.alpha = 0.6; text.anchor.set(0.5, 0); tile.addChild(text); tile.baseZ = 0; tile.baseTint = 0xF3F3F3; tile.anchor.set(0.5, 0); } else { tile = game.add.isoSprite(getIsoX(x), getIsoY(y), 0, 'sheet', "tiles/tile", isoGroup); tile.baseZ = 0; tile.baseTint = colorScheme.tileTint; tile.anchor.set(0.5, 0); } tile.isTile = true; tile.tileX = x; tile.tileY = y; tile.tint = tile.baseTint; self.tiles.push(tile); } } }; this.setTerrain(terrain); this.update = function (terrain) { for (var i = 0; i < mar.world.objects.length; i++) { mar.world.objects[i].destroy(); } for (var i = 0; i < mar.world.tiles.length; i++) { mar.world.tiles[i].destroy(); } mar.world.objects = []; mar.world.tiles = []; this.setTerrain(terrain); game.iso.topologicalSort(isoGroup); }; /** * Get object from the list of 'current' objects (Objects shown on the screen) * @param id objectId of the object */ this.getObject = function (id) { for (var i = 0; i < self.objects.length; i++) { if (self.objects[i].id === id) { return self.objects[i]; } } return null; }; /** * Update object from parsed JSON string sent from the server * @param response parsed JSON string sent from the server */ this.updateObjects = function (response) { //Mark objects as not updated for (i = 0; i < self.objects.length; i++) { self.objects[i].updated = false; } for (var i = 0; i < response.length; i++) { //Update/Create the object var existingObject = self.getObject(response[i].i); if (existingObject !== null) { //Object already exists existingObject.updated = true; // console.log("Update " + existingObject.id); existingObject = updateGameObject(existingObject, response[i]); } else { //Object is new var newObj = createGameObject(response[i]); newObj.updated = true; self.objects.push(newObj); } } //Delete not updated objects (see above comments) for (var i = 0; i < self.objects.length; i++) { if (!self.objects[i].updated) { //Check if the object we are removing is our controlledUnit, if so, follow it if (mar.client.username !== "guest") { if (self.objects[i].type === 1 && self.objects[i].username === mar.client.username) { findMyRobot(); console.log("Following Cubot " + mar.client.username) } } self.objects[i].destroy(); dispatchTileLeave(self.objects[i].tileX, self.objects[i].tileY); self.objects.splice(i, 1); } } }; } function updateGameObject(object, responseObj) { object.direction = responseObj.direction; if (object.type === 1) { object.action = responseObj.action; object.energy = responseObj.energy; //Update location if ((object.tileX !== responseObj.x || object.tileY !== responseObj.y)) { //location changed //Walk if (object.action === 2) { dispatchTileLeave(object.tileX, object.tileY); object.tileX = responseObj.x; object.tileY = responseObj.y; cubotMove(object, object.direction, undefined, CUBOT_WALK_FRAMES); } else if (object.action === 6) { //Jump dispatchTileLeave(object.tileX, object.tileY); object.tileX = responseObj.x; object.tileY = responseObj.y; cubotMove(object, object.direction, undefined, CUBOT_WALK_FRAMES, true); } } //Update Inventory if (object.heldItem !== responseObj.heldItem) { if (object.inventory !== undefined) { object.inventory.destroy(); } object.inventory = createInventory([responseObj.heldItem]); object.addChild(object.inventory); object.heldItem = responseObj.heldItem; } //Battery indication if (object.tint !== colorScheme.cubotHoverTint) { if (object.energy <= LOW_ENERGY) { object.tint = 0xFF0000; } else { object.tint = 0xFFFFFF; } } //Update direction switch (object.direction) { case DIR_NORTH: object.animations.frame = 194; break; case DIR_EAST: object.animations.frame = 164; break; case DIR_SOUTH: object.animations.frame = 240; break; case DIR_WEST: object.animations.frame = 254; break; } //Update hologram if (object.hologram !== undefined) { object.hologram.destroy(); } var color = false; if (responseObj.holoC) { color = (responseObj.holoC & 0xFFFFFF).toString(16) color = "#" + ("000000".substr(color.length) + color); } if (responseObj.holoMode === 1) { //Hex object.hologram = game.make.text(0, 32, "0x" + ("0000" + Number(responseObj.holo).toString(16).toUpperCase()).slice(-4), { fontSize: 32, fill: color ? color : colorScheme.hologramFill, stroke: colorScheme.hologramStroke, strokeThickness: 1, font: "fixedsys" }); console.log(Number(color).toString(16)) } else if (responseObj.holoMode === 2) { //String object.hologram = game.make.text(0, 32, responseObj.holoStr.replace(/[\n|\t]/g, ''), { fontSize: 27, fill: color ? color : colorScheme.hologramFill, stroke: colorScheme.hologramStroke, strokeThickness: 1, font: "fixedsys" }); } else if (responseObj.holoMode === 3) { //Decimal object.hologram = game.make.text(0, 32, Number(responseObj.holo).toString(), { fontSize: 32, fill: color ? color : colorScheme.hologramFill, stroke: colorScheme.hologramStroke, strokeThickness: 1, font: "fixedsys" }); } if (object.hologram !== undefined) { object.hologram.alpha = colorScheme.hologramAlpha; object.hologram.anchor.set(0.5, 0); object.addChild(object.hologram); game.add.tween(object.hologram).to({tint: 0xFFFFF0, alpha: colorScheme.hologramAlpha - 0.1}, mar.client.tickLength, Phaser.Easing.Bounce.In, true); } if (object.action === 1) { //Dig cubotDig(object, object.direction); } } else if (object.type === 10) { object.action = responseObj.action; //Update location if ((object.tileX !== responseObj.x || object.tileY !== responseObj.y)) { //location changed dispatchTileLeave(object.tileX, object.tileY); object.tileX = responseObj.x; object.tileY = responseObj.y; cubotMove(object, object.direction, undefined, HARVESTER_WALK_FRAMES); } //Update direction switch (object.direction) { case DIR_NORTH: object.animations.frame = HARVESTER_WALK_FRAMES.north; break; case DIR_EAST: object.animations.frame = HARVESTER_WALK_FRAMES.east; break; case DIR_SOUTH: object.animations.frame = HARVESTER_WALK_FRAMES.south; break; case DIR_WEST: object.animations.frame = HARVESTER_WALK_FRAMES.west; break; } } } function itemColor(item) { switch (item) { case 1: return colorScheme.biomassTint; case 3: return colorScheme.itemIron; case 4: return colorScheme.itemCopper; } } function createInventory(items) { var inventory = game.make.group(); switch (items.length) { case 0: return inventory; case 1: if (items[0] !== 0) { var shadow = game.make.sprite(0, 0, "sheet", "inventory/inv1x1"); shadow.anchor.set(0.5, 0.1); shadow.alpha = 0.5; var item = game.make.sprite(0, 0, "sheet", "inventory/item"); item.anchor.set(0.5, 0.1); item.tint = itemColor(items[0]); inventory.addChild(shadow); inventory.addChild(item); } return inventory; } for (var i = 0; i < items.length; i++) { } } function createGameObject(objData) { if (objData.t === 1) { var cubot = game.add.isoSprite(getIsoX(objData.x), getIsoY(objData.y), 15, "sheet", null, isoGroup); cubot.anchor.set(0.5, 0); cubot.inputEnabled = true; cubot.events.onInputDown.add(function () { debugObj = "Cubot: " + cubot.tileX + ", " + cubot.tileY; }); cubot.events.onInputOver.add(function () { document.body.style.cursor = 'pointer'; }); cubot.events.onInputOut.add(function () { document.body.style.cursor = 'default'; }); cubot.id = objData.i; cubot.type = 1; cubot.tileX = objData.x; cubot.tileY = objData.y; cubot.username = objData.parent; cubot.heldItem = objData.heldItem; cubot.direction = objData.direction; cubot.action = objData.action; cubot.energy = objData.energy; cubot.inventory = createInventory([cubot.heldItem]); cubot.addChild(cubot.inventory); dispatchTileEnter(objData.x, objData.y); cubot.isAt = function (x, y) { return this.tileX === x && this.tileY === y; }; cubot.onTileHover = function () { game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); game.add.tween(this.scale).to({x: 1.2, y: 1.2}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotHoverTint; }; cubot.onTileOut = function () { document.body.style.cursor = 'default'; game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); this.tint = 0xFFFFFF; }; //Battery indication if (cubot.energy <= LOW_ENERGY) { cubot.tint = 0xCC0000; } cubot.animations.add("walk_w", mar.animationFrames.walk_w, true); cubot.animations.add("walk_s", mar.animationFrames.walk_s, true); cubot.animations.add("walk_e", mar.animationFrames.walk_e, true); cubot.animations.add("walk_n", mar.animationFrames.walk_n, true); cubot.animations.add("dig_w", mar.animationFrames.dig_w, false); cubot.animations.add("dig_s", mar.animationFrames.dig_s, false); cubot.animations.add("dig_e", mar.animationFrames.dig_e, false); cubot.animations.add("dig_n", mar.animationFrames.dig_n, false); cubot.queuedAnims = []; switch (cubot.direction) { case DIR_NORTH: cubot.animations.frame = 194; break; case DIR_EAST: cubot.animations.frame = 164; break; case DIR_SOUTH: cubot.animations.frame = 240; break; case DIR_WEST: cubot.animations.frame = 254; break; } var username = game.make.text(0, -24, cubot.username, { fontSize: 22, fill: colorScheme.textFill, stroke: colorScheme.textStroke, strokeThickness: 2, font: "fixedsys" }); username.alpha = 0.85; username.anchor.set(0.5, 0); if (cubot.username === mar.client.username) { username.tint = 0xFB4D0A; } else { cubot.alpha = 0.6; } cubot.addChild(username); return cubot; } else if (objData.t === 2) { var biomass = game.add.isoSprite(getIsoX(objData.x), getIsoY(objData.y), 10, "sheet", 1, isoGroup); biomass.animations.add("idle", mar.mar.animationFrames.biomassIdle, true); biomass.anchor.set(0.5, 0); biomass.type = 2; biomass.tileX = objData.x; biomass.tileY = objData.y; biomass.id = objData.i; biomass.tint = colorScheme.biomassTint;// "#3BB886" biomass.hoverText = game.make.text(0, 0, "Biomass", { fontSize: 22, fill: colorScheme.textFill, stroke: colorScheme.textStroke, strokeThickness: 2, font: "fixedsys" }); biomass.hoverText.alpha = 0; biomass.hoverText.anchor.set(0.5, 0); biomass.addChild(biomass.hoverText); biomass.isAt = function (x, y) { return this.tileX === x && this.tileY === y; }; biomass.isAt = function (x, y) { return this.tileX === x && this.tileY === y; }; biomass.onTileHover = function () { game.tweens.removeFrom(this); document.body.style.cursor = 'pointer'; game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); this.tint = colorScheme.biomassHoverTint; game.add.tween(this.scale).to({x: 1.2, y: 1.2}, 200, Phaser.Easing.Linear.None, true); game.add.tween(this.hoverText).to({alpha: 0.9}, 200, Phaser.Easing.Quadratic.In, true); biomass.hoverText.visible = true; }; biomass.onTileOut = function () { game.tweens.removeFrom(this); document.body.style.cursor = 'default'; game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.biomassTint; game.add.tween(this.hoverText).to({alpha: 0}, 200, Phaser.Easing.Quadratic.Out, true); }; biomass.animations.play("idle", 45, true); return biomass; } else if (objData.t === 10) { var harvester = game.add.isoSprite(getIsoX(objData.x), getIsoY(objData.y), 15, "sheet", null, isoGroup); harvester.anchor.set(0.5, 0); harvester.id = objData.i; harvester.type = 10; harvester.tileX = objData.x; harvester.tileY = objData.y; harvester.direction = objData.direction; harvester.action = objData.action; dispatchTileEnter(objData.x, objData.y); harvester.isAt = function (x, y) { return this.tileX === x && this.tileY === y; }; harvester.onTileHover = function () { game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); game.add.tween(this.scale).to({x: 1.2, y: 1.2}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotHoverTint; }; harvester.onTileOut = function () { game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotTint; }; harvester.animations.add("walk_w", mar.animationFrames.harvester_walk_w, true); harvester.animations.add("walk_s", mar.animationFrames.harvester_walk_s, true); harvester.animations.add("walk_e", mar.animationFrames.harvester_walk_e, true); harvester.animations.add("walk_n", mar.animationFrames.harvester_walk_n, true); harvester.queuedAnims = []; switch (harvester.direction) { case DIR_NORTH: harvester.animations.frame = HARVESTER_WALK_FRAMES.north; break; case DIR_EAST: harvester.animations.frame = HARVESTER_WALK_FRAMES.east; break; case DIR_SOUTH: harvester.animations.frame = HARVESTER_WALK_FRAMES.south; break; case DIR_WEST: harvester.animations.frame = HARVESTER_WALK_FRAMES.west; break; } return harvester; } else if (objData.t === 3) { //Factory var factory = game.add.isoSprite(getIsoX(objData.x), getIsoY(objData.y), 15, "sheet", "objects/factory", isoGroup); factory.anchor.set(0.5, .25); factory.id = objData.i; factory.type = 3; factory.tileX = objData.x; factory.tileY = objData.y; factory.hoverText = game.make.text(0, 0, "Factory", { fontSize: 22, fill: colorScheme.textFill, stroke: colorScheme.textStroke, strokeThickness: 2, font: "fixedsys" }); factory.hoverText.alpha = 0; factory.hoverText.anchor.set(0.5, 0); factory.addChild(factory.hoverText); factory.isAt = function (x, y) { return (this.tileX === x || this.tileX + 1 === x) && (this.tileY + 1 === y || this.tileY === y); }; factory.onTileHover = function () { game.tweens.removeFrom(this); game.add.tween(this).to({isoZ: 25}, 200, Phaser.Easing.Quadratic.InOut, true); game.add.tween(this.scale).to({x: 1.06, y: 1.06}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotHoverTint; game.add.tween(this.hoverText).to({alpha: 0.9}, 200, Phaser.Easing.Quadratic.In, true); factory.hoverText.visible = true; }; factory.onTileOut = function () { game.tweens.removeFrom(this); game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotTint; game.add.tween(this.hoverText).to({alpha: 0}, 200, Phaser.Easing.Quadratic.Out, true); }; return factory; } else if (objData.t === 4) { //Radio tower var radioTower = game.add.isoSprite(getIsoX(objData.x), getIsoY(objData.y), 15, "sheet", "objects/RadioTower", isoGroup); radioTower.anchor.set(0.5, 0.64); radioTower.id = objData.i; radioTower.type = 4; radioTower.tileX = objData.x; radioTower.tileY = objData.y; radioTower.hoverText = game.make.text(0, 0, "Radio Tower", { fontSize: 22, fill: colorScheme.textFill, stroke: colorScheme.textStroke, strokeThickness: 2, font: "fixedsys" }); radioTower.hoverText.alpha = 0; radioTower.hoverText.anchor.set(0.5, 0); radioTower.addChild(radioTower.hoverText); radioTower.isAt = function (x, y) { return this.tileX === x && this.tileY === y; }; radioTower.onTileHover = function () { game.tweens.removeFrom(this); game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); game.add.tween(this.scale).to({x: 1.15, y: 1.15}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotHoverTint; game.add.tween(this.hoverText).to({alpha: 0.9}, 200, Phaser.Easing.Quadratic.In, true); radioTower.hoverText.visible = true; }; radioTower.onTileOut = function () { game.tweens.removeFrom(this); game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); this.tint = colorScheme.cubotTint; game.add.tween(this.hoverText).to({alpha: 0}, 200, Phaser.Easing.Quadratic.Out, true); }; return radioTower; } } // -------------------------- //Integer distance between 2 tiles function manhanttanDistance(x1, y1, x2, y2) { return Math.abs(x1 - x2) + Math.abs(y1 - y2) } function codeListener(message) { if (message.t === "code") { ace.edit("editor").setValue(message.code); } } /** * Listens for authentications responses from the server */ function authListener(message) { if (message.t === "auth") { if (message.m === "ok") { console.log("Auth successful"); mar.client.requestUserInfo(); } else { alert("Authentication failed. Please make sure you are logged in and reload the page."); } } } function codeResponseListener(message) { if (message.t === "codeResponse") { alert("Uploaded and assembled " + message.bytes + " bytes") } } /** * Listens for user info responses from the server */ function userInfoListener(message) { if (message.t === "userInfo") { //Create new world / Find my robot console.log(message); mar.worldX = message.worldX; mar.worldY = message.worldY; mar.maxWidth = message.maxWidth; mar.client.requestTerrain(); } } function terrainListener(message) { if (message.t === "terrain") { if (mar.bigMessage) { mar.bigMessage.destroy(); } if (message.ok) { if (mar.world !== undefined) { mar.client.socket.send(JSON.stringify({t: "object", x: mar.worldX, y: mar.worldY})); mar.world.update(message.terrain); } else { mar.world = new Word(message.terrain); console.log("Gameloop started"); //Handle keypresses game.input.keyboard.onDownCallback = function (event) { //If the game has focus if (document.activeElement === document.getElementById("game")) { if ((event.keyCode >= 37 && event.keyCode <= 40) || event.keyCode === 116 || event.keyCode === 32) { event.preventDefault(); } if (mar.client.username !== "guest" && mar.kbBuffer.length <= 16) { mar.client.sendKeypress(event.keyCode); //Locally update the buffer mar.kbBuffer.push(event.keyCode); mar.kbBufferText = formattedKeyBuffer(mar.kbBuffer); } } }; //Grab focus when clicked (For chrome, Opera) game.input.onDown.add(function () { document.getElementById("game").focus(); }) } } else { //World is not available if (mar.world !== undefined) { mar.world.update([]); } else { mar.world = new Word([]) } mar.bigMessage = game.add.text(908, 450, "[Uncharted World]", { fontSize: 46, fill: "#ff803d", stroke: colorScheme.textStroke, strokeThickness: 2, font: "fixedsys" }, textGroup); } } } function objectListener(message) { if (message.t === "object") { mar.world.updateObjects(message.objects); } } function floppyListener(message) { document.getElementById("floppyDown").innerHTML = " "; var blob = new Blob([message.data], {type: "application/octet-stream"}); saveAs(blob, "floppy.bin"); } function tickListener(message) { if (message.t === "tick") { //Request objects mar.client.socket.send(JSON.stringify({t: "object", x: mar.worldX, y: mar.worldY})); //Update key buffer display if (message.keys !== undefined) { mar.kbBuffer = message.keys; mar.kbBufferText = formattedKeyBuffer(mar.kbBuffer); } var myConsole = document.getElementById('console'); if (message.cm === 0) { //Clear command was sent myConsole.innerHTML = ""; mar.lastLines = ""; } //Update console if (message.c !== undefined) { var str = mar.lastLines; for (var i = 0; i < message.c.length; i++) { str += message.c[i]; } //Limit lines to 40 chars myConsole.innerHTML = ""; var tmpBuffer = ""; var lines = str.split("\n"); for (var i = 0; i < lines.length; i++) { if (lines[i].length >= 40) { //Split the line... var subLines = lines[i].match(/.{1,40}/g); for (var j = 0; j < subLines.length; j++) { //Don't put a newline at the end if (j !== subLines.length - 1) { tmpBuffer += "\n"; } } } else { tmpBuffer += lines[i] + "\n"; } } myConsole.innerHTML = tmpBuffer; mar.lastLines = str; //Autoscroll myConsole.scrollTop = myConsole.scrollHeight; } } } var GameClient = function (callback) { var self = this; var listeners = []; var xhr = new XMLHttpRequest(); xhr.open("GET", "./getServerInfo.php", true); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log("Received server info " + xhr.responseText); setTimeout(function () { var info = JSON.parse(xhr.responseText); console.log(info.address); self.socket = new WebSocket(info.address); self.username = info.username; self.tickLength = info.tickLength; self.serverName = info.serverName; mar.client.socket.binaryType = 'arraybuffer'; self.socket.onopen = function () { //Send auth request self.socket.send(info.token); //Setup event managers listeners.push(authListener); listeners.push(userInfoListener); listeners.push(terrainListener); listeners.push(tickListener); listeners.push(objectListener); listeners.push(codeListener); listeners.push(codeResponseListener); mar.client.socket.onmessage = function (received) { try { var message = JSON.parse(received.data); } catch (e) { console.log(e) floppyListener(received); } for (var i = 0; i < listeners.length; i++) { listeners[i](message); } }; self.reloadCode(); if (callback !== undefined) { callback(); } }; self.socket.onerror = function (e) { alert("Can't connect to game server at address " + info.address); console.log(e); }; self.socket.onclose = function (e) { alert("Disconnected from server"); console.log(e); } }, 100); } }; xhr.send(null); this.requestUserInfo = function () { this.socket.send(JSON.stringify({t: "userInfo"})); }; this.requestTerrain = function () { this.socket.send(JSON.stringify({t: "terrain", x: mar.worldX, y: mar.worldY})); }; this.uploadCode = function (code) { console.log("Uploaded code"); this.socket.send(JSON.stringify({t: "uploadCode", code: code})) }; this.reloadCode = function () { this.socket.send(JSON.stringify({t: "codeRequest"})) }; this.sendKeypress = function (key) { if (key !== 0) { this.socket.send(JSON.stringify({t: "k", k: key})); } }; this.requestFloppy = function () { document.getElementById("floppyDown").innerHTML = ""; this.socket.send(JSON.stringify({t: "floppyDown"})); }; this.notifyFloppyUp = function () { this.socket.send(JSON.stringify({t: "floppyUp"})); } }; function dispatchTileHover(x, y) { for (var i in mar.world.objects) { var object = mar.world.objects[i]; if (object.isAt(x, y)) { object.onTileHover(); } } } function dispatchTileOut(x, y) { for (var i in mar.world.objects) { var object = mar.world.objects[i]; if (object.isAt(x, y)) { object.onTileOut(); } } } var count = 0; var BasicGame = function (game) { }; BasicGame.Boot = function (game) { }; var isoGroup, cursorPos, cursor; var textGroup; var debugTile; var debugObj; var objectsGroup; var cursors; var tmpLine; BasicGame.Boot.prototype = { preload: function () { game.load.atlasJSONHash("sheet", "./mar/sprites.png", "./mar/sprites.json"); game.time.advancedTiming = true; // Add and enable the plug-in. game.plugins.add(new Phaser.Plugin.Isometric(game)); // This is used to set a game canvas-based offset for the 0, 0, 0 isometric coordinate - by default // this point would be at screen coordinates 0, 0 (top left) which is usually undesirable. game.iso.anchor.setTo(0.5, 0); game.world.setBounds(0, 0, 2200, 1100); //Make camera more or less centered (tested on 1080 screen) game.camera.x = 280; game.camera.y = 90; game.stage.disableVisibilityChange = true; this.scale.scaleMode = Phaser.ScaleManager.RESIZE; this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true; }, create: function () { // Create a group for our tiles. isoGroup = game.add.group(); objectsGroup = game.add.group(); textGroup = game.add.group(); //Initialise Cubot Animations Frames lists initialiseAnimations(); // Let's make a load of tiles on a grid. this.spawnTiles(); // Provide a 3D position for the cursor cursorPos = new Phaser.Plugin.Isometric.Point3(); cursors = game.input.keyboard.createCursorKeys(); }, update: function () { game.scale.refresh(); // Update the cursor position. // It's important to understand that screen-to-isometric projection means you have to specify a z position manually, as this cannot be easily // determined from the 2D pointer position without extra trickery. By default, the z position is 0 if not set. game.iso.unproject(game.input.activePointer.position, cursorPos); // Loop through all tiles and test to see if the 3D position from above intersects with the automatically generated IsoSprite tile bounds. isoGroup.forEach(function (tile) { if (tile.isTile) { var inBounds = tile.isoBounds.containsXY(cursorPos.x, cursorPos.y); // If it does, do a little animation and tint change. if (!tile.selected && inBounds) { tile.selected = true; tile.tint = colorScheme.tileHoverTint; debugTile = tile.tileX + ", " + tile.tileY; dispatchTileHover(tile.tileX, tile.tileY); game.add.tween(tile).to({isoZ: tile.baseZ + 8}, 200, Phaser.Easing.Quadratic.InOut, true); } // If not, revert back to how it was. else if (tile.selected && !inBounds) { dispatchTileOut(tile.tileX, tile.tileY); tile.selected = false; tile.tint = tile.baseTint; game.add.tween(tile).to({isoZ: tile.baseZ}, 200, Phaser.Easing.Quadratic.InOut, true); } } }); if (this.game.input.activePointer.isDown) { if (this.game.origDragPoint) { // move the camera by the amount the mouse has moved since last update this.game.camera.x += this.game.origDragPoint.x - this.game.input.activePointer.position.x; this.game.camera.y += this.game.origDragPoint.y - this.game.input.activePointer.position.y; } // set new drag origin to current position this.game.origDragPoint = this.game.input.activePointer.position.clone(); } else { this.game.origDragPoint = null; } count++; if (count % 10 === 0) { game.iso.topologicalSort(isoGroup); } // if(mar.world){ // for(var i = 0; i < mar.world.objects.length; i++){ // if(mar.world.objects[i].animations){ // console.log(mar.world.objects[i].animations.currentFrame) // // } // } // } }, render: function () { if (mar.worldX !== undefined) { game.debug.text("World: (" + Number(mar.worldX).toString(16) + ", " + Number(mar.worldY).toString(16) + ")", 10, 20); } else { game.debug.text("World: (?,?)", 10, 20); } if (debugTile) { game.debug.text(debugTile, 10, 40); } if (mar.client.username !== "guest") { game.debug.text(mar.kbBufferText, 210, 20); } // game.debug.text(debugObj, 32, 190); // game.debug.text(game.time.fps || '--', 2, 14, "#a7aebe"); // game.debug.cameraInfo(game.camera, 32, 32); if (tmpLine !== undefined) { game.debug.geom(tmpLine); game.debug.lineInfo(tmpLine, 32, 32); } }, spawnTiles: function () { mar.client = new GameClient(); } }; function setupWorldArrows() { var northArrow = game.make.isoSprite(528, -10, 10, "sheet", "ui/arrow_north", isoGroup); northArrow.inputEnabled = true; northArrow.events.onInputDown.add(function () { if (mar.worldY === 0) { mar.worldY = mar.maxWidth; } else { mar.worldY--; } mar.client.requestTerrain(); }); northArrow.events.onInputOver.add(function () { northArrow.tint = 0x00ff00; document.body.style.cursor = "pointer"; }); northArrow.events.onInputOut.add(function () { northArrow.tint = 0xFFFFFF; document.body.style.cursor = "default"; }); isoGroup.addChild(northArrow); var eastArrow = game.make.isoSprite(1115, 587, 10, "sheet", "ui/arrow_east", isoGroup); eastArrow.inputEnabled = true; eastArrow.events.onInputDown.add(function () { if (mar.worldX === mar.maxWidth) { mar.worldX = 0; } else { mar.worldX++; } mar.client.requestTerrain(); }); eastArrow.events.onInputOver.add(function () { eastArrow.tint = 0x00ff00; document.body.style.cursor = "pointer"; }); eastArrow.events.onInputOut.add(function () { eastArrow.tint = 0xFFFFFF; document.body.style.cursor = "default"; }); isoGroup.addChild(eastArrow); var southArrow = game.make.isoSprite(528, 1170, 10, "sheet", "ui/arrow_south", isoGroup); southArrow.inputEnabled = true; southArrow.events.onInputDown.add(function () { if (mar.worldY === mar.maxWidth) { mar.worldY = 0; } else { mar.worldY++; } mar.client.requestTerrain(); }); southArrow.events.onInputOver.add(function () { southArrow.tint = 0x00ff00; document.body.style.cursor = "pointer"; }); southArrow.events.onInputOut.add(function () { southArrow.tint = 0xFFFFFF; document.body.style.cursor = "default"; }); isoGroup.addChild(southArrow); var westArrow = game.make.isoSprite(-60, 587, 10, "sheet", "ui/arrow_west", isoGroup); westArrow.inputEnabled = true; westArrow.events.onInputDown.add(function () { if (mar.worldX === 0) { mar.worldX = mar.maxWidth; } else { mar.worldX--; } mar.client.requestTerrain(); }); westArrow.events.onInputOver.add(function () { westArrow.tint = 0x00ff00; document.body.style.cursor = "pointer"; }); westArrow.events.onInputOut.add(function () { westArrow.tint = 0xFFFFFF; document.body.style.cursor = "default"; }); isoGroup.addChild(westArrow); } function cubotDig(cubot, direction, callback) { if (direction === DIR_NORTH) { cubot.animations.play("dig_n", 45); } else if (direction === DIR_EAST) { cubot.animations.play("dig_e", 45); } else if (direction === DIR_SOUTH) { cubot.animations.play("dig_s", 45); } else if (direction === DIR_WEST) { cubot.animations.play("dig_w", 45); } } function cubotMove(cubot, direction, callback, walkFrames, jump) { var tween; if (direction === DIR_SOUTH) { var walk = function (duration) { if (jump) { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); var zTween1 = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoZ: 90}, duration / 2, Phaser.Easing.Quadratic.Out, true); zTween1.onComplete.add(function () { game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoZ: 5}, duration / 2, Phaser.Easing.Quadratic.In, true); }) } else { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); cubot.animations.play("walk_s", 60, true); } dispatchTileEnter(cubot.tileX, cubot.tileY); tween.onComplete.add(function () { cubot.animations.stop(); cubot.animations.frame = walkFrames.south; // cubot.tileY++; cubot.onTileOut(); //Resync position cubot.isoX = getIsoX(cubot.tileX); cubot.isoY = getIsoY(cubot.tileY); if (callback !== undefined) { callback(); } for (var i = 0; i < cubot.queuedAnims.length; i++) { cubot.queuedAnims[i](500); cubot.queuedAnims.splice(i, 1) } }) } } else if (direction === DIR_NORTH) { walk = function (duration) { if (jump) { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); var zTween1 = game.add.tween(cubot).to({isoZ: 90}, duration / 2, Phaser.Easing.Quadratic.Out, true); zTween1.onComplete.add(function () { game.add.tween(cubot).to({isoZ: 5}, duration / 2, Phaser.Easing.Quadratic.In, true); }) } else { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); cubot.animations.play("walk_n", 60, true); } dispatchTileEnter(cubot.tileX, cubot.tileY); tween.onComplete.add(function () { cubot.animations.stop(); cubot.animations.frame = walkFrames.north; // cubot.tileY--; cubot.onTileOut(); //Resync position cubot.isoX = getIsoX(cubot.tileX); cubot.isoY = getIsoY(cubot.tileY); if (callback !== undefined) { callback(); } for (var i = 0; i < cubot.queuedAnims.length; i++) { cubot.queuedAnims[i](500); cubot.queuedAnims.splice(i, 1) } }) } } else if (direction === DIR_WEST) { walk = function (duration) { if (jump) { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); var zTween1 = game.add.tween(cubot).to({isoZ: 90}, duration / 2, Phaser.Easing.Quadratic.Out, true); zTween1.onComplete.add(function () { game.add.tween(cubot).to({isoZ: 5}, duration / 2, Phaser.Easing.Quadratic.In, true); }) } else { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); cubot.animations.play("walk_w", 60, true); } dispatchTileEnter(cubot.tileX, cubot.tileY); tween.onComplete.add(function () { cubot.animations.stop(); cubot.animations.frame = walkFrames.west; // cubot.tileX--; cubot.onTileOut(); //Resync position cubot.isoX = getIsoX(cubot.tileX); cubot.isoY = getIsoY(cubot.tileY); if (callback !== undefined) { callback(); } for (var i = 0; i < cubot.queuedAnims.length; i++) { cubot.queuedAnims[i](500); cubot.queuedAnims.splice(i, 1) } }) } } else if (direction === DIR_EAST) { walk = function (duration) { if (jump) { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); var zTween1 = game.add.tween(cubot).to({isoZ: 90}, duration / 2, Phaser.Easing.Quadratic.Out, true); zTween1.onComplete.add(function () { game.add.tween(cubot).to({isoZ: 5}, duration / 2, Phaser.Easing.Quadratic.In, true); }) } else { tween = game.add.tween(cubot).to({isoX: getIsoX(cubot.tileX), isoY: getIsoY(cubot.tileY)}, duration, Phaser.Easing.Linear.None, true); cubot.animations.play("walk_e", 60, true); } dispatchTileEnter(cubot.tileX, cubot.tileY); tween.onComplete.add(function () { cubot.animations.stop(); cubot.animations.frame = walkFrames.east; // cubot.tileX++; cubot.onTileOut(); //Resync position cubot.isoX = getIsoX(cubot.tileX); cubot.isoY = getIsoY(cubot.tileY); if (callback !== undefined) { callback(); } for (var i = 0; i < cubot.queuedAnims.length; i++) { cubot.queuedAnims[i](500); cubot.queuedAnims.splice(i, 1) } }) } } if (cubot.animations.currentAnim.isPlaying) { //Queue up the animation cubot.queuedAnims.push(walk); console.log("Queued Animation"); } else { walk(800); } } function initialiseAnimations() { //Walk =------------------------------------------------------- //East mar.animationFrames.walk_e_start = []; for (var i = 0; i < 10; i++) { mar.animationFrames.walk_e_start.push("cubot/walk_e/" + ("0000" + i).slice(-4)); } mar.animationFrames.walk_e = []; for (i = 10; i < 30; i++) { mar.animationFrames.walk_e.push("cubot/walk_e/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_e_start = []; for (var i = 0; i < 10; i++) { mar.animationFrames.harvester_walk_e_start.push("harvester/walk_e/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_e = []; for (i = 10; i < 30; i++) { mar.animationFrames.harvester_walk_e.push("harvester/walk_e/" + ("0000" + i).slice(-4)); } //North mar.animationFrames.walk_n_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.walk_n_start.push("cubot/walk_n/" + ("0000" + i).slice(-4)); } mar.animationFrames.walk_n = []; for (i = 10; i < 30; i++) { mar.animationFrames.walk_n.push("cubot/walk_n/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_n_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.harvester_walk_n_start.push("harvester/walk_n/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_n = []; for (i = 10; i < 30; i++) { mar.animationFrames.harvester_walk_n.push("harvester/walk_n/" + ("0000" + i).slice(-4)); } //South mar.animationFrames.walk_s_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.walk_s_start.push("cubot/walk_s/" + ("0000" + i).slice(-4)); } mar.animationFrames.walk_s = []; for (i = 10; i < 30; i++) { mar.animationFrames.walk_s.push("cubot/walk_s/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_s_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.harvester_walk_s_start.push("harvester/walk_s/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_s = []; for (i = 10; i < 30; i++) { mar.animationFrames.harvester_walk_s.push("harvester/walk_s/" + ("0000" + i).slice(-4)); } //West mar.animationFrames.walk_w_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.walk_w_start.push("cubot/walk_w/" + ("0000" + i).slice(-4)); } mar.animationFrames.walk_w = []; for (i = 10; i < 30; i++) { mar.animationFrames.walk_w.push("cubot/walk_w/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_w_start = []; for (i = 0; i < 10; i++) { mar.animationFrames.harvester_walk_w_start.push("harvester/walk_w/" + ("0000" + i).slice(-4)); } mar.animationFrames.harvester_walk_w = []; for (i = 10; i < 30; i++) { mar.animationFrames.harvester_walk_w.push("harvester/walk_w/" + ("0000" + i).slice(-4)); } //Dig =------------------------------------------------------- mar.animationFrames.dig_e = []; for (i = 1; i <= 41; i++) { mar.animationFrames.dig_e.push("cubot/dig_e/" + ("0000" + i).slice(-4)); } mar.animationFrames.dig_n = []; for (i = 1; i <= 41; i++) { mar.animationFrames.dig_n.push("cubot/dig_n/" + ("0000" + i).slice(-4)); } mar.animationFrames.dig_s = []; for (i = 1; i <= 41; i++) { mar.animationFrames.dig_s.push("cubot/dig_s/" + ("0000" + i).slice(-4)); } mar.animationFrames.dig_w = []; for (i = 1; i <= 41; i++) { mar.animationFrames.dig_w.push("cubot/dig_w/" + ("0000" + i).slice(-4)); } //Biomass =------------------------------------------------------- mar.animationFrames.biomassIdle = []; for (i = 1; i < 60; i++) { mar.animationFrames.biomassIdle.push("objects/biomass/idle/" + ("0000" + i).slice(-4)); } } function getIsoX(tileX) { return (tileX * 71.5) } function getIsoY(tileY) { return (tileY * 71.5) } function findMyRobot() { if (mar.client.username === "guest") { alert("You are not logged in!"); } else { mar.client.requestUserInfo() } } function formattedKeyBuffer(kbBuffer) { var str = "KB: "; for (var i = 0; i < 16; i++) { if (kbBuffer[i] !== undefined) { str += kbBuffer[i].toString(16) + " "; } else { str += "__ "; } } return str; } game.state.add('Boot', BasicGame.Boot); game.state.start('Boot');