经典的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", draging.documentSelectStart );
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", [{ left: number }] );
}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", [{ top: number }] );
}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", [{ width: unknown }] );
}else if( typeof unknown == "string" ){
el.style.width = unknown;
this.fireEvent( "infect", [{ width: unknown }] );
}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", [{ height: unknown }] );
}else if( typeof unknown == "string" ){
el.style.height = unknown;
this.fireEvent( "infect", [{ height: unknown }] );
}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", [{ display: bool }] );
}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( "infect", fn.bind( this ));
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", "over,out,down,up" );
* 使用效果: el 会在 "xbutton xbutton-over","xbutton xbutton-out","xbutton xbutton-down","xbutton xbutton-up"
* 等四个 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;
});
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; i<play.map.length; i++){
for (var n=0; n<play.map[i].length; n++){
var key = play.map[i][n];
if (key){
com.mans[key].x=n;
com.mans[key].y=i;
com.mans[key].isShow = true;
}
}
}
play.show(); //绑定点击事件
com.canvas.addEventListener("click",play.clickCanvas)
//clearInterval(play.timer);
//com.get("autoPlay").addEventListener("click", function(e) {
//clearInterval(play.timer);
//play.timer = setInterval("play.AIPlay()",1000);
// play.AIPlay()
//})
/*
com.get("offensivePlay").addEventListener("click", function(e) {
play.isOffensive=true;
play.isPlay=true ;
com.get("chessRight").style.display = "none";
play.init();
}) com.get("defensivePlay").addEventListener("click", function(e) {
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; i<map.length; i++){
for (var n=0; n<map[i].length; n++){
var key = map[i][n];
if (key){
com.mans[key].x=n;
com.mans[key].y=i;
com.mans[key].isShow = true;
}
}
}
var pace= play.pace;
pace.pop();
pace.pop(); for (var i=0; i<pace.length; i++){
var p= pace[i].split("")
var x = parseInt(p[0], 10);
var y = parseInt(p[1], 10);
var newX = parseInt(p[2], 10);
var newY = parseInt(p[3], 10);
var key=map[y][x];
//try{ var cMan=map[newY][newX];
if (cMan) com.mans[map[newY][newX]].isShow = false;
com.mans[key].x = newX;
com.mans[key].y = newY;
map[newY][newX] = key;
delete map[y][x];
if (i==pace.length-1){
com.showPane(newX ,newY,x,y)
}
//} catch (e){
// com.show()
// z([key,p,pace,map]) // }
}
play.map = map;
play.my=1;
play.isPlay=true;
com.show();
} //点击棋盘事件
play.clickCanvas = function (e){
if (!play.isPlay) return false;
var key = play.getClickMan(e);
var point = play.getClickPoint(e); var x = point.x;
var y = point.y; if (key){
play.clickMan(key,x,y);
}else {
play.clickPoint(x,y);
}
play.isFoul = play.checkFoul();//检测是不是长将
} //点击棋子,两种情况,选中或者吃子
play.clickMan = function (key,x,y){
var man = com.mans[key];
//吃子
if (play.nowManKey&&play.nowManKey != key && man.my != com.mans[play.nowManKey ].my){
//man为被吃掉的棋子
if (play.indexOfPs(com.mans[play.nowManKey].ps,[x,y])){
man.isShow = false;
var pace=com.mans[play.nowManKey].x+""+com.mans[play.nowManKey].y
//z(bill.createMove(play.map,man.x,man.y,x,y))
delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
play.map[y][x] = play.nowManKey;
com.showPane(com.mans[play.nowManKey].x ,com.mans[play.nowManKey].y,x,y)
com.mans[play.nowManKey].x = x;
com.mans[play.nowManKey].y = y;
com.mans[play.nowManKey].alpha = 1 play.pace.push(pace+x+y);
play.nowManKey = false;
com.pane.isShow = false;
com.dot.dots = [];
com.show()
com.get("clickAudio").play();
setTimeout("play.AIPlay()",500);
if (key == "j0") play.showWin (-1);
if (key == "J0") play.showWin (1);
}
// 选中棋子
}else{
if (man.my===1){
if (com.mans[play.nowManKey]) com.mans[play.nowManKey].alpha = 1 ;
man.alpha = 0.6;
com.pane.isShow = false;
play.nowManKey = key;
com.mans[key].ps = com.mans[key].bl(); //获得所有能着点
com.dot.dots = com.mans[key].ps
com.show();
//com.get("selectAudio").start(0);
com.get("selectAudio").play();
}
}
} //点击着点
play.clickPoint = function (x,y){
var key=play.nowManKey;
var man=com.mans[key];
if (play.nowManKey){
if (play.indexOfPs(com.mans[key].ps,[x,y])){
var pace=man.x+""+man.y
//z(bill.createMove(play.map,man.x,man.y,x,y))
delete play.map[man.y][man.x];
play.map[y][x] = key;
com.showPane(man.x ,man.y,x,y)
man.x = x;
man.y = y;
man.alpha = 1;
play.pace.push(pace+x+y);
play.nowManKey = false;
com.dot.dots = [];
com.show();
com.get("clickAudio").play();
setTimeout("play.AIPlay()",500);
}else{
//alert("不能这么走哦!")
}
} } //Ai自动走棋
play.AIPlay = function (){
//return
play.my = -1 ;
var pace=AI.init(play.pace.join(""))
if (!pace) {
play.showWin (1);
return ;
}
play.pace.push(pace.join(""));
var key=play.map[pace[1]][pace[0]]
play.nowManKey = key; var key=play.map[pace[3]][pace[2]];
if (key){
play.AIclickMan(key,pace[2],pace[3]);
}else {
play.AIclickPoint(pace[2],pace[3]);
}
com.get("clickAudio").play(); } //检查是否长将
play.checkFoul = function(){
var p=play.pace;
var len=parseInt(p.length,10);
if (len>11&&p[len-1] == p[len-5] &&p[len-5] == p[len-9]){
return p[len-4].split("");
}
return false;
} play.AIclickMan = function (key,x,y){
var man = com.mans[key];
//吃子
man.isShow = false;
delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
play.map[y][x] = play.nowManKey;
play.showPane(com.mans[play.nowManKey].x ,com.mans[play.nowManKey].y,x,y) com.mans[play.nowManKey].x = x;
com.mans[play.nowManKey].y = y;
play.nowManKey = false; com.show()
if (key == "j0") play.showWin (-1);
if (key == "J0") play.showWin (1);
} play.AIclickPoint = function (x,y){
var key=play.nowManKey;
var man=com.mans[key];
if (play.nowManKey){
delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
play.map[y][x] = key; com.showPane(man.x,man.y,x,y) man.x = x;
man.y = y;
play.nowManKey = false; }
com.show();
} play.indexOfPs = function (ps,xy){
for (var i=0; i<ps.length; i++){
if (ps[i][0]==xy[0]&&ps[i][1]==xy[1]) return true;
}
return false; } //获得点击的着点
play.getClickPoint = function (e){
var domXY = com.getDomXY(com.canvas);
var x=Math.round((e.pageX-domXY.x-com.pointStartX-20)/com.spaceX)
var y=Math.round((e.pageY-domXY.y-com.pointStartY-20)/com.spaceY)
return {"x":x,"y":y}
} //获得棋子
play.getClickMan = function (e){
var clickXY=play.getClickPoint(e);
var x=clickXY.x;
var y=clickXY.y;
if (x < 0 || x>8 || y < 0 || y > 9) return false;
return (play.map[y][x] && play.map[y][x]!="0") ? play.map[y][x] : false;
} play.showWin = function (my){
play.isPlay = false;
if (my===1){
alert("恭喜你,你赢了!");
}else{
alert("很遗憾,你输了!");
}
}
HTML5五子棋游戏
HTML5版Flappy Bird游戏
Flappy Bird这款变态游戏也被改造成HTML5版,这也是意料之中的事情。
核心Javascript代码:
// Initialize Phaser, and creates a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
var game_state = {}; // Creates a new 'main' state that will contain the game
game_state.main = function() { };
game_state.main.prototype = { // Function called first to load all the assets
preload: function() {
// Change the background color of the game
this.game.stage.backgroundColor = '#71c5cf'; // Load the bird sprite
this.game.load.image('bird', 'assets/bird.png'); // Load the pipe sprite
this.game.load.image('pipe', 'assets/pipe.png');
}, // Fuction called after 'preload' to setup the game
create: function() {
// Display the bird on the screen
this.bird = this.game.add.sprite(100, 245, 'bird'); // Add gravity to the bird to make it fall
this.bird.body.gravity.y = 1000; // Call the 'jump' function when the spacekey is hit
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this); // Create a group of 20 pipes
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe'); // Timer that calls 'add_row_of_pipes' ever 1.5 seconds
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this); // Add a score label on the top left of the screen
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
}, // This function is called 60 times per second
update: function() {
// If the bird is out of the world (too high or too low), call the 'restart_game' function
if (this.bird.inWorld == false)
this.restart_game(); // If the bird overlap any pipes, call 'restart_game'
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
}, // Make the bird jump
jump: function() {
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
}, // Restart the game
restart_game: function() {
// Remove the timer
this.game.time.events.remove(this.timer); // Start the 'main' state, which restarts the game
this.game.state.start('main');
}, // Add a pipe on the screen
add_one_pipe: function(x, y) {
// Get the first dead pipe of our group
var pipe = this.pipes.getFirstDead(); // Set the new position of the pipe
pipe.reset(x, y); // Add velocity to the pipe to make it move left
pipe.body.velocity.x = -200; // Kill the pipe when it's no longer visible
pipe.outOfBoundsKill = true;
}, // Add a row of 6 pipes with a hole somewhere in the middle
add_row_of_pipes: function() {
var hole = Math.floor(Math.random()*5)+1; for (var i = 0; i < 8; i++)
if (i != hole && i != hole +1)
this.add_one_pipe(400, i*60+10); this.score += 1;
this.label_score.content = this.score;
},
}; // Add and start the 'main' state to start the game
game.state.add('main', game_state.main);
game.state.start('main');
HTML5太空战机游戏
很普通的战机游戏,但是用HTML5实现就略显高大上了。
核心Javascript代码:
var g_canvas;
var g_context;
var g_soundsLoaded;
var g_isChr;
var g_onscreenControls;
var g_paused;
var g_renderInterval;
var g_clockInterval; var g_totalItems;
var g_itemsLoaded; var g_background;
var g_foreground; var g_ship;
var g_gameState;
var g_highScore; var g_powerups;
var g_floatyText;
var g_projectiles;
var g_enemyProjectiles;
var g_enemies;
var g_afterEffects;
var g_rainbow; var g_basicShotSound;
var g_laserShotSound;
var g_dinkSound;
var g_smallExplodeSound;
var g_bonusSound;
var g_explodeSound;
var g_artifact_chard_sound;
var g_double_sound;
var g_gem_sound;
var g_gun_sound;
var g_shot_sound;
var g_speed_sound; var g_levelDirector;
var g_shotsFired;
var g_shotsRequired;
var g_accuracy;
var g_showAccuracy;
var g_enemiesDestroyed; //
// main() is called once the game has loaded and the user has clicked
// on the "new game" button on the splash screen. This is a clean slate
// with no registered timers or event listeners.
//
function main()
{
var level_1_loop = document.getElementById("level_1_loop");
var bossLoop = document.getElementById("boss_loop"); //dbg("engine = " + navigator.userAgent, false);
g_rainbow = new Array("yellow", "orange", "white", "red"); document.addEventListener('keydown', keyDown, false);
document.addEventListener('keyup', keyUp, false); if ( g_basicShotSound == null )
{ g_basicShotSound = new Sound("basic_shot",5);
g_laserShotSound = new Sound("laser",5);
g_smallExplodeSound = new Sound("small_explode",5);
g_bonusSound = new Sound("bonus_sound",4);
g_explodeSound = new Sound("explode", 3); g_artifact_chard_sound = new Sound("artifact_chard_sound", 2);
g_double_sound = new Sound("double_sound", 2);
g_gem_sound = new Sound("gem_sound", 4);
g_gun_sound = new Sound("gun_sound", 2);
g_shot_sound = new Sound("shot_sound", 3);
g_speed_sound = new Sound("speed_sound", 3);
} g_highScore = 0;
g_gameState = "setup";
g_levelDirector = new LevelDirector(); //
// telling the level director to start will put the clock and
// render loops on interval timers
//
g_levelDirector.startLevel();
} //
// map a sound name to a global audio object
//
function lookupSound(name)
{
if ( name == "double_sound" )
return g_double_sound;
else if ( name == "gem_sound" )
return g_gem_sound;
else if ( name == "gun_sound" )
return g_gun_sound;
else if ( name == "shot_sound" )
return g_shot_sound;
else if ( name == "speed_sound" )
return g_speed_sound; dbg("Failed sound lookup: " + name, false); return null;
} //
// the level director will kick off an interval that calls
// this function every 100ms
//
function clockLoop()
{
if ( g_paused )
return; g_levelDirector.myClock += 100;
//dbg("Clock = " + g_levelDirector.myClock, false); g_levelDirector.launchSorties();
g_levelDirector.gameEvents();
} //
// the LevelDirector will kick off an interval that calls this function
// which redraws the entire screen. that interval determines the game's
// fps.
//
function renderLoop()
{
if ( g_paused )
return; g_background.render();
g_ship.render(); var remainingPowerups = new Array();
for (var i = 0; i < g_powerups.length; ++i)
{
if (g_powerups[i].render())
{
remainingPowerups.push(g_powerups[i]);
}
else delete g_powerups[i];
}
delete g_powerups;
g_powerups = remainingPowerups; var remainingText = new Array();
for (var i = 0; i < g_floatyText.length; ++i)
{
if (g_floatyText[i].render())
{
remainingText.push(g_floatyText[i]);
}
else delete g_floatyText[i];
}
delete g_floatyText;
g_floatyText = remainingText; var remainingEnemies = new Array();
for (var i = 0; i < g_enemies.length; ++i)
{
if (g_enemies[i].render())
{
remainingEnemies.push(g_enemies[i]);
}
else delete g_enemies[i];
}
delete g_enemies;
g_enemies = remainingEnemies; var remainingProjectiles = new Array();
for (var i = 0; i < g_projectiles.length; ++i)
{
if (g_projectiles[i].render())
{
remainingProjectiles.push(g_projectiles[i]);
}
else delete g_projectiles[i];
}
delete g_projectiles;
g_projectiles = remainingProjectiles; var remainingEnemyProjectiles = new Array();
for (var i = 0; i < g_enemyProjectiles.length; ++i)
{
if (g_enemyProjectiles[i].render())
{
remainingEnemyProjectiles.push(g_enemyProjectiles[i]);
}
else delete g_enemyProjectiles[i];
}
delete g_enemyProjectiles;
g_enemyProjectiles = remainingEnemyProjectiles; var remainingAfterEffects = new Array();
for (var i = 0; i < g_afterEffects.length; ++i)
{
if (g_afterEffects[i].render())
{
remainingAfterEffects.push(g_afterEffects[i]);
}
else delete g_afterEffects[i];
}
delete g_afterEffects;
g_afterEffects = remainingAfterEffects; g_levelDirector.renderSpecialText(); g_foreground.render(); if ( g_onscreenControls )
{
var ox = 40;
var oy = 300;
var ow = 30; var tx = 8;
var ty = 22; g_context.fillStyle = "yellow";
g_context.strokeStyle = "yellow";
g_context.strokeRect(ox,oy,ow,ow);
g_context.strokeRect(ox-35,oy+35,ow,ow);
g_context.strokeRect(ox+35,oy+35,ow,ow);
g_context.strokeRect(ox,oy+70,ow,ow);
g_context.strokeRect(ox+520,oy+35,ow,ow);
g_context.strokeRect(ox+270,oy+35,ow,ow); g_context.fillText("U",ox+tx,oy+ty);
g_context.fillText("L", ox-35+tx,oy+35+ty);
g_context.fillText("R", ox+35+tx,oy+35+ty);
g_context.fillText("D", ox+tx,oy+70+ty);
g_context.fillText("Z",ox+520+tx,oy+35+ty);
g_context.fillText("P",ox+270+tx,oy+35+ty);
} g_ship.renderPowers();
} //--------------------------- BEGIN MUSIC LOOPING FUNCTIONS-------------// //
// no browser currently correctly implements the looping feature
// of the Autdio object yet, so we have to listen for the ended event
// on our background music and play it again
//
function start_level_1_loop(terminate)
{
var level_1_loop = document.getElementById("level_1_loop"); if ( terminate != undefined )
{
if ( terminate.toString() == "boss" )
{
level_1_loop.volume = 0;
level_1_loop.removeEventListener("ended", l1_loopit, true);
return;
}
else if ( terminate.toString() == "gameover" )
{
level_1_loop.removeEventListener("ended", l1_loopit, true);
level_1_loop.pause();
return;
}
} l1_loopit();
} function l1_loopit()
{
var level_1_loop = document.getElementById("level_1_loop");
level_1_loop.volume = 1;
level_1_loop.play();
level_1_loop.addEventListener("ended", l1_loopit, true);
} function startBossLoop(terminate)
{
var bossLoop = document.getElementById("boss_loop"); if ( terminate != undefined && terminate.toString() == "end_boss")
{
bossLoop.volume = 0;
bossLoop.removeEventListener("ended", bos_loopit, true);
return;
} bos_loopit();
}
function bos_loopit()
{
var bossLoop = document.getElementById("boss_loop");
bossLoop.volume = 1;
bossLoop.play();
bossLoop.addEventListener("ended", bos_loopit, true);
} function startLevel2Loop(terminate)
{
var penguinLoop = document.getElementById("level_2_loop"); if ( terminate != undefined && terminate.toString() == "terminate")
{
penguinLoop.volume = 0;
penguinLoop.removeEventListener("ended", l2_loopit, true);
return;
}
l2_loopit();
} function l2_loopit()
{
var penguinLoop = document.getElementById("level_2_loop");
penguinLoop.volume = 1;
penguinLoop.play();
penguinLoop.addEventListener("ended", l2_loopit, true);
} //
// write message to debug area
//
function dbg(str, append)
{
var dbgObj = document.getElementById("dbg");
dbgObj.innerHTML = append? (dbgObj.innerHTML + str): str;
} //
// appends all game sounds to the document. called after the loading
// screen itself is loaded. The GameSounds.php file does a base64_encode
// on the actual .ogg files residing on the server. This is so the sound
// objects can be repeatedly re-initialized without a network hit. This
// is part of a workaround for Chrome because that browser does not
// correctly re-play short audio sounds (which is just about every sound
// effect in the game)
//
function loadGameSounds()
{
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", "http://dougx.net/plunder/GameSounds.php") var agent = navigator.userAgent;
if ( agent.indexOf("MSIE") != -1 )
{
//
// IE9 does not support OGG so we have to load a special
// version of the file that has MP3 encoded sound
//
fileref.setAttribute("src", "GameSoundsIE9.php")
} fileref.onload = function() { g_soundsLoaded = true; } document.getElementsByTagName("head")[0].appendChild(fileref)
} function pause()
{
if (g_paused == null )
g_paused = false; g_paused = !g_paused; if ( g_paused )
dbg("Game Paused", false);
else
dbg("", false);
}
HTML5超级玛丽游戏重体验
重温少年时的快乐,这是用HTML5改版的超级玛丽游戏。
HTML5跳伞游戏
跳伞游戏,比谁先安全着陆,点击鼠标开始下落,再点击鼠标展开降落伞,你要控制好时机,让自己最先安全着陆。
经典的HTML5游戏及其源码分析的更多相关文章
- 8个经典的HTML5游戏在线试玩及源码学习
原文地址:http://www.oschina.net/news/32364/html5-games 游戏,毫无疑问是拿来供大家娱乐玩耍的,这也无可厚非,但是,今天给大家分享的8个HTML5游戏,在好 ...
- hadoop之hdfs------------------FileSystem及其源码分析
FileSystem及其源码分析 FileSystem这个抽象类提供了丰富的方法用于对文件系统的操作,包括上传.下载.删除.创建等.这里多说的文件系统通常指的是HDFS(DistributedFile ...
- Qt QComboBox之setEditable和currentTextChanged及其源码分析
目录 Qt QComboBox之setEditable和currentTextChanged以及其源码分析 前言 问题的出现 问题分析 currentTextChanged信号触发 源码分析 Qt Q ...
- QQ空间玩吧HTML5游戏引擎使用比例分析
GameLook报道/“Cocos 2015开发者大会(春季)”于4月2日在国家会议中心圆满落下帷幕.在会上全新的3D编辑器,Cocos Runtime等产品重磅公布,给业界带来了Cocos这款国产引 ...
- pdfmake.js使用及其源码分析
公司项目在需要将页面的文本导出成DPF,和支持打印时,一直没有做过这样的功能,花了一点时间将其做了出来,并且本着开源的思想和技术分享的目的,将自己的编码经验分享给大家,希望对大家有用. 现在是有一个文 ...
- 8.深入k8s:资源控制Qos和eviction及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com,源码版本是1.19 又是一个周末,可以愉快的坐下来静静的品味一段源码,这一篇涉及到资源的 ...
- 9.深入k8s:调度器及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 这次讲解的是k8s的调度器部分的代码,相对来说比较复杂,慢慢的梳理清 ...
- Golang的Context介绍及其源码分析
简介 在Go服务中,对于每个请求,都会起一个协程去处理.在处理协程中,也会起很多协程去访问资源,比如数据库,比如RPC,这些协程还需要访问请求维度的一些信息比如说请求方的身份,授权信息等等.当一个请求 ...
- 13.深入k8s:Pod 水平自动扩缩HPA及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 Pod 水平自动扩缩 Pod 水平自动扩缩工作原理 Pod 水平自动 ...
随机推荐
- Codeforces.911F.Tree Destruction(构造 贪心)
题目链接 \(Description\) 一棵n个点的树,每次可以选择树上两个叶子节点并删去一个,得到的价值为两点间的距离 删n-1次,问如何能使最后得到的价值最大,并输出方案 \(Solution\ ...
- 2845 ACM 豆子 beans
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2845 题意:吃豆子游戏 , 当你吃了一个格子的豆子 , 该格子左右两个和上下两行就不能吃了 , 输入每个格 ...
- [NOIp2015提高组]跳石头
OJ题号:洛谷2678 思路:贪心+二分. 从前往后扫,一旦这个石头到上一个选的石头的距离小于二分的值就把这块石头移走. #include<cstdio> #include<queu ...
- Scala:Functions and Closures
object Functions { def main(args: Array[String]) { // 本地函数 def localFun(msg: String) = println(msg) ...
- nginx多站路由配置tomcat
server { listen 80; server_name 1.goal.cn; index index index.html index.htm index.jsp; root /www/ser ...
- crucible 的 破解
crucible这个东西用了很久,但是从来都没有想过去破解它,毕竟在公司是不能使用破解 软件的.于是再家里面玩一下而已.下载地址 运行crucible_keygen 如图: 点击 patch 将选择安 ...
- Revit对齐工具之多重对齐
Revit对齐工具用来将一个或多个图元与选定图元对齐,比如建筑建筑时可以将梁.墙.柱等对齐到轴网,或者其它类似的图元的对齐,可以对齐同一类型的图元,或者不同类型族间的对齐,可以在二维视图.立面视图和三 ...
- Vue加载组件、动态加载组件的几种方式
https://cn.vuejs.org/v2/guide/components.html https://cn.vuejs.org/v2/guide/components-dynamic-async ...
- openssl命令行工具简介 - 指令x509
原文链接: http://blog.csdn.net/allwtg/article/details/4982507 openssl命令行工具简介 - 指令x509 用法: open ...
- Spark 论文篇-RDD:一种为内存化集群计算设计的容错抽象(中英双语)
论文内容: 待整理 参考文献: Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster C ...