经典的HTML5游戏及其源码分析
HTML5已经相当强⼤,在HTML5平台上,我们可以完成很多⾮常复杂的动画效果,包括游戏在内。早期我们只能利⽤flash来实现⽹络游戏,现在我们⼜多了⼀种选择,即⽤HTML5制作游戏。相⽐flash,HTML5更加灵活⽅便,随着浏览器技术的不断升级,HTML5⼀定会⼴泛使⽤,⾄少在⽹页动画⽅⾯,下⾯是⼀些利⽤HTML5完成的游戏作品。
HTML5版切⽔果游戏
这曾是风靡全球的⼀款⼿机APP游戏切⽔果,现在JS⼩组已经将其改版成HTML5,并将其开源。核⼼Javascript代码:
Ucren.BasicDrag = Ucren.Class( /* constructor */ function( conf ){ conf = Ucren.fixConfig( conf );
this.type = Ucren.fixString( conf.type, \"normal\" );
var isTouch = this.isTouch = \"ontouchstart\" in window;
this.TOUCH_START = isTouch ? \"touchstart\" : \"mousedown\ this.TOUCH_MOVE = isTouch ? \"touchmove\" : \"mousemove\ this.TOUCH_END = isTouch ? \"touchend\" : \"mouseup\"; },
/* methods */ {
bind: function( el, handle ){ el = Ucren.Element( el );
handle = Ucren.Element( handle ) || el;
var evt = {};
evt[this.TOUCH_START] = function( e ){ e = Ucren.Event( e ); this.startDrag();
e.cancelBubble = true;
e.stopPropagation && e.stopPropagation(); return e.returnValue = false; }.bind( this );
handle.addEvents( evt ); this.target = el; },
//private
getCoors: function( e ){ var coors = [];
if ( e.targetTouches && e.targetTouches.length ) { // iPhone var thisTouch = e.targetTouches[0]; coors[0] = thisTouch.clientX; coors[1] = thisTouch.clientY;
}else{ // all others coors[0] = e.clientX; coors[1] = e.clientY; }
return coors; },
//private
startDrag: function(){ var target, draging, e; target = this.target;
draging = target.draging = {};
this.isDraging = true;
draging.x = parseInt( target.style( \"left\" ), 10 ) || 0; draging.y = parseInt( target.style( \"top\" ), 10 ) || 0;
e = Ucren.Event();
var coors = this.getCoors( e ); draging.mouseX = coors[0]; draging.mouseY = coors[1];
this.registerDocumentEvent(); },
//private
endDrag: function(){
this.isDraging = false;
this.unRegisterDocumentEvent(); },
//private
registerDocumentEvent: function(){ var target, draging; target = this.target;
draging = target.draging;
draging.documentSelectStart =
Ucren.addEvent( document, \"selectstart\function( e ){ e = e || event;
e.stopPropagation && e.stopPropagation(); e.cancelBubble = true;
return e.returnValue = false; });
draging.documentMouseMove =
Ucren.addEvent( document, this.TOUCH_MOVE, function( e ){ var ie, nie; e = e || event;
ie = Ucren.isIe && e.button != 1; nie = !Ucren.isIe && e.button != 0; if( (ie || nie ) && !this.isTouch ) this.endDrag();
var coors = this.getCoors( e ); draging.newMouseX = coors[0]; draging.newMouseY = coors[1];
e.stopPropagation && e.stopPropagation(); return e.returnValue = false; }.bind( this ));
draging.documentMouseUp =
Ucren.addEvent( document, this.TOUCH_END, function(){ this.endDrag(); }.bind( this ));
var lx, ly;
clearInterval( draging.timer );
draging.timer = setInterval( function(){ var x, y, dx, dy;
if( draging.newMouseX != lx && draging.newMouseY != ly ){ lx = draging.newMouseX; ly = draging.newMouseY;
dx = draging.newMouseX - draging.mouseX; dy = draging.newMouseY - draging.mouseY; x = draging.x + dx; y = draging.y + dy; if( this.type == \"calc\" ){
this.returnValue( dx, dy, draging.newMouseX, draging.newMouseY ); }else{
target.left( x ).top( y ); } }
}.bind( this ), 10 ); },
//private
unRegisterDocumentEvent: function(){ var draging = this.target.draging;
Ucren.delEvent( document, this.TOUCH_MOVE, draging.documentMouseMove ); Ucren.delEvent( document, this.TOUCH_END, draging.documentMouseUp ); Ucren.delEvent( document, \"selectstart\ clearInterval( draging.timer ); },
//private
returnValue: function( dx, dy, x, y ){ //todo something } } );
// Ucren.Template
Ucren.Template = Ucren.Class( /* constructor */ function(){
this.string = join.call( arguments, \"\" ); },
/* methods */ {
apply: function( conf ){
return this.string.format( conf );
} } );
// Ucren.BasicElement
Ucren.BasicElement = Ucren.Class( /* constructor */ function( el ){ this.dom = el;
this.countMapping = {}; },
/* methods */ {
isUcrenElement: true,
attr: function( name, value ){ if( typeof value == \"string\" ){
this.dom.setAttribute( name, value ); }else{
return this.dom.getAttribute( name ); }
return this; },
style: function( /* unknown1, unknown2 */ ){ var getStyle = Ucren.isIe ? function( name ){
return this.dom.currentStyle[name]; } :
function( name ){ var style;
style = document.defaultView.getComputedStyle( this.dom, null ); return style.getPropertyValue( name ); };
return function( unknown1, unknown2 ){ if( typeof unknown1 == \"object\" ){
Ucren.each( unknown1, function( value, key ){ this[key] = value; }.bind( this.dom.style ));
}else if( typeof unknown1 == \"string\" && typeof unknown2 == \"undefined\" ){ return getStyle.call( this, unknown1 );
}else if( typeof unknown1 == \"string\" && typeof unknown2 != \"undefined\" ){ this.dom.style[unknown1] = unknown2; }
return this; }; }(),
hasClass: function( name ){
var className = \" \" + this.dom.className + \" \"; return className.indexOf( \" \" + name + \" \" ) > -1; },
setClass: function( name ){
if( typeof( name ) == \"string\" )
this.dom.className = name.trim(); return this; },
addClass: function( name ){ var el, className; el = this.dom;
className = \" \" + el.className + \" \";
if( className.indexOf( \" \" + name + \" \" ) == -1 ){ className += name;
className = className.trim();
className = className.replace( / +/g, \" \" ); el.className = className; }
return this; },
delClass: function( name ){ var el, className; el = this.dom;
className = \" \" + el.className + \" \";
if( className.indexOf( \" \" + name + \" \" ) > -1 ){
className = className.replace( \" \" + name + \" \ className = className.trim();
className = className.replace( / +/g, \" \" ); el.className = className; }
return this;
},
html: function( html ){ var el = this.dom;
if( typeof html == \"string\" ){ el.innerHTML = html;
}else if( html instanceof Array ){ el.innerHTML = html.join( \"\" ); }else{
return el.innerHTML; }
return this; },
left: function( number ){ var el = this.dom;
if( typeof( number ) == \"number\" ){ el.style.left = number + \"px\";
this.fireEvent( \"infect\ }else{
return this.getPos().x; }
return this; },
top: function( number ){ var el = this.dom;
if( typeof( number ) == \"number\" ){ el.style.top = number + \"px\";
this.fireEvent( \"infect\ }else{
return this.getPos().y; }
return this; },
width: function( unknown ){ var el = this.dom;
if( typeof unknown == \"number\" ){ el.style.width = unknown + \"px\";
this.fireEvent( \"infect\ }else if( typeof unknown == \"string\" ){ el.style.width = unknown;
this.fireEvent( \"infect\ }else{
return this.getSize().width; }
return this; },
height: function( unknown ){ var el = this.dom;
if( typeof unknown == \"number\" ){ el.style.height = unknown + \"px\";
this.fireEvent( \"infect\ }else if( typeof unknown == \"string\" ){ el.style.height = unknown;
this.fireEvent( \"infect\ }else{
return this.getSize().height; }
return this; },
count: function( name ){
return this.countMapping[name] = ++ this.countMapping[name] || 1; },
display: function( bool ){ var dom = this.dom;
if( typeof( bool ) == \"boolean\" ){
dom.style.display = bool ? \"block\" : \"none\"; this.fireEvent( \"infect\ }else{
return this.style( \"display\" ) != \"none\"; }
return this; },
first: function(){
var c = this.dom.firstChild;
while( c && !c.tagName && c.nextSibling ){ c = c.nextSibling;
}
return c; },
add: function( dom ){ var el;
el = Ucren.Element( dom );
this.dom.appendChild( el.dom ); return this; },
remove: function( dom ){ var el; if( dom ){
el = Ucren.Element( dom ); el.html( \"\" );
this.dom.removeChild( el.dom ); }else{
el = Ucren.Element( this.dom.parentNode ); el.remove( this ); }
return this; },
insert: function( dom ){ var tdom;
tdom = this.dom; if( tdom.firstChild ){
tdom.insertBefore( dom, tdom.firstChild ); }else{
this.add( dom ); }
return this; },
addEvents: function( conf ){ var blank, el, rtn; blank = {}; rtn = {};
el = this.dom;
Ucren.each( conf, function( item, key ){
rtn[key] = Ucren.addEvent( el, key, item ); });
return rtn; },
removeEvents: function( conf ){ var blank, el; blank = {}; el = this.dom;
Ucren.each( conf, function( item, key ){ Ucren.delEvent( el, key, item ); });
return this; },
getPos: function(){
var el, parentNode, pos, box, offset; el = this.dom; pos = {};
if( el.getBoundingClientRect ){
box = el.getBoundingClientRect(); offset = Ucren.isIe ? 2 : 0; var doc = document;
var scrollTop = Math.max( doc.documentElement.scrollTop, doc.body.scrollTop );
var scrollLeft = Math.max( doc.documentElement.scrollLeft, doc.body.scrollLeft ); return {
x: box.left + scrollLeft - offset, y: box.top + scrollTop - offset }; }else{ pos = {
x: el.offsetLeft, y: el.offsetTop };
parentNode = el.offsetParent; if( parentNode != el ){ while( parentNode ){
pos.x += parentNode.offsetLeft; pos.y += parentNode.offsetTop;
parentNode = parentNode.offsetParent;
} }
if( Ucren.isSafari && this.style( \"position\" ) == \"absolute\" ){ // safari doubles in some cases pos.x -= document.body.offsetLeft; pos.y -= document.body.offsetTop; } }
if( el.parentNode ){
parentNode = el.parentNode; }else{
parentNode = null; }
while( parentNode && parentNode.tagName.toUpperCase() != \"BODY\" &&
parentNode.tagName.toUpperCase() != \"HTML\" ){ // account for any scrolled ancestors pos.x -= parentNode.scrollLeft; pos.y -= parentNode.scrollTop; if( parentNode.parentNode ){
parentNode = parentNode.parentNode; }else{
parentNode = null; } }
return pos; },
getSize: function(){ var dom = this.dom;
var display = this.style( \"display\" );
if ( display && display !== \"none\" ) {
return { width: dom.offsetWidth, height: dom.offsetHeight }; }
var style = dom.style; var originalStyles = {
visibility: style.visibility, position: style.position, display: style.display };
var newStyles = { visibility: \"hidden\ display: \"block\" };
if ( originalStyles.position !== \"fixed\" ) newStyles.position = \"absolute\";
this.style( newStyles );
var dimensions = {
width: dom.offsetWidth, height: dom.offsetHeight };
this.style( originalStyles );
return dimensions; },
observe: function( el, fn ){ el = Ucren.Element( el );
el.on( \"infecthis )); return this; },
usePNGbackground: function( image ){ var dom;
dom = this.dom;
if( /\\.png$/i.test( image ) && Ucren.isIe6 ){ dom.style.filter =
\"progid:DXImageTransform.Microsoft.AlphaImageLoader( src='\" + image + \"',sizingMethod='scale' );\"; /// _background: none;
/// _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader( src='images/pic.png',sizingMethod='scale' ); }else{
dom.style.backgroundImage = \"url( \" + image + \" )\"; }
return this; },
setAlpha: function(){
var reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/; return function( value ){
var element = this.dom, es = element.style; if( !Ucren.isIe ){
es.opacity = value / 100;
/* }else if( es.filter === \"string\" ){ */ }else{
if ( element.currentStyle && !element.currentStyle.hasLayout ) es.zoom = 1;
if ( reOpacity.test( es.filter )) {
value = value >= 99.99 ? \"\" : ( \"alpha( opacity=\" + value + \" )\" ); es.filter = es.filter.replace( reOpacity, value ); } else {
es.filter += \" alpha( opacity=\" + value + \" )\"; } }
return this; }; }(),
fadeIn: function( callback ){
if( typeof this.fadingNumber == \"undefined\" ) this.fadingNumber = 0;
this.setAlpha( this.fadingNumber );
var fading = function(){
this.setAlpha( this.fadingNumber ); if( this.fadingNumber == 100 ){
clearInterval( this.fadingInterval ); callback && callback(); }else
this.fadingNumber += 10; }.bind( this );
this.display( true );
clearInterval( this.fadingInterval );
this.fadingInterval = setInterval( fading, Ucren.isIe ? 20 : 30 );
return this; },
fadeOut: function( callback ){
if( typeof this.fadingNumber == \"undefined\" ) this.fadingNumber = 100;
this.setAlpha( this.fadingNumber );
var fading = function(){
this.setAlpha( this.fadingNumber ); if( this.fadingNumber == 0 ){
clearInterval( this.fadingInterval ); this.display( false ); callback && callback(); }else
this.fadingNumber -= 10; }.bind( this );
clearInterval( this.fadingInterval );
this.fadingInterval = setInterval( fading, Ucren.isIe ? 20 : 30 );
return this; },
useMouseAction: function( className, actions ){ /**
* 调⽤⽰例: el.useMouseAction( \"xbutton\
* 使⽤效果: el 会在 \"xbutton xbutton-over\ * 等四个 className 中根据相应的⿏标事件来进⾏切换。 * 特别提⽰: useMouseAction 可使⽤不同参数多次调⽤。 */
if( !this.MouseAction )
this.MouseAction = new Ucren.MouseAction({ element: this }); this.MouseAction.use( className, actions ); return this; } } );
if( Ucren.isIe )
document.execCommand( \"BackgroundImageCache\false, true );
for( var i in Ucren ){ exports[i] = Ucren[i];
};
return exports;});
View Code
HTML5中国象棋游戏
这款HTML5中国象棋游戏还可以⾃定义游戏难度,⽪肤也不错。核⼼Javascript代码:
/*! ⼀叶孤⾈ | qq:28701884 | 欢迎指教 */var play = play||{};
play.init = function (){
play.my = 1; //玩家⽅
play.map = com.arr2Clone (com.initMap); //初始化棋盘 play.nowManKey = false; //现在要操作的棋⼦ play.pace = []; //记录每⼀步 play.isPlay = true ; //是否能⾛棋 play.mans = com.mans; play.bylaw = com.bylaw; play.show = com.show;
play.showPane = com.showPane; play.isOffensive = true; //是否先⼿
play.depth = play.depth || 3; //搜索深度
play.isFoul = false; //是否犯规长将
com.pane.isShow = false; //隐藏⽅块
//初始化棋⼦
for (var i=0; ifor (var n=0; ncom.mans[key].x=n; com.mans[key].y=i;com.mans[key].isShow = true; } } }
play.show();
//绑定点击事件
com.canvas.addEventListener(\"click\ //clearInterval(play.timer);
//com.get(\"autoPlay\").addEventListener(\"click\ //clearInterval(play.timer);
//play.timer = setInterval(\"play.AIPlay()\ // play.AIPlay() //}) /*
com.get(\"offensivePlay\").addEventListener(\"click\ play.isOffensive=true; play.isPlay=true ;
com.get(\"chessRight\").style.display = \"none\"; play.init(); })
com.get(\"defensivePlay\").addEventListener(\"click\ play.isOffensive=false; play.isPlay=true ;
com.get(\"chessRight\").style.display = \"none\"; play.init(); }) */
com.get(\"regretBn\").addEventListener(\"click\function(e) { play.regret(); })
/*
var initTime = new Date().getTime(); for (var i=0; i<=100000; i++){
var h=\"\"
var h=play.map.join(); //for (var n in play.mans){
// if (play.mans[n].show) h+=play.mans[n].key+play.mans[n].x+play.mans[n].y //} }
var nowTime= new Date().getTime(); z([h,nowTime-initTime]) */ }
//悔棋
play.regret = function (){
var map = com.arr2Clone(com.initMap); //初始化所有棋⼦
for (var i=0; ifor (var n=0; n