Saturday, 21 December 2013

Let's Play Permissions for Open Source Games With Free Art

Let's Play (LP) is an uprising form of previewing and experiencing video games.

While a review summarizes the experience, a LP allows to look a player over their shoulder and indirectly experience the game from one perspective in its entirety - if both Let's Player and viewer have the endurance.

LPs have many styles: non-commented, informational, humorous... And their production quality varies too, be it video, audio or presentation.

Example of a Let's Play video in its natural environment

Some creators of LPs ("LPers") earn money using YouTube's monetization features. When they do, YouTube's semi-automatic moderation process starts paying more attention to the videos' compliance with copyright.

Sometimes, LPers will contact game developers to receive permission to create LPs. To many creators of games, LPs are a welcome form of promotion and they will always say yes.

Clint Bellanger of FLARE released a Let's Play policy, which elegantly covers both the situation in which a game's art assets are CC-BY-SA 3.0 licensed and where all copyright belongs to one person.

FLARE is a collaborative effort of many artists who agreed to release their art under CC-BY-SA 3.0 and I think that FLARE's LP policy reflects the intention of the license very well.

A complicated case might be a game which contains art that is under the GPL, which could be interpreted in a way, that requires the resulting video, as well as video project files to be made available under GPL as well.

In theory, any LP could be considered "fair use". However, for-profit use and use of large portions of a work are often considered as not being "fair use" - for example by YouTube.

For game designers, I consider LPs to be a valuable resource, allowing to look up features or part-experience gameplay, where acquiring, installing and playing the game would be impossible, due to time restrictions.

I recommend looking up games that you have fond memories of or which you always wanted to try but the installation effort was too high on lparchive.org or just YouTube's search function with "let's play" in the query.

If YouTube's HTML5 doesn't work for you, youtube-dl will allow you to circumvent flash player issues (monetized YouTube videos appear to require flash).

How to Create a Sitemap or Table of Contents in Blogger

One of the limitations of a blog is that it doesn't have an index or sitemap of the site to make it easier for readers to find the content that they are searching for. While the blog archive and labels have all the information about the published post, these do not appear on a single page completely, so searching for more posts is not always easy.

Luckily, this gadget will help you to add a table of contents or sitemap on Blogger showing the index of all posts separated by categories that have been published. It will also show the latest posts with a text saying New!

table of contents, sitemap, blogger

Demo: You can see it in action by clicking here.

How To Add a Sitemap with a List of Posts to Blogger

To implement it on your blog, follow the steps below:

Step 1. Login to your Blogger Dashboard and select your blog

Step 2. Go to "Pages" > click the "New Page" button.

