We will build a Twitter game that allows players to guess which user posted a tweet.

pic

Demo | Github Page

1. Install Node

2. Get Structure

git clone git@github.com:DruRly/build_a_twitter_game.git
cd build_a_twitter_game
git checkout bootstrap

The bootstrap tag includes directories, empty files, libraries and some CSS.

3. Add HTML

app/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Who said that?</title>
  </head>
  <body>
    <div id="app-container" class="container-fluid auto-margin">
      <div id="app-title">
        <p class="header auto-margin">
          Who said that?
        </p>
      </div>

      <p class="selected-tweet auto-margin">
      </p>

      <div id="user-images" class="auto-margin">
        <div class="image auto-margin">
        </div>
      </div>
    </div>
  </body>
</html>

Start your server: node scripts/web-server.js

Visit the index page: localhost:8000/app/index.html

Remember to refresh your browser between steps.

4. Call Dependencies

app/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Who said that?</title>
    <link rel="stylesheet" href="css/app.css"/>
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.0.4/css/bootstrap.min.css"/>
    <link href='http://fonts.googleapis.com/css?family=Merriweather+Sans' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Abril+Fatface' rel='stylesheet' type='text/css'>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="lib/angular/angular.js"></script>
    <script src="lib/angular/angular-resource.js"></script>
    <script src="js/app.js"></script>
  </head>
  <body>
    <div id="app-container" class="container-fluid auto-margin">
      <div id="app-title">
        <p class="header auto-margin">
          Who said that?
        </p>
      </div>

      <p class="selected-tweet auto-margin">
      </p>

      <div id="user-images" class="auto-margin">
        <div class="image auto-margin">
        </div>
      </div>
    </div>
  </body>
</html>

CSS: Lines 6-7

Google Fonts: Lines 8-9

Underscore.JS: Line 10

JQuery: Line 11

Angular.JS: Lines 12-13

5. Show Tweet and Users

app/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!doctype html>
<html ng-app="Twitter">
  <head>
    <meta charset="utf-8">
    <title>Who said that?</title>
    <link rel="stylesheet" href="css/app.css"/>
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.0.4/css/bootstrap.min.css"/>
    <link href='http://fonts.googleapis.com/css?family=Merriweather+Sans' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Abril+Fatface' rel='stylesheet' type='text/css'>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="lib/angular/angular.js"></script>
    <script src="lib/angular/angular-resource.js"></script>
    <script src="js/app.js"></script>
  </head>
  <body>
    <div ng-controller="TwitterCtrl" id="app-container" class="container-fluid auto-margin">
      <div id="app-title">
        <p class="header auto-margin">
          Who said that?
        </p>
      </div>

      <p class="selected-tweet auto-margin">
        "{{selected_tweet_text}}"
      </p>

      <div id="user-images" class="auto-margin">
        <div ng-repeat="tweet in shuffled_tweets" class="image auto-margin">
          <img ng-src="{{tweet.profile_image_url}}">
        </div>
      </div>
    </div>
  </body>
</html>

Bootstrap Angular App: Line 2 (More info)

Define Controller: Line 17 (More info)

Show Selected Tweet: Line 25 displays the text of the selected tweet.

Show Profile Images: Lines 29-31 iterate through tweets to display the profile image of each user.

6. Pull Data

app/js/app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
angular.module('Twitter', ['ngResource']);

function TwitterCtrl($scope, $resource) {

  $scope.twitter = $resource('http://search.twitter.com/:action',
      {action:'search.json', callback:'JSON_CALLBACK'},
      {get:{method:'JSONP', params: {rpp: 4}}});

  $scope.twitterResult = $scope.twitter.get({q:"i"}, function() {
    $scope.tweets = $scope.twitterResult.results;

    $scope.shuffled_tweets = _.shuffle($scope.tweets);

    $scope.selected_tweet_text = $scope.tweets[0].text;

    $scope.selected_tweet_user = $scope.tweets[0].from_user;
  });
}

Include Resource Class: Line 1 calls resource which gives us high-level methods for API calls..

Establish Endpoint: Lines 5-7 establish Twitter as an endpoint and limits searches to return 4 tweets.

Call Twitter: Line 9 searches for tweets including the string “i”. Feel free to change customize your query.

Assign Tweets: Line 10 assigns the search results to tweets.

Shuffle Tweets: Line 12 shuffles the tweets and assigns the result to shuffled_tweets.

Select Tweet Text: Line 14 selects the text of the tweet that will be displayed.

Select Tweet User: Line 16 assigns the user of the selected tweet to selected_tweet_user.

7. Judge Answer

app/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!doctype html>
<html ng-app="Twitter">
  <head>
    <meta charset="utf-8">
    <title>Who said that?</title>
    <link rel="stylesheet" href="css/app.css"/>
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.0.4/css/bootstrap.min.css"/>
    <link href='http://fonts.googleapis.com/css?family=Merriweather+Sans' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Abril+Fatface' rel='stylesheet' type='text/css'>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="lib/angular/angular.js"></script>
    <script src="lib/angular/angular-resource.js"></script>
    <script src="js/app.js"></script>
  </head>
  <body>
    <div ng-controller="TwitterCtrl" id="app-container" class="container-fluid auto-margin">
      <div id="app-title">
        <p class="header auto-margin">
          Who said that?
        </p>
      </div>

      <p class="selected-tweet auto-margin">
        "{{selected_tweet_text}}"
      </p>

      <div id="user-images" class="auto-margin">
        <div ng-repeat="tweet in shuffled_tweets" class="image auto-margin">
          <img ng-src="{{tweet.profile_image_url}}" ng-click="revealAnswer()" class="{{answer}}-{{tweet.from_user == selected_tweet_user}}">
        </div>
      </div>
    </div>
  </body>
</html>

Reveal Answer: Line 30 triggers revealAnswer() when a user image is clicked.

Dynamic Class: Line 30 determines img the class by using an answer variable then evaluating whether the user was the source of the selected tweet. Our == expression will return true or false. The answer variable will be undefined at first. answer is defined by revealAnswer() which is called when a player clicks an image. .answer-true and .answer-false are CSS classes whose attributes indicate whether a player’s selection was right or wrong. Check these classes out at the bottom of app/css/app.css.

app/js/app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
angular.module('Twitter', ['ngResource']);

function aReload() {
  window.location.reload()
}

function startReload() {
  setTimeout("aReload()", 1000);
}

function TwitterCtrl($scope, $resource) {

  $scope.twitter = $resource('http://search.twitter.com/:action',
      {action:'search.json', callback:'JSON_CALLBACK'},
      {get:{method:'JSONP', params: {rpp: 4}}});

  $scope.twitterResult = $scope.twitter.get({q:"i"}, function() {
    $scope.tweets = $scope.twitterResult.results;

    $scope.shuffled_tweets = _.shuffle($scope.twitterResult.results);

    $scope.selected_tweet_text = $scope.tweets[0].text;

    $scope.selected_tweet_user = $scope.tweets[0].from_user;
  });

  $scope.revealAnswer = function() {
    $scope.answer = "answer";
    startReload();
  };
}

Reload Delay: Lines 3-9 will be used to start new games.

Reveal Answer: Line 28 defines the answer variable which maps to .answer-true and .answer-false.

Start New Game: Line 29 starts a new game by refreshing the page one second after the answers have been revealed.

Subsribe or follow me for updates.

Comments