» Archive for the ‘JavaScript’ Category
Games & JavaScriptSunday, April 15th, 2007
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
Games & JavaScriptTuesday, March 13th, 2007
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.
Games & JavaScriptSunday, March 4th, 2007
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)
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
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)