首页 > 代码库 > HTML5游戏源码 飞翔的字母 可自定义内容

HTML5游戏源码 飞翔的字母 可自定义内容

 

  相信大家都玩过飞翔的小鸟吧,当然,可能已经有很多人因为这个游戏砸了不少手机。吼吼。

 

  废话不多说,回到主题,源码如下,需要打包源码的朋友们请留言邮箱地址。当然还有,不要忘了点赞哦~谢谢大家的支持。

 

技术分享

 

  直接上源码:一共是三个文件:页面、js、css。

 

HTML(index.html)页面源码如下:

 1 <!DOCTYPE html> 2 <html> 3 <head> 4   <meta charset="UTF-8"> 5   <title>飞翔的字母 - 孤影</title> 6     <link rel="stylesheet" href="style.css" media="screen" type="text/css" /> 7 </head> 8  9 <body>10   <div id="canvasContainer"></div>11     <span id="textInputSpan">12       1.输入内容,2.点击屏幕开始游戏,请输入内容(最大8个字符):13       <input id="textInput" maxlength="10" type="text" width="150" />14       <button onclick="changeText()">确定!</button>15     </span>    16   <script src="index.js"></script>17 </body>18 </html>

 

JavaScript脚本文件(index.js)如下:

  1    2 (function (window){  3   4   var Sakri = window.Sakri || {};  5   window.Sakri = window.Sakri || Sakri;  6       7     Sakri.MathUtil = {};  8       9     //used for radiansToDegrees and degreesToRadians 10     Sakri.MathUtil.PI_180 = Math.PI/180; 11     Sakri.MathUtil.ONE80_PI = 180/Math.PI; 12      13     //precalculations for values of 90, 270 and 360 in radians 14     Sakri.MathUtil.PI2 = Math.PI*2; 15     Sakri.MathUtil.HALF_PI = Math.PI/2; 16  17  18     //return number between 1 and 0 19     Sakri.MathUtil.normalize = function(value, minimum, maximum){ 20         return (value - minimum) / (maximum - minimum); 21     }; 22  23     //map normalized number to values 24     Sakri.MathUtil.interpolate = function(normValue, minimum, maximum){ 25         return minimum + (maximum - minimum) * normValue; 26     }; 27  28     //map a value from one set to another 29     Sakri.MathUtil.map = function(value, min1, max1, min2, max2){ 30         return Sakri.MathUtil.interpolate( Sakri.MathUtil.normalize(value, min1, max1), min2, max2); 31     }; 32  33     Sakri.MathUtil.getRandomNumberInRange = function(min, max){ 34         return min + Math.random() * (max - min); 35     }; 36      37     Sakri.MathUtil.getRandomIntegerInRange = function(min, max){ 38         return Math.round(Sakri.MathUtil.getRandomNumberInRange(min, max)); 39     }; 40  41      42 }(window)); 43  44 (function (window){ 45  46     var Sakri = window.Sakri || {}; 47     window.Sakri = window.Sakri || Sakri; 48  49       Sakri.Geom = {}; 50  51     //================================================== 52     //=====================::POINT::==================== 53     //================================================== 54  55     Sakri.Geom.Point = function (x,y){ 56         this.x = isNaN(x) ? 0 : x; 57         this.y = isNaN(y) ? 0 : y; 58     }; 59  60     Sakri.Geom.Point.prototype.clone = function(){ 61         return new Sakri.Geom.Point(this.x,this.y); 62     }; 63  64     Sakri.Geom.Point.prototype.update = function(x, y){ 65         this.x = isNaN(x) ? this.x : x; 66         this.y = isNaN(y) ? this.y : y; 67     }; 68  69     Sakri.Geom.Point.prototype.equals = function(point){ 70         return this.x==point.x && this.y==point.y; 71     }; 72  73     Sakri.Geom.Point.prototype.toString = function(){ 74         return "{x:"+this.x+" , y:"+this.y+"}"; 75     }; 76  77  78      79     //================================================== 80     //===================::RECTANGLE::================== 81     //================================================== 82  83     Sakri.Geom.Rectangle = function (x, y, width, height){ 84         this.update(x, y, width, height); 85     }; 86      87     Sakri.Geom.Rectangle.prototype.update = function(x, y, width, height){ 88         this.x = isNaN(x) ? 0 : x; 89         this.y = isNaN(y) ? 0 : y; 90         this.width = isNaN(width) ? 0 : width; 91         this.height = isNaN(height) ? 0 : height; 92     }; 93  94    95     Sakri.Geom.Rectangle.prototype.getRight = function(){ 96         return this.x + this.width; 97     }; 98      99     Sakri.Geom.Rectangle.prototype.getBottom = function(){100         return this.y + this.height;101     };102 103     Sakri.Geom.Rectangle.prototype.getCenterX = function(){104         return this.x + this.width/2;105     };106 107     Sakri.Geom.Rectangle.prototype.getCenterY = function(){108         return this.y + this.height/2;109     };110 111     Sakri.Geom.Rectangle.prototype.containsPoint = function(x, y){112         return x >= this.x && y >= this.y && x <= this.getRight() && y <= this.getBottom();113     };114 115     116     Sakri.Geom.Rectangle.prototype.clone = function(){117         return new Sakri.Geom.Rectangle(this.x, this.y, this.width, this.height);118     };119     120     Sakri.Geom.Rectangle.prototype.toString = function(){121         return "Rectangle{x:"+this.x+" , y:"+this.y+" , width:"+this.width+" , height:"+this.height+"}";122     };123     124 }(window)); 125 126 (function (window){127 128     var Sakri = window.Sakri || {};129     window.Sakri = window.Sakri || Sakri;130 131     Sakri.CanvasTextUtil = {};132 133     //returns the biggest font size that best fits into rect134     Sakri.CanvasTextUtil.getFontSizeForRect = function(string, fontProps, rect, canvas, fillStyle){135         if(!canvas){136             var canvas = document.createElement("canvas");137         }138         if(!fillStyle){139             fillStyle = "#000000";140         }141         var context = canvas.getContext(‘2d‘);142         context.font = fontProps.getFontString();143         context.textBaseline = "top";144 145         var copy = fontProps.clone();146         //console.log("getFontSizeForRect() 1  : ", copy.fontSize);147         context.font = copy.getFontString();148         var width = context.measureText(string).width;149         //console.log(width, rect.width);150 151         //SOME DISAGREEMENT WHETHER THIS SHOOULD BE WITH && or ||152         if(width < rect.width){153             while(context.measureText(string).width < rect.width || copy.fontSize*1.5 < rect.height){154                 copy.fontSize++;155                 context.font = copy.getFontString();156             }157         }else if(width > rect.width){158             while(context.measureText(string).width > rect.width || copy.fontSize*1.5 > rect.height){159                 copy.fontSize--;160                 context.font = copy.getFontString();161             }162         }163         //console.log("getFontSizeForRect() 2  : ", copy.fontSize);164         return copy.fontSize;165     }166 167     //=========================================================================================168     //==============::CANVAS TEXT PROPERTIES::====================================169     //========================================================170 171     Sakri.CanvasTextProperties = function(fontWeight, fontStyle, fontSize, fontFace){172         this.setFontWeight(fontWeight);173         this.setFontStyle(fontStyle);174         this.setFontSize(fontSize);175         this.fontFace = fontFace ? fontFace : "sans-serif";176     };177 178     Sakri.CanvasTextProperties.NORMAL = "normal";179     Sakri.CanvasTextProperties.BOLD = "bold";180     Sakri.CanvasTextProperties.BOLDER = "bolder";181     Sakri.CanvasTextProperties.LIGHTER = "lighter";182 183     Sakri.CanvasTextProperties.ITALIC = "italic";184     Sakri.CanvasTextProperties.OBLIQUE = "oblique";185 186 187     Sakri.CanvasTextProperties.prototype.setFontWeight = function(fontWeight){188         switch (fontWeight){189             case Sakri.CanvasTextProperties.NORMAL:190             case Sakri.CanvasTextProperties.BOLD:191             case Sakri.CanvasTextProperties.BOLDER:192             case Sakri.CanvasTextProperties.LIGHTER:193                 this.fontWeight = fontWeight;194                 break;195             default:196                 this.fontWeight = Sakri.CanvasTextProperties.NORMAL;197         }198     };199 200     Sakri.CanvasTextProperties.prototype.setFontStyle = function(fontStyle){201         switch (fontStyle){202             case Sakri.CanvasTextProperties.NORMAL:203             case Sakri.CanvasTextProperties.ITALIC:204             case Sakri.CanvasTextProperties.OBLIQUE:205                 this.fontStyle = fontStyle;206                 break;207             default:208                 this.fontStyle = Sakri.CanvasTextProperties.NORMAL;209         }210     };211 212     Sakri.CanvasTextProperties.prototype.setFontSize = function(fontSize){213         if(fontSize && fontSize.indexOf && fontSize.indexOf("px")>-1){214             var size = fontSize.split("px")[0];215             fontProperites.fontSize = isNaN(size) ? 24 : size;//24 is just an arbitrary number216             return;217         }218         this.fontSize = isNaN(fontSize) ? 24 : fontSize;//24 is just an arbitrary number219     };220 221     Sakri.CanvasTextProperties.prototype.clone = function(){222         return new Sakri.CanvasTextProperties(this.fontWeight, this.fontStyle, this.fontSize, this.fontFace);223     };224 225     Sakri.CanvasTextProperties.prototype.getFontString = function(){226         return this.fontWeight + " " + this.fontStyle + " " + this.fontSize + "px " + this.fontFace;227     };228 229 }(window));230 231 232 window.requestAnimationFrame =233         window.__requestAnimationFrame ||234                 window.requestAnimationFrame ||235                 window.webkitRequestAnimationFrame ||236                 window.mozRequestAnimationFrame ||237                 window.oRequestAnimationFrame ||238                 window.msRequestAnimationFrame ||239                 (function () {240                     return function (callback, element) {241                         var lastTime = element.__lastTime;242                         if (lastTime === undefined) {243                             lastTime = 0;244                         }245                         var currTime = Date.now();246                         var timeToCall = Math.max(1, 33 - (currTime - lastTime));247                         window.setTimeout(callback, timeToCall);248                         element.__lastTime = currTime + timeToCall;249                     };250                 })();251 252 var readyStateCheckInterval = setInterval( function() {253     if (document.readyState === "complete") {254         clearInterval(readyStateCheckInterval);255         init();256     }257 }, 10);258 259 //========================260 //general properties for demo set up261 //========================262 263 var canvas;264 var context;265 var canvasContainer;266 var htmlBounds;267 var bounds;268 var minimumStageWidth = 300;269 var minimumStageHeight = 300;270 var maxStageWidth = 800;271 var maxStageHeight = 1100;272 var resizeTimeoutId = -1;273 //var stats;274 275 function init(){276     canvasContainer = document.getElementById("canvasContainer");277     window.onresize = resizeHandler;278     //stats = new Stats();279     //canvasContainer.appendChild( stats.getDisplayElement() );280     window.addEventListener( "keydown", keyUpEventHandler, false )281     commitResize();282 }283 284 function getWidth( element ){return Math.max(element.scrollWidth,element.offsetWidth,element.clientWidth );}285 function getHeight( element ){return Math.max(element.scrollHeight,element.offsetHeight,element.clientHeight );}286 287 //avoid running resize scripts repeatedly if a browser window is being resized by dragging288 function resizeHandler(){289     context.clearRect(0,0,canvas.width, canvas.height);290     clearTimeout(resizeTimeoutId);291     clearTimeoutsAndIntervals();292     resizeTimeoutId = setTimeout(commitResize, 300 );293 }294 295 function commitResize(){296     if(canvas){297         canvasContainer.removeChild(canvas);298     }299     canvas = document.createElement(‘canvas‘);300     canvas.style.position = "absolute";301     context = canvas.getContext("2d");302     canvasContainer.appendChild(canvas);303 304     htmlBounds = new Sakri.Geom.Rectangle(0,0, getWidth(canvasContainer) , getHeight(canvasContainer));305     if(htmlBounds.width >= maxStageWidth){306         canvas.width = maxStageWidth;307         canvas.style.left = htmlBounds.getCenterX() - (maxStageWidth/2)+"px";308     }else{309         canvas.width = htmlBounds.width;310         canvas.style.left ="0px";311     }312     if(htmlBounds.height > maxStageHeight){313         canvas.height = maxStageHeight;314         canvas.style.top = htmlBounds.getCenterY() - (maxStageHeight/2)+"px";315     }else{316         canvas.height = htmlBounds.height;317         canvas.style.top ="0px";318     }319     bounds = new Sakri.Geom.Rectangle(0,0, canvas.width, canvas.height);320     context.clearRect(0,0,canvas.width, canvas.height);321 322     if(bounds.width<minimumStageWidth || bounds.height<minimumStageHeight){323         stageTooSmallHandler();324         return;325     }326 327     var textInputSpan = document.getElementById("textInputSpan");328     var textInputSpanY = (canvas.height - canvas.height*.85)/2 + 15;//15 is an estimate for half of textInputHeight329     textInputSpan.style.top = htmlBounds.getCenterY() + (bounds.height/2) - textInputSpanY +"px";330     textInputSpan.style.left = (htmlBounds.getCenterX() - getWidth(textInputSpan)/2)+"px";331 332     startDemo();333 }334 335 function stageTooSmallHandler(){336     var warning = "Sorry, bigger screen required :(";337     context.font = "bold normal 24px sans-serif";338     context.fillText(warning, bounds.getCenterX() - context.measureText(warning).width/2, bounds.getCenterY()-12);339 }340 341 342 343 344 //========================345 //Demo specific properties346 //========================347 348 349     var HOME = 0;350     var GAME = 1;351     var GAME_OVER = 2;352     var gameState;353     var scrollSpeed = 3;354     var score;355     var fontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 100);356 357     var word = "张董";358 359     function startDemo(){360         canvas.addEventListener(‘touchstart‘, handleUserTap, false);361         canvas.addEventListener(‘mousedown‘, handleUserTap, false);362 363         var logoText = "飞翔的字母";364         if(!logoCanvas){365             logoCanvas = document.createElement("canvas");366             logoCanvasBG = document.createElement("canvas");367         }368         createLogo("飞翔的字母", logoCanvas, logoCanvasBG);369         if(!gameOverCanvas){370             gameOverCanvas = document.createElement("canvas");371             gameOverCanvasBG = document.createElement("canvas");372         }373         createLogo("行了 到此为止吧", gameOverCanvas, gameOverCanvasBG);374 375         createGroundPattern();376         createBird();377         createTubes();378         createCityGraphic();379         score = 0;380         gameState = HOME;381         loop();382     }383 384     function loop(){385         switch(gameState){386             case HOME:387                 renderHome();388                 break;389             case GAME :390                 renderGame();391                 break;392             case GAME_OVER:393                 renderGameOver();394                 break;395         }396         //stats.tick();397     }398 399     function handleUserTap(event){400         switch(gameState){401             case HOME:402                 gameState = GAME;403                 break;404             case GAME :405                 birdYSpeed = -tapBoost;406                 break;407             case GAME_OVER:408                 commitResize();409                 break;410         }411         if(event){412             event.preventDefault();413         }414     }415 416     function keyUpEventHandler(event){417         //event.keyCode == 32 -> Space418         if(event.keyCode == 38){419             handleUserTap(event);420         }421     }422 423     function renderHome(){424         context.clearRect(0, 0, canvas.width, canvas.height);425         renderGroundPattern();426         renderLogo();427         renderInstructions();428         window.requestAnimationFrame(loop, canvas);429     }430 431     function renderGame(){432         context.clearRect(0, 0, canvas.width, canvas.height);433         updateTubes();434         renderTubes();435         updateBird();436         if(!characters.length){437             gameOverHandler();438             return;439         }440         renderBird();441         renderGroundPattern();442         updateScore();443         renderScore();444         window.requestAnimationFrame(loop, canvas);445     }446 447     function gameOverHandler(){448         context.clearRect(0, 0, canvas.width, canvas.height);449         gameState = GAME_OVER;450         renderGameOver();451     }452 453     function renderGameOver(){454 455         //game over logo456         context.drawImage(gameOverCanvas, bounds.getCenterX() - logoCanvas.width/2, canvas.height *.2);457 458         var instruction = "点击重新任性、";459         context.font = "bold normal 24px sans-serif";460         context.fillStyle = "#FFFFFF";461         context.fillText(instruction, bounds.getCenterX() - context.measureText(instruction).width/2, canvas.height *.25 + gameOverCanvas.height);462         renderScore();463 464         //window.requestAnimationFrame(loop, canvas);465     }466 467     function renderLogo(){468         logoCurrentY += logoDirection;469         context.drawImage(logoCanvas, bounds.getCenterX() - logoCanvas.width/2, logoCurrentY);470         if(logoCurrentY <= logoY || logoCurrentY >= logoMaxY){471             logoDirection *= -1;472         }473     }474 475     function renderInstructions(){476         var instruction = "飞翔的字母 - 孤影";477         context.font = "bold normal 24px sans-serif";478         context.fillStyle = "#FFFFFF";479         context.fillText(instruction, bounds.getCenterX() - context.measureText(instruction).width/2, canvas.height *.2);480     }481 482     function renderScore(){483         context.font = fontProperties.getFontString();484         context.fillStyle = "#FFFFFF";485         context.strokeStyle = "#000000";486         context.lineWidth = 3;487         var x = bounds.getCenterX() - context.measureText(score).width/2;488         var y = bounds.height*.1;489         context.fillText(score, x, y);490         context.strokeText(score, x, y);491     }492 493     //========================================================================494     //========================:: LOGO ::======================================495     //========================================================================496 497     var logoCanvas;498     var logoCanvasBG;499 500     var gameOverCanvas;501     var gameOverCanvasBG;502 503     var logoY;504     var logoCurrentY;505     var logoMaxY;506     var logoDirection;507 508     function createLogo(logoText, logoCanvas, logoCanvassBG){509         logoCanvas.width = logoCanvasBG.width = canvas.width;510         logoCanvas.height = logoCanvasBG.height = canvas.height / 4;511         logoCurrentY = logoY = canvas.height * .25;512         logoMaxY = canvas.height * .35;513         logoDirection = 1;514         var logoContext = logoCanvas.getContext("2d");515         logoContext.textBaseline = "top";516         var textRect = new Sakri.Geom.Rectangle(0, 0, logoCanvas.width * .8, logoCanvas.height);517         var logoFontProps = fontProperties.clone();518         logoFontProps.fontSize = Sakri.CanvasTextUtil.getFontSizeForRect(logoText, fontProperties, textRect);519 520 521         var logoBGContext = logoCanvasBG.getContext("2d");522         logoBGContext.fillStyle = "#f5eea5";523         logoBGContext.fillRect(0, 0, logoCanvasBG.width, logoCanvasBG.height);524         logoBGContext.fillStyle = "#9ce358";525         logoBGContext.fillRect(0, logoFontProps.fontSize/2, logoCanvasBG.width, logoCanvasBG.height);526 527         logoContext.font = logoFontProps.getFontString();528         logoContext.fillStyle = logoContext.createPattern(logoCanvasBG, "repeat-x");529         logoContext.strokeStyle = "#000000";530         logoContext.lineWidth = 3;531         var x = logoCanvas.width/2 - logoContext.measureText(logoText).width/2;532         var y = logoFontProps.fontSize/2;533         logoContext.fillText(logoText, x, 0);534         logoContext.strokeText(logoText, x, 0);535     }536 537     //========================================================================538     //========================:: BIRD ::==================================539     //========================================================================540 541     var birdCanvas;542     var birdYSpeed = 0;543     var gravity = 1;544     var tapBoost = 12;545     var birdSize = 60;546 547     function updateBird(){548         characters[0].y += birdYSpeed;549         birdYSpeed += gravity;550 551         //floor552         if(characters[0].y >= groundGraphicRect.y - birdCanvas.height){553             characters[0].y = groundGraphicRect.y - birdCanvas.height;554             birdYSpeed = 0;555         }556         //celing557         if(characters[0].y<=0){558             characters[0].y = 1;559             birdYSpeed = 0;560         }561         //tube collision562         if(!isHit && checkTubesCollision()){563             context.fillStyle = "#FFFFFF";564             context.fillRect(0,0,canvas.width, canvas.height);565             removeCharacter();566             isHit = true;567         }568     }569 570     var currentTube;571     var isHit = false;572     var ffScoreBugFix = 0;// for some reason the score would fire multiple times on firefox573 574     function updateScore(){575         if(ffScoreBugFix>10 && currentTube.topRect.getRight() < characters[0].x){576             if(!isHit){577                 score++;578             }579             isHit = false;580             var index = tubes.indexOf(currentTube) + 1;581             index %= tubes.length;582             currentTube = tubes[index];583             ffScoreBugFix = 0;584         }585         ffScoreBugFix++;586     }587 588     function renderBird(){589         context.drawImage(characters[0].image, characters[0].x, characters[0].y );590         for(var i = 1; i < characters.length; i++){591              characters[i].y = characters[i-1].y - (characters[i-1].y - characters[i].y) * .9;592              context.drawImage(characters[i].image, characters[i].x, characters[i].y );593         }594     }595 596     function removeCharacter(){597         if(characters.length==1){598             //game over599             gameState = GAME_OVER;600         }601         for(var i=0; i<characters.length-1;i++){602             characters[i].image = characters[i+1].image;603         }604         characters.pop();605     }606 607     function checkTubesCollision(){608         for(var i= 0; i<tubes.length;i++){609             if(checkTubeCollision(tubes[i])){610                 return true;611             }612         }613         return false;614     }615 616 617     var collisionPoint = new Sakri.Geom.Point();618     var birdPoints = [];619 620     function checkTubeCollision(tube){621         birdPoints[0] = characters[0].x;622         birdPoints[1] = characters[0].y;623         birdPoints[2] = characters[0].x + birdSize;624         birdPoints[3] = characters[0].y;625         birdPoints[4] = characters[0].x + birdSize;626         birdPoints[5] = characters[0].y + birdSize;627         birdPoints[6] = characters[0].x;628         birdPoints[7] = characters[0].y + birdSize;629         for(var i=0; i<8; i+=2){630             collisionPoint.x = birdPoints[i];631             collisionPoint.y = birdPoints[i+1];632             if(tube.topRect.containsPoint(collisionPoint.x, collisionPoint.y) || tube.bottomRect.containsPoint(collisionPoint.x, collisionPoint.y)){633                 return true;634             }635         }636         return false;637     }638 639     var characters;640     var birdFontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 50);641 642     function createBird(){643 644         if(!birdCanvas){645             birdCanvas = document.createElement("canvas");646         }647         birdCanvas.width = birdSize;648         birdCanvas.height = birdSize;649 650         characters = [];651         characters[0] = {}652         characters[0].x = canvas.width / 3;653         characters[0].y = groundGraphicRect.y / 2;654         characters[0].image = createCharacterImage(word.charAt(word.length - 1));655 656         var x = characters[0].x -(birdCanvas.width + birdCanvas.width*.2);657         for(var i=1; i<word.length ; i++){658             characters[i] = {};659             characters[i].x = x;660             characters[i].y = characters[0].y;661             x -= (birdCanvas.width + birdCanvas.width*.2);662             characters[i].image = createCharacterImage(word.charAt(word.length - i - 1));663         }664     }665 666     function createCharacterImage(character){667         var birdContext = birdCanvas.getContext("2d");668         birdContext.textBaseline = "top";669 670         birdContext.font = birdFontProperties.getFontString();671         birdContext.fillStyle = "#d5bb22";672         birdContext.fillRect(0, 0, birdSize, birdSize/2);673         birdContext.fillStyle = "#e97b13";674         birdContext.fillRect(0, birdSize/2, birdSize, birdSize/2);675         //hilite676         birdContext.fillStyle = "#e0e9a9";677         birdContext.fillRect(0, 0, birdSize, 6);678         //"mouth"679         birdContext.fillStyle = "#da473b";680         birdContext.fillRect(0, birdSize - 10, birdSize, birdSize);681 682         birdContext.lineWidth = 3;683         birdContext.strokeStyle = "#4d2f3b";684         birdContext.strokeRect(2, 2, birdSize-4, birdSize-4);685 686         birdContext.fillStyle = "#e8fcd6";687         birdContext.fillText(character, birdSize/2 - birdContext.measureText(character).width/2, 0);688         birdContext.strokeText(character, birdSize/2 - birdContext.measureText(character).width/2, 0);689 690         var image = new Image();691         image.width = birdSize;692         image.height = birdSize;693         image.src =http://www.mamicode.com/ birdCanvas.toDataURL();694         return image;695     }696 697 698     //========================================================================699     //========================:: TUBES ::==================================700     //========================================================================701 702     var tubeGapHeight = 230;//needs some logic703     var tubesGapWidth;704     var tubes;705     var tubeWidth = 100;//needs some logic706     var minTubeHeight = 50;//needs some logic707 708     function updateTubes(){709         for(var i= 0; i<tubes.length;i++){710             updateTube(tubes[i]);711         }712     }713 714     function updateTube(tube){715         tube.topRect.x -= scrollSpeed;716         tube.bottomRect.x = tube.topRect.x;717         if(tube.topRect.x <= -tubeWidth ){718             tube.topRect.x = tube.bottomRect.x = canvas.width;719             renderTube(tube);720         }721     }722 723 724     function renderTubes(){725         for(var i= 0; i<tubes.length;i++){726             context.drawImage(tubes[i].canvas, tubes[i].bottomRect.x, 0);727         }728     }729 730     function createTubes(){731         tubes = [];732         var totalTubes = 2;733         tubesGapWidth = Math.floor(canvas.width/totalTubes);734 735         for(var i = 0; i < totalTubes; i++){736             tubes[i] = {};737             tubes[i].canvas = document.createElement("canvas");738             tubes[i].topRect = new Sakri.Geom.Rectangle(canvas.width+(i * tubesGapWidth));739             tubes[i].bottomRect = new Sakri.Geom.Rectangle(canvas.width+(i * tubesGapWidth));740             renderTube(tubes[i]);741         }742         currentTube = tubes[0];743     }744 745     var tubeOutlineColor = "#534130";746     var tubeMainColor = "#75be2f";747     var tubeCapHeight = 40;748 749     function renderTube(tube){750         tube.canvas.width = tubeWidth;751         tube.canvas.height = groundGraphicRect.y;752 753         tube.bottomRect.width = tube.topRect.width = tubeWidth;754         tube.topRect.y = 0;755         tube.topRect.height = minTubeHeight + Math.round(Math.random()*(groundGraphicRect.y-tubeGapHeight-minTubeHeight*2));756 757         tube.bottomRect.y = tube.topRect.getBottom() + tubeGapHeight;758         tube.bottomRect.height = groundGraphicRect.y - tube.bottomRect.y - 1;//minus one for stroke759 760         var tubeContext = tube.canvas.getContext("2d");761         tubeContext.lineWidth = 2;762         //top tube763         renderTubeElement(tubeContext , 3, 0, tubeWidth-6, tube.topRect.height);764         renderTubeElement(tubeContext , 1, tube.topRect.getBottom() - tubeCapHeight, tubeWidth-2, tubeCapHeight);765 766         //bottom tube767         renderTubeElement(tubeContext , 3, tube.bottomRect.y, tubeWidth-6, tube.bottomRect.height);768         renderTubeElement(tubeContext , 1, tube.bottomRect.y, tubeWidth-2, tubeCapHeight);769     }770 771     function renderTubeElement(ctx, x, y, width, height){772         ctx.fillStyle = tubeMainColor;773         ctx.fillRect(x, y, width, height);774         ctx.fillStyle = "#9de85a";775         ctx.fillRect(x, y, width*.25, height);776 777         ctx.fillStyle = "#d9f881";778         ctx.fillRect(x+width *.05, y, width *.05, height);779 780         ctx.fillStyle = "#547e25";781         ctx.fillRect(x+width- width * .1, y, width *.1, height);782         ctx.fillRect(x+width- width * .2, y, width *.05, height);783 784         ctx.strokeRect(x, y, width, height);785     }786 787 788     //========================================================================789     //========================:: CITY BG ::==================================790     //========================================================================791 792 var cityGraphicCanvas;793 794 function createCityGraphic(){795 796     if(cityGraphicCanvas){797         canvasContainer.removeChild(cityGraphicCanvas);798     }799     cityGraphicCanvas = document.createElement("canvas");800     cityGraphicCanvas.style.position = "absolute";801     cityGraphicCanvas.style.left = canvas.style.left;802     cityGraphicCanvas.style.top = canvas.style.top;803     cityGraphicCanvas.width = canvas.width;804     cityGraphicCanvas.height = canvas.height;805     var cgContext = cityGraphicCanvas.getContext("2d");806     var cityGraphicHeight = canvas.height * .25;807 808     //fill with blue sky809     cgContext.fillStyle = "#71c5cf";810     cgContext.fillRect(0, 0, canvas.width, canvas.height);811 812     cgContext.fillStyle = "#e9fad8";813 814     cgContext.save();815     cgContext.translate(0, groundGraphicRect.y - cityGraphicHeight);816 817     //CLOUDS818     var maxCloudRadius = cityGraphicHeight * .4;819     var minCloudRadius = maxCloudRadius * .5;820 821     for(iterator=0; iterator<canvas.width; iterator+=minCloudRadius){822         cgContext.beginPath();823         cgContext.arc( iterator , maxCloudRadius, Sakri.MathUtil.getRandomNumberInRange(minCloudRadius, maxCloudRadius), 0, Sakri.MathUtil.PI2);824         cgContext.closePath();825         cgContext.fill();826     }827 828     cgContext.fillRect(0,maxCloudRadius, canvas.width, cityGraphicHeight );829 830     //HOUSES831     var houseWidth;832     var houseHeight;833     cgContext.fillStyle = "#deefcb";834     for(iterator=0; iterator<canvas.width; iterator+=(houseWidth+8)){835         houseWidth = 20 + Math.floor(Math.random()*30);836         houseHeight = Sakri.MathUtil.getRandomNumberInRange(cityGraphicHeight *.5 , cityGraphicHeight - maxCloudRadius *.8);837         cgContext.fillRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight);838     }839 840     cgContext.fillStyle = "#dff1c4";841     cgContext.strokeStyle = "#9fd5d5";842     cgContext.lineWidth = 3;843     for(iterator=0; iterator<canvas.width; iterator+=(houseWidth+8)){844         houseWidth = 20 + Math.floor(Math.random()*30);845         houseHeight = Sakri.MathUtil.getRandomNumberInRange(cityGraphicHeight *.5 , cityGraphicHeight - maxCloudRadius *.8);846         cgContext.fillRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight);847         cgContext.strokeRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight);848     }849 850     //TREES851     var maxTreeRadius = cityGraphicHeight * .3;852     var minTreeRadius = maxTreeRadius * .5;853     var radius;854     var strokeStartRadian = Math.PI + Math.PI/4;855     var strokeEndRadian = Math.PI + Math.PI/4;856     cgContext.fillStyle = "#81e18b";857     cgContext.strokeStyle = "#72c887";858     for(iterator=0; iterator<canvas.width; iterator+=minTreeRadius){859         cgContext.beginPath();860         radius = Sakri.MathUtil.getRandomNumberInRange(minCloudRadius, maxCloudRadius)861         cgContext.arc( iterator , cityGraphicHeight, radius, 0, Sakri.MathUtil.PI2);862         cgContext.closePath();863         cgContext.fill();864 865         cgContext.beginPath();866         cgContext.arc( iterator , cityGraphicHeight, radius, strokeStartRadian, strokeEndRadian);867         cgContext.closePath();868         cgContext.stroke();869     }870 871     cgContext.restore();872     //sand873     cgContext.fillStyle = sand;874     cgContext.fillRect(0,groundGraphicRect.y, canvas.width, canvas.height);875 876     canvasContainer.insertBefore(cityGraphicCanvas, canvasContainer.firstChild);877 }878 879 880     //========================================================================881     //========================:: GROUND ::==================================882     //========================================================================883 884     var groundX = 0;885     function renderGroundPattern(){886         context.drawImage(groundPatternCanvas, groundX, groundGraphicRect.y);887         groundX -= scrollSpeed;888         groundX %= 16;889     }890 891 892     //colors893     var groundLightGreen = "#97e556";894     var groundDarkGreen = "#73be29";895     var groundDarkerGreen = "#4b7e19";896     var groundShadow = "#d1a649";897     var groundBorder = "#4c3f48";898     var sand = "#dcd795";899     var groundGraphicRect = new Sakri.Geom.Rectangle();900     var groundPatternCanvas;901 902     function createGroundPattern(){903         groundGraphicRect.y = canvas.height*.85;904         if(!groundPatternCanvas){905             groundPatternCanvas = document.createElement("canvas");906         }907         groundPatternCanvas.width = 16;908         groundPatternCanvas.height = 16;909         var groundContext = groundPatternCanvas.getContext("2d");910         groundContext.fillStyle = groundLightGreen;911         groundContext.fillRect(0,0,16,16);912 913         //diagonal graphic914         groundContext.fillStyle = groundDarkGreen;915         groundContext.beginPath();916         groundContext.moveTo(8,3);917         groundContext.lineTo(16,3);918         groundContext.lineTo(8,13);919         groundContext.lineTo(0,13);920         groundContext.closePath();921         groundContext.fill();922 923         //top border924         groundContext.fillStyle = groundBorder;925         groundContext.globalAlpha = .2;926         groundContext.fillRect(0,0,16,1);927         groundContext.globalAlpha = 1;928         groundContext.fillRect(0,1,16,1);929         groundContext.globalAlpha = .6;930         groundContext.fillRect(0,2,16,1);931 932         //hilite933         groundContext.fillStyle = "#FFFFFF";934         groundContext.globalAlpha = .3;935         groundContext.fillRect(0,3,16,2);936 937         //bottom border938         groundContext.fillStyle = groundDarkerGreen;939         groundContext.globalAlpha = .3;940         groundContext.fillRect(0,10,16,3);941         groundContext.globalAlpha = 1;942         groundContext.fillRect(0,11,16,1);943 944         //shadow945         groundContext.fillStyle = groundShadow;946         groundContext.fillRect(0,13,16,3);947 948         var groundPattern = context.createPattern(groundPatternCanvas, "repeat-x");949 950         groundPatternCanvas.width = canvas.width + 16;951         groundPatternCanvas.height = 16;952 953         groundContext.fillStyle = groundPattern;954         groundContext.fillRect(0, 0, groundPatternCanvas.width, 16);955 956     }957 958     function clearTimeoutsAndIntervals(){959         gameState = -1;960     }961 962     var maxCharacters = 8;963 964     function changeText(){965         var textInput = document.getElementById("textInput");966         if(textInput.value && textInput.text!=""){967             if(textInput.value.length > maxCharacters){968                 alert("Sorry, there is only room for "+maxCharacters+" characters. Try a shorter name.");969                 return;970             }971             if(textInput.value.indexOf(" ")>-1){972                 alert("Sorry, no support for spaces right now :(");973                 return;974             }975             word = textInput.value;976             clearTimeoutsAndIntervals();977             animating = false;978             setTimeout(commitResize, 100);979         }980     }

 

CSS页面样式文件(style.css)如下:

 1 html, body{ 2     margin : 0px; 3     width : 100%; 4     height : 100%; 5     overflow: hidden; 6     background-color: #FFFFFF; 7 } 8  9 #canvasContainer{10     margin : 0px;11     width : 100%;12     height : 100%;13 }14 15 #textInputSpan{16     position: absolute;17     color: #000000;18     font-family: sans-serif;19 }

 

 

  如果需要源码 复制不了代码的,留言邮箱我给大家打包发过去。

 

  当然还有,不要忘了点赞哦~谢谢大家的支持。谢谢大家了,哈哈。

  (*^_^*)

 

 

原程序来自:HTML5资源教程

  

HTML5游戏源码 飞翔的字母 可自定义内容