Passa al contingut principal

How to create a game using jQuery

How to create a game using jQuery

How to create a game using jQuery



Today we are making a simple puzzle game called “Fifteen”. The purpose of the game is to slide 15 square blocks around to form an image. The goal of this tutorial is to look at this simple browser-based game and explain how it was made line by line. It’s a great way to learn jQuery. For this tutorial, We will use a 2D image square-sliding game I created last week and I will go over each line of code to demonstrate the train of thought. I really do believe that breaking this game up into explanations on per-line basis will help you understand how to use jQuery in your own projects.


Live Demo

download in package



Creating a Game as a jQuery Plugin


A jQuery plugin is a perfect way to create image slideshows, custom user interface controls and of course browser-based games. We won’t just write JavaScript code here, we will create a jQuery plugin.


A plugin is nothing more than our own custom jQuery method. You know how we have jQuery’s methods .css() and .animate()? Well, jQuery gives us the ability to extend its own functionality with custom methods that we create ourselves. Like the existing jQuery methods, we can apply the method we will create to a jQuery selector.[1]


Well, the game is called Fifteen, and we want to make our game “embeddable” inside an arbitrary HTML element like <div id="game_object">here</div> so we can move it around anywhere on the page (Different sites have different layouts, wouldn’t you like to have the ability to embed your jQuery game/plugin into an arbitrary DIV element on any site?)


Let’s get started with the jQuery code.


We will actually create our own jQuery method and call it .fifteen(). Therefore, in order to launch the game inside an HTML element with id “#game_object” we will call this command:



$("#game_object").fifteen(175);

This will create and attach the game board to the div whose id is “game_object.” Also, each square will become 175 by 175 pixels in width and height based on the only passed parameter.


In this tutorial I used the image of a kitty. You can replace it with any image you want.


Executing a custom method as shown in the code above will pass the selector string “#game_object” to our plugin function which grabs the DIV. Inside our custom method, we can refer to that selector/element using the this keyword. And we can also enable jQuery methods on it by passing it to the new jQuery object like so: $(this); — inside the extended function we will create.


In order to create our own jQuery plugin we will use the $.fn.extend method.


We can also refer to this as extending functionality of the jQuery library with our own methods. Let’s take a look:



$.fn.extend({
fifteen: function (square_size) {
// Game code goes here...

// Example -- set the width of all DIVs to what was passed as square_size
$("div").css({width: square_size});

// The basics of the inner-workings of a plugin:
var a = this; // refers to the passed selector,
// eg: $("#game_object")
var b = $(this); // same thing, but with jQuery methods enabled

// Let's do something with the HTML element passed as the CSS selector
this.style.color = "red"; // paint all text inside "#game_object" red
$(this).css("color", "red"); // same exact thing, using jQuery method .css()
}
});

That’s it! This is the basic structure of any jQuery plugin.


The code examples I use above are just examples that show how the basics work internally. But we will write an entire game within the scope of the function we called “fifteen”.


Within the scope of the plugin the this object refers to what was passed in the selector. Also, the square_size parameter is just a custom, arbitrary parameter passed to our game.


We decide what the parameters should be, and if your game or plugin require more, simply define more parameters, as in:


$.fn.extend( { fifteen: function(square_size, param2, param3, etc) { /*.. game code…*/ } } );


Within the scope of your plugin you refer to parameters by the very same names.


In my case square_size is the only parameter. It defines the arbitrary size of the square in the game. I use 175 (as in 175 pixels in width and height). The grid is 16 by 16, but there are only 15 movable squares, because one is always empty. However, we still create all 16 DIVs, and just make one white. We do this in order to simulate the shadow effect on an empty square.


Before we get into the code, let’s take a look at the game’s construction as far as HTML goes. You will notice that there are 16 squares and each square is a separate DIV element:


game fifteen


The point of the game is to shuffle the image, one square at a time (by shifting it into the empty square, thus swapping locations) until the image is complete.


The white square is always empty. You are only allowed to shift squares that can physically be shifted into the empty spot, as if on a physical game board. This means only squares to the north, south, west and east of the empty square can be shifted. This test is performed within the stand-alone function I wrote and called Move() – it is separate from the plugin itself, it’s like a helper function.


Before I show you the code, I want to briefly talk about some common problems we will face while designing a plugin-based game.


1. Embedding the Plugin Into Arbitrary DIVs (or other HTML elements)


Remember that when writing your plug-in it is wise to inject the HTML elements which are created as part of the game… into a parent DIV. The purpose of this is that your plug-in becomes embeddable into any arbitrary HTML element. Different websites have different layouts. So it’s important for our plug-in to be flexible. That it could be embedded into an arbitrary HTML element anywhere on the page. In this example I called that element:



<div id="game_object"></div>

Moving around this element will physically move the game around anywhere on the page.


2. Injecting HTML into Empty Elements Using the .append(html) Method


We leave <div id="game_object"></div> unpopulated with any game HTML. Why’s that? This is because the plugin itself will generate game’s HTML elements and insert them into the target DIV. No need to pre-type them “by hand.”


