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 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资源教程

  

【来自:张董'Blogs:http://www.cnblogs.com/LonelyShadow,转载请注明出处。】

亲们。码字不容易,觉得不错的话记得点赞哦。。

目录
相关文章
|
3天前
黑色个人主页HTML源码
黑色个人主页HTML源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面
24 6
黑色个人主页HTML源码
|
5天前
漂亮的七彩引导页导航HTML源码
漂亮的七彩引导页导航HTML源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
2 0
漂亮的七彩引导页导航HTML源码
|
6天前
|
移动开发 HTML5
HTML5漫画风格个人介绍源码
HTML5漫画风格个人介绍源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
11 0
HTML5漫画风格个人介绍源码
|
12天前
2024个人导航HTML源码
2024个人导航HTML源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
14 0
2024个人导航HTML源码
|
16天前
|
移动开发 HTML5
唯美首页纯静态html源码
唯美首页纯静态html5引导页源码,格子化win8风格官方引导页面源码
12 0
唯美首页纯静态html源码
|
16天前
漂亮的个人主页HTML源码
漂亮的个人主页HTML源码
13 0
漂亮的个人主页HTML源码
|
17天前
一款简约单双页版HTML源码
开源的单页个人主页纯静态源码、目前有两个主页版本:master单页版、double双页版、非常漂亮的单页HTML源码
12 1
一款简约单双页版HTML源码
|
1月前
|
前端开发 容器 内存技术
使用CSS3画出一个叮当猫HTML源码
本文教程介绍了如何使用CSS3绘制叮当猫,通过HTML结构和CSS样式逐步构建叮当猫的各个部位,如头部、脸部、脖子、身体、手脚等。代码示例展示了如何利用渐变、边框、阴影和定位技巧实现三维效果和细节特征。此外,还添加了眼珠的动画效果,让叮当猫的眼睛能够转动。整个过程适合对CSS3感兴趣的读者参考学习,以提升动态图形创作技能。
16 0
使用CSS3画出一个叮当猫HTML源码
|
1月前
酷炫的粒子动态表白HTML源码
酷炫的粒子动态表白HTML源码,自己自定义文字,动态组合文字,进行表白,喜欢的朋友可以下载使用,很不错的表白HTML代码
20 0
酷炫的粒子动态表白HTML源码
|
1月前
六个好看实用的html简单登录页面源码
六个好看实用的html简单登录页面源码
19 0
六个好看实用的html简单登录页面源码