Wednesday, March 16, 2011

A Complete JQuery Sample

Hey...


So far we have learned JQuery-Core, JQuery-DOM, JQuery-CSS-JavaScript and JQuery-Events-Effects. Here I am going to present a sample to take some features we have learned.

Plane Rider

Plane Rider is a game which uses jquery. Some obstacles will be generated frequently and player should pass them. every 20 levels a new plane will be awarded. and in up level the obstacle generation rate will increase. Player can speed up or down by handling the available gears(from 1 to 5).

Game Logic

The game logic takes these major steps:
  1. Scene Creation: First of all the game scene should be created. It contains a game table and some other extra information such as saved plane, level, gear and so on.
  2. Plane Creation: In plane creation function, first the old position of the plane should vanish.
  3. Keydown Event Handling: Here left, top, right and down arrow keys, Esc and F1 keys should be handled on onkeydown.
  4. Play Game: This method call itself every specified time based on selected gear until ending of game.
    1. Create Obstacle: The obstacle should be created in every obstacle delay time(It is a setting variable. Its default value is 10)
    2. Redraw the plane: To have more accurate result of accident.
    3. Play Obstacles: This method iterates the obstacle array. First I should omit old position of obstacle then create obstacle in its new place. If the new place passes the game table ends it should vanish.
    4. Check Game: The obstacle array is iterated and if any cell has both obstacle and plane, the accident occurs. If there are some saved planes the obstacle should vanish and a new plane will assign the game. If there is no saved plane, it will be game over time.

JQuery Tricks

1. System Setting Extension
Any applications have its own settings like width, height, rows and so on. But the user who use our api can change them. On the other hands the consumer can change the system defaults or even extend it. In my sample, I create a system default object including width, height, rows and so on. I also add a new functions to jquery functions(the planeRider). So every jquery object of page elements have this function. This method take a setting object. This passed setting object has higher priority than system defaults. the code is available here.
    $.planeRider = {
        defaults:{
            width:600,
            height:200,
            rows:20,
            cols:60,
            delayObstacle:10,
            gears:[100,80,40,20,10],
            container:null
        }};

    $.fn.extend({
        planeRider: function(settings) {
            settings = $.extend({}, $.planeRider.defaults, settings);            settings.container = this;
            this.attr({align:'center'});
            startPlaneRider(settings);
        }
    });

2. Objective Java Script
In javascript any methods can be both function and class. If you want to create private methods for your class, you can create a function in the major function. If you want to have a public function you can create it by this object. Notice to this sample:
function testClass(){
  function privateFunction(){
  }
  this.publicFunction = function(){
  }
}
You can new an object instance of testClass and then call its publicFunction method like this.
var tc = new testClass();
tc.publicFunction();
In my sample I do all game functionalities in startPlaneRider class. It has a lot of inner functions. In planeRider method of jquery I just call this class.
$.fn.extend({
planeRider: function(settings) {
settings = $.extend({}, $.planeRider.defaults, settings);
settings.container = this;
this.attr({align:'center'});
startPlaneRider(settings);}
});
function startPlaneRider(settings) {
var gameCells = new Array();
var obstacleRep = new Array();
var playTime = settings.delayObstacle - 1;
var level = 1;
var obstacleCount = 0;
var currentRow = settings.rows / 2;
var lastCurrentRow = settings.rows / 2;
var currentGear = 0;
var savedPlane = 2;
var endGame = false;
var plane = $("<img></img>").attr({src:"images/Rocket-08-june.gif"}).css({position:"absolute"}).appendTo(settings.container);
createScene();
drawPlane();
$(document).keydown(function(event) {
...});
playGame();
function createScene() {
...}
...}

