LibGDX and google-mobile-ads Robopods integration (iOS)

I just started porting my existing android game (word-hunter) to iOS and ran into a lot of troubles trying to make adMob works on iOS with libgdx and robovm, so I figure someone else might need this :)

You should probably already have an Interface in your libgdx core project to specify the actions correspond to the display of ads:

public interface AdsDisplayInterface{
   public void loadAd();
   public void showAd();
}

And your game constructor should expect an implementation of this interface as argument:

public class Game implements ApplicationListener {
   ...
   public AdsDisplayInterface _adsDisplay;

   public Game(AdsDisplayInterface adsDisplay){
      _adsDisplay = adsDisplay;
   }

   public Game(){
      ...
   }

   @Override
      public void create() {
      ...
   }
}

Now you can call _adsDisplay.loadAd() and _adsDisplay.showAd() anytime you want in your game, see this post for more details on how this works.

Now we want to create a class implementing this Interface in the platform where we want to display ads, in our case: iOS.

First we need to integrate the google-mobile-ads robopod binding (git repo).

Follow the instructions from the README in the git website and use either graddle or maven to add the binding.

I added compile “org.robovm:robopods-google-mobile-ads-ios:$roboVMVersion” in the dependencies of the project(“:ios”) in the main build.gradle of my libgdx projects, used ./gradlew eclipse and then imported the projects into Eclipse.

Another option if you don’t want to use graddle or maven is to directly grab the jar files you need (robopods-google-mobile-ads-ios-$robovmVersion.jar and robopods-google-apis-ios$robovmVersion.jar) from the robovm maven directory and add then to your ios project /lib folder (create it if necessary) and add both jar to the build bath.

Now we need to create an implementation of the AdsDisplayInterface in our ios project:

@CustomClass("ViewController")
public class ViewController implements AdsDisplayInterface {
 private GADInterstitial interstitial;

 private GADInterstitial createAndLoadInterstitial() {
     //Ad Unit ID of your interstital, from your adMob account. Use the TEST one for now
     GADInterstitial interstitial = new GADInterstitial("ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");
     interstitial.setDelegate(new GADInterstitialDelegateAdapter() {
         @Override
         public void didDismissScreen(GADInterstitial ad) {
             ViewController.this.interstitial = createAndLoadInterstitial();
         }
     });
     interstitial.loadRequest(createRequest());
     return interstitial;
 }

 private GADRequest createRequest() {
     GADRequest request = new GADRequest();
     // To test on your devices, add their UDIDs here:
     request.setTestDevices(Arrays.asList(GADRequest.getSimulatorID()));
     return request;
 }

 @Override
 public void loadAds() {
     interstitial = createAndLoadInterstitial();
 }

 @Override
 public void showAds() {
     if (interstitial.isReady()) {
         interstitial.present(UIApplication.getSharedApplication().getKeyWindow().getRootViewController());
     } else {
         System.out.println("Interstitial not ready!");
     }
 }

}

I used this sample application and modified a couple of things to make it work with libgdx. If you need to add banners, check the sample and it should be quite straightforward.

Now we need to modify our IOSLauncher in the libgdx IOS application:

public class IOSLauncher extends IOSApplication.Delegate {

 private GADInterstitial interstitial;

 @Override
 protected IOSApplication createApplication() {
     Words.setPlatformResolver(new DesktopResolver());

     IOSApplicationConfiguration config = new IOSApplicationConfiguration();
     return new IOSApplication(new Game(new ViewController()), config);
 }

 public static void main(String[] argv) {
     NSAutoreleasePool pool = new NSAutoreleasePool();
     UIApplication.main(argv, null, IOSLauncher.class);
     pool.close();
 }

And now it should work :) Your IOS ad will show up whenever you call loadAd() then showAd() in your game.

Hopefully I didn’t forget any steps, otherwise let me know !

LibGDX and Google Play Game Service Integration

I have been hard working on Google Play Game integration in my upcoming game : Word Hunter and I am posting my finding heres. Hopefully it can help someone else :)

Configuring Google Play Game

Log on to the developer console (if you don’t already have an account, you will need to create one for 25$)

Select “Game Services” and follow the instructions to create a new game.

