zoukankan      html  css  js  c++  java
  • 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+" , "+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 rect
    134     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 number
    216             return;
    217         }
    218         this.fontSize = isNaN(fontSize) ? 24 : fontSize;//24 is just an arbitrary number
    219     };
    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 up
    261 //========================
    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 dragging
    288 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 textInputHeight
    329     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 properties
    346 //========================
    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 -> Space
    418         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 logo
    456         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         //floor
    552         if(characters[0].y >= groundGraphicRect.y - birdCanvas.height){
    553             characters[0].y = groundGraphicRect.y - birdCanvas.height;
    554             birdYSpeed = 0;
    555         }
    556         //celing
    557         if(characters[0].y<=0){
    558             characters[0].y = 1;
    559             birdYSpeed = 0;
    560         }
    561         //tube collision
    562         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 firefox
    573 
    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 over
    599             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         //hilite
    676         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 = birdCanvas.toDataURL();
    694         return image;
    695     }
    696 
    697 
    698     //========================================================================
    699     //========================:: TUBES ::==================================
    700     //========================================================================
    701 
    702     var tubeGapHeight = 230;//needs some logic
    703     var tubesGapWidth;
    704     var tubes;
    705     var tubeWidth = 100;//needs some logic
    706     var minTubeHeight = 50;//needs some logic
    707 
    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 stroke
    759 
    760         var tubeContext = tube.canvas.getContext("2d");
    761         tubeContext.lineWidth = 2;
    762         //top tube
    763         renderTubeElement(tubeContext , 3, 0, tubeWidth-6, tube.topRect.height);
    764         renderTubeElement(tubeContext , 1, tube.topRect.getBottom() - tubeCapHeight, tubeWidth-2, tubeCapHeight);
    765 
    766         //bottom tube
    767         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 sky
    809     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     //CLOUDS
    818     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     //HOUSES
    831     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     //TREES
    851     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     //sand
    873     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     //colors
    893     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 graphic
    914         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 border
    924         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         //hilite
    933         groundContext.fillStyle = "#FFFFFF";
    934         groundContext.globalAlpha = .3;
    935         groundContext.fillRect(0,3,16,2);
    936 
    937         //bottom border
    938         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         //shadow
    945         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资源教程

      

  • 相关阅读:
    多阶段构建Docker镜像
    Docker容器跨主机通信
    数说海南——简单分析海南各市县近六年人口吸引力情况
    数说海南——透过几组数据简单分析近十年海南人口情况
    Kubernetes1.7—DNS安装
    BP神经网络
    Centos7——NFS(Network File System)服务
    Kafka中时间轮分析与Java实现
    Centos安装完成后,ifconfig:command not found
    Oracle VM VirtualBox虚拟机安装Centos
  • 原文地址:https://www.cnblogs.com/geeksss/p/4216812.html
Copyright © 2011-2022 走看看