Showing posts with label Facebook. Show all posts
Showing posts with label Facebook. Show all posts

Monday, July 22, 2013

Diamond Reaction: An HTML5 Chain Reaction Game using Crafty JS

I've been away from blogging for a long time. Maybe because I've not been learning code-detailed topics. I've been more like learning the basics in topics I've never tries before (like PHP) and learning some theoretical topics.

Anyways, this time I'm trying a new approach to gain more experience. This was I can gain experience from anything I want to learn. So here is my almost-full game implementation of an HTML5 chain reaction game called: Diamond Reaction.

Play Diamond Reaction now



Let's talk a bit about it:

Idea:
I wanted to make a game for fun, with the focus on game mechanics. So I started thinking of some ideas that can be fun for a 'mario-lover' like me. Whenever I think of an idea, I search about it and see how frequent I find the same mechanics on the web. Till I arrived at this concept that did not have a big hit before: chain reaction games.

Theme:
If you look at a game like Angry Birds, you can find the game mechanics are not that hard or new. But the theme is what made it a big hit. I'm doing my game for fun and experience and I'm not a graphic designer, so I started searching for the common simple themes for the popular games these days, especially on Facebook. The most noticed theme was the cartoonish diamonds theme (plus bubbles and animals). So I picked this theme because It will not need much effort to make, plus it actually makes the game more fun to play (you can search for chain reaction games and see how boring their graphics are).

Implementation:
Since the concept of chain reaction game is not that hard to implement, and I already know how to use Crafty JS framework, the game did not take much time to get to the first demo.

Gamification:
I thought about adding a small feature to add more fun and challenge to the game: highscore and leaderoard. but I did not to keep user data on my small server. So I decided to add an optional Facebook login button to login with Facebook credentials so that I can use the Scores API the Facebook has.

Balance:
These kinds of small games can get boring if I did not find the right balance for the game. Since it was a very small game with no big details, fine-tuning was made easily by playing and -trial-and-error.

Missing features:
- No sound was added, maybe I can add it later.
- I'm not satisfied with the current balancing.
- Add more items and surprises to the game to make it more fun and engaging.

Play Diamond Reaction now




Wednesday, May 8, 2013

Facebook Scores API with Koala Gem

Here is a code snippet for a piece of code that I found a lot of people asking about on the web. Since Koala gem does not have an explicit API for Facebook Scores API, some people wonder why it isn't there.

Actually, there is a generic call that can do the job just fine:

After getting your Koala gem to work: check this URL for more about Creating a Facebook Rails app with Koala gem.


Read the set of scores for a user and their friends

Facebook Scores API states that: "You can read the set of scores for a user and their friends for your app by issuing an HTTP GET request to /APP_ID/scores with the user access_token for that app."

So this can be done with the 'get_object()' method,
api = Koala::Facebook::API.new(session[:access_token])
scores = api.get_object(APP_ID + "/scores")


Create or update a score for a user:

Facebook Scores API states that: "You can post a score for a user by issuing an HTTP POST request to /USER_ID/scores with a user or app access_token as long as the user has granted the publish_actions permission for your app."

So this can be done with the 'put_connections()' method,
api = Koala::Facebook::API.new(session[:access_token])
user_profile = api.get_object("me")
result = api.put_connections(user_profile['id'], 'scores?score='+my_score)

if result == true
    #great!
else
    #oops!
end



Sunday, December 16, 2012

Ruby on Rails Facebook Application using Koala Gem

Here is a another Facebook application example (check the python example), but this time it is with Ruby on Rails using Koala gem. The great thing about Koala is how it is easy integrated and straight forward. Here are the steps from the very beginning:

1- Create a new Ruby on Rails project:
rails new rorApp


2- Delete ./public/index.html file as it is not needed.


3- In Gemfile add:
gem 'koala', '1.3.0'


4- In ./config/initializers folder, add a constants.rb file with the following data:
APP_ID= '123456789' # please change!
APP_SECRET= '1b2n3n5n6n7m8m9n9m0m' # please change!
SITE_URL = 'http://localhost:3000/' # please change!


Where APP_ID and APP_SECRET are the values you have from the Facebook application you create in the developers section, and the SITE_URL is the root URL of your application website ('http://localhost:3000/' if our case of testing locally)


5- In ./config/routes.rb, add the following routes:
root :to => 'home#index'

match '/index' => 'home#index'
match '/login' => 'home#login'

The first line makes calling the root of your application points to your index page.

6- In ./app/views folder, create a 'home' folder and inside it create a 'index.html.erb' with any content you want to show. It will only be available after user logs in.

