UNPKG

ycc-engine

Version:

Mini and powerful canvas engine for creating App or Game.

427 lines (331 loc) 10.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover"> <title>游戏-别踩白块</title> <link rel="stylesheet" href="../style.css"> <style> body{ font-size: 0; position: relative; } </style> </head> <body> <div class="score">分数: <span id="score-number">0</span></div> </body> </html> <script src="../common.js"></script> <script src="../../build/ycc.js"></script> <script> if(!Ycc.utils.isMobile()) alert("此示例在移动端查看效果更佳!"); var canvas = document.createElement('canvas'); console.log(document.documentElement.clientWidth,document.documentElement.clientHeight); canvas.width=document.documentElement.clientWidth; canvas.height=document.documentElement.clientHeight; document.body.appendChild(canvas); var ycc = new Ycc().bindCanvas(canvas); var stageW = ycc.getStageWidth(); var stageH = ycc.getStageHeight(); // 所有的图片资源 var images = null; // 所有音频资源 var audio = null; // 当前场景 var currentScene = null; // 帧率 var frameRate = 60; // 加载资源 ycc.loader.loadResOneByOne([ {name:"start",url:"./images/start.png"}, {name:"restart",url:"./images/restart.png"}, ],function (lise,imgs) { console.log(imgs,222); images = imgs; ycc.loader.loadResOneByOne([ {name:'bg',url:"./audio/bg.mp3",type:"audio"}, {name:'over',url:"./audio/over.wav",type:'audio'}, {name:'tap',url:"./audio/tap.mp3",type:'audio'}, ],function (audios) { audio=audios; currentScene = new StartScene(); ycc.layerManager.reRenderAllLayerToStage(); }); }); // 开启动画,每帧都更新场景 ycc.ticker.start(frameRate); ycc.ticker.addFrameListener(function () { currentScene && currentScene.update && currentScene.update(); ycc.layerManager.reRenderAllLayerToStage(); }); function StartScene(){ var self = this; this.layer = ycc.layerManager.newLayer({enableEventManager:true}); this.layer.addUI(new Ycc.UI.Image({ rect:new Ycc.Math.Rect(stageW/2-200/2,stageH/2-60/2,200,60), fillMode:"scale", res:images.start, ontap:function (e) { self.delSelf(); ycc.layerManager.deleteAllLayer(); currentScene = new GameScene(); } })); } /** * 删除自身 */ StartScene.prototype.delSelf = function () { ycc.layerManager.deleteLayer(this.layer); }; function GameScene(){ // 游戏进行中的图层 this.layer = ycc.layerManager.newLayer({enableEventManager:true}); // 游戏结束后的弹出层 this.overLayer = ycc.layerManager.newLayer({enableEventManager:true,show:false}); // 四列 this.col = 4; // 五行 this.row = 3; // y轴总的偏移量 this.offsetY = 0; // 每帧Y轴的步长 this.spaceY = 5; // 最大速度 this.maxSpaceY = 20; // 方框宽度 this.rectW = parseInt(stageW/this.col); // 方框高度 this.rectH = parseInt(stageH/this.row); // 初始时所有方块可能的y值 this.rectYList = []; // 已偏移的方块个数 this.offsetNumber=-1; this.colLines = []; this.rowLines = []; this.rects = []; // 当前得分 this.score = 0; this.scoreText=null; // 最终得分的文本UI this.finalScoreText=null; // 根据最终得分显示对应的提示文本 this.finalTipText = null; // 游戏是否结束 this.end = false; this.bgm = ycc.loader.getResByName('bg',audio); this.gameOverBgm = ycc.loader.getResByName('over',audio); this.bgmTap = ycc.loader.getResByName('tap',audio); this.createRect(); this.createColLine(); this.createRowLine(); this.createTextScore(); this.createGameOverLayer(); console.log('play'); if(this.bgm) { this.bgm.res.loop = true; this.bgm.res.play(); } } // 添加竖线 GameScene.prototype.createColLine = function () { for(var i=0;i<this.col;i++){ var x = (this.rectW*i); var line = new Ycc.UI.Line({ color:'white', start:new Ycc.Math.Dot(x,0), end:new Ycc.Math.Dot(x,stageH) }); this.colLines.push(line); this.layer.addUI(line); } }; // 画横线 GameScene.prototype.createRowLine = function () { for(var i=-2;i<this.row+2;i++){ var y = (this.rectH*i); var line = new Ycc.UI.Line({ color:'white', start:new Ycc.Math.Dot(0,y), end:new Ycc.Math.Dot(stageW,y) }); this.rowLines.push(line); this.layer.addUI(line); } }; // 创建方块 GameScene.prototype.createRect = function () { var self = this; for(var i=-2;i<this.row+1;i++){ for(var j=0;j<this.col;j++){ var x = (this.rectW*j); var y = (this.rectH*i); if(this.rectYList.indexOf(y)===-1) this.rectYList.push(y); var rect = new Ycc.UI.Rect({ rect:new Ycc.Math.Rect(x,y,this.rectW,this.rectH), color:'black', ontap:function (e) { self.rectOnTap(e); } }); this.rects.push(rect); this.layer.addUI(rect); } } }; // 创建计分文本 GameScene.prototype.createTextScore = function(){ this.scoreText = new Ycc.UI.SingleLineText({ rect:new Ycc.Math.Rect(0,10,stageW,50), xAlign:"center", content:"SCORE: "+this.score +" "+"SPEED:"+this.spaceY, fontSize:"16px", color:"green" }); this.layer.addUI(this.scoreText); }; // 创建游戏结束的图层页 GameScene.prototype.createGameOverLayer = function(){ // 半透明背景 this.overLayer.addUI(new Ycc.UI.Rect({ rect:new Ycc.Math.Rect(0,0,stageW,stageH), color:"rgba(0,0,0,0.7)" })); var fontSize = "20px"; var lineHeight = 30; this.overLayer.addUI(new Ycc.UI.SingleLineText({ content:"游戏结束", xAlign:"center", rect:new Ycc.Math.Rect(0,stageH/2+lineHeight*-2,stageW,lineHeight), color:"red", fontSize:fontSize })); this.finalScoreText = new Ycc.UI.SingleLineText({ content:"您最终得了"+this.score+"分", xAlign:"center", rect:new Ycc.Math.Rect(0,stageH/2+lineHeight*-1,stageW,lineHeight), color:"red", fontSize:fontSize }) this.overLayer.addUI(this.finalScoreText); this.finalTipText = new Ycc.UI.SingleLineText({ content:"手速超过了99%的单身狗!", xAlign:"center", rect:new Ycc.Math.Rect(0,stageH/2,stageW,lineHeight), color:"red", fontSize:fontSize }); this.overLayer.addUI(this.finalTipText); var imgW = 200, imgH = 60; this.overLayer.addUI(new Ycc.UI.Image({ rect:new Ycc.Math.Rect(stageW/2-imgW/2,stageH/2+lineHeight,imgW,imgH), fillMode:"scale", res:images.restart, ontap:function (e) { //self.delSelf(); ycc.layerManager.deleteAllLayer(); currentScene = new GameScene(); } })); this.overLayer.addUI(new Ycc.UI.SingleLineText({ content:"项目地址", rect:new Ycc.Math.Rect(stageW/2-10,stageH/2+lineHeight+10+imgH,-14*4,20), color:"#308eef", fontSize:"14px", ontap:function (e) { window.location.href="https://github.com/lizhiqianduan/ycc/tree/develop"; } })); this.overLayer.addUI(new Ycc.UI.SingleLineText({ content:"作者博客", rect:new Ycc.Math.Rect((stageW)/2+10,stageH/2+lineHeight+10+imgH,14*4,20), color:"#308eef", fontSize:"14px", ontap:function (e) { window.location.href="http://www.lizhiqianduan.com/blog"; } })); }; // 每个方块的点击事件 GameScene.prototype.rectOnTap = function (e) { //console.log(this,e); if(e.target.color==="white"){ if(this.bgmTap) { this.bgmTap.res.currentTime=0; this.bgmTap.res.play(); } this.score++; e.target.color="red"; // 修改分数的文字 this.scoreText.content = "SCORE:"+(" ".slice(0,4-(this.score+'').length))+this.score+" "+"SPEED:"+this.spaceY } }; GameScene.prototype.update = function () { if(this.end) return; var i=0,j=0; // 根据时间差计算而得的实际Y轴速度 var spaceY = parseInt(this.spaceY*((Date.now()-ycc.ticker.lastFrameTime)/(1000/frameRate))); // 如果spaceY超出了最大值的2倍,视为程序被置后台,此帧不更新视图 // if(spaceY>=this.space*3){ // console.log('丢弃帧 spaceY::',spaceY); // return; // } this.offsetY+=spaceY; if(this.offsetNumber!==parseInt(this.offsetY/this.rectH)){ this.offsetNumber=parseInt(this.offsetY/(this.rectH)); console.log('偏移个数-->',this.offsetNumber); // 每3行速度就增加1个像素 if(this.offsetNumber%3===2 && this.spaceY<this.rectH-20 && this.spaceY<this.maxSpaceY) this.spaceY+=1; // 所有横线减去一个方块的偏移量 for(j=0;j<this.rowLines.length;j++){ this.rowLines[j].start.y-=this.rectH; this.rowLines[j].end.y-=this.rectH; } // 方块的总行数 var rectRow = this.rects.length/this.col; var rowIndex=rectRow-(this.offsetNumber)%rectRow-1; // 将最末一行方块的坐标更改至最上方,并随机修改其颜色 for(i=0;i<this.col;i++){ var rect = this.rects[(rowIndex)*this.col+i]; // 存在未点击的白块,游戏结束 if(rect.color==="white") { this.overLayer.show = true; this.finalScoreText.content = "您最终得了"+this.score+"分"; if(this.score<50) this.finalTipText.content = "太菜了,还需努力哦!"; else if(this.score<100) this.finalTipText.content = "哎哟,不错哟!"; else if(this.score<200) this.finalTipText.content = "手速超过了99%的单身狗!"; else this.finalTipText.content = "您的手速已超神!"; if(this.bgm) { this.bgm.res.currentTime = 0; this.bgm.res.pause(); } if(this.gameOverBgm) this.gameOverBgm.res.play(); this.end=true; break; } var before = rect.rect.y; rect.rect.y = before-(rectRow)*this.rectH; rect.color=Math.random()>0.2?"black":"white"; // console.log('方块的总行数-->',rectRow,'需要变化的行下标-->',rowIndex,'更改前的y-->',before,'更改后的y-->',rect.y); } } for(i=0;i<this.rects.length;i++){ this.rects[i].rect.y+=spaceY; } for(j=0;j<this.rowLines.length;j++){ this.rowLines[j].start.y+=spaceY; this.rowLines[j].end.y+=spaceY; } // 修改分数的文字 this.scoreText.content = "SCORE:"+(" ".slice(0,4-(this.score+'').length))+this.score+" "+"SPEED:"+this.spaceY }; </script>