Step 3. Click on the HTML tab and paste the following code inside the empty box:
<style>
p.labels a{color: #242424; text-transform: uppercase;font-size: 15px;}
a.post-titles {color: #0000FF;}
ol li{list-style-type:decimal;line-height:25px;}
</style>
<script>
//<![CDATA[
var postTitle=new Array();var postUrl=new Array();var postPublished=new Array();var postDate=new Array();var postLabels=new Array();var postRecent=new Array();var sortBy="titleasc";var tocLoaded=false;var numChars=250;var postFilter="";var numberfeed=0;function bloggersitemap(a){function b(){if("entry" in a.feed){var d=a.feed.entry.length;numberfeed=d;ii=0;for(var h=0;h<d;h++){var n=a.feed.entry[h];var e=n.title.$t;var m=n.published.$t.substring(0,10);var j;for(var g=0;g<n.link.length;g++){if(n.link[g].rel=="alternate"){j=n.link[g].href;break}}var o="";for(var g=0;g<n.link.length;g++){if(n.link[g].rel=="enclosure"){o=n.link[g].href;break}}var c="";if("category" in n){for(var g=0;g<n.category.length;g++){c=n.category[g].term;var f=c.lastIndexOf(";");if(f!=-1){c=c.substring(0,f)}postLabels[ii]=c;postTitle[ii]=e;postDate[ii]=m;postUrl[ii]=j;postPublished[ii]=o;if(h<10){postRecent[ii]=true}else{postRecent[ii]=false}ii=ii+1}}}}}b();sortBy="titleasc";sortPosts(sortBy);sortlabel();tocLoaded=true;displayToc2();document.write('</br><div class="sitemap-link"><a href="http://helplogger.blogspot.com/2013/12/add-sitemap-table-of-contents-to-blogger.html" style="font-size: 10px; text-decoration:none; color: #5146CD;">Get This Widget</a></div>')}function filterPosts(a){scroll(0,0);postFilter=a;displayToc(postFilter)}function allPosts(){sortlabel();postFilter="";displayToc(postFilter)}function sortPosts(d){function c(e,g){var f=postTitle[e];postTitle[e]=postTitle[g];postTitle[g]=f;var f=postDate[e];postDate[e]=postDate[g];postDate[g]=f;var f=postUrl[e];postUrl[e]=postUrl[g];postUrl[g]=f;var f=postLabels[e];postLabels[e]=postLabels[g];postLabels[g]=f;var f=postPublished[e];postPublished[e]=postPublished[g];postPublished[g]=f;var f=postRecent[e];postRecent[e]=postRecent[g];postRecent[g]=f}for(var b=0;b<postTitle.length-1;b++){for(var a=b+1;a<postTitle.length;a++){if(d=="titleasc"){if(postTitle[b]>postTitle[a]){c(b,a)}}if(d=="titledesc"){if(postTitle[b]<postTitle[a]){c(b,a)}}if(d=="dateoldest"){if(postDate[b]>postDate[a]){c(b,a)}}if(d=="datenewest"){if(postDate[b]<postDate[a]){c(b,a)}}if(d=="orderlabel"){if(postLabels[b]>postLabels[a]){c(b,a)}}}}}function sortlabel(){sortBy="orderlabel";sortPosts(sortBy);var a=0;var b=0;while(b<postTitle.length){temp1=postLabels[b];firsti=a;do{a=a+1}while(postLabels[a]==temp1);b=a;sortPosts2(firsti,a);if(b>postTitle.length){break}}}function sortPosts2(d,c){function e(f,h){var g=postTitle[f];postTitle[f]=postTitle[h];postTitle[h]=g;var g=postDate[f];postDate[f]=postDate[h];postDate[h]=g;var g=postUrl[f];postUrl[f]=postUrl[h];postUrl[h]=g;var g=postLabels[f];postLabels[f]=postLabels[h];postLabels[h]=g;var g=postPublished[f];postPublished[f]=postPublished[h];postPublished[h]=g;var g=postRecent[f];postRecent[f]=postRecent[h];postRecent[h]=g}for(var b=d;b<c-1;b++){for(var a=b+1;a<c;a++){if(postTitle[b]>postTitle[a]){e(b,a)}}}}function displayToc(a){var l=0;var h="";var e="Post Title";var m="Click to sort by title";var d="Date";var k="Click to sort by date";var c="Category";var j="";if(sortBy=="titleasc"){m+=" (descending)";k+=" (newest first)"}if(sortBy=="titledesc"){m+=" (ascending)";k+=" (newest first)"}if(sortBy=="dateoldest"){m+=" (ascending)";k+=" (newest first)"}if(sortBy=="datenewest"){m+=" (ascending)";k+=" (oldest first)"}if(postFilter!=""){j="Click to view all"}h+="<table>";h+="<tr>";h+='<td class="header1">';h+='<a href="javascript:toggleTitleSort();" title="'+m+'">'+e+"</a>";h+="</td>";h+='<td class="header2">';h+='<a href="javascript:toggleDateSort();" title="'+k+'">'+d+"</a>";h+="</td>";h+='<td class="header3">';h+='<a href="javascript:allPosts();" title="'+j+'">'+c+"</a>";h+="</td>";h+='<td class="header4">';h+="Read all";h+="</td>";h+="</tr>";for(var g=0;g<postTitle.length;g++){if(a==""){h+='<tr><td class="entry1"><a href="'+postUrl[g]+'">'+postTitle[g]+'</a></td><td class="entry2">'+postDate[g]+'</td><td class="entry3">'+postLabels[g]+'</td><td class="entry4"><a href="'+postPublished[g]+'">Read</a></td></tr>';l++}else{z=postLabels[g].lastIndexOf(a);if(z!=-1){h+='<tr><td class="entry1"><a href="'+postUrl[g]+'">'+postTitle[g]+'</a></td><td class="entry2">'+postDate[g]+'</td><td class="entry3">'+postLabels[g]+'</td><td class="entry4"><a href="'+postPublished[g]+'">Read</a></td></tr>';l++}}}h+="</table>";if(l==postTitle.length){var f='<span class="toc-note">Show All '+postTitle.length+" Posts<br/></span>"}else{var f='<span class="toc-note">Show '+l+" posts by category '";f+=postFilter+"' the "+postTitle.length+" Total Posts<br/></span>"}var b=document.getElementById("toc");b.innerHTML=f+h}function displayToc2(){var a=0;var b=0;while(b<postTitle.length){temp1=postLabels[b];document.write("<p/>");document.write('<p class="labels"><a href="/search/label/'+temp1+'">'+temp1+"</a></p><ol>");firsti=a;do{document.write("<li>");document.write('<a class="post-titles" href="'+postUrl[a]+'">'+postTitle[a]+"</a>");if(postRecent[a]==true){document.write(' - <strong><span style="color: rgb(255, 0, 0);">New!</span></strong>')}document.write("</li>");a=a+1}while(postLabels[a]==temp1);b=a;document.write("</ol>");sortPosts2(firsti,a);if(b>postTitle.length){break}}}function toggleTitleSort(){if(sortBy=="titleasc"){sortBy="titledesc"}else{sortBy="titleasc"}sortPosts(sortBy);displayToc(postFilter)}function toggleDateSort(){if(sortBy=="datenewest"){sortBy="dateoldest"}else{sortBy="datenewest"}sortPosts(sortBy);displayToc(postFilter)}function showToc(){if(tocLoaded){displayToc(postFilter);var a=document.getElementById("toclink")}else{alert("Just wait... TOC is loading")}}function hideToc(){var a=document.getElementById("toc");a.innerHTML="";var b=document.getElementById("toclink");b.innerHTML='<a href="#" onclick="scroll(0,0); showToc(); Effect.toggle(\'toc-result\',\'blind\');">?? Display Table of Contents</a> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit5b9DVugDIpBexNhk43nR9zgf7tgjS_uHNnsTd1JC36tBA7tfyuuBYS0PpJSVaWPtq5GlTlcFbY4HuwW3E4NCJlJy6MoU7xxcGGNVykCpzdetA1egttiMPZb2Eq1yOm9dILNFjWcW8nSs/s1600/new_icon.gif"/>'}function looptemp2(){for(var a=0;a<numberfeed;a++){document.write("<br>");document.write('Post Link : <a href="'+postUrl[a]+'">'+postTitle[a]+"</a><br>");document.write('Read all : <a href="'+postPublished[a]+'">'+postTitle[a]+"</a><br>");document.write("<br>")}};
//]]>
</script>
<script src="http://helplogger.blogspot.com/feeds/posts/default?max-results=9999&amp;alt=json-in-script&amp;callback=bloggersitemap"></script>
After adding the above code, replace http://helplogger.blogspot.com with the address of your blog.

How to Customize the Sitemap for Blogger

  • to change the color and font size of categories title, replace the values in red
  • to change the color of the links, replace the value in green
Step 4. Click "Options" on the right side of the post editor and select "Don't allow, hide existing" for the Reader comments.

Step 5. Finally, click the "Publish" button and see the page. That's it!

The index of the posts is sorted alphabetically and is updated automatically each time a new post is published.

Thursday, 19 December 2013

Using JQuery + EasyDrag to Move Elements or Images by Clicking on Them

This is a simple and easy-to-use jQuery plugin which enables drag and drop functionality to make your site more interactive so that readers can "play" with certain elements on the page by dragging them from one side to another. For example, they can drag the images with a script to move them on any part of the blog just with a mouse click.


Drag and Drop Elements or Images on click with jQuery & EasyDrag

To see how this works, please visit the demo blog and click on any item, then move it anywhere on the screen:


Adding EasyDrag & jQuery to Move Elements or Images in Blogger

1. Login to your Blogger account, go to 'Template' and click the 'Edit HTML' button:


2. Click anywhere inside the template's code and press the CTRL + F keys to search for this tag:
</head>
3. Just before </head> paste the following scripts:
<script src='http://code.jquery.com/jquery-latest.js' type='text/javascript'/>
<script type='text/javascript'>
//<![CDATA[
(function($){var isMouseDown=false;var currentElement=null;var dropCallbacks={};var dragCallbacks={};var lastMouseX;var lastMouseY;var lastElemTop;var lastElemLeft;var dragStatus={};$.getMousePosition=function(e){var posx=0;var posy=0;if(!e)var e=window.event;if(e.pageX||e.pageY){posx=e.pageX;posy=e.pageY;}
else if(e.clientX||e.clientY){posx=e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;posy=e.clientY+document.body.scrollTop+document.documentElement.scrollTop;}
return{'x':posx,'y':posy};};$.updatePosition=function(e){var pos=$.getMousePosition(e);var spanX=(pos.x-lastMouseX);var spanY=(pos.y-lastMouseY);$(currentElement).css("top",(lastElemTop+spanY));$(currentElement).css("left",(lastElemLeft+spanX));};$(document).mousemove(function(e){if(isMouseDown&&dragStatus[currentElement.id]=='on'){$.updatePosition(e);if(dragCallbacks[currentElement.id]!=undefined){dragCallbacks[currentElement.id](e,currentElement);}
return false;}});$(document).mouseup(function(e){if(isMouseDown&&dragStatus[currentElement.id]=='on'){isMouseDown=false;if(dropCallbacks[currentElement.id]!=undefined){dropCallbacks[currentElement.id](e,currentElement);}
return false;}});$.fn.ondrag=function(callback){return this.each(function(){dragCallbacks[this.id]=callback;});};$.fn.ondrop=function(callback){return this.each(function(){dropCallbacks[this.id]=callback;});};$.fn.dragOff=function(){return this.each(function(){dragStatus[this.id]='off';});};$.fn.dragOn=function(){return this.each(function(){dragStatus[this.id]='on';});};$.fn.easydrag=function(allowBubbling){return this.each(function(){if(undefined==this.id||!this.id.length)this.id="easydrag"+(new Date().getTime());dragStatus[this.id]="on";$(this).css("cursor","move");$(this).mousedown(function(e){$(this).css("position","absolute");$(this).css("z-index","10000");isMouseDown=true;currentElement=this;var pos=$.getMousePosition(e);lastMouseX=pos.x;lastMouseY=pos.y;lastElemTop=this.offsetTop;lastElemLeft=this.offsetLeft;$.updatePosition(e);return allowBubbling?true:false;});});};})(jQuery);
//]]>
</script>
Note: If you already have jQuery, please remove the code in red.

4. Save the changes by clicking the 'Save template' button.

How to Move Elements or Images on Click Using EasyDrag & jQuery

Now, when you want to use EasyDrag to drag and drop an image, use the code below inside the HTML of your post or page (create a New post, then switch to the HTML tab):
<img id="easydrag1" src="image-URL" style="border: 0px none; cursor: move;" />
<script type="text/javascript">
$(function(){ $("#easydrag1").easydrag();});
</script>
Note: change the text in blue with the URL of your image and please note that each image has an unique id. Here, for example, the id is called easeydrag1 which has been added both in the HTML of the image and JavaScript function.

If you need to use EasyDrag to move a second element, then add your image with a different id, for example easydrag2, otherwise it won't work:
<img id="easydrag1" src="image-URL" style="border: 0px none; cursor: move;" />
<script type="text/javascript">
<img id="easydrag2" src="image-URL" style="border: 0px none; cursor: move;" />
<script type="text/javascript">
$(function(){ $("#easydrag1").easydrag();});
$(function(){ $("#easydrag2").easydrag();});
</script>

How to add a link to a draggable image?

We will add a JavaScript event, so that when we will double click on the image, to open the page we want.

The code to use should look something this:
<img id="easydrag1" style="cursor:move; border:0px;" ondblClick="javascript:window.open('link-URL')" src="image-URL" /><script type="text/javascript">
$(function(){ $("#easydrag1").easydrag();});
</script>
Using the script above, the image can be dragged around easily and be activated by double clicking on it.

Wednesday, 18 December 2013

Reminder: 1 week left to vote

Voting for the Linux Game Awards January 2014 will come to an end in about one week (24th of December).



So if you haven't voted yet, don't waste any time!
You can read more about the award in this older blog entry.

Tuesday, 17 December 2013

android intent example

In this post we are going to make an example that demonstrate the use of intent, intent filter and startActivity in android.
Create a new android application project in eclipse and name it as IntentDemo. I change the activity name as First_Activity and corresponding layout name as first_layout.
Ads by Google


Place a button on the first_layout.xml file as shown bellow.
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".First_Activity" >
<Button
android:id="@+id/bn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="51dp"
android:text="Go TO SECOND ACTIVITY" />
</RelativeLayout>

Now create a new Activity with class name  Second_Activity.java and layout name second_layout.xml.
Open the AndroidManifest.xml file and add the following code within the application tag.

 <activity  
android:name=".Second_Activity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="second_filter" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Create an object of the intent in First_Activity.java file and start the second activity using startActivity method.

                     Intent i = new Intent("second_filter");  
startActivity(i);

Finalized code for First_Activity.java is given bellow.

 package com.intentdemo;  
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class First_Activity extends Activity {
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
button = (Button)findViewById(R.id.bn);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent("second_filter");
startActivity(i);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.first_, menu);
return true;
}
}

Code for Second_Activity.java
 package com.intentdemo;  
import android.app.Activity;
import android.os.Bundle;
public class Second_Activity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
}
}