Some notes :

    • Use the debug certificate in your android sdk install folder
      • You will be able to test Google Play Game integration directly when you launch your application from Eclipse without having to sign it with your production certificate
      • But you will have to restart the process all over again once you want to push it to production (…)
    • Use your production certificate that you use to publish your application to google play
      • You will need to sign your APK using your production certificate (right click on your project -> Export as Android Application) and then install this APK on your device to test it
      • And you are done, you can simply publish the game when you are done and it will work

I went with solution #2 since I am publishing my game in Alpha state in Google play and I want my testers to be able to use it

  • DO NOT forget to add your testers email in the list of testers for the GAME, it is a different list than the application testers or even the Alpha testers
  • Do not bother trying to test Google Play Game with your developer account, even if it is marked as a tester, it just doesn’t work. Use another account.

Once you are done, you should get an application ID associated to your game, follow this documentation to make it available in your game (short version, create an ids.xml file in the android res/values folder and add this id in it as a string with name app_id). This is also where you will put the key for your leaderboards/achievements. You will also need to modify your manifest as indicated in the documentation.

Configuring the libGDX Core project

In your Core project, create an interface with all the actions that you want to be able to do from your game. The basis are :

  • Logon
  • Logoff
  • Send a score to the leaderboard
  • Unlock an achievement
  • Show the Score Leaderboard
  • Show the Achievements Screen

Pastebin code

Configuring the Android project

Once this is done, we need to do several things:

First follow the instructions to download the sample apps from here .

You should get the google-play-services-lib when you install the google play service SDK. Add it to your workspace and add it to your Android project as a library (right click on your android projects -> Properties)

From the BaseGameUtils projects, copy the GameHelper.java class directly into your Android project.

Now we will modify the Android project MainActivity class.

First it needs to implement the previously created interface, as well as the GameHelper.GameHelperListener interface (from the GameHelper class we just copied) :

public class MainActivity extends AndroidApplication implements LeaderboardInterface, GameHelper.GameHelperListener

In this class, we will need to instantiate a GameHelper and implement the different methods specified in the Interface. Most of this code was inspired/copied from the BaseGameActivity available in the sample Android project.
Once this is done, we need to pass the MainActivity itself as an argument of the initialize method.

Here is the code

Possible improvements :

  • Show a toast when the unlockAchievement method is called by user is not logged in google play
  • Push scores and achievements right after login, in the onSignInSucceeded method

I noticed that by using this method, the Title Bar now appears in game. To solve this issue, simply add the following theme to your main activity in the manifest :

android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

How to use it in game

In your main class in the core libGDX project (the one which implements ApplicationListener), create a variable of type GameServiceInterface and set it using the arguments passed in the constructor :

public class Game implements ApplicationListener {

public GameServiceInterface _leaderboard;

public Game(GameServiceInterface leaderboard){

         this._leaderboard = leaderboard;

}

And now you can just call/bind _leaderboard.login() or any other method of the GameServiceInterface anytime in your game.

LibGDX and RevMob integration

I figured I would do a small tutorial on this subject since I had to implement it recently on my current project.

I want to display Full Screen RevMob ad in my Android game in between two levels. Displaying banner ads is slightly different and won’t be covered here.

Setup and configure RevMob

  1. First, grab the RevMob SDK from their website, for this tutorial, I will pick Android as the target platform. (You can also check the configuration step from their website for the most up to date instructions)
  2. Copy the revmob-n.n.n.jar in your android project libs’s folder and add it to your build path (in Eclipse, right click on the jar -> Add to build path)
  3. Modify your project’s manifest, add the following permissions
    • <uses-permission android:name="android.permission.INTERNET"/>
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    • <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    • <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> (This one is optional but recommended)
  4. Add the following activity to your manifest (supposing you want to use full screen ads in your application)
    • <activity android:name=”com.revmob.ads.fullscreen.FullscreenActivity” android:configChanges=”keyboardHidden|orientation”> </activity>
  5. Also don’t forget to create your application in the RevMob console and grab your application ID

Configure LibGDX projects

Next you want to configure your LibGDX projects. Let’s suppose your game is multiplatform and you have an Android, Web, Desktop. You want to display RevMob ads only in your Android game and use another ads platform for Web/Desktop (since RevMob is mobile only) or maybe your desktop version won’t be displaying any ads anyway.

First let’s create an Interface in your main project to specify the actions correspond to the display of ads.

public interface AdsDisplayInterface{
   public void showFullScreenAds();
   public void openAdsLink();
}

This interface correspond to the different actions you might want to do in your game (for example show a full screen ads between two levels, or open the affiliate link when the “More Applications” button is clicked…)

Now you want to create a class implementing this Interface in the platforms where you want to display ads

In the Android project, we will create the following class

public class RevMobDisplay implements AdsDisplayInterface {
   private static final String REVMOB_APP_ID = &quot;copy your RevMob App ID here&quot;;
   private MainActivity activity;
   private RevMob revmob;

