记录下开放过程。做小游戏开发,又要跨平台,flash又不支持iPhone,html5是最好的选择。
先看看最后效果:
好了,开始demo。
1.准备工作:
图片素材(省略...最后代码一起打包)
了解 HTML5 Canvas API
2.开工:
首先创建Canvas
1 <div style=" background-image:url(sudoku-bg.png); 590px; height:632px; position:relative"> 2 <canvas id="CanvasCup" width="540" height="500"></canvas> 3 </div>
ok,简单明了,现在要搞清楚的是摆放9张图片到Canvas,计算下x,y坐标,下面我定义一个数组
var bgImg=[]; bgImg[0]=[20,0]; bgImg[1]=[190,0]; bgImg[2]=[360,0]; bgImg[3]=[20,170]; bgImg[4]=[190,170]; bgImg[5]=[360,170]; bgImg[6]=[20,340]; bgImg[7]=[190,340]; bgImg[8]=[360,340];
要画在Canvas上面,直接循环下即可,首先定义下 Canvas对象,Image对象,初始化Image对象高,宽
var imageWidth = 150; var imageheight = 150;,然后调用HTML5 Canvas API 去绘画
var canvas =document.getElementById("CanvasCup"); var context2D = canvas.getContext("2d"); var pic = new Image(); pic.src = "bg.png"; //注意目录结构,这里是把图片和html放在一个目录 for(var i =0;i<9;i++){ pic.onload = function(){ context2D.drawImage(pic,bgImg[i][0], bgImg[i][1],imageWidth,imageheight); } }
好了,现在就可以看到9张图片摆放的整整齐齐。
接下来的动作就是动画效果,从第1~9张图片 一张一张 向中间移动,既然要向中间移动的话就要知道中间的坐标位置,就是bgImg[4]=[190,170];第一张坐标是bgImg[1]=[20,0] ,相当于是从20移动到190,0移动到170,移动的时候按Speed计算,这里我把速度初始化为 Speed = 1,fps = 1000的话 ,那么1毫秒x移动1个单位,y移动1个单位。第二的时候 x坐标等于190,y坐标0,相对中心点而言,只需移动y坐标即可,以此类推。最后去维护一个setInterval函数
1 function draw(){ 2 if( iy+Speed == CenterPint[1] || ix + Speed == CenterPint[0] || ix == CenterPint[0] && iy == CenterPint[1] ){ 3 if(t<9){t++; ix = bgImg[t][0]; iy = bgImg[t][1];} 4 } 5 if(ix != CenterPint[0]){ 6 CenterPint[0]-ix > 0 ? ix = ix + Speed : ix = ix - Speed; 7 } 8 if(iy != CenterPint[1]){ 9 CenterPint[1]-iy > 0 ? iy = iy + Speed : iy = iy - Speed; 10 } 11 12 context2D.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height")); 13 if( t >= 4) {context2D.drawImage(pic,bgImg[4][0], bgImg[4][1],imageWidth,imageheight);}; 14 for(var i =0;i<9;i++){ 15 if( t < i ){ 16 context2D.drawImage(pic,bgImg[i][0], bgImg[i][1],imageWidth,imageheight); 17 } 18 } 19 context2D.save();//保存画笔状态 20 context2D.translate(ix ,iy); 21 context2D.drawImage(pic,0, 0,imageWidth,imageheight); 22 context2D.restore();//绘制结束以后,恢复画笔状态 23 24}interval = setInterval(draw, 1000/fps);
这样就可以实现动画效果了。(截图的时候正在移动.....)
最终都会移动到中心点集合。现在又要返回去移动到原来的9个点的坐标,就是从中心点向外移动。原理与正方向移动一样,这里还需要维护一个正方向和反方向的bool,反方向时候的第一次初始化x,y, 这里我重新改造下draw函数,增加反方向到最后一个的时候 增加点击事件
1 var direction = true; //true正面转动,false 反面转动 stop(); return; 2 var bool = true; //维护反方向 x坐标 第一次初始化赋值 3 var booly = true; //维护反方向 y坐标 第一次初始化赋值 4 function draw(){ 5 if(t > 8){ direction=false;t--;ix = bgImg[t][0]; iy = bgImg[t][1];} 6 if(t < 0){ direction=true; t++; stop(); boxclick(canvas,context2D); return;}//点击事件 7 if(direction){ 8 if( iy+Speed == CenterPint[1] || ix + Speed == CenterPint[0] || ix == CenterPint[0] && iy == CenterPint[1] ){ 9 if(t<9){t++; ix = bgImg[t][0]; iy = bgImg[t][1];} 10 } 11 } 12 else{ 13 if(iy+Speed == bgImg[t][1] || ix+Speed == bgImg[t][0] || ix == CenterPint[0] && iy == CenterPint[1]) 14 if(t>=0){t--; ix = bgImg[t][0];iy = bgImg[t][1]; bool=true; booly=true;} 15 } 16 if(ix != CenterPint[0]){ 17 if(direction){CenterPint[0]-ix > 0 ? ix = ix + Speed : ix = ix - Speed;} 18 else{ 19 if(CenterPint[0]-ix < 0){ 20 if(bool){ 21 bool =false; 22 ix = CenterPint[0]; 23 } 24 ix = ix+ Speed; 25 } 26 else { if(bool){ 27 bool =false;ix = CenterPint[0]; 28 } 29 ix = ix- Speed;} 30 } 31 } 32 if(iy != CenterPint[1]){ 33 if(direction){ 34 CenterPint[1]-iy > 0 ? iy = iy + Speed : iy = iy - Speed;} 35 else{ 36 if(CenterPint[1]-iy < 0){ 37 if(booly){ 38 booly =false; 39 iy = CenterPint[1]; 40 } 41 iy = iy+ Speed; 42 } 43 else { if(booly){ 44 booly =false;iy = CenterPint[1]; 45 } 46 iy = iy - Speed; 47 } 48 } 49 } 50 context2D.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height")); 51 if( t >= 4) {context2D.drawImage(pic,bgImg[4][0], bgImg[4][1],imageWidth,imageheight);}; 52 for(var i =0;i<9;i++){ 53 if( t < i ){ 54 context2D.drawImage(pic,bgImg[i][0], bgImg[i][1],imageWidth,imageheight); 55 } 56 } 57 context2D.save();//保存画笔状态 58 context2D.translate(ix ,iy); 59 context2D.drawImage(pic,0, 0,imageWidth,imageheight); 60 context2D.restore();//绘制结束以后,恢复画笔状态 61 } 62 interval = setInterval(draw, 1000/fps);
下面是点击事件函数,当点击的时候获取到点击的坐标,然后去判断坐标区域在9个坐标的哪个坐标范围内,再进行图片替换。我这里是demo就直接图片替换了,做成抽奖的话,还需要通过后台概率,然后返回前端去显示对应的图片。
1 function boxclick(canvas,context2D){ 2 canvas.onclick = function(e) { 3 var canvasOffset = $(canvas).offset(); 4 var canvasX = Math.floor(e.pageX - canvasOffset.left); 5 var canvasY = Math.floor(e.pageY - canvasOffset.top); 6 //console.log("x:"+canvasX +" y:"+canvasY); 7 var p = new Image(); 8 p.src = "get-2.png"; //注意目录结构,这里是把图片和html放在一个目录的 9 lottery(canvasX,canvasY,context2D,p); 10 } 11 } 12 function lottery(x,y,context2D,p){ 13 //alert("x:"+x+"y:"+y); 14 for(var i =0;i<9;i++){ 15 var w = bgImg[i][0] + imageWidth; 16 var h = bgImg[i][1] + imageheight; 17 18 if(bgImg[i][0] <=x && x <= w && bgImg[i][1]<=y && y<=h) 19 { 20 console.log("p:"+i); 21 var pWidth = bgImg[i][0]; 22 var pHeight = bgImg[i][1]; 23 p.onload = function(){ 24 context2D.drawImage(p,pWidth,pHeight,imageWidth,imageheight); 25 } 26 } 27 } 28 } 29 function stop(){ 30 clearInterval(interval); 31 }
请各位大牛们指点,小弟在此由衷的感谢。