FindWithFriends

By Maria Yala

Creation & Computation – Experiment 4 / Networking

FindWithFriends is a collaborative web-app game that is built using p5.js and PubNub a data stream network used to send and receive messages between players’ devices. When the game starts, each player is presented with an identical game board made up of a matrix of clickable tiles and a list of words to find, however each player is assigned a random color to differentiate them from other players. Words are arranged on the board in varying directions – forwards, backwards, upwards, downwards, and diagonally. Players can either play collaboratively, or competitively. Every time a player clicks on a tile, the tile’s color changes to the player’s assigned color. Once a player finds a word, they can lock their tiles to prevent other players from stealing tiles that they have found. If a player clicks on an unlocked tile, it will turn white again. When the ‘lock tiles’ button is clicked, the player’s score is calculated and drawn on the screen.

Background

For this project, I wanted to learn more about creating custom classes in JavaScript as I didn’t have much experience with them in JavaScript before. Additionally, I was drawn to the idea of working visually with objects in a matrix when we went over some of the examples in class. I wanted to challenge myself to learn more about custom classes and nested for-loops.

Ideation & Inspiration

My main inspiration was to initially create something to do with collaborative storytelling, however, since I was thinking of working with grids/matrices, I ended up choosing word games particularly crosswords and word find puzzles. In the end, I settled on the idea of a collaborative word find game where each player was identified by a different color. This was inspired mainly by a word find game in a zine I had created and the game WordsWithFriends.

Step 1 – The Tile Class

I created a custom class to represent the tile objects of the game board. In the beginning I circular and square tiles using the ellipse() and rect() functions. Each tile had the following attributes: x and y coordinates and size dimensions. The Tile class also had a display function that when called would draw the tile at the object’s x and y position.

Step 2 – The Matrix

I began by testing out – creating a 3×3 matrix of square objects onto the screen. This was done by using a nested for loop that upon each inner iteration would create a new tile passing the x and y positions in the for-loop to a mapping function to generate a position on the screen. The matrix was restricted to a size of 600 and 600 and these were the dimensions used to map coordinates.

An image showing testing of a 3×3, 15×15, and 30×30 matrix on a screen portion of 600×600 pixels.

Step 3 – The Letters

I then created a second custom class to overlay letters over each tile. The Letter class was also created using a nested for-loop iterating over an array of letters. Each Letter object had the following attributes: a letter, an x and y coordinate. The Letter class had one method; a display function that when called, draws the letter on the corresponding tile. Below is an example of a 3×3 sample that was iterated over to generate a nested 3×3 array of Letter objects.

var test = [‘A’,’P’,’J’,’X’,’E’,’I’,’C’,’O’,’W’];

An image showing the letters overlaid onto a 3×3 game board

Step 4 – Clicking on tiles

Upon success with drawing the tiles and letters onto the canvas, I began to work on interacting with the objects on the screen so that a tile would change color when clicked. I began by creating a variable pcolor to hold the players random color assignment which is generated when the page is loaded. Using the mousePressed() function, I got the x and y position of the mouse when the user clicked and then passed it to a new method in the Tile class, clickCheck(). This function, clickCheck(), used the x and y coordinates of the player’s click and the x and y coordinates of the tile, calculating the distance between the two to determine if the player had indeed clicked within the tiles radius. If the click was within the radius, the color of the tile would change from white to the player’s color. Here I also updated the Tile class, adding the clickCheck() function and color attributes i.e r, g, and b for RGB color mode. The nested for-loop that created the array of Tile objects was then updated to initially create tiles as white in color. Initially I was using mouseClicked() but changed it to mousePressed() because during testing I found that it worked on a laptop but not on the iPad.

An image showing testing of clicking on tiles to change their color, with color randomly updating upon page refresh

Step 5 – Adding another player

Once basic game functionality was working for one-player, I began to integrate PubNub so as to allow for multi-player functionality. I updated the mousePressed() function to publish a message to pubnub and upon receipt of a message back in the readIncoming() function, the clickCheck would be called. The message passed to and from PubNub carried information about the mouse x and y coordinates and player color. These were then passed to the clickCheck() function which would update the tiles accordingly.

An image of a game screen showing a 2 player game where each player is a different color

Step 6 – Testing Tile Size When Matrix Size Increases

I changed the test array(as shown below) containing letters, switching from the 3×3 grid to a 7×7 grid to begin testing out how the grid would look with a words that were placed in different directions on the grid. And tested adjusting the size of the tiles so that the background would be covered.

Figuring out correct size for the tiles on a new, and larger game board

Testing the game using a game board with circular tiles and 3 players

I ended up removing the circular tiles as square tiles were more visually pleasing because they didn’t overlap with the other tiles.

Step 7 – The “Steal tiles” feature

