经典的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代码:

 
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跳伞游戏

跳伞游戏,比谁先安全着陆,点击鼠标开始下落,再点击鼠标展开降落伞,你要控制好时机,让自己最先安全着陆。

在线演示        源码下载

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

短暂又灿烂的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值