   public RevMobDisplay(MainActivity mainActivity){
      this.activity = mainActivity;
      revmob = RevMob.start(mainActivity, REVMOB_APP_ID);
   }
   @Override
   public void showFullScreenAds(){
      revmob.showFullscreen(activity);
   }

   @Override
   public void openAdsLink(){
      revmob.openAdLink(activity, listener);
   }
}

Now, in the main Android class, create an instance of this class and pass it as an argument to the Game constructor:

public class MainActivity extends AndroidApplication {
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

      initialize(new Game(new RevMobDisplay(this)), cfg);
   }
}

Eclipse should warn you that there is an error with this modified code because the Game constructor does not expect this argument.So we will create a new constructor that expects this argument in your main project’s Game class (this is the Class that implements ApplicationListener)

public class Game implements ApplicationListener {
   ...
   public AdsDisplayInterface _adsDisplay;

   public Game(AdsDisplayInterface adsDisplay){
      _adsDisplay = adsDisplay;
   }

   public Game(){
      ...
   }

   @Override
      public void create() {
      ...
   }
}

Displaying Ads

Now, whenever you want to display a fullscreen ad, you can simply do the following:

if (_adsDisplay!=null){
   _adsDisplay.showFullScreenAds();
}

Remember we only created this class for the Android application, so if we tried to display ads from another platform, it would crash with a null pointer exception, so we check if it is null beforehand.

There you go, let me know if you have any questions in comments.

Playskool, my first Game ! – Part 1

As you might know from my previous post, or if you are following me on twitter (Shameless plug : ). I am currently working on my first Android Game!

As I have learned from my previous Android Application (a Time’s Up application). It takes a lot of time to develop and finish an application. You HAVE to cut features if you ever want to release a first version, so I was aiming pretty low (as it turns out I wasn’t aiming low enough yet!)

Inspirations:

Ikaruga

Ikaruga – First level

Younger, I once had the opportunity to play Ikaruga at one of my friends place, lucky owner of a Dreamcast at the time :) Unfortunately, I couldn’t last more than 30 or so second before dying so I didn’t stuck with the game, but the game stuck with me, or rather the principle of changing colors to beat enemies. So years later, I set out to do a game around this concept.

I also have some nice ideas about limited visibility in game (fog of war like, with light and shadows). You wouldn’t be able to see too far off and enemy behavior would change based on the fact that they were within the field of vision or not.

Constraints/Challenges:

  • It is my first “real” game. Years ago, I followed a tutorial to create a platformer game in html5, nothing really came out of it, but it was a great learning experience and helped me get around the concept of frame rates and many game effects such as parallax scrolling or sprite sheets.
  • First time I would use OpenGL, I looked around a bit for various engines/libs, I wanted to stick with Java since it’s a language I already know and also wanted to target mobiles (Android, IOS) since it would easily solve the packaging/distributions issues. I decided to pick libgdx, which brings me to my next point.
  • First time using libgdx
  • One man team, no visual designers, no artist, no ability to create my own graphics (low level of Photoshop skills)
  • While I had a basic concept (changing colors) I did not have a clear vision for the game, and I even had other ideas I wanted to implement, more or less (in)compatible with this concept.

Strengths:

  • Programming knowledge
  • Strong willingness to finish my game.
  • Very strong willingness to cut corners/features and not get distracted by unnecessary issues

Original plan

What I set up to do : A shoot em up style game (in space) but without any shooting ! The logic being the plan was that I needed to pick something very simple, and then make it even simpler. So removing the shooting would fit this needs:

  • Less sprite to display
  • Less effects
  • Less collision detection
  • Less everything :)

I would then try to implement features based on my inspirations stated above.

Hit the road Jack!

I first started by following the basic libgdx tutorial (here) then modified it to try to fit to my vision of the game. Fortunately, it turns out libgdx is quite easy to use and solves many of the problems I thought I would meet in openGL. I  but I soon hit a roadblock: Graphics, I couldn’t find images resources that would fit my theme (space, spaceships etc..) and my concepts. I had tons of ideas but couldn’t find the right art for them, and all my Photoshop attempts ended up in utter failure. For example I did find some images for a spaceships but couldn’t with my poor Photoshops skills, turn it into a good looking red/blue spaceship (if I had known about the hue/saturation option in Photoshop at the time, things might be different now >_<).

So I scoured the web for game resources that I could use freely and that would be adapted to my game, I decided to adapt the theme (spaceships) but kept the original concept (changing color/mode). For example I thought of replacing the spaceship by a boat (viking style) flowing through a river, and instead of changing colors, the boat would switch from a combat boat (to fight foes) to a fishing boat (to collect fishes ^^) by spinning on itself (the other boat mode would then be “underwater” whatever that means).

Unfortunately I couldn’t find suitable graphics for that either…

So I kept scouring, filling my file system with various resources that seemed useful, and looking for inspiration.

If anyone is interested, I used the following to find resources (among others):

I finally found something very simple (hint: it involves blocks) that would fit my needs so I based my games on that, and tried to find/make other graphics that would fit within that theme. I also ended up completely setting aside (for another game!) the light/shadow/visibility concept.

OpenGameArt

OpenGameArt – Browsing images

Embrace constraints : Constraints are good. Having too many options isn’t so, it spreads your attention between too many subjects. Limitations in one subject let you focus on another. Since I had no artists and no desire to spend too much time on arts, I spent some time looking for some graphics, letting it set the “theme” of my game, allowing me to focus on other aspects (concept, gameplay etc..). This is why one game month or game jams concepts are great, with great time constraints, it becomes absolutely necessary to cut graphics, features etc…allowing you to focus on other parts of your game.

Be adaptable : Cut corners/features when necessary, be willing to make concessions. Especially for a first game. I really liked my idea with the boat/river as the theme but once I saw that I couldn’t find any good resources and that I had no idea how I would do a good looking water (flowing effect, waves around the boat, boat entering/exiting water when spinning etc…) I changed to something much simpler for which I had available resources. Here is a great article on this subjects.

While in my case my specific problem had a lot to do about graphics, those principles can be applied in many more aspect of game design.

Just thoughts of a very cool game feature that would require you to rewrite most of your code ? Unless you are in the very early stages of your game and doing prototyping, put the idea on the side for another project and move on. Better yet, did you try to implement this feature through a little trick that would be much cheaper but yield similar results ? Something you would consider an ugly hack is actually a clever hack if it can make your game better and helps you finish it in time.

Part 2 available here !

Online Scoreboards services for Android

UPDATED : Updated with google play game informations.

I have been working for some time on my first Android game, which is basically an endless vertical scroller. I obviously have an offline scoreboard where you can see your best scores. But I also want to integrate an online scoreboard to promote some competition in my game.

Unfortunately, since I am not on IOS, I do not have any obvious solution for this issue (HINT : GameCenter !). With Google Play Game now available, I’d consider it the default “go to” solution on Android. My two options are basically : implement something myself and deal with all the hassle of handling authentication, hosting scores etc…or pick an existing solution. Since I am interested in making games and not online leaderboard systems, I went with the later option :)

There are many web services providing online scoreboards on android, many of them are free to use and also provide other useful services such as handling IAPs (In App Purchases), social integration (twitter, facebook) etc..

But it has been quite tedious to find the one best suited to my needs. There is no central hub of information, each platforms specificities are often accessible only after setting up an account… So I decided to try them out :)

Non exhaustive list of services available  :

  • Google Play Game
  • Scoreoid
  • Swarm
  • ScoreLoop
  • ScoreNinja

There might be others available but to my knowledge, those are the main ones for android and should cover most use cases, let me know if I missed any.

I shall do a more detailed analysis of some of those after I try them out further:

Google Play Game

This is the service provided by google with the following features

  • Online leaderboards
  • Achievements
  • Synchronous multiplayer (there is no easy solution for asynchronous multiplayer, which is a shame)
  • Cloud saving

Pros :

  • Free
  • Cross platform (Android, IOS, Web)
  • You can customize your user experience or use the default UI

Cons :

  • Set up is not really simple but examples are available (you can see my tutorial here)
  • Integrated with google+, doesn’t work if your users are not google+ users (this can be considered a pro)
  • SDK must be included in your app

Scoreoid

Scoreoid is a web service that currently provide the following gaming features:

  1. Online leaderboards
  2. In game notifications.

It doesn’t require a SDK to include in your game and use the standard REST HTTP(s) protocol to handle all features

Pros :

  • Currently free with pro accounts in the working (with prices and quotas that SEEMS reasonable)
  • Truly cross platform (Desktop, mobile etc..)
  • Doesn’t require a SDK, which means one less library to include in your project
  • You can customize your user experience and user interface to truly meet your needs, since you implement everything yourself, using only the rest API to communicate to the servers

Cons :

  • The biggest strenght of Scoreoid is also its biggest weakness, since it doesn’t provide a SDK, you will have to implement all the screens/user Interface/services in your application yourself. Even for the simplest features (but many examples are available).

ScoreLoop

SDK based service that provide the following features :

  • Online leaderboards
  • Achievements system
  • Challenges (ability to sent a notification to one of your friend to challenge him to a game)
  • In app purchases
  • Social features
  • Cloud storage (save game progress to the cloud and access it from another device)

Pros :

  • Free (they take a cut of IAPs that goes through their service and user can buy “coins” to challenge each others). You are still free to use google in app purchase API without going through ScoreLoop if you want to.
  • Support multiple platforms: BlackBerry, IOS, Windows Phone, Android
  • UDPATED : It creates a default user for you if you have never used their service before, low entry barrier for new users (the “only” thing they have to do is accept the TOS)
  • Very extensive feature list

Cons :

  • Set up is not as simple as I would have hoped but examples are available
  • Online dashboard to handle Scoreloop feature and configure your application is quite overwhelming at first, and seems to be quite complex.
  • UPDATED : Customized leaderboard is not simple at all if you want to have modes, levels … Documentation on this subject is sub par.
  • SDK must be included in your app (~500kb for Android)

ScoreNinja

ULTRA LIGHTWEIGHT android only online leaderboard system, it has no other feature, doesn’t require registration, the whole website is only one page with straightforward documentation and form to get your application’s key.

Pros :

  • Ultra lightweight, nothing to configure, the SDK takes 8kb
  • It literally takes no more than 5 minutes to set up
  • Handles game mode/difficulty levels

Cons :

  • Android only
  • Obviously limited in functionality
  • Only first ten scores are shown in boards and your position relative to them

Swarm

SDK based service that provide the following features :

  1. Online leaderboards
  2. Achievements system
  3. In app purchases
  4. Social features
  5. Cloud storage (save game progress to the cloud and access it from another device)

Seems quite similar to Scoreloop, minus cross platform support and challenges, seems easier to set up.

Pros :

  • Free (they take a cut of IAPs)
  • Extensive feature list

Cons :

  • Android only
  • SDK must be included in your app

As for myself and my game :

  • I tried Scoreoid but after setting up my score page (good example here) I figured it to be too much work to implement myself, I am rather looking for a quick solution. Should be useful for anyone who wants to have as much control as possible over their user experience and for any game that’s going to be released on both desktop and mobile.
  • I am now trying Scoreloop, setting it up is not so easy but the examples helps.
  • I have looked at the Swarm Documentation and it seems much more straightforward than Scoreloop so I might try that next.
  • ScoreNinja seems really good but I’d like to be able to extend my app to use more features later. It might be more suited to One Game Month challenges or game jams.

So which services are you using and why ?

Cool Jquery stuff for beginners part 2

I’ve started playing around with Jquery while working on a personal project, and it’s actually very easy. I’ve stumbled upon some nice stuff that I have decided to share with everyone.

