频道栏目
首页 > 资讯 > HTML/CSS > 正文

canvas黑白块游戏教程

18-08-01        来源:[db:作者]  
收藏   我要投稿

今天手把手教大家写canvas黑白块小游戏

其实canvas基本代码都是在js中写的,我写这个是如果带入到网页中 最好用手机版查看。

首先是css和html

css:

html,body{
    		width: 100%;
    		height: 100%;
    		margin: 0;
    		padding: 0;
    		text-align: center;
    		overflow: hidden;
}

html:

然后开始写js

//获取宽高
var h = document.documentElement.clientHeight;
var w = document.documentElement.clientWidth;

//canvas对象
var canvas = document.getElementById("mycan");

//获取绘制的环境
var ctx = canvas.getContext("2d");

//设置画布宽高
canvas.width = w;
canvas.height = h;

这时候在浏览器中查看,也是一片空白,然后我们在画布中加点自己想要的东西,

比如先画三条线

/*
	 			mw mh 和mx my是一样的 为什么要写2次,
				 主要是w,h 是宽高
				xy 是坐标 所以写2个 做个区分
				其实也没啥区别,只写一个也没关系,
				至于为什么加1,主要是为了让边框显示出来不至于0,0坐标的方块left和top 没有框
			 * */
			var mw = parseInt(w/4)+1;
			var mh = parseInt(h/5)+1;
			var mx = parseInt(w/4)+1;
			var my = parseInt(h/5)+1;
			
			function drawline(x,y){
				//beginPath主要是为了重新绘制的时候不至于被上一个所影响或者,不被下一个所消除
				ctx.beginPath();
				//设置颜色
				ctx.strokeStyle = 'black';
				//开始划线
				ctx.moveTo(x,y);
				ctx.lineTo(x,h-1);
				ctx.stroke();
			}
					
			function setline(){
				for(var i = 1;i <= 3; i++){
					drawline(mw*i,1);
				}
			}
			
			setline();

然后看看效果:

线画好了,然后开始画框

//new一个数组
var list = new Array();
for(var i = 0; i < 6; i++) {
    //内部添加数组长度为2   1个是用于存储 x 值 另一个用于存储 颜色的true和flase 
    var arr = new Array(2);
    //应该随机一个值  0-3
    var n = Math.floor(Math.random() * 4);
    console.log("n",n);
    arr[0] = n;
    arr[1] = true;
    //刚开始的时候 如果y值 大于屏幕的高度,就将y值放到最上面去至于为什么是6 
    //因为高度是分成5分的  所以必须加1 才能保证方块沾满屏幕
    if(my*i > h){
	    list[i] = new kuang(my*i -  my*6, arr);
    }else{
	    list[i] = new kuang(my*i, arr);
    }
}
					
function drawmian(){
	/*
	 没什么用这个canvas.width = canvas.width;
	其实每次画布都是清空重画,每次设置画布的宽高的时候画布自动清空,所以先清空画布,在从新绘制 
	 * */
	canvas.width = canvas.width;
	//当然如果全是白色也太单调了,我选择加上一张背景图片
			
	//创建 img对象
	var Img=document.createElement('img');
	//设置img的路径
				                        Img.src='/uploadfile/2018/0726/20180726040245324.jpg';
//将图片绘制到画布上去
	ctx.drawImage(Img,0,0,w,h);
				
	//因为画布清空了一次,所以需要将划线写到内部
	setline();
	for(var i = 0; i < list.length ;i++){
	    ctx.beginPath();
		//设置颜色
		if(list[i].arr[1]){
			//绿色	不要吐槽我的审美,我毫无审美观,随便写的颜色
			ctx.fillStyle = "rgba(155, 187, 89, 1)"; 
		}else{
			//灰色
			ctx.fillStyle = "rgba(192,192,192, 1)"; 
		}
		//画方块然后填充自己设置的颜色
	ctx.fillRect(mw*list[i].arr[0] , list[i].y, mw, mh);
	ctx.strokeStyle = "white";
	//话边框,边框颜色自己设置
	ctx.strokeRect(mw*list[i].arr[0] , list[i].y, mw, mh);
	ctx.stroke();
	ctx.closePath();
	}
				
}
			
			
drawmian();

然后再看看效果:

解析一下ctx.fillRect(mw*list[i].arr[0] , list[i].y, mw, mh);

这个函数就是相当于设置 一个方块参数分别的 坐标x,y 和宽高w,h

然后设置x的坐标是 mw*先前在数组里面存的n值

y坐标就是这个当前的高度

然后设置方块的大小宽高,现在也就好理解为什么我要设置两次 mw,mh,mx和my了吧

 

然后是在让这个canvas动起来

//这个就是设置每次移动的大小,数字越大移动的越快
var add = 2;
function ksgame() {
	//先画出来
	drawmian();
	//然后开始循环判断
	for(var i = 0; i < list.length; i++) {
		list[i].y+=add;
		//每当方块过了屏幕的高度
		if(list[i].y > h) {
			var n = Math.floor(Math.random() * 4);
    		list[i].arr[0] = n;
			list[i].arr[1] = true;
			//放到最上面去
			list[i].y -= mh * 6;
		}
	}
		
	//这个函数相当于setInterval ,而且比setInterval平滑很多,
	//不至于看起来像卡了一样,需要了解可以去百度一下
	time  = requestAnimationFrame(goGame);
}
		
//drawmian();
ksgame();

这个只有自己看去看效果了,只要画布动起来了 我们只需要加上一点逻辑判断就可以,修改一部分代码,这个游戏就算完成了

首先在上层添加3个参数

var score = 0;				//分数
var time = null;			//用于停止动画
var start = false;			//开始按钮

