Simplifying JavaScript game developer’s life… PART II
In the second part of dhtml game developing tutorial I want to present simple and very effective sprite animation technique. The Background positioning. 1. You need to have an image that contains all animation frames of your sprite.
- All frames should have the same size.
- Put the frames in a suitable sequence.First frame: Mario stands,
Mario first, second, third step in right
Mario first, second, third step in left. - The start position of the next frame should be the end position of the last frame.For example:First frame position: (0,y)Second frame position: (0+width,y) Third frame position: ((0+width)*2,y) So the main formula will be: n- frame number (width*(n-1),y) Your frame have 32px width and you need the position of the fourth frame (32*3,y) = (96,y) Remember this work only when all frames have the same width.
- Save your image as a GIF or PNG format. The JPEG is recommended for large images. Do not use BMP format.
2. Create a layer with the width of the one frame:
position: absolute; // we’ll use left, top, right, bottom properties,
width: 32px; // only one frame will be visible,
height: 64px; // the height of frame,
left: 0; top: 0; // place it wherever you want,
background-image: url(mario.gif); // path to our image,
background-position: 0 0; // This is important, pointing at the first frame.
3. Animation: Now, we need to change/move the frame:
background-position: -(width*(n-1)) 0; so, which frame do you want? fourth? ok (32*(4-1))*(-1)= -96 background-position: -96px 0;
Why we multiply by -1? Fourth frame starts at 96px, but we see only frame at position 0, so we need to move the image 96px left. Rule is simple: Plus - when we need to move right, Minus - when we need to move left. Here is a simple demonstration of this technique in action, also I’m using collision detection and getValue functions described in the previous part of this tutorial…
Background positioning demo - Mario
3D Girl
It’s been a long time since my last post, but I had so much things to do. I’ve got new job. Also, I spent two weeks playing with Blender, making (I hope) very nice model. 3D girl. My first 3D girl, from 4 vertices plane to the full shape in two weeks… I’m proud of my self.
Actually, I’m learning Blender and this my first full, finished shape, the other projects are still unfinished.
I have plans and ideas for the full scene and I will want to use some of my new 3d models in the next game (of course as a graphic).
The 3D girl is most detailed blender project I ever done - she has fingernails and hair. Actually I don’t have
an idea for full scene with this object, maybe she will find her place in the future projects.
Is she beautifull? Well, no I think, maybe a little bit not much, but I love it, my first virtual girl.
Simplifying JavaScript game developer’s life… PART I
Today I will present few JavaScript functions that might be helpful in game programming.
All these functions was tested in the latest Firefox, Opera and IE.
Let’s go:
1. getValue(val)
Converts numbers in a string value to the float/integer values. It is usefull when you have to manipulate on top,left,right,bottom or z-index attributes, but also it will work with any strings that contains numbers.
function getValue(val) {
if (val==”) return ”;
if (isNaN(val)) {
val=val.toLowerCase();
var num=[];
var ar=val.split(’ ‘);
for (i in ar) {
var b=(ar[i].substr(0,ar[i].length-2));
if (b==”) b=ar[i];
if (!isNaN(b)) num.push(parseFloat(b)); else num.push(ar[i]);
}
val=num.length>1 ? num : num[0];
} else val=parseFloat(val);
return val;
}
Example:
var el=document.getElementById(’test’);
el.style.margin=’10px 20px 30px 40px’;
var n=getValue(el.style.margin);
Result: n = Array [10,20,30,40]
n=getValue(el.style.margin)[0]+2;
Result: n=12; - not array
el.style.width=”10%”;
n=getValue(el.style.width);
Result: n=10; - not array
n=getValue(’foo bar 10px foo bar 1.3em foo bar 10%’);
Result: n= Array [10,1.3,10]
2. colorToRGB(val)
Converts a color string value to decimal rgb values.
function colorToRGB(val) {
val=val.toLowerCase();
var n=[];
if (val.indexOf(’rgb’)!=-1) {
n=((val.slice(val.indexOf(’rgb’)+4,val.indexOf(’)'))).replace(/ /g,”)).split(’,');
n[0]=parseInt(n[0]);
n[1]=parseInt(n[1]);
n[2]=parseInt(n[2]);
} else
if (val.indexOf(’#')!=-1) {
if ( val.charCodeAt(val.indexOf(’#')+4)==32 || isNaN(val.charCodeAt(val.indexOf(’#')+4))
) {
var x=val.split(”);
n[0]=parseInt(x[val.indexOf('#')+1]+x[val.indexOf('#')+1],16);
n[1]=parseInt(x[val.indexOf('#')+2]+x[val.indexOf('#')+2],16);
n[2]=parseInt(x[val.indexOf('#')+3]+x[val.indexOf('#')+3],16);
} else {
n[0]=parseInt(val.substr(val.indexOf(’#')+1,2),16);
n[1]=parseInt(val.substr(val.indexOf(’#')+3,2),16);
n[2]=parseInt(val.substr(val.indexOf(’#')+5,2),16);
}
} else
{
var col=[
'alicebluef0f8ff','antiquewhitefaebd7','aqua00ffff',
'aquamarine7fffd4','azuref0ffff','beigef5f5dc',
'bisqueffe4c4','black000000','blanchedalmondffebcd',
'blue0000ff','blueviolet8a2be2','browna52a2a',
'burlywooddeb887','cadetblue5f9ea0','chartreuse7fff00',
'chocolated2691e','coralff7f50','cornflowerblue6495ed',
'cornsilkfff8dc','crimsondc143c','cyan00ffff',
'darkblue00008b','darkcyan008b8b','darkgoldenrodb8860b',
'darkgraya9a9a9','darkgreen006400','darkkhakibdb76b',
'darkmagenta8b008b','darkolivegreen556b2f','darkorangeff8c00',
'darkorchid9932cc','darkred8b0000','darksalmone9967a',
'darkseagreen8fbc8f','darkslateblue483d8b','darkslategray2f4f4f',
'darkturquoise00ced1','darkviolet9400d3','deeppinkff1493',
'deepskyblue00bfff','dimgray696969','dodgerblue1e90ff',
'firebrickb22222','floralwhitefffaf0','forestgreen228b22',
'fuchsiaff00ff','gainsborodcdcdc','ghostwhitef8f8ff',
'goldffd700','goldenroddaa520','gray808080',
'green008000','greenyellowadff2f','honeydewf0fff0',
'hotpinkff69b4','indianredcd5c5c','indigo4b0082',
'ivoryfffff0','khakif0e68c','lavendere6e6fa',
'lavenderblushfff0f5','lawngreen7cfc00','lemonchiffonfffacd',
'lightblueadd8e6','lightcoralf08080','lightcyane0ffff',
'lightgoldenrodyellowfafad2','lightgrayd3d3d3','lightgreen90ee90',
'lightpinkffb6c1','lightsalmonffa07a','lightseagreen20b2aa',
'lightskyblue87cefa','lightslategray778899','lightsteelblueb0c4de',
'lightyellowffffe0','lime00ff00','limegreen32cd32',
'linenfaf0e6','magentaff00ff','maroon800000',
'mediumaquamarine66cdaa','mediumblue0000cd','mediumorchidba55d3',
'mediumpurple9370d8','mediumseagreen3cb371','mediumslateblue7b68ee',
'mediumspringgreen00fa9a','mediumturquoise48d1cc','mediumvioletredc71585',
'midnightblue191970','mintcreamf5fffa','mistyroseffe4e1',
'moccasinffe4b5','navajowhiteffdead','navy000080',
'oldlacefdf5e6','olive808000','olivedrab6b8e23',
'orangeffa500','orangeredff4500','orchidda70d6',
'palegoldenrodeee8aa','palegreen98fb98','paleturquoiseafeeee',
'palevioletredd87093','papayawhipffefd5','peachpuffffdab9',
'perucd853f','pinkffc0cb','plumdda0dd',
'powderblueb0e0e6','purple800080','redff0000',
'rosybrownbc8f8f','royalblue4169e1','saddlebrown8b4513',
'salmonfa8072','sandybrownf4a460','seagreen2e8b57',
'seashellfff5ee','siennaa0522d','silverc0c0c0',
'skyblue87ceeb','slateblue6a5acd','slategray708090',
'snowfffafa','springgreen00ff7f','steelblue4682b4',
'tand2b48c','teal008080','thistled8bfd8',
'tomatoff6347','turquoise40e0d0','violetee82ee',
'wheatf5deb3','whiteffffff','whitesmokef5f5f5',
'yellowffff00','yellowgreen9acd32'];
for (i in col) if (val.indexOf(col[i].substr(0,col[i].length-6))!=-1) break;
n=colorToRGB(’#'+col[i].substr(col[i].length-6));
}
return n;
}
Example:
var el=document.getElementById(’test’);
el.style.color=”#FFFFFF”;
var n=colorToRGB(el.style.color);
Result: n= Array [255,255,255];
el.style.background=”#666″;
var n=colorToRGB(el.style.background);
Result: n= Array [102,102,102];
el.style.border=”1px solid turquoise”;
var n=colorToRGB(el.style.border);
Result: n= Array [64,224,208]
el.style.color=”white”;
var n=colorToRGB(el.style.color);
Result: n= Array [255,255,255]
3. getLayerCrd(id)
Gets the current positions of first (X,Y) and opposite (X+width,Y+height) vertex of an element based on container coordinates.
function getLayerCrd(id) {
if (document.getElementById(id)) {
var n=[];
var obj=document.getElementById(id);
n[0]=obj.offsetLeft;
n[1]=obj.offsetTop;
n[2]=obj.offsetLeft+obj.offsetWidth;
n[3]=obj.offsetTop+obj.offsetHeight;
return n;
} else return -1;
}
Example of use:
var n=getLayer(’test’);
el.style.margin=’10px 20px 30px 40px’;
Result: n= Array [x,y,x+width,y+height]
Note: getLayerCrd(id) should be used with block objects.
4. colDetect(id1,id2)
Returns true if two objects overlapping each other. Simple collision detection based on object coordinates (getLayerCrd(id) function is required)
function colDetect(id1,id2) {
var n1=getLayerCrd(id1);
var n2=getLayerCrd(id2);
if ((n1!=-1) && (n2!=-1)) {
if ((((n1[2]>=n2[0]) && (n1[2]<=n2[2])) ||
((n1[0]<=n2[2]) && (n1[0]>=n2[0]))) &&
(((n1[3]>=n2[1]) && (n1[3]<=n2[3])) ||
((n1[1]<=n2[3]) && (n1[1]>=n2[1]))))
{ return true;} else return false;
} else return false;
}
Example of use:
var n=colDetect(’test1′,’test2′);
el.style.margin=’10px 20px 30px 40px’;
returns true or false
Note: Same as with getLayerCrd(id) - use with block objects. Both objects should be placed in the same container or you will have to modify the getLayerCrd(id) function for geting position based on page coordinates.
c# to JavaScript and Space Invaders
Thanks to Zproxy I found something what is called JSC - C# to JavaScript.
JSC is a compiler (or a decompiler) and as the name points out JSC will helps you prepare the JavaScript applications in the C# language. See the project website for more details.
Also, Zproxy has made nice implementation of the Space Invaders, written in C# and precompiled to JavaScript by using mentioned compiler.
Space Invaders (JSC version)
Solitaire - JavaScript version
Long time since last post. I’ve played with SuSe 10.2, very nice distro, I had no problems with any application which I’ve tried to install on it. Also, I’ve made another JavaScript game based on YUI. I think, everyone knows what the word “Solitaire” means.Copule of years ago I wrote similar project in Delphi. The main feature of that application
was that the cards were automatically generated by functions implemented in the code. Instead of using 52 images which would represent each of the card I used only small pictures of figures,symbols and small images of king, queen and jack, the rest were done by specified functions.
The JavaScript version works the same.This is very controversial technique, It’s hard to say what exactly is faster and what is slower: loading one big image (16/8 colors GIF - with size 71×96px) or a few small images (2 colors GIF with size - ~15×15px). The answer is not that simple. However I choose the second way and this version of the Solitaire demostrate how that technique works.
Firefox and Opera are loading images only once; if, for example, two objects refers to the one image in the same document, then on the second time the image will be loaded from cache. On IE each image will be loaded separately, so if you’re using IE you will need to wait a little bit longer.
This also is a demonstration of YUI drag and drop techniques…
Enjoy…
Extended Google Ajax News Bar
As I promised, I wrote new application based on Google Ajax News Bar. This is not exactly new application, it might be say that this is an extension to the original News bar.
Google provides two kinds of ways in displaying the results:
- Horizontal - animated bar with ability to show the description in the other wrapper (
options.horizontal=true,andoptions.currentResult=document.getElementsById(wrapper)). - Vertical - all the news results and its parts (title, description, etc.) are displayed in the specified container plus you have ability to switch between search items.
My version is between these two methods but near the first one. It is the normal horizontal bar but the difference is that the title and description are displayed in the popup box near mouse pointer when you move it over the news title.
You can use all options that are available in the original New Bar (and for horizontal method) except of currentResutls and horizontal (always true) - these are used internally and values will be bypassed.
The bad or good information is that this version using prototype.js.
Google Ajax News Bar
Google provides new feature called AJAX News Bar. This application lets you add news search results to your website or blog. You can specify the orientations, the number of results (of course 4 or 8, nothing has changed), etc. The interesting thing is controlling through the links in your page which news results are displayed (works same as my green-links). If you are not good in JavaScript you can use Wizard, it will generates the code for you.
Here are the links to reference, example, and
Wizard.
So, I’m starting to write new application right now, lets see what we can do with it…
Web browser memory usage
Couple of days ago I found the interesting article - “Reduce your Linux memory footprint“, the author writes how to reduce the amount of memory used by applications working on Ubuntu.
For me the most interesting part was about the web browsers. The results form “Comparison of Web browser memory usage” table are not very good for Firefox.
I decide to make same test on Windows XP with the latest version of the browsers.
This is what I did:
I launched the browser, then I opened the page, when loading was done I checked the memory usage with Process Explorer (browser was maximized),
then I closed the browser.
Each test I did three time.
And the results:
BLANK PAGE
| Browser | Average memory use |
| Firefox | 36MB |
| IE7 | 27MB |
page: www.digitalinsane.com
| Browser | Average memory use |
| Firefox | 41MB |
| IE7 | 25MB |
page: www.google.com
| Browser | Average memory use |
| Firefox | 39MB |
| IE7 | 31MB |
page: www.yahoo.com
| Browser | Average memory use |
| Firefox | 45MB |
| IE7 | 43MB |
page: www.msn.com
| Browser | Average memory use |
| Firefox | 45MB |
| IE7 | 44MB |
three tabs with all above pages
| Browser | Average memory use |
| Firefox | 53MB |
| IE7 | 66MB |
It’s not hard to guess that the Opera uses less memory than the other browsers. Internet Explorer is a little bit better than Firefox (in these tests), but it ate more memory when more tabs were open.
And the verdict is:
- Opera - first place! (fast and less memory usage),
- IE7 - second place (very interesting),
- And at the last position, The really hungry Fox!
While I’m writing this post Opera and Firefox are lunched, so lets see the actual memory usage:
Opera (6 tabs opened/6 pages loaded) uses 32 320 Kb,
FireFox (5 tabs opened/5 pages loaded) uses 77 924 Kb
Hmm… Nothing else to say…
Browser choice?
Digging through the articles about the web browsers you can find a lot of opinions about which browser is better.
Opera users says: “My browser is faster, secure and easy customizable“,
Firefox users says: “My browser is more customizable, web services friendly, secure, and have open source code.“,
IE users says: “I’m using Internet Explorer” - forgive me, but I still can not find any benefits of using this browser. (I only run it when I have to check the pages).
Safari users says: “I have Mac and I’m using Safari” - I don’t have Mac so I can’t tell you more about this browser.
Let’s focus on the Opera and Firefox, and on which is better?
About the Opera:
- It is fast, very fast. If you are IE user you’ll probably see the difference. Opera is based on it’s own engine (not another Gecko clone) ,and have it’s own quality. I found that it is faster than Firefox while running lots of loops (in the same time) written in JavaScript.
- Have a mouse gestures (not extension needed) - however I never use that features.
- Mail client.
- Feed Reader - simple and the best, I didn’t find any extension for Firefox that could be better than this.
- Saving the last session - very useful.
- Easy customizable when it goes about profile files. (I use the same profiles for Opera installed on Windows XP and on Windows Vista (BETA), and everything is working great.)
- Fine download manager (sometimes not working properly).
- Widgets - nice, colored extension, something similar we will find in Windows Vista’s Sidebar. Useful for those who are using it :).
- Secure - Fraud protection, popup blocker, etc.
About the Firefox:
- Slowly start. Probably every Firefox user know about this “great” feature. I think, it is not very depended on the count of extensions.
- Very customizable. This have its good and bad sides. You can change almost everything and use those add-ons which you are really need. However, there are many extension and you will need a lots of time to find something suitable. After installation Firefox is very “empty”, have more than IE and less than Opera.
- Web services friendly. Yes! Especially when it goes about Google.
- Secure. But I trust more Opera.
- Profile files customization - same as in Opera.
- About the rest, well, depended on how you customize it and what extension will you choose.
So, Which is better? For the very regular user, the best will be the Opera. Install and browse, you don’t have to do anything else. But if you want play with customization and you are addicted to web services, toolbars etc, the best for you will be Gecko based browser.
I’m using Firefox and Opera when I’m online and offline while I’m checking the pages. Firefox have a very helpful webmaster extensions, Google toolbar and easy cooperate with Google services - notepad, gmail, etc. - so it is useful for such a thing).
As I said at the beginning of this post: I’m using IE only for testing the pages, not for regular browsing.
Of course if you are webmaster you’ll have to have them all on your disk…
Space Invaders!
My first contact with “Space Invaders” was about 6 years ago. It was an assembler version found in programmersheaven.com. I think this game is a grand grandmother of all space shooter games, look at the first release date - 1978. WOW! (four years older than me :)).
Couple of weeks ago I decided to create my own version of “Space Invaders”. The code was written by me but the sprites (aliens, UFO, laser gun) is taken from the original version. Everything is written in JavaScript, with the little (read big) help of Yahoo User Interface (same as the last two games).
I had the problem with Firefox, because instead of Opera and IE, in the Firefox the use of the processor while the game was running, was very big (maybe because that a lot of loops were running at the same time). So, I have to rebuild the first project and optimize it for the Firefox. However, still you can see some delay while aliens and UFO are moving (maybe it is some proof that the Gecko engine is slower than IE’s engine :/, no it can not be!). (If you have some time you can check which browser is faster, just turn on window.setInterval(); function (three or four different at the same time) with some loops (not infinite, you can change top and left attributes of some div elements).
This game also wasn’t tested in the Safari browser. Works fine in the latest version of Opera, Firefox, and IE.
Enjoy…




