HTML5游戏源码 飞翔的字母 可自定义内容
相信大家都玩过飞翔的小鸟吧,当然,可能已经有很多人因为这个游戏砸了不少手机。吼吼。
废话不多说,回到主题,源码如下。
博客园上传空间大小有限制,没法上传了,需要打包源码的朋友们请留言邮箱地址。当然还有,不要忘了点赞哦~谢谢大家的支持。
直接上源码:一共是三个文件:页面、js、css。
HTML(index.html)页面源码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>飞翔的字母 - 孤影</title> <link rel="stylesheet" href="style.css" media="screen" type="text/css" /> </head> <body> <div id="canvasContainer"></div> <span id="textInputSpan"> 1.输入内容,2.点击屏幕开始游戏,请输入内容(最大8个字符): <input id="textInput" maxlength="10" type="text" width="150" /> <button onclick="changeText()">确定!</button> </span> <script src="index.js"></script> </body> </html>
JavaScript脚本文件(index.js)如下:
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri; Sakri.MathUtil = {}; //used for radiansToDegrees and degreesToRadians Sakri.MathUtil.PI_180 = Math.PI/180; Sakri.MathUtil.ONE80_PI = 180/Math.PI; //precalculations for values of 90, 270 and 360 in radians Sakri.MathUtil.PI2 = Math.PI*2; Sakri.MathUtil.HALF_PI = Math.PI/2; //return number between 1 and 0 Sakri.MathUtil.normalize = function(value, minimum, maximum){ return (value - minimum) / (maximum - minimum); }; //map normalized number to values Sakri.MathUtil.interpolate = function(normValue, minimum, maximum){ return minimum + (maximum - minimum) * normValue; }; //map a value from one set to another Sakri.MathUtil.map = function(value, min1, max1, min2, max2){ return Sakri.MathUtil.interpolate( Sakri.MathUtil.normalize(value, min1, max1), min2, max2); }; Sakri.MathUtil.getRandomNumberInRange = function(min, max){ return min + Math.random() * (max - min); }; Sakri.MathUtil.getRandomIntegerInRange = function(min, max){ return Math.round(Sakri.MathUtil.getRandomNumberInRange(min, max)); }; }(window)); (function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri; Sakri.Geom = {}; //================================================== //=====================::POINT::==================== //================================================== Sakri.Geom.Point = function (x,y){ this.x = isNaN(x) ? 0 : x; this.y = isNaN(y) ? 0 : y; }; Sakri.Geom.Point.prototype.clone = function(){ return new Sakri.Geom.Point(this.x,this.y); }; Sakri.Geom.Point.prototype.update = function(x, y){ this.x = isNaN(x) ? this.x : x; this.y = isNaN(y) ? this.y : y; }; Sakri.Geom.Point.prototype.equals = function(point){ return this.x==point.x && this.y==point.y; }; Sakri.Geom.Point.prototype.toString = function(){ return "{x:"+this.x+" , y:"+this.y+"}"; }; //================================================== //===================::RECTANGLE::================== //================================================== Sakri.Geom.Rectangle = function (x, y, width, height){ this.update(x, y, width, height); }; Sakri.Geom.Rectangle.prototype.update = function(x, y, width, height){ this.x = isNaN(x) ? 0 : x; this.y = isNaN(y) ? 0 : y; this.width = isNaN(width) ? 0 : width; this.height = isNaN(height) ? 0 : height; }; Sakri.Geom.Rectangle.prototype.getRight = function(){ return this.x + this.width; }; Sakri.Geom.Rectangle.prototype.getBottom = function(){ return this.y + this.height; }; Sakri.Geom.Rectangle.prototype.getCenterX = function(){ return this.x + this.width/2; }; Sakri.Geom.Rectangle.prototype.getCenterY = function(){ return this.y + this.height/2; }; Sakri.Geom.Rectangle.prototype.containsPoint = function(x, y){ return x >= this.x && y >= this.y && x <= this.getRight() && y <= this.getBottom(); }; Sakri.Geom.Rectangle.prototype.clone = function(){ return new Sakri.Geom.Rectangle(this.x, this.y, this.width, this.height); }; Sakri.Geom.Rectangle.prototype.toString = function(){ return "Rectangle{x:"+this.x+" , y:"+this.y+" , width:"+this.width+" , height:"+this.height+"}"; }; }(window)); (function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri; Sakri.CanvasTextUtil = {}; //returns the biggest font size that best fits into rect Sakri.CanvasTextUtil.getFontSizeForRect = function(string, fontProps, rect, canvas, fillStyle){ if(!canvas){ var canvas = document.createElement("canvas"); } if(!fillStyle){ fillStyle = "#000000"; } var context = canvas.getContext('2d'); context.font = fontProps.getFontString(); context.textBaseline = "top"; var copy = fontProps.clone(); //console.log("getFontSizeForRect() 1 : ", copy.fontSize); context.font = copy.getFontString(); var width = context.measureText(string).width; //console.log(width, rect.width); //SOME DISAGREEMENT WHETHER THIS SHOOULD BE WITH && or || if(width < rect.width){ while(context.measureText(string).width < rect.width || copy.fontSize*1.5 < rect.height){ copy.fontSize++; context.font = copy.getFontString(); } }else if(width > rect.width){ while(context.measureText(string).width > rect.width || copy.fontSize*1.5 > rect.height){ copy.fontSize--; context.font = copy.getFontString(); } } //console.log("getFontSizeForRect() 2 : ", copy.fontSize); return copy.fontSize; } //========================================================================================= //==============::CANVAS TEXT PROPERTIES::==================================== //======================================================== Sakri.CanvasTextProperties = function(fontWeight, fontStyle, fontSize, fontFace){ this.setFontWeight(fontWeight); this.setFontStyle(fontStyle); this.setFontSize(fontSize); this.fontFace = fontFace ? fontFace : "sans-serif"; }; Sakri.CanvasTextProperties.NORMAL = "normal"; Sakri.CanvasTextProperties.BOLD = "bold"; Sakri.CanvasTextProperties.BOLDER = "bolder"; Sakri.CanvasTextProperties.LIGHTER = "lighter"; Sakri.CanvasTextProperties.ITALIC = "italic"; Sakri.CanvasTextProperties.OBLIQUE = "oblique"; Sakri.CanvasTextProperties.prototype.setFontWeight = function(fontWeight){ switch (fontWeight){ case Sakri.CanvasTextProperties.NORMAL: case Sakri.CanvasTextProperties.BOLD: case Sakri.CanvasTextProperties.BOLDER: case Sakri.CanvasTextProperties.LIGHTER: this.fontWeight = fontWeight; break; default: this.fontWeight = Sakri.CanvasTextProperties.NORMAL; } }; Sakri.CanvasTextProperties.prototype.setFontStyle = function(fontStyle){ switch (fontStyle){ case Sakri.CanvasTextProperties.NORMAL: case Sakri.CanvasTextProperties.ITALIC: case Sakri.CanvasTextProperties.OBLIQUE: this.fontStyle = fontStyle; break; default: this.fontStyle = Sakri.CanvasTextProperties.NORMAL; } }; Sakri.CanvasTextProperties.prototype.setFontSize = function(fontSize){ if(fontSize && fontSize.indexOf && fontSize.indexOf("px")>-1){ var size = fontSize.split("px")[0]; fontProperites.fontSize = isNaN(size) ? 24 : size;//24 is just an arbitrary number return; } this.fontSize = isNaN(fontSize) ? 24 : fontSize;//24 is just an arbitrary number }; Sakri.CanvasTextProperties.prototype.clone = function(){ return new Sakri.CanvasTextProperties(this.fontWeight, this.fontStyle, this.fontSize, this.fontFace); }; Sakri.CanvasTextProperties.prototype.getFontString = function(){ return this.fontWeight + " " + this.fontStyle + " " + this.fontSize + "px " + this.fontFace; }; }(window)); window.requestAnimationFrame = window.__requestAnimationFrame || window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || (function () { return function (callback, element) { var lastTime = element.__lastTime; if (lastTime === undefined) { lastTime = 0; } var currTime = Date.now(); var timeToCall = Math.max(1, 33 - (currTime - lastTime)); window.setTimeout(callback, timeToCall); element.__lastTime = currTime + timeToCall; }; })(); var readyStateCheckInterval = setInterval( function() { if (document.readyState === "complete") { clearInterval(readyStateCheckInterval); init(); } }, 10); //======================== //general properties for demo set up //======================== var canvas; var context; var canvasContainer; var htmlBounds; var bounds; var minimumStageWidth = 300; var minimumStageHeight = 300; var maxStageWidth = 800; var maxStageHeight = 1100; var resizeTimeoutId = -1; //var stats; function init(){ canvasContainer = document.getElementById("canvasContainer"); window.onresize = resizeHandler; //stats = new Stats(); //canvasContainer.appendChild( stats.getDisplayElement() ); window.addEventListener( "keydown", keyUpEventHandler, false ) commitResize(); } function getWidth( element ){return Math.max(element.scrollWidth,element.offsetWidth,element.clientWidth );} function getHeight( element ){return Math.max(element.scrollHeight,element.offsetHeight,element.clientHeight );} //avoid running resize scripts repeatedly if a browser window is being resized by dragging function resizeHandler(){ context.clearRect(0,0,canvas.width, canvas.height); clearTimeout(resizeTimeoutId); clearTimeoutsAndIntervals(); resizeTimeoutId = setTimeout(commitResize, 300 ); } function commitResize(){ if(canvas){ canvasContainer.removeChild(canvas); } canvas = document.createElement('canvas'); canvas.style.position = "absolute"; context = canvas.getContext("2d"); canvasContainer.appendChild(canvas); htmlBounds = new Sakri.Geom.Rectangle(0,0, getWidth(canvasContainer) , getHeight(canvasContainer)); if(htmlBounds.width >= maxStageWidth){ canvas.width = maxStageWidth; canvas.style.left = htmlBounds.getCenterX() - (maxStageWidth/2)+"px"; }else{ canvas.width = htmlBounds.width; canvas.style.left ="0px"; } if(htmlBounds.height > maxStageHeight){ canvas.height = maxStageHeight; canvas.style.top = htmlBounds.getCenterY() - (maxStageHeight/2)+"px"; }else{ canvas.height = htmlBounds.height; canvas.style.top ="0px"; } bounds = new Sakri.Geom.Rectangle(0,0, canvas.width, canvas.height); context.clearRect(0,0,canvas.width, canvas.height); if(bounds.width<minimumStageWidth || bounds.height<minimumStageHeight){ stageTooSmallHandler(); return; } var textInputSpan = document.getElementById("textInputSpan"); var textInputSpanY = (canvas.height - canvas.height*.85)/2 + 15;//15 is an estimate for half of textInputHeight textInputSpan.style.top = htmlBounds.getCenterY() + (bounds.height/2) - textInputSpanY +"px"; textInputSpan.style.left = (htmlBounds.getCenterX() - getWidth(textInputSpan)/2)+"px"; startDemo(); } function stageTooSmallHandler(){ var warning = "Sorry, bigger screen required :("; context.font = "bold normal 24px sans-serif"; context.fillText(warning, bounds.getCenterX() - context.measureText(warning).width/2, bounds.getCenterY()-12); } //======================== //Demo specific properties //======================== var HOME = 0; var GAME = 1; var GAME_OVER = 2; var gameState; var scrollSpeed = 3; var score; var fontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 100); var word = "张董"; function startDemo(){ canvas.addEventListener('touchstart', handleUserTap, false); canvas.addEventListener('mousedown', handleUserTap, false); var logoText = "飞翔的字母"; if(!logoCanvas){ logoCanvas = document.createElement("canvas"); logoCanvasBG = document.createElement("canvas"); } createLogo("飞翔的字母", logoCanvas, logoCanvasBG); if(!gameOverCanvas){ gameOverCanvas = document.createElement("canvas"); gameOverCanvasBG = document.createElement("canvas"); } createLogo("行了 到此为止吧", gameOverCanvas, gameOverCanvasBG); createGroundPattern(); createBird(); createTubes(); createCityGraphic(); score = 0; gameState = HOME; loop(); } function loop(){ switch(gameState){ case HOME: renderHome(); break; case GAME : renderGame(); break; case GAME_OVER: renderGameOver(); break; } //stats.tick(); } function handleUserTap(event){ switch(gameState){ case HOME: gameState = GAME; break; case GAME : birdYSpeed = -tapBoost; break; case GAME_OVER: commitResize(); break; } if(event){ event.preventDefault(); } } function keyUpEventHandler(event){ //event.keyCode == 32 -> Space if(event.keyCode == 38){ handleUserTap(event); } } function renderHome(){ context.clearRect(0, 0, canvas.width, canvas.height); renderGroundPattern(); renderLogo(); renderInstructions(); window.requestAnimationFrame(loop, canvas); } function renderGame(){ context.clearRect(0, 0, canvas.width, canvas.height); updateTubes(); renderTubes(); updateBird(); if(!characters.length){ gameOverHandler(); return; } renderBird(); renderGroundPattern(); updateScore(); renderScore(); window.requestAnimationFrame(loop, canvas); } function gameOverHandler(){ context.clearRect(0, 0, canvas.width, canvas.height); gameState = GAME_OVER; renderGameOver(); } function renderGameOver(){ //game over logo context.drawImage(gameOverCanvas, bounds.getCenterX() - logoCanvas.width/2, canvas.height *.2); var instruction = "点击重新任性、"; context.font = "bold normal 24px sans-serif"; context.fillStyle = "#FFFFFF"; context.fillText(instruction, bounds.getCenterX() - context.measureText(instruction).width/2, canvas.height *.25 + gameOverCanvas.height); renderScore(); //window.requestAnimationFrame(loop, canvas); } function renderLogo(){ logoCurrentY += logoDirection; context.drawImage(logoCanvas, bounds.getCenterX() - logoCanvas.width/2, logoCurrentY); if(logoCurrentY <= logoY || logoCurrentY >= logoMaxY){ logoDirection *= -1; } } function renderInstructions(){ var instruction = "飞翔的字母 - 孤影"; context.font = "bold normal 24px sans-serif"; context.fillStyle = "#FFFFFF"; context.fillText(instruction, bounds.getCenterX() - context.measureText(instruction).width/2, canvas.height *.2); } function renderScore(){ context.font = fontProperties.getFontString(); context.fillStyle = "#FFFFFF"; context.strokeStyle = "#000000"; context.lineWidth = 3; var x = bounds.getCenterX() - context.measureText(score).width/2; var y = bounds.height*.1; context.fillText(score, x, y); context.strokeText(score, x, y); } //======================================================================== //========================:: LOGO ::====================================== //======================================================================== var logoCanvas; var logoCanvasBG; var gameOverCanvas; var gameOverCanvasBG; var logoY; var logoCurrentY; var logoMaxY; var logoDirection; function createLogo(logoText, logoCanvas, logoCanvassBG){ logoCanvas.width = logoCanvasBG.width = canvas.width; logoCanvas.height = logoCanvasBG.height = canvas.height / 4; logoCurrentY = logoY = canvas.height * .25; logoMaxY = canvas.height * .35; logoDirection = 1; var logoContext = logoCanvas.getContext("2d"); logoContext.textBaseline = "top"; var textRect = new Sakri.Geom.Rectangle(0, 0, logoCanvas.width * .8, logoCanvas.height); var logoFontProps = fontProperties.clone(); logoFontProps.fontSize = Sakri.CanvasTextUtil.getFontSizeForRect(logoText, fontProperties, textRect); var logoBGContext = logoCanvasBG.getContext("2d"); logoBGContext.fillStyle = "#f5eea5"; logoBGContext.fillRect(0, 0, logoCanvasBG.width, logoCanvasBG.height); logoBGContext.fillStyle = "#9ce358"; logoBGContext.fillRect(0, logoFontProps.fontSize/2, logoCanvasBG.width, logoCanvasBG.height); logoContext.font = logoFontProps.getFontString(); logoContext.fillStyle = logoContext.createPattern(logoCanvasBG, "repeat-x"); logoContext.strokeStyle = "#000000"; logoContext.lineWidth = 3; var x = logoCanvas.width/2 - logoContext.measureText(logoText).width/2; var y = logoFontProps.fontSize/2; logoContext.fillText(logoText, x, 0); logoContext.strokeText(logoText, x, 0); } //======================================================================== //========================:: BIRD ::================================== //======================================================================== var birdCanvas; var birdYSpeed = 0; var gravity = 1; var tapBoost = 12; var birdSize = 60; function updateBird(){ characters[0].y += birdYSpeed; birdYSpeed += gravity; //floor if(characters[0].y >= groundGraphicRect.y - birdCanvas.height){ characters[0].y = groundGraphicRect.y - birdCanvas.height; birdYSpeed = 0; } //celing if(characters[0].y<=0){ characters[0].y = 1; birdYSpeed = 0; } //tube collision if(!isHit && checkTubesCollision()){ context.fillStyle = "#FFFFFF"; context.fillRect(0,0,canvas.width, canvas.height); removeCharacter(); isHit = true; } } var currentTube; var isHit = false; var ffScoreBugFix = 0;// for some reason the score would fire multiple times on firefox function updateScore(){ if(ffScoreBugFix>10 && currentTube.topRect.getRight() < characters[0].x){ if(!isHit){ score++; } isHit = false; var index = tubes.indexOf(currentTube) + 1; index %= tubes.length; currentTube = tubes[index]; ffScoreBugFix = 0; } ffScoreBugFix++; } function renderBird(){ context.drawImage(characters[0].image, characters[0].x, characters[0].y ); for(var i = 1; i < characters.length; i++){ characters[i].y = characters[i-1].y - (characters[i-1].y - characters[i].y) * .9; context.drawImage(characters[i].image, characters[i].x, characters[i].y ); } } function removeCharacter(){ if(characters.length==1){ //game over gameState = GAME_OVER; } for(var i=0; i<characters.length-1;i++){ characters[i].image = characters[i+1].image; } characters.pop(); } function checkTubesCollision(){ for(var i= 0; i<tubes.length;i++){ if(checkTubeCollision(tubes[i])){ return true; } } return false; } var collisionPoint = new Sakri.Geom.Point(); var birdPoints = []; function checkTubeCollision(tube){ birdPoints[0] = characters[0].x; birdPoints[1] = characters[0].y; birdPoints[2] = characters[0].x + birdSize; birdPoints[3] = characters[0].y; birdPoints[4] = characters[0].x + birdSize; birdPoints[5] = characters[0].y + birdSize; birdPoints[6] = characters[0].x; birdPoints[7] = characters[0].y + birdSize; for(var i=0; i<8; i+=2){ collisionPoint.x = birdPoints[i]; collisionPoint.y = birdPoints[i+1]; if(tube.topRect.containsPoint(collisionPoint.x, collisionPoint.y) || tube.bottomRect.containsPoint(collisionPoint.x, collisionPoint.y)){ return true; } } return false; } var characters; var birdFontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 50); function createBird(){ if(!birdCanvas){ birdCanvas = document.createElement("canvas"); } birdCanvas.width = birdSize; birdCanvas.height = birdSize; characters = []; characters[0] = {} characters[0].x = canvas.width / 3; characters[0].y = groundGraphicRect.y / 2; characters[0].image = createCharacterImage(word.charAt(word.length - 1)); var x = characters[0].x -(birdCanvas.width + birdCanvas.width*.2); for(var i=1; i<word.length ; i++){ characters[i] = {}; characters[i].x = x; characters[i].y = characters[0].y; x -= (birdCanvas.width + birdCanvas.width*.2); characters[i].image = createCharacterImage(word.charAt(word.length - i - 1)); } } function createCharacterImage(character){ var birdContext = birdCanvas.getContext("2d"); birdContext.textBaseline = "top"; birdContext.font = birdFontProperties.getFontString(); birdContext.fillStyle = "#d5bb22"; birdContext.fillRect(0, 0, birdSize, birdSize/2); birdContext.fillStyle = "#e97b13"; birdContext.fillRect(0, birdSize/2, birdSize, birdSize/2); //hilite birdContext.fillStyle = "#e0e9a9"; birdContext.fillRect(0, 0, birdSize, 6); //"mouth" birdContext.fillStyle = "#da473b"; birdContext.fillRect(0, birdSize - 10, birdSize, birdSize); birdContext.lineWidth = 3; birdContext.strokeStyle = "#4d2f3b"; birdContext.strokeRect(2, 2, birdSize-4, birdSize-4); birdContext.fillStyle = "#e8fcd6"; birdContext.fillText(character, birdSize/2 - birdContext.measureText(character).width/2, 0); birdContext.strokeText(character, birdSize/2 - birdContext.measureText(character).width/2, 0); var image = new Image(); image.width = birdSize; image.height = birdSize; image.src = birdCanvas.toDataURL(); return image; } //======================================================================== //========================:: TUBES ::================================== //======================================================================== var tubeGapHeight = 230;//needs some logic var tubesGapWidth; var tubes; var tubeWidth = 100;//needs some logic var minTubeHeight = 50;//needs some logic function updateTubes(){ for(var i= 0; i<tubes.length;i++){ updateTube(tubes[i]); } } function updateTube(tube){ tube.topRect.x -= scrollSpeed; tube.bottomRect.x = tube.topRect.x; if(tube.topRect.x <= -tubeWidth ){ tube.topRect.x = tube.bottomRect.x = canvas.width; renderTube(tube); } } function renderTubes(){ for(var i= 0; i<tubes.length;i++){ context.drawImage(tubes[i].canvas, tubes[i].bottomRect.x, 0); } } function createTubes(){ tubes = []; var totalTubes = 2; tubesGapWidth = Math.floor(canvas.width/totalTubes); for(var i = 0; i < totalTubes; i++){ tubes[i] = {}; tubes[i].canvas = document.createElement("canvas"); tubes[i].topRect = new Sakri.Geom.Rectangle(canvas.width+(i * tubesGapWidth)); tubes[i].bottomRect = new Sakri.Geom.Rectangle(canvas.width+(i * tubesGapWidth)); renderTube(tubes[i]); } currentTube = tubes[0]; } var tubeOutlineColor = "#534130"; var tubeMainColor = "#75be2f"; var tubeCapHeight = 40; function renderTube(tube){ tube.canvas.width = tubeWidth; tube.canvas.height = groundGraphicRect.y; tube.bottomRect.width = tube.topRect.width = tubeWidth; tube.topRect.y = 0; tube.topRect.height = minTubeHeight + Math.round(Math.random()*(groundGraphicRect.y-tubeGapHeight-minTubeHeight*2)); tube.bottomRect.y = tube.topRect.getBottom() + tubeGapHeight; tube.bottomRect.height = groundGraphicRect.y - tube.bottomRect.y - 1;//minus one for stroke var tubeContext = tube.canvas.getContext("2d"); tubeContext.lineWidth = 2; //top tube renderTubeElement(tubeContext , 3, 0, tubeWidth-6, tube.topRect.height); renderTubeElement(tubeContext , 1, tube.topRect.getBottom() - tubeCapHeight, tubeWidth-2, tubeCapHeight); //bottom tube renderTubeElement(tubeContext , 3, tube.bottomRect.y, tubeWidth-6, tube.bottomRect.height); renderTubeElement(tubeContext , 1, tube.bottomRect.y, tubeWidth-2, tubeCapHeight); } function renderTubeElement(ctx, x, y, width, height){ ctx.fillStyle = tubeMainColor; ctx.fillRect(x, y, width, height); ctx.fillStyle = "#9de85a"; ctx.fillRect(x, y, width*.25, height); ctx.fillStyle = "#d9f881"; ctx.fillRect(x+width *.05, y, width *.05, height); ctx.fillStyle = "#547e25"; ctx.fillRect(x+width- width * .1, y, width *.1, height); ctx.fillRect(x+width- width * .2, y, width *.05, height); ctx.strokeRect(x, y, width, height); } //======================================================================== //========================:: CITY BG ::================================== //======================================================================== var cityGraphicCanvas; function createCityGraphic(){ if(cityGraphicCanvas){ canvasContainer.removeChild(cityGraphicCanvas); } cityGraphicCanvas = document.createElement("canvas"); cityGraphicCanvas.style.position = "absolute"; cityGraphicCanvas.style.left = canvas.style.left; cityGraphicCanvas.style.top = canvas.style.top; cityGraphicCanvas.width = canvas.width; cityGraphicCanvas.height = canvas.height; var cgContext = cityGraphicCanvas.getContext("2d"); var cityGraphicHeight = canvas.height * .25; //fill with blue sky cgContext.fillStyle = "#71c5cf"; cgContext.fillRect(0, 0, canvas.width, canvas.height); cgContext.fillStyle = "#e9fad8"; cgContext.save(); cgContext.translate(0, groundGraphicRect.y - cityGraphicHeight); //CLOUDS var maxCloudRadius = cityGraphicHeight * .4; var minCloudRadius = maxCloudRadius * .5; for(iterator=0; iterator<canvas.width; iterator+=minCloudRadius){ cgContext.beginPath(); cgContext.arc( iterator , maxCloudRadius, Sakri.MathUtil.getRandomNumberInRange(minCloudRadius, maxCloudRadius), 0, Sakri.MathUtil.PI2); cgContext.closePath(); cgContext.fill(); } cgContext.fillRect(0,maxCloudRadius, canvas.width, cityGraphicHeight ); //HOUSES var houseWidth; var houseHeight; cgContext.fillStyle = "#deefcb"; for(iterator=0; iterator<canvas.width; iterator+=(houseWidth+8)){ houseWidth = 20 + Math.floor(Math.random()*30); houseHeight = Sakri.MathUtil.getRandomNumberInRange(cityGraphicHeight *.5 , cityGraphicHeight - maxCloudRadius *.8); cgContext.fillRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight); } cgContext.fillStyle = "#dff1c4"; cgContext.strokeStyle = "#9fd5d5"; cgContext.lineWidth = 3; for(iterator=0; iterator<canvas.width; iterator+=(houseWidth+8)){ houseWidth = 20 + Math.floor(Math.random()*30); houseHeight = Sakri.MathUtil.getRandomNumberInRange(cityGraphicHeight *.5 , cityGraphicHeight - maxCloudRadius *.8); cgContext.fillRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight); cgContext.strokeRect(iterator, cityGraphicHeight - houseHeight, houseWidth, houseHeight); } //TREES var maxTreeRadius = cityGraphicHeight * .3; var minTreeRadius = maxTreeRadius * .5; var radius; var strokeStartRadian = Math.PI + Math.PI/4; var strokeEndRadian = Math.PI + Math.PI/4; cgContext.fillStyle = "#81e18b"; cgContext.strokeStyle = "#72c887"; for(iterator=0; iterator<canvas.width; iterator+=minTreeRadius){ cgContext.beginPath(); radius = Sakri.MathUtil.getRandomNumberInRange(minCloudRadius, maxCloudRadius) cgContext.arc( iterator , cityGraphicHeight, radius, 0, Sakri.MathUtil.PI2); cgContext.closePath(); cgContext.fill(); cgContext.beginPath(); cgContext.arc( iterator , cityGraphicHeight, radius, strokeStartRadian, strokeEndRadian); cgContext.closePath(); cgContext.stroke(); } cgContext.restore(); //sand cgContext.fillStyle = sand; cgContext.fillRect(0,groundGraphicRect.y, canvas.width, canvas.height); canvasContainer.insertBefore(cityGraphicCanvas, canvasContainer.firstChild); } //======================================================================== //========================:: GROUND ::================================== //======================================================================== var groundX = 0; function renderGroundPattern(){ context.drawImage(groundPatternCanvas, groundX, groundGraphicRect.y); groundX -= scrollSpeed; groundX %= 16; } //colors var groundLightGreen = "#97e556"; var groundDarkGreen = "#73be29"; var groundDarkerGreen = "#4b7e19"; var groundShadow = "#d1a649"; var groundBorder = "#4c3f48"; var sand = "#dcd795"; var groundGraphicRect = new Sakri.Geom.Rectangle(); var groundPatternCanvas; function createGroundPattern(){ groundGraphicRect.y = canvas.height*.85; if(!groundPatternCanvas){ groundPatternCanvas = document.createElement("canvas"); } groundPatternCanvas.width = 16; groundPatternCanvas.height = 16; var groundContext = groundPatternCanvas.getContext("2d"); groundContext.fillStyle = groundLightGreen; groundContext.fillRect(0,0,16,16); //diagonal graphic groundContext.fillStyle = groundDarkGreen; groundContext.beginPath(); groundContext.moveTo(8,3); groundContext.lineTo(16,3); groundContext.lineTo(8,13); groundContext.lineTo(0,13); groundContext.closePath(); groundContext.fill(); //top border groundContext.fillStyle = groundBorder; groundContext.globalAlpha = .2; groundContext.fillRect(0,0,16,1); groundContext.globalAlpha = 1; groundContext.fillRect(0,1,16,1); groundContext.globalAlpha = .6; groundContext.fillRect(0,2,16,1); //hilite groundContext.fillStyle = "#FFFFFF"; groundContext.globalAlpha = .3; groundContext.fillRect(0,3,16,2); //bottom border groundContext.fillStyle = groundDarkerGreen; groundContext.globalAlpha = .3; groundContext.fillRect(0,10,16,3); groundContext.globalAlpha = 1; groundContext.fillRect(0,11,16,1); //shadow groundContext.fillStyle = groundShadow; groundContext.fillRect(0,13,16,3); var groundPattern = context.createPattern(groundPatternCanvas, "repeat-x"); groundPatternCanvas.width = canvas.width + 16; groundPatternCanvas.height = 16; groundContext.fillStyle = groundPattern; groundContext.fillRect(0, 0, groundPatternCanvas.width, 16); } function clearTimeoutsAndIntervals(){ gameState = -1; } var maxCharacters = 8; function changeText(){ var textInput = document.getElementById("textInput"); if(textInput.value && textInput.text!=""){ if(textInput.value.length > maxCharacters){ alert("Sorry, there is only room for "+maxCharacters+" characters. Try a shorter name."); return; } if(textInput.value.indexOf(" ")>-1){ alert("Sorry, no support for spaces right now :("); return; } word = textInput.value; clearTimeoutsAndIntervals(); animating = false; setTimeout(commitResize, 100); } }
CSS页面样式文件(style.css)如下:
html, body{ margin : 0px; width : 100%; height : 100%; overflow: hidden; background-color: #FFFFFF; } #canvasContainer{ margin : 0px; width : 100%; height : 100%; } #textInputSpan{ position: absolute; color: #000000; font-family: sans-serif; }
如果需要源码 复制不了代码的,留言邮箱我给大家打包发过去。
当然还有,不要忘了点赞哦~谢谢大家的支持。谢谢大家了,哈哈。
(*^_^*)
原程序来自:HTML5资源教程
HTML5游戏源码 飞翔的字母 可自定义内容的更多相关文章
- html5 游戏源码下载网站,你值得拥有!
在游戏开发的学习或工作中,利用完好的游戏源码可以事半功倍,不仅可以逆向学习开拓思维,也可以大大减少设计周期. HTML5是构建Web内容的一种语言描述方式. HTML5是Web中核心语言HTML的规范 ...
- html5 canvas简易版捕鱼达人游戏源码
插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...
- 飞翔的圆(Flappy Bird)游戏源码
这个源码是一个不错的休闲类的游戏源码,飞翔的圆(Flappy Bird)游戏源码V1.0,本项目是一个仿Flappy Bird的小游戏,只不过是把Flappy Bird里面的鸟替换成了简单的圆.感兴趣 ...
- HTML5小游戏源码收藏
html5魅族创意的贪食蛇游戏源码下载 html5网页版打砖块小游戏源码下载 html5 3D立体魔方小游戏源码下载 html5网页版飞机躲避游戏源码下载 html5三国人物连连看游戏源码下载 js ...
- 基于html5制作3D拳击游戏源码下载
今天给大家分享一款基于HTML5实现的3d拳王游戏源码.这款实例适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器. 在线预览 ...
- 3D坦克大战游戏源码
3D坦克大战游戏源码,该游戏是基于xcode 4.3,ios sdk 5.1开发.在xcode4.3.3上完美无报错.兼容ios4.3-ios6.0 ,一款ios平台上难得的3D坦克大战游戏源码,有2 ...
- iOS版打地鼠游戏源码
打地鼠游戏源码,游戏是一款多关卡基于cocos2d的iPad打地鼠游戏源码,这也是一款高质量的打地鼠游戏源码,可以拥有逐步上升的关卡的设置,大家可以在关卡时设置一些商业化的模式来盈利的,非常完美的一款 ...
- ios跑酷游戏源码完整版
今天在网上看到了一个很流行的ios游戏源码,酷跑游戏源码,个人下载感觉非常不错,运行起来非常不错的,大家可以研究一下吧,由于源码文件较大,没有上传,请大家见谅. 由于文件较大,没有上传了,大家可以到这 ...
- ios源码-ios游戏源码-ios源码下载
游戏源码 一款休闲类的音乐小游戏源码 该源码实现了一款休闲类的音乐小游戏源码,该游戏的源码很简单,而且游戏的玩法也很容易学会,只要我们点击视图中的grid,就可以 人气:2943运行环境:/Xco ...
随机推荐
- 网页提交中文到WEB容器的经历了些什么过程....
先准备一个网页 <html><meta http-equiv="Content-Type" content="text/html; charset=gb ...
- 重温Http协议--请求报文和响应报文
http协议是位于应用层的协议,我们在日常浏览网页比如在导航网站请求百度首页的时候,会先通过http协议把请求做一个类似于编码的工作,发送给百度的服务器,然后在百度服务器响应请求时把相应的内容再通过h ...
- AndroidTips-052:.aar文件依赖
aar aar 文件是android 类库项目的输出文件,其中可以包含普通的.class,清单,以及android项目特有的资源文件. 使用方式 将.aar文件放在在自己项目的libs目录下 在gra ...
- web前端基础知识
#HTML 什么是HTML,和他ML... 网页可以比作一个装修好了的,可以娶媳妇的房子. 房子分为:毛坯房,精装修 毛坯房的修建: 砖,瓦,水泥,石头,石子.... 精 ...
- 如何利用ansible callback插件对执行结果进行解析
最近在写一个批量巡检工具,利用ansible将脚本推到各个机器上执行,然后将执行的结果以json格式返回来. 如下所示: # ansible node2 -m script -a /root/pyth ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- Entity Framework 教程——DBContext
DBContext: 在之前的章节<创建实体数据模型>中,EDM为我们创建了SchoolDBEntities 类,它派生子System.Data.Entity.DbContext这个类,这 ...
- Autofac - 方法注入
方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...
- 【干货分享】流程DEMO-借款申请
流程名: 借款申请 业务描述: 当员工个人在工作中需要进行借款时,通过此项流程提交借款申请,审批通过后,财务部进行款项支付. 流程相关文件: 流程包.xml WebService业务服务.xm ...
- Android手机相册的布局
实现类似下面的这种布局的方法