修改一下drawmian 主要是下面添加一个分数和 开始的文本

function drawmian() {
				/*
				 没什么用这个canvas.width = canvas.width;
				其实每次画布都是清空重画,每次设置画布的宽高的时候画布自动清空,所以先清空画布,在从新绘制 
				 * */
				canvas.width = canvas.width;
				//当然如果全是白色也太单调了,我选择加上一张背景图片

				//创建 img对象
				var Img = document.createElement('img');
				//设置img的路径
				Img.src = '/uploadfile/2018/0726/20180726040245324.jpg';
				//将图片绘制到画布上去
				ctx.drawImage(Img, 0, 0, w, h);

				//因为画布清空了一次,所以需要将划线写到内部
				setline();
				
				var tadd = parseInt(w/2);
				
				
				for(var i = 0; i < list.length; i++) {
					ctx.beginPath();
					//设置颜色
					if(list[i].arr[1]) {
						//绿色	不要吐槽我的审美,我毫无审美观,随便写的颜色
						ctx.fillStyle = "rgba(155, 187, 89, 1)";
					} else {
						//灰色
						ctx.fillStyle = "rgba(192,192,192, 1)";
					}
					//画方块然后填充自己设置的颜色
					ctx.fillRect(mw * list[i].arr[0], list[i].y, mw, mh);
					ctx.strokeStyle = "white";
					//话边框,边框颜色自己设置
					ctx.strokeRect(mw * list[i].arr[0], list[i].y, mw, mh);
					ctx.stroke();
					ctx.closePath();
				}
				//显示分数
				kais(tadd,50,score,"50","red");
				//如果没有开始,设置开始(只是设置文字)
				if(!start){
					var x1 = (mw*list[4].arr[0] + mw/2);
					var y1 = (list[4].y + mh/2);
					kais(x1,y1,"开始");
				}

			}

然后再修改一下 ksgeme,添加了一个 没有点击的判断

function ksgame() {
				//先画出来
				drawmian();
				//然后开始循环判断
				for(var i = 0; i < list.length; i++) {
					list[i].y += add;
					//每当方块过了屏幕的高度
					if(list[i].y > h) {
						//添加一个判断,如果没有点击超过了 高度,停止动画,并显示
						if(list[i].arr[1] == true){
							list[i].y -= 20;
							drawmian();
							window.cancelAnimationFrame(time);
							return;
						}
						var n = Math.floor(Math.random() * 4);
						list[i].arr[0] = n;
						list[i].arr[1] = true;
						//放到最上面去
						list[i].y -= mh * 6;
					}
				}

				//这个函数相当于setInterval ,而且比setInterval平滑很多,
				//不至于看起来像卡了一样,需要了解可以去百度一下
				time = requestAnimationFrame(ksgame);
			}
//用于给添加一个文字,
			/*
			 x  x坐标
			 y  y坐标
			 text 文本内容
			 px 大小
			 color 颜色
			 至于其他的位置,我注释掉的可以自己去试下
			 * */
			function kais(x,y,text,px,color){
				ctx.beginPath();
				if(px){
					ctx.font = px + "px Georgia";
				}else{
					ctx.font = "30px Georgia";
				}
		        ctx.fillStyle = color  color : "black";
		        //ctx.textAlign="start";
		        //ctx.textAlign="end";
		        //ctx.textAlign="left";
				ctx.textAlign="center";
				//ctx.textAlign="right";
				
		//		ctx.textBaseline ="top";//顶部对齐
		//		ctx.textBaseline ="hanging";//悬挂
		//		ctx.textBaseline ="middle";//中间对齐
		//		ctx.textBaseline ="bottom";//底部对齐
				ctx.textBaseline ="alphabetic";//默认
				ctx.fillText(text,x,y);
				ctx.stroke();
				ctx.closePath();
			}

然后添加一个点击事件,是鼠标按下事件


			//添加一个点击事件,至于移动端的  触屏事件我懒得写了
			canvas.addEventListener("mousedown", function(event) {
				event = event || window.event;
				//这是当前点击的位置
				var x = event.clientX;
				var y = event.clientY;
				if(!start){
					if(list[4].y < y && list[4].arr[0]*mw < x ){
						ksgame();
						start = !start;
					}
				}
				//循环判断点击的是那个方块
				for(var i = 0; i < list.length; i++) {
					//先判断点击的是那一排,也就是高度的坐标
					if(list[i].y < y && list[i].y + mh > y) {
						//然后再查看点击的是那一列,也就是宽度的坐标
						var j = parseInt(x/mw);
						//j 就是点击的是哪一列
						//然后再讲这个排的 随机数n 于j对比,如果相同,那么点击的就是对的
						//否则就是点的空白区
						if(list[i].arr[0] == j) {
							//点击后将true变为false 设置颜色,而且不让多次点击得分
							if(list[i].arr[1] == true) {
								list[i].arr[1] = false;
								//这里是分数每次超过20,就让速度变快一点
								if(score % 20 == 0){
									add++;
								}
								//分数
								score++;
							}
						} else {
							console.log("进入取消");
							window.cancelAnimationFrame(time);
							drawmian();
							return;
						}

					}
				}
			})

这样一个 游戏基本没啥问题了,如果想要完善一点,自己写个重新开始之类的,如果读懂了我写的代码(应该是比较好理解了,已经解析的这么细致了),在继续开发应该是很容易的,好了,谢谢大家!,不懂可以留言!

相关TAG标签
上一篇:通过定义JSON数组,定义SELECT下拉框
下一篇:mysql下按某一字段分组取最大(小)值所在行的数据的技巧分享
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站