I will do this in several part, one post per coding “trick”.

If you are learning Jquery, you can use those examples to see what can be done and get you started.

All the examples should work if you just copy/paste them in a html page, if additional extensions are required, download them and put them in the same directory as your html page.

Make stuff appear and dissapear !

This is a little script that will let you make part of your html page visible – when your mouse goes over certain areas (this event is called “hover”) – and hidden – when your mouse leave that area

Required :

<html>
<head>
<script type="text/javascript"
	src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	//function called when the mouse goes over an <img>
    $("img").hover(function(event){
        //Here I query the id attribute of the image your are hovering
        //so that I can use it to distinguish which image is active
    	var clicked = $(this).attr("id");
    	//Change the visibility and position of the html element
    	//with id "text$theIdOfTheActiveImage" example : text0
    	$("#text"+clicked).css({"visibility":"visible", "position":"absolute", "top":"35px","left":"300px"});
    }, function(event){ //mouse leave the image
    	var clicked = $(this).attr("id");
    	//make the text invisible again
    	$("#text"+clicked).css({"visibility":"hidden"});
        }
    );
});
</script>
</head>
<body>
<img id="0"
	src="https://upandcrawling.files.wordpress.com/2010/06/img_32831.jpg"
	style="width: 100px; height: 100px;" />
<img id="1"
	src="https://upandcrawling.files.wordpress.com/2010/06/img_3287.jpg"
	style="width: 100px; height: 100px;" />
<p id="text0" style="visibility: hidden;">This is a picture of the moon!</p>
<p id="text1" style="visibility: hidden;">This is a picture of the sky !</p>
</body>
</html>

Notice that I have assigned an id to each image to distinguish them from each other, this id also appears in the id attribute of the <p> that I want to associate with the image, and I use it to make the chosen text visible.

The attributes that I change (visibility and position) are CSS parameters,  you can customize this script to change the image color, text size, font  and much more…

Go ahead and have some fun !

Have any tricks you want to share with us ? Mail me or post a comment !

This is part 2 of my “Cool Jquery stuff for beginners” series.

Here is part 1

Cool Jquery stuff for beginners part 1

I’ve started playing around with Jquery while working on a personal project, and it’s actually very easy. I’ve stumbled upon some nice stuff that I have decided to share with everyone.

I will do this in several part, one post per coding “trick”.

If you are learning Jquery, you can use those examples to see what can be done and get you started.

All the examples should work if you just copy/paste them in a html page, if additional extensions are required, download them and put them in the same directory as your html page.

Zoom on images with your mouse wheel

Required :

Here is the code

&lt;html&gt;
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot;
	src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;jquery.mousewheel.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function(){
	//Function called when a mousewheel event happen on the selected area (html here)
	$(&quot;html&quot;).mousewheel(function(event, delta) {
		if (delta &gt; 0) { //Scroll up
			$(&quot;img&quot;).css( { //increase the width and height of all img in the area
				&quot;width&quot; : function(index, value) {
					return parseFloat(value) + 10;
				},
				&quot;height&quot; : function(index, value) {
					return parseFloat(value) + 10;
				}
			});
		} else if (delta &lt; 0) { //Scroll Down
			$(&quot;img&quot;).css( { //decrease the width and height of all img in the area
				&quot;width&quot; : function(index, value) {
					return parseFloat(value) - 10;
				},
				&quot;height&quot; : function(index, value) {
					return parseFloat(value) - 10;
				}
			});
		}
		return false;//cancel the default scroll action on the selected area (html here)
	});
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;img src=&quot;http://www.wordpress-fr.net/wp-content/uploads/2008/08/netmn-planet.png&quot; style=&quot;width: 100px; height:100px;&quot;/&gt;
&lt;/body&gt;
&lt;/html&gt;


Possible improvement as an exercise : If you have tried the script, you will have realized that there is no limit at how much you can zoom in or out. Go ahead and try to add a limit to the zoom, you can also change the zoom “speed” (more zoom per scroll).

Go ahead and have some fun !

Have any tricks you want to share with us ? Mail me or post a comment ! Or follow me on twitter !

This is part 1 of my “Cool Jquery stuff for beginners” series.

You can find part 2 here