This is smart, because it keeps the parent element clean. But also, this example in particular allows us to explore the jQuery’s native .append(html) method. It literally appends new HTML at the end of a specified element. That is, you never even have to write HTML into the document itself, the .append() method injects HTML into the web page dynamically, you just specify the target element using a selector like:



$('#board').append("<div></div>"); // Add one div to the end of #board

3. Using :nth-child(index) Instead of IDs or Classes


I think it’s worth mentioning that we can refer to DIVs inside, say, a parent DIV as children. This is really helpful. For example, let’s say we have 16 DIVs (children) stored inside one parent DIV:



<div id="board"> <!-- This is called a "parent" element //-->
<div></div>
<div></div>
<div></div>
<!-- ... ok, imagine 16 DIVs here. These are the "children" of "#board" //-->
<div></div>
<div></div>
</div>

You don’t really need to assign 16 IDs to all 16 DIVs! jQuery takes care of that for us. For example, to refer to the 3rd DIV inside a parent DIV (in our game it’s #board,) instead, we can do something like this without ever assigning any classes or ids to any of the children:



// Hide 3rd DIV in the list of children. No need to assign an id to each one!
$('#board').children('div:nth-child(3)').hide();

Notice we used the .children() method to grab all children of a parent (DIVs inside parent,) and then we also specified that we need a 3rd child using the literal selector :nth-child(n) where n is the index of the DIV we need. Note, however that this index doesn’t start with 0 like JavaScript arrays. It starts with index of 1. :nth-child(0) will not select anything.


Well, I think we are ready to start writing the code. Let’s get to it.


Step 1. HTML


First, let’s prepare HTML markup for our game:



<!-- add styles -->
<link href="css/main.css" rel="stylesheet" type="text/css" />

<!-- add scripts -->
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="js/main.js"></script>

<!-- This is where the game will be injected -->
<div id="game_object"></div>

Step 2. CSS


There are a few styles for our game:


css/main.css



#game_object {
background-color: #ffffff;
height: 705px;
margin: 20px auto;
position: relative;
width: 705px;
}
#board div {
background: url("../images/cat_face.jpg") no-repeat scroll 0 0 #ffffff;
cursor: pointer;
height: 175px;
line-height: 175px;
position: absolute;
text-align: center;
width: 175px;

/* css3 shadow */
-moz-box-shadow: inset 0 0 20px #555555;
-webkit-box-shadow: inset 0 0 20px #555555;
-ms-box-shadow: inset 0 0 20px #555555;
-o-box-shadow: inset 0 0 20px #555555;
box-shadow: inset 0 0 20px #555555;
}

Step 3. JS


Now, the most interesting step – the game code (as jQuery plugin):


js/main.js



// This is a JavaScript event. It means - once DOM is finished loading,
// execute everything inside the callback function scope
// This is where we initialize the game
$(document).ready(function() {
// Initialize the game and create the plugin

// When the squares swap places, the moving square must always appear on top
var zi = 1; // We increment z-index each time a square is shifted

// The index of the empty square by default, the 16th square
var EmptySquare = 16;

// Now, this is where we create the plugin and call it fifteen.

$.fn.extend({ fifteen:

function(square_size) {
// Grab the id of the HTML element into which we are placing the game,
// it is the selector - "#game_object" from $("#game_object").fifteen(175);
var gameObjectElement = '#' + $(this).attr('id');

var sqSize = square_size + 'px';
var boardSize = (square_size * 4) + 'px';

// Inject DIV into game_object, this is our game board
$(gameObjectElement).html('<div id="board"></div>');

$('#board').css({ position:'absolute', width: boardSize, height: boardSize, border: '1px solid gray' });

// Populate the game board's HTML container with 15 squares
for (var i = 0; i < 16; i++) {
// A dirty way to create an arbitrary DIV and append it into HTML dynamically
// Notice each square uses the same image. It just uses a different x/y offset for each square
$('#board').append("<div style='left: " + ((i % 4) * square_size) + "px; top: " + Math.floor(i / 4) * square_size + "px; width: " + square_size + "px; height: " + square_size + "px; background-position: " + (-(i % 4) * square_size) + "px " + -Math.floor(i / 4) * square_size + "px '></div>");
}

// Empty up the 16th square, as the starting point
// EmptySquare = 16
$('#board').children("div:nth-child(" + EmptySquare + ")").css({backgroundImage: "", background: "#ffffff"});

// Attach click event to each square
$('#board').children('div').click(function() {
Move(this, square_size);
});
}
});

// Move() is the function that is called when a square is clicked
// Note that it is independent of the plugin itself which is described above
// It takes two parameters,
// 1. object handle to the square that was clicked, and
// 2. the width of the square
function Move(clicked_square, square_size) {
// We need to locate movable tiles based on where the empty spot is,
// We can only move the four surrounding squares
var movable = false;

// Swap x/y between the clicked square and the currently empty square
var oldx = $('#board').children("div:nth-child(" + EmptySquare + ")").css('left');
var oldy = $('#board').children("div:nth-child(" + EmptySquare + ")").css('top');

var newx = $(clicked_square).css('left');
var newy = $(clicked_square).css('top');

// The clicked square is north of the empty square
if (oldx == newx && newy == (parseInt(oldy) - square_size) + 'px')
movable = true;

// The clicked square is south of the empty square
if (oldx == newx && newy == (parseInt(oldy) + square_size) + 'px')
movable = true;

// The clicked square is west of the empty square
if ((parseInt(oldx) - square_size) + 'px' == newx && newy == oldy)
movable = true;

// The clicked square is east of the empty square
if ((parseInt(oldx) + square_size) + 'px' == newx && newy == oldy)
movable = true;

if (movable) {
// Increment zindex so the new tile is always on top of all others
$(clicked_square).css('z-index', zi++);

// Swap squares... Animate new square into old square position
$(clicked_square).animate({ left: oldx, top: oldy }, 200, function() {
//Move old square into new square position
$('#board').children("div:nth-child(" + EmptySquare + ")").css('left', newx);
$('#board').children("div:nth-child(" + EmptySquare + ")").css('top', newy);
});
}
}

// Ok, we're ready to initialize the game, let's do it.
// Create a game with 175 by 175 squares inside "#game_object" div:
$('#game_object').fifteen(175);
});