Here I updated the Tile Class, adding 3 new attributes – ‘c’ a string to hold the color id of the tile e.g white would be 255255255, ‘isLocked’ a boolean to check whether a tile is locked or not, ‘isWhite’ a boolean to check whether a tile is white or colored. I used the ‘isWhite’ variable to detect clicks on tiles; a tile is created as white, when it is clicked, it’s color is changed and this variable is set to false. When a user clicks again on a tile they had already clicked, I compare the tile’s ‘isWhite’ value and its current color id to determine whether it is being stolen or the click is simply an undo. If it is an undo click, color reverts to white, if not, another player is stealing the tile. I had trouble with implementing an undo click because I was calling the clickCheck function twice i.e in my mousePressed() and again in my readIncoming() functions. This caused the color of the tile to change from the players color to white and then it remained white. I solved this by removing the call to the clickCheck function in the mousePressed listener.

An image showing testing the “undo click” feature and “steal tiles” feature

Step 8 – A “Lock tiles” feature

I used the ‘isLocked’ boolean to prevent a tile from being stolen by another player. I also added a button on the screen that when clicked would lock all the tiles that had the same color as the player. To do this I created 3 new method: lock() – a function to pass the player color to the tile’s lock function, updateLock(p) – a function to update other players screen locking all tiles belonging to a particular color, pubLock() a function to publish a message indicating a lock has occurred. I also added a new boolean ‘lockPressed’ that would be used to determine what kind of message was being sent i.e a normal message or a lock message. If lock id in message was 0 then the message was a normal message, if it was 1 then it was a lock message and the readIncoming() function would call the updateLock(p) function for the player who initiated the lock.

Step 9 – Final 15×15 matrix & Game Text (Hints)

I settled on a 15×15 grid for the final game and using a word find puzzle from the Huffington Post, I created a new array to hold the matrix. Text hints were drawn to the side of the game board with a ‘lock tiles’ button underneath. When choosing the theme for the puzzle, I wanted to pick a topic that was universal and a little controversial so I ended up in the realm of politics and Donald Trump with the “Who has Trump offended?” puzzle from Huffington Post. The 15×15 grid size was chosen as it was the best size that allowed legibility and precise clicks on a tablet and laptop using a fixed portion of the canvas.

Who Has Trump Offended?” puzzle from The Huffington Post

The final 15×15 game board matrix array

The final 15×15 game board matrix

Step 10 – Adding a Score

I updated the code, adding a points array that would be mapped to tiles the same way that letters were. The points system I created was that tiles in words positioned forwards or downwards were each worth 1 point each. Tiles in words going backwards were worth 2 points each. Tiles in words positioned diagonally were worth 3 points each. Tiles in the hidden word were worth bonus points of 2 points each. I added a points and a global variable score to calculate a players score based on locked tiles. Tiles that were not part of the words were each assigned 0 points. Calculation was triggered when the lock button was clicked. This score was then drawn to the screen in large font and was colored in the player’s color.

The points matrix for the final 15×15 game board

Testing the score calculation – PRESS is 5 points, HISTORIANS is 10 points

Testing the game

Video link of test from the image below – Testing the game with 2 players playing on iPad & Laptop

End result of the test between two players

Presentation (Setup & the experience )

For the presentation, I decided to use iPads instead of a combination of iPads and laptops, this was done mostly to ensure mobility. I didn’t want the players to be tied to one place. Although I had provided 5 iPads I anticipated that people may form teams when playing and would pick up the iPad or move about with them. I did use one laptop, hooked up to a projector so that onlookers would not be left out of the FindWithFriends experience. Projecting the game board on the wall was a choice that ended up being beneficial to the presentation as it heightened the game experience as people watched the tiles change color. Ultimately, the game experience changed when players realized they could steal each other’s tiles and once words had been found they proceeded to try and see who could get the most colored tiles on the screens. Below are some video and images from the presentation.

Video link to the presentation

Feedback & Future Plans

Some future adjustments to the game I would like to make would be to add the other players score onto the individual screens so as to heighten the competitive aspect. I would also like to explore turning this into an installation piece. This is inspired by feedback from the cohort and the experience of how that game turned from a simple word find to a different game when the players were notified that they could “steal” each other’s tiles. It shifted from collaborative play to competitive play when I informed them of the lock button’s functionality. Comments were also given about the choice of theme – Trump & politics. When some players were playing they would spontaneously shout out things like “I found humanity” or “I’m stealing immigrants” The words being found have the potential to make people uncomfortable and I would like to explore this further by perhaps playing with different contexts. It was also suggested that because of projecting the game board onto the wall, a new interaction could be actually having players pick tiles on the wall. This is also something that I would like to explore in the future.

Links:

Code on github – FindWithFriends

Reference Links

 https://github.com/DigitalFuturesOCADU/CC18/blob/master/Experiment%204/P5/pubnub/06A_LOCAL_ONLYcommonCanvas_animSpeed_inertia/sketch.js
 https://randomcolor.lllllllllllllllll.com/
 http://nikolay.rocks/2015-10-29-rainbows-generator-in-javascript
 https://p5js.org/examples/color-color-variables.html
 https://stackoverflow.com/questions/42101752/styling-buttons-in-javascript

https://p5js.org/reference/#/p5.Element/parent