3. Crate HTML Elements And Setting Their Attributes
As we have learned, I create HTML elements dynamically and set their attributes using jquery API as easy as possible. Take a look to createScene sample:
function createScene() {
            var gameTable = $("<table></table");
            for (var i = 0; i < settings.rows; i++) {
                gameCells.push(new Array());
                var tr = $("<tr></tr>");
                for (var j = 0; j < settings.cols; j++) {
                    var td = $("<td></td>").css({'background-repeat':'no-repeat'}).attr({isPlane:false, isObstacle:false});                    td.appendTo(tr);                    gameCells[i].push(td);                }
                tr.appendTo(gameTable);            }
            gameTable.attr({'cellpadding':0, 'cellspacing':0}).css({width:settings.width, height:settings.height, 'border-width':'1px', 'border-style':'solid'});            gameTable.appendTo(settings.container);            $("<table></table>").css({width:settings.width}).append($("<tr></tr>").append($("<td></td>").append($("<div id='gearDiv'></div>").html("Gear:" + (currentGear + 1)))).append($("<td></td>").append($("<div id='levelDiv'></div>").html("Level:1"))).append($("<td></td>").append($("<table></table>").append($("<tr></tr>").append($("<td></td>").append($("<img></img>").attr({src:'images/jimbo.gif'}))).append($("<td></td>").append($("<span id='savedPlaneDiv'></span>").html("2")))))).append($("<td></td>").append($("<div id='helpDiv'></div>").html("Press F1 to help you...")))).appendTo(settings.container);}
All red lines are jquery API.

4. Position of an element
I set some extra attributes for any cells of the game table: isObstacle and isPlane. In the game scenario I will play these attributes and realize if a cell has obstacle or plain. I use a plane image on the cells which are plane cells. So I should find the position of the plane cells and move plane image to their top and left. JQuery has a very useful API for that. See this:
        function drawPlane() {
            clearPlane();
            for(var i = 13; i >=4; i--){
                gameCells[currentRow][i].attr({isPlane:true});
            }
            for(var i = 10; i >=4; i--){
                gameCells[currentRow - 1][i].attr({isPlane:true});
            }
            for(var i = 13; i >=4; i--){
                gameCells[currentRow + 1][i].attr({isPlane:true});
            }
            for(var i = 6; i >=4; i--){
                gameCells[currentRow + 2][i].attr({isPlane:true});
            }
            var pos = gameCells[currentRow - 1][0].offset();
            plane.css({top:pos.top, left:pos.left});

        }
I use the top left corner cell of the plane and find its position then move the plane image.

5. Animation and Effect
When Game Over take place a faded window including the "Game Over" text should be shown. It should the fade opacity should increase incrementally. JQuery has a very simple and useful API for that. Take a look this:
        function checkGame() {
            for (var i = 0; i < obstacleRep.length; i++) {
                if (gameCells[obstacleRep[i].row][obstacleRep[i].col].attr("isPlane").toString() == "true" && gameCells[obstacleRep[i].row][obstacleRep[i].col].attr("isObstacle").toString() == "true") {
                    if (savedPlane > 0) {
                        alert("accident...");
                        deleteObstacle(obstacleRep[i]);
                        i--;
                        savedPlane --;
                        $("#savedPlaneDiv").html(savedPlane);
                    } else {
                        endGame = true;
                        $("<div></div>").hide().append($("<div></div>").html("Game Over").

css({top:"50%", left:"50%", position:"absolute", padding:3, 'background-color':'#fff', border:'1px solid #ccc', color:'#f00'})).
css({position:"absolute", width:"100%", height:"100%", top:0, left:0, "background-color":"gray"}).
appendTo(settings.container).fadeTo("slow", 0.8);                        return false;
                    }
                }
            }
            return true;
        }
I do this just by fadeTo function. You can read this method and other similar methods specifications in my previous post.


I think its the time to download the sample and take tour in it yourselves. again I retell that all those jquery methods which I used in this sample and other extra jquery methods have been explained in my previous posts. Please refer to them to catch jquery concepts more.


By the way happy norooz to all persian ones...
Have nice days in your HOLIDAY...



all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

No comments: