// list of destinations var destinations = [{ name: "SOUTHSIDE", num: 0, }, { name: "FRANCE", num: 0, }, { name: "TADS", num: 0, }, { name: "SAVOYS", num: 0, }, { name: "PIZZA", num: 0, }, { name: "KITCHEN", num: 0, }, ]; var title = "FOODICATOR: RELOADED"; var titlefont = "40px Arial"; var destfont = "25px Arial"; var winningfont = "30px Arial"; // to block until ready var ready = false; // My ID var myId; // List of other players var playerList = {}; // Set up the eureca server var eurecaServer; // Client setup function var eurecaClientSetup = function() { // create an instance of eureca.io client var eurecaClient = new Eureca.Client(); // Ready function for getting the server eurecaClient.ready(function(proxy) { eurecaServer = proxy; }); // export functions can be called on the server side // Handshake function to hand over ID eurecaClient.exports.handshake = function(id) { //create() is moved here to make sure nothing is created before uniq id assignation myId = id; create(); state = { x: player.sprite.x, y: player.sprite.y } eurecaServer.updateMe(state); ready = true; } // close a connection eurecaClient.exports.kill = function(id) { var pl = playerList[id]; // if we have this player if (pl) { // Kill the player and log pl.kill(); console.log(id, " disconnected ", pl); } } // Spawn another player eurecaClient.exports.spawnPlayer = function(i, x, y) { if (i === myId) return; // do nothing for me // log and create the player console.log(i, " connected"); var player = new Player(i, x, y); // add to our list playerList[i] = player; } // Update a player state eurecaClient.exports.updateState = function(id, state) { if (id === myId) return; // do nothing for me var pl = playerList[id]; // if we have this player update it's pos if (pl) { pl.sprite.x = state.x; pl.sprite.y = state.y; } else { // If we don't have it, we probably should so add it var player = new Player(id, state.x, state.y); // add to our list playerList[i] = player; } } } var width = 800; var height = 540; // Create the game var game = new Phaser.Game(width, height, Phaser.AUTO, '', { preload: preload, create: eurecaClientSetup, update: update }); // get the length of a vector function lengthV(vec) { return length(vec.x, vec.y); } function length(x, y) { return Math.sqrt((x * x) + (y * y)); } // get the length of a vector function distance(x1, y1, x2, y2) { return length(x1 - x2, y1 - y2); } // Normalise a vector function normaliseV(vec) { var len = lengthV(vec); vec.x = (vec.x / len); vec.y = (vec.y / len); } // Player object Player = function(id, x, y) { // Constants this.id = id; this.topSpeed = 5; this.acceleration = 2; this.friction = 0.6; this.alive = false; // varying this.velocity = { x: 0, y: 0 }; // Create a sprite this.sprite = game.add.sprite(x, y, 'dude'); // set alive this.alive = true; } // Update a player Player.prototype.update = function() { // early out if dead if (!this.alive) return; // control force var force = { x: 0.0, y: 0.0 } // Grab the members, javascript is weird? var sprite = this.sprite; var velocity = this.velocity; var topSpeed = this.topSpeed; var acceleration = this.acceleration; var friction = this.friction; // Left and right if (controls.left.isDown) { // Move to the left force.x = -1.0; } else if (controls.right.isDown) { // Move to the right force.x = 1.0; } // Up and down if (controls.up.isDown) { // Move up force.y = -1.0; } else if (controls.down.isDown) { // Move down force.y = 1.0; } // normalise and apply acceleration if (lengthV(force) !== 0) normaliseV(force); force.x = force.x * acceleration; force.y = force.y * acceleration; // apply the force velocity.x += force.x; velocity.y += force.y; // apply friction when no force if (force.x === 0.0) { // if no force, then apply friction velocity.x = velocity.x * friction; } if (force.y === 0.0) { velocity.y = velocity.y * friction; } // limit speed if (lengthV(velocity) > 0.1) { // Limit to pos velocity.x = Math.min(velocity.x, topSpeed); velocity.y = Math.min(velocity.y, topSpeed); // Limit to neg velocity.x = Math.max(velocity.x, -topSpeed); velocity.y = Math.max(velocity.y, -topSpeed); } else { velocity.x = 0.0; velocity.y = 0.0; } // set sprite position and update server if (lengthV(velocity) !== 0.0) { sprite.position.x = sprite.position.x + velocity.x; if (sprite.position.x < -50) sprite.position.x = width; if (sprite.position.x > width) sprite.position.x = -50; sprite.position.y = sprite.position.y + velocity.y; if (sprite.position.y < -50) sprite.position.y = height; if (sprite.position.y > height) sprite.position.y = -50; var state = { x: sprite.position.x, y: sprite.position.y } eurecaServer.updateMe(state) } } // Kill a player Player.prototype.kill = function() { // The player and its settings this.sprite.kill(); this.alive = false; } function createDests() { var minX = 0; var maxX = width - minX; var minY = 150; var maxY = height + 100; var len = destinations.length; // we need 3 columns max var numCols = 3; var numRows = len / numCols; var colsep = ((maxX - minX) * (1 / numCols)); var rowsep = ((maxY - minY) * (1 / numRows)); var num = 0; var row = 0; var col = 0; for (var i = 0; i < len; ++i) { var dest = destinations[i]; var posX = minX + (colsep * col) + (colsep * 0.5); var posY = minY + (rowsep * row); // Create our destination text var destText = game.add.text(posX, posY, dest.name, { font: destfont, fill: "#FFFFFF" }); destText.anchor.x = Math.round(destText.width * 0.5) / destText.width; // Add to our group textGroup.add(destText); dest.text = destText; // increment num, rows and cols num++; col = num % numCols; if (col === 0) row++; } } function updateDests() { var votingRange = 100; // Get number of voters var len = destinations.length for (var i = 0; i < len; ++i) { var dest = destinations[i]; dest.num = 0; dest.vote = false; // For each external player for (var p in playerList) { var dist = distance(playerList[p].sprite.x, playerList[p].sprite.y, dest.text.x, dest.text.y); if (dist < votingRange) dest.num++; } // Add for the current player var dist = distance(player.sprite.x, player.sprite.y, dest.text.x, dest.text.y); if (dist < votingRange) { dest.num++; dest.vote = true; } } // Set the texts var winners = []; for (var i = 0; i < len; ++i) { var dest = destinations[i]; dest.text.setText(dest.name + " HAS " + dest.num); // add to the array if ((winners.length === 0) || (dest.num == winners[0].num)) { winners.push(dest); } else if ((dest.num > winners[0].num)) // clear array and add { winners = []; winners.push(dest); } } var wintext; if (winners.length === 0) { wintext = "NO WINNER"; } else if (winners.length === 1) { wintext = winners[0].name + " IS WINNINGS"; } else { wintext = "DRAW BETWEEN " + winners[0].name; var left = winners.length; for (var i = 1; i < left; ++i) { wintext += " AND " + winners[i].name; } } winningText.setText(wintext); } // Phaser functions // preload all assets function preload() { // Set centered game.scale.pageAlignHorizontally = true; game.scale.pageAlignVertically = true; // load the background game.load.image("bg", "assets/bg.png"); // Load the dude game.load.image('dude', 'assets/dude.png', 50, 50); } // Create the game function create() { // Add the background sprite var background = game.add.sprite(0, 0, "bg"); // create our player player = new Player(myId, game.world.centerX + (25 - Math.random() * 50), game.world.centerY + (25 - Math.random() * 50)); // Get controls controls = game.input.keyboard.createCursorKeys(); // Create the text group textGroup = game.add.group(); // Create our title text var titleText = game.add.text(game.world.centerX, 20, title, { font: titlefont, fill: "#FFFFFF" }); titleText.anchor.x = Math.round(titleText.width * 0.5) / titleText.width; // Add to our group textGroup.add(titleText); createDests(); winningText = game.add.text(game.world.centerX, height - 60, "NO WINNER", { font: winningfont, fill: "#FFFFFF" }); winningText.anchor.x = Math.round(winningText.width * 0.5) / winningText.width; } // On update function update() { // do nothing if not ready yet if (!ready) return; // update our player player.update(); // Bring the text group to the top game.world.bringToTop(textGroup); // Update our destinations updateDests(); }