7- In ./app/controller folder, create a 'home_controller.rb' file with the following content:
class HomeController < ApplicationController
            
    def index   
        if params[:code]
            # acknowledge code and get access token from FB
            session[:access_token] = session[:oauth].get_access_token(params[:code])
        end  

        # auth established, now do a graph call:
        @api = Koala::Facebook::API.new(session[:access_token])

        begin
            @user_profile = @api.get_object("me")
        rescue Exception=>ex
            puts ex.message
            #if user is not logged in and an exception is caught, redirect to the page where logging in is requested
            redirect_to '/login' and return
        end

        respond_to do |format|
         format.html {   }    
        end
    end
    
    #########################################################
    
    def login
        session[:oauth] = Koala::Facebook::OAuth.new(APP_ID, APP_SECRET, SITE_URL + '/')
        @auth_url =  session[:oauth].url_for_oauth_code(:permissions=>"read_stream publish_stream")  

        redirect_to @auth_url
    end
    
    #########################################################
end

The code explains itself, but here is a quick explanation: When the index page is called, the application looks for the access token for the current user in the cookies ('session[]'). If not found, it will redirect to the login page. The login handler will do the authentication headache for you with the extra permissions you want and passes the root URL as a call back so that Facebook will call it after authentication is done. Then when the index page is called one more time with an authentication code, it will be used to get the access token needed for any later requests.
So when the user opens the index page, he will notice some redirects and message boxes asking for allowing your application and for extra permissions then he is redirected to your index page.

8- Now you have your application ready. Just run 'bundle' from your terminal (make sure you are in the root folder of your application) to install Koala and then 'rails s' to start the web service.
bundle
rails s


9- Finally here are some Graph API calls that you may use to get profile data, friends list, post text/image and text to user's wall.
@api = Koala::Facebook::API.new(session[:access_token])
@user_profile = @api.get_object("me")
@friends = @api.get_connections(user_profile["id"], "friends")
@api.put_wall_post("hi")
@api.put_picture("http://www.example.com/image.png", {:message => "an image of mine!"})


You can learn more about Koala gem from this link: https://github.com/arsduo/koala

Friday, November 30, 2012

Google App Engine Facebook Application Example Using Python

This is a detailed example built on Facebook Python SDK example. In this example I'll take it step by step from the very beginning to login, get user data, get friends list, invite friends, and post to wall. So let's start. (also check the Ruby on Rails with Koala example)

- Download "facebook.py" from this link on GitHub.

- Add the downloaded file to your Google App Engine project.

- You can now make you own Facebook application code or re-use the current example (which I choose to do).

- Take these global variables and imports into your application (your GAE python file)
FACEBOOK_APP_ID = "123456789" #your own FB app id here
FACEBOOK_APP_SECRET = "756483568435475" #your own FB app secret here
INVITATION_TEXT = "I invite you to try my app. It is amazing!"

import facebook
import os.path
import wsgiref.handlers
import logging
import urllib2
import hashlib

from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from google.appengine.api.urlfetch import fetch

import webapp2

- Add this Model and Base Class that will be used to determine the user ID from cookies
class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    profile_url = db.StringProperty(required=True)
    access_token = db.StringProperty(required=True)

class BaseHandler(webapp.RequestHandler):
    """Provides access to the active Facebook user in self.current_user

    The property is lazy-loaded on first access, using the cookie saved
    by the Facebook JavaScript SDK to determine the user ID of the active
    user. See http://developers.facebook.com/docs/authentication/ for
    more information.
    """
    @property
    def current_user(self):
        if not hasattr(self, "_current_user"):
            self._current_user = None
            cookie = facebook.get_user_from_cookie(
                self.request.cookies, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET)
            if cookie:
                # Store a local instance of the user data so we don't need
                # a round-trip to Facebook on every request
                user = User.get_by_key_name(cookie["uid"])
                if not user:
                    graph = facebook.GraphAPI(cookie["access_token"])
                    profile = graph.get_object("me")
                    user = User(key_name=str(profile["id"]),
                                id=str(profile["id"]),
                                name=profile["name"],
                                profile_url=profile["link"],
                                access_token=cookie["access_token"])
                    user.put()
                elif user.access_token != cookie["access_token"]:
                    user.access_token = cookie["access_token"]
                    user.put()
                self._current_user = user
        return self._current_user

- Now let's create our handler. Note that in case you wan to use your application inside Facebook frame, you will have to handle POST request too.

- Logging In and Inviting Friends