I tried to explain the code to the best of my ability here but some details were skipped because there is so much more to JavaScript.


If you feel like you still need to understand what some of the things mean I recommend grabbing a copy of my jquery tutorial book [2] which contains a multitude of tutorials and visual diagrams. They are designed to help you build your understanding of JavaScript and jQuery so you can write your own plugins, games, etc.




Live Demo

download in package



Conclusion


I hope you enjoyed this tutorial and perhaps learned a thing or two. Thanks for reading!


Greg Sidelnikov







via Script Tutorials»Script Tutorials | Web Developer Tutorials | HTML5 and CSS3 Tutorials http://www.script-tutorials.com/how-to-create-a-game-using-jquery/

Comentaris

Entrades populars d'aquest blog

10 alternativas a Cuevana para ver películas online

10 alternativas a Cuevana para ver películas online : Durante este último tiempo, en Cuevana se sucedieron varios “problemas” por los cuales hubo que ajustar algunas cosas antes de tiempo (como el rediseño del sitio), que dejaron a algunos usuarios ciertos problemas para acceder a las películas o series del portal. Pero realmente esto es algo que no incumbe a los usuarios y, como sabemos, existen muchas otras alternativas a Cuevana dando vueltas por Internet, que intentaremos presentar aquí mismo. Los sitios que repasaremos funcionan del mismo modo que Cuevana, mediante la instalación de un plugin que permite visualizar los videos de Megaupload o WUShare, entre otros servicios, en una calidad de imágen realmente excelente. Tal como sucede con el más popular servicio, todos ellos tienen publicidad que en algunos casos resulta insoportable, pero como dice Federico en DotPod “a caballo regalado no se le miran los dientes”. Alternativas a Cuevana 1. Moviezet Posiblemente el mejor clon d

Sitio alternativo a Cuevana: Moviezet

Sitio alternativo a Cuevana: Moviezet : Nadie se quiere enfrentar al monstruo Cuevana , tan popular por estos días que es casi imposible ver tu serie favorita o tu película sin tener problema de saturación de tráfico. Pero hay proyectos muy sanos y prometedores, sobre todo porque están basados como una muy buena alternativa . Señores estamos hablando obviamente de un sitio alternativo a Cuevana, llamado Moviezet. Como bien dijimos, Moviezet es una excelente alternativa a Cuevana, ya que podremos ver películas y series de forma gratuita sin necesidad de que existan cortes – al mejor estilo Megavideo – y que podremos tener un seguimiento, es decir, si miramos una serie, podremos ver toda la lista con los capítulos disponibles. Lo que tiene de novedoso este sitio web Moviezet , es que tiene películas y series que quizá en Cuevana no se puedan conseguir, pero atención, que puede suceder lo mismo, pero al revés. Entonces aquí intervenimos nosotros y te daremos un sabio consejo, para no

Learn Composition from the Photography of Henri Cartier-Bresson

“Do you see it?” This question is a photographic mantra. Myron Barnstone , my mentor, repeats this question every day with the hopes that we do “see it.” This obvious question reminds me that even though I have seen Cartier-Bresson’s prints and read his books, there are major parts of his work which remain hidden from public view. Beneath the surface of perfectly timed snap shots is a design sensibility that is rarely challenged by contemporary photographers. Henri Cartier-Bresson. © Martine Franck Words To Know 1:1.5 Ratio: The 35mm negative measures 36mm x 24mm. Mathematically it can be reduced to a 3:2 ratio. Reduced even further it will be referred to as the 1:1.5 Ratio or the 1.5 Rectangle. Eyes: The frame of an image is created by two vertical lines and two horizontal lines. The intersection of these lines is called an eye. The four corners of a negative can be called the “eyes.” This is extremely important because the diagonals connecting these lines will form the breakdown