class HomeHandler(BaseHandler):
    def get(self):
        self.show_main()

    def post(self):
        self.show_main()
        
    def show_main(self):
        path = os.path.join(os.path.dirname(__file__), "templates/main.html")
        args = dict(current_user=self.current_user,
                    facebook_app_id=FACEBOOK_APP_ID,
                    invitation_text=INVITATION_TEXT)
        self.response.out.write(template.render(path, args))

- Now let's create the template for the HTML template. Here is how it goes: If the passed "current_user" parameter is valid, it will show the content of your app and a link to a JQuery function to invite friends using Facebook Javascript SDK initialized at the bottom. Otherwise, it will show a Facebook login button.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Application Title</title>
    
    <script type="text/javascript" src="/js/jquery-1.8.2.min.js"></script>
    <script type="text/javascript">
        $('#sendRequest').click(function() {
          FB.ui(
            {
              method  : 'apprequests',
              message : $(this).attr('data-message')
            },
            function (response) {
              // If response is null the user canceled the dialog
              if (response != null) {
                //logResponse(response);
              }
            }
          );
        });
    });
    </script>
  </head>
  <body>
  
    {% if not current_user %}
    <div style="margin:0 auto; text-align:center;">
        <fb:login-button autologoutlink="false" scope="publish_stream"></fb:login-button>
    </div> 
    
    {% else %}
    
    <br>
    Welcome! Here is my application.
    <br>
    <a href="#" id="sendRequest" data-message="{{invitation_text}}">
      Send Requests
    </a>
    
    {% endif %}

    <div id="fb-root"></div>
    <script>
      window.fbAsyncInit = function() {
        FB.init({appId: '{{ facebook_app_id }}', status: true, cookie: true,
                 xfbml: true});
        FB.Event.subscribe('{% if current_user %}auth.logout{% else %}auth.login{% endif %}', function(response) {
          window.location.reload();
        });
      };
      (function() {
        var e = document.createElement('script');
        e.type = 'text/javascript';
        e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
        e.async = true;
        document.getElementById('fb-root').appendChild(e);
      }());
    </script>
  </body>
</html>

- At this point, you should be having a working Python Google App Engine Facebook application. Next I'll go though some basic information that you may need to implement in your service. You may prefer XML, JSON, or a custom format. Anyways, here is the basic example that you may customize as you want and add more handling for special cases.

- User Profile

class ProfileHandler(BaseHandler):
    def get(self):
        self.show_profile()

    def post(self):
        self.show_profile()
        
    def show_profile(self):
        profile = ''
        current_user = self.current_user
        if current_user:
            graph = facebook.GraphAPI(current_user.access_token)
            profile = profile = graph.get_object("me")
        path = os.path.join(os.path.dirname(__file__), "templates/profile.html")
        args = dict(current_user=current_user,
                    facebook_app_id=FACEBOOK_APP_ID,
                    profile=profile)
        self.response.out.write(template.render(path, args))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title></title>
  </head>
  <body>
    
    {% if current_user %}
        {% if profile %}
            {{profile}}
        {% endif %}
    {% endif %}

  </body>
</html>

- Friends List

class FriendsHandler(BaseHandler):
    def get(self):
        self.show_friends()

    def post(self):
        self.show_friends()
        
    def show_friends(self):
        friends_list = []
        current_user = self.current_user
        if current_user:
            graph = facebook.GraphAPI(current_user.access_token)
            friends_list = graph.get_connections("me", "friends")['data']
        path = os.path.join(os.path.dirname(__file__), "templates/friends.html")
        args = dict(current_user=current_user,
                    facebook_app_id=FACEBOOK_APP_ID,
                    friends_list=friends_list)
        self.response.out.write(template.render(path, args))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title></title>
  </head>
  <body>
    
    {% if current_user %}
        {% if friends_list %}
            {{friends_list}}
        {% else %}
        {% endif %}
    {% else %}
    {% endif %}

  </body>
</html>

- Post Text to Wall (Arabic-friendly)

class PostTextHandler(BaseHandler):
    def post(self):
        text = self.request.get('text')
        if text:
            text = text.encode('utf-8') # for non-english text  
            current_user = self.current_user
            if current_user:
                graph = facebook.GraphAPI(current_user.access_token)
                graph.put_object("me", "feed", message=text)
                self.response.out.write('yes') # just a feedback reponse
            else:
                self.response.out.write('no') # just a feedback reponse
        else:
            self.response.out.write('no') # just a feedback reponse

- And off course do not forget to add these handlers to the suitable URLs for your service. (side note: the /?$ sign is useful to allow URL with/out the slash)
app = webapp2.WSGIApplication([
                            ('/', HomeHandler),
                            ('/profile/?$', ProfileHandler),
                            ('/friends/?$', FriendsHandler),
                            ('/posttext/?$', PostTextHandler)])