• 蛤?你要用html做游戏?(笔记版)


    标签(空格分隔):canvas html game


    本书是看《html5 Canvas游戏开发实战》(2013)笔记

    博主小白,啥也不懂类型,这只是一个笔记,需要的话可以看原书。

    书张这样:

    本博客的标题只是个噱头,其实命令行也能做游戏!之所以选择canvas是因为它更酷炫,而且可以加到我的blog上。

    可以参考我无意中看到的一位博主的作品:

    http://www.cnblogs.com/axes/tag/canvas/

    第一部分 准备工作

    第一章 准备工作

    Canvas本书没有绘图能力,只是一个绘图API,它需要借助JavaScript来实现。值得一提的是。<canvas>标记开始是由Apple在Safari 1.3 Web浏览器中引入的。

    1.1 JavaScript基础

    对应原书1.6节开始的内容

    我们做游戏一般是面向对象,下面简单了解一下js中如何面向对象。

    js中函数就是类,所以本书有时讲函数,有时讲类,其实是一个东西。

    如何在js中声明一个类

    function MyClass(name, age){
        this.name = name;
        this.age = age;
        this.toString() = function(){
            alert(this.name+":"+this.age);
        };
    };
    var cls1 = new MyClass("lufy", 10);
    

    为对象添加方法/静态类

    cls2.toNumber() = function(){
        ...;
    }
    

    注意:是为对象添加方法

    这个way可以用来做静态类。

    类外添加方法

    每一个函数都有一个prototype属性,prototype属性指向一个prototype对象。在默认条件下,每个函数都对应的prototype对象的constructor属性又会指向该函数。

    当构造函数创建新的对象时,新对象会获取构造函数的prototype属性所指向的prototype对象的所有属性和方法。

    由于对象没有prototype属性,不能像构造函数那样直接调用prototype对象。

    当我们用函数prototype对象给函数(类)添加方法,那么在创建新的对象时,并不会复制函数(类)的所有方法,而是指向了这个函数所有的方法。

    MyClass.prototype.toString = function(){
        this.name...
    };
    
    MyClass.prototype = {
        toString:function(){
            alert(this.name + ":" + this.age);
        },
        sayHello:function(){
            alert(this.name + "你好!");
        }
    }
    

    继承

    用apply方法将父对象的构造函数绑定在子对象上。

    function PeopleClass(){
        this.type = "人"
    };
    PeopleClass.prototype = {
        getType:function(){
            alert("这是一个人");
        }
    };
    function StudentClass(name, sex){
        PeopleClass.apply(this, arguments);
        this.name = name;
        this.sex = sex;
    };
    var stu - new StudentClass("lufy", "男");
    alert(stu.type);
    

    但这样不能继承方法。需要加也循环。(好奇葩呀-。-)

    function PeopleClass(){
        this.type = "人"
    };
    PeopleClass.prototype = {
        getType:function(){
            alert("这是一个人");
        }
    };
    function StudentClass(name, sex){
        PeopleClass.apply(this, arguments);
        this.name = name;
        this.sex = sex;
        
        var prop;
        var proto = this.constructor.prototype;
        for(prop in PeopleClass.protoptype){
            if(!proto[prop]){
                proto[prop] = PeopleClass.prototype[prop];
            }
            proto[prop]["super"] = PeopleClass.prototype;
        }
    };
    var stu - new StudentClass("lufy", "男");
    alert(stu.type);
    

    第二部分 基础知识篇

    第二章 Canvas 基本功能

    2.1 绘制基本图形

    2.1.1 直线

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    
    <canvas id="myCanvas" width="200" height="200">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	ctx.lineWidth=10;
    	ctx.lineCap="butt"
    	ctx.strokeStyle="red";
    	ctx.beginPath();
        <!--创建一个新的路径-->
    	ctx.moveTo(10,10);
    	ctx.lineTo(150,50);
    	ctx.stroke();
    </script>
        
    </body>
    </html>
    

    ctx.lineCap="XX"

    直线线帽

    描述
    butt 默认。向线条的每个末端添加平直的边缘。
    round 向线条的每个末端添加圆形线帽。
    square 向线条的每个末端添加正方形线帽。

    2.1.2 矩形

    • 描边矩形
    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    
    <canvas id="myCanvas" width="200" height="200">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	ctx.lineWidth=5;
    	ctx.strokeStyle="red";
    	ctx.beginPath();
    	ctx.strokeRect(10,10,70,40);
    </script>
    
    
    </body>
    </html>
    
    • 填心矩形
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	ctx.lineWidth=5;
    	ctx.fillStyle="red";
    	ctx.beginPath();
    	ctx.fillRect(10,10,70,40);
    </script>
    

    或者

    ctx.rect(10,10,70,40);
    ctx.fill();
    

    2.2.3 圆

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    <canvas id="myCanvas" width="200" height="200">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	ctx.lineWidth=5;
    	ctx.strokeStyle="red";
    	ctx.fillStyle="blue";
    	ctx.beginPath();
    	ctx.arc(100,100,70,0,130*Math.PI/180,true);
    	ctx.stroke();
    	ctx.fill();
    </script>
    
    </body>
    </html>
    

    2.1.4 圆角矩形

    用前面学的直线和圆弧可以画圆弧和圆角矩形

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    <canvas id="myCanvas" width="200" height="200">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
        ctx.beginPath();
    	ctx.moveTo(20,20);
    	ctx.lineTo(70,20);
    	ctx.arcTo(120,30,120,70,50);
    	ctx.lineTo(120,120);
    	ctx.stroke();
    	
    </script>
    
    </body>
    </html>
    

    2.1.5 擦除Canvas画板

    这个功能就像windows画图程序的橡皮擦,可以擦去矩形区域。

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    <canvas id="myCanvas" width="200" height="200">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.fileStyle="red";
    	ctx.beginPath();
    	ctx.fillRect(10,10,200,100);
    	ctx.clearRect(20,20,50,50);
    	
    </script>
    
    </body>
    </html>
    

    2.2 绘制复杂图形

    2.2.1 画曲线

    贝塞尔曲线,图像学常用曲线。

    • 二次贝塞尔
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.moveTo(100,100);
    	ctx.quadraticCurveTo(20,50,200,20);
    	ctx.stroke();
    </script>
    
    • 三次贝塞尔
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.moveTo(100,100);
    	ctx.bezierCurveTo(20,10,268,10,268,170);
    	ctx.stroke();
    </script>
    

    2.2.2 利用clip在指定区域绘图

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.arc(100,100,40,0,360*Math.PI/180,true);
    	ctx.clip();
    	ctx.beginPath();
    	ctx.fillStyle='lightblue';
    	ctx.fillRect(0,0,300,150);
    </script>
    

    2.3 绘制文本

    2.3.1 绘制文字

    • 用filltext绘制文字
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.font="30px Arial";
    	ctx.fillText("he;;o wor;d",100,50);
    </script>
    

    fillText()第五个参数表示宽度,填了会进行拉伸或者压缩。

    • 用strokeText绘制文字
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.font="30px Arial";
    	ctx.strokeText("he;;o wor;d",100,50);
    </script>
    

    这个很好理解,就像空心矩形和实心矩形一样。

    • 加粗和斜体

    ctx.font="XXXX"

    font-weight 功能
    normal 正常
    bold 粗体
    bolder 更粗
    lighter 更细
    某个数字
    font-style 功能
    italic 斜体
    oblique 斜体
    • 文字对齐

      ctx.textAlign="XXX"

    水平对齐 功能
    start
    end
    left
    center
    right
    textBaseline 看不出来

    竖直对齐 功能
    alphabetic
    bottom
    hanging
    ideographaic
    middle
    top

    2.3.2 “画”文字

    drawText();

    
    

    2.4 图片操作

    2.4.1 利用drawImage绘制图片

    • 利用image标签
    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    img标签<br />
    <img id="face" src="img/0.jpg" alt="The Face" width="267" height="326"/><br />
    canvas画板<br />
    <canvas id="myCanvas" width="400" height="400">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var img=document.getElementById("face");
    	img.onload=function(){
    		ctx.drawImage(img,10,10);
    	};
    </script>
    
    </body>
    </html>
    

    由于图片是异步加载,图片还没加载成功就调用drawImage()方法,所以图片无法显示。用onload事件会在页面或者图像加载完毕后立即发生,所以我们把drawImage()放到onload事件中。

    • 利用image对象
    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    canvas画板<br />
    <canvas id="myCanvas" width="400" height="400">
    	你的浏览器不支持HTML5
    </canvas>
    
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var image = new Image();
    	image.src="img/0.jpg"
    	image.onload=function(){
    		ctx.drawImage(image,10,10);
    	};
    </script>
    
    </body>
    </html>
    
    • 三种函数原型的不同
    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var image = new Image();
    	image.src="img/0.jpg"
    	image.onload=function(){
    		ctx.drawImage(image,10,10);
    		ctx.drawImage(image,			  260,10 ,100,100);
    		ctx.drawImage(image,50,50,100,100,260,130,100,100);
    		<!--截取图片从(50,50)到(100,100)的部分-->
    	};
    </script>
    

    2.4.2 利用getImageData和putImageData绘制图片

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var image = new Image();
    	image.src="img/0.jpg";
    	image.onload=function(){
    		ctx.drawImage(image,10,10);
    		var imgData=ctx.getImageData(50,50,200,200);
    		ctx.putImageData(imgData,10,400);
    		ctx.putImageData(imgData,200,400,50,50,100,100);
    		<!--截取图片从(50,50)到(100,100)的部分-->
    	};
    </script>
    

    2.4.3 利用createImageData新建像素

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var image = new Image();
    	image.src="img/0.jpg";
    	image.onload=function(){
    		ctx.drawImage(image,10,10);
    		var imgData=ctx.getImageData(50,50,200,200);
    		
    		var imgData01=ctx.createImageData(imgData);
    		for(i=0;i<imgData01.width*imgData01.height*4;i+=4){
    			imgData01.data[i+0]=255;
    			imgData01.data[i+1]=0;
    			imgData01.data[i+2]=0;
    			imgData01.data[i+3]=255;
    		}
    		ctx.putImageData(imgData01,10,400);	
    	};
    </script>
    

    第三章 Canvas 高级功能

    3.1 变形

    • 放大缩小

    scale(x,y);

    横轴放大x,纵轴y倍

    小于1为缩小

    负数为翻转

    • 平移

    translate(x,y);

    平移的是画板

    • 旋转

    rotate(angle);

    默认为以原点为中心,需要平移-旋转-平移才可以变为以物体为中心。

    • 用transform矩阵实现多样化变形

    translate(a,b,c,d,e,f);

    [left( egin{matrix} a & c & e\ b & d & f\ 0 & 0 & 1\ end{matrix} ight) ]

    缩放:translate(a,0,0,d,0,0);

    平移:translate(1,0,0,1,e,f);

    旋转:(translate(cos heta,sin heta,-sin heta,cos heta,0,0);)

    我们还可以用settranslate(),会清除上一个transform效果。

    • 倾斜

    详见书P61

    到时候放两张图

    • 图片的扭曲效果

    代码先跳过。就是把图片分成几部分。clip()后加个restore()函数

    3.2 图形的渲染

    3.2.1 渐变

    • 线性渐变

    createLinearGradient(x1,y1,x2,y2,color);

    addColorStop(position,color);

    position是0~1的一个数,表示渐变中颜色的地位。

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var grd=ctx.createLinearGradient(0,0,200,0);
    	ctx.beginPath();
    	grd.addColorStop(0.2,"#00ff00");
    	grd.addColorStop(0.8,"#ff0000");
    	
    	ctx.fillStyle=grd;
    	ctx.fillRect(0,0,200,100);
    	ctx.closePath();
    
    </script>
    
    • 径向渐变

    createRadialGradient(x0,y0,r0,x1,y1,r1);

    addColorStop(position,color);

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	var grd=ctx.createRadialGradient(100,100,10,100,100,50);
    	ctx.beginPath();
    	grd.addColorStop(0.2,"#00ff00");
    	grd.addColorStop(0.8,"#ff0000");
    	
    	ctx.fillStyle=grd;
    	ctx.fillRect(0,0,200,200);
    	ctx.closePath();
    
    </script>
    

    3.2.2 颜色合成

    先跳过。

    3.2.3 颜色反转

    就是用255-RGB

    3.2.4 灰度控制

    书上用的是心理学公式的灰度值。

    3.2.5 阴影效果

    shadowColor="XXX";颜色

    shadowBlur="XXX";羽化量,就是模糊量

    shadowOffsetX=20;

    shadowOffsetY=30;

    <script type="text/javascript">
    	var c=document.getElementById("myCanvas");
    	var ctx=c.getContext("2d");
    	
    	ctx.shadowColor="#ff0000";
    	ctx.shadowBlur=10;
    	ctx.shadowOffsetX=10;
    	ctx.shadowOffsetY=10;
    	
    	var image = new Image();
    	image.src="img/0.jpg";
    	image.onload=function(){
    		ctx.drawImage(image,0,0);
    	};
    </script>
    

    3.3 自定义画板-.-

    3.3.1 画板的建立-.-

    很有趣

    paint0代码演示

    <script type="text/javascript">
    	var canvas=document.getElementById("myCanvas");
    	var ctx=canvas.getContext("2d");
    	
    	//黑色区域作为画板
    	ctx.fillStyle="black";
    	ctx.fillRect(0,0,600,300);
    	
    	//按下标记
    	var on_off=false;
    	var oldx= -10;
    	var oldy= -10;
    	
    	//线的颜色
    	var linecolor="white";
    	//线宽
    	var linw=4;
    	//鼠标事件,当鼠标按下时会启用XX函数
    	canvas.addEventListener("mousemove",draw,true);
    	canvas.addEventListener("mousedown",down,false);
    	canvas.addEventListener("mouseup",up,false);
    
    	function down(event){
    		on_off=true;
    		oldx=event.pageX-10;
    		oldy=event.pageY-10;
    	}
    	function up(){
    		on_off=false;
    	}
    	function draw(event){
    		if(on_off==true){
    			var newx=event.pageX-10;
    			var newy=event.pageY-10;
    			ctx.beginPath();
    			ctx.moveTo(oldx,oldy);
    			ctx.lineTo(newx,newy);
    			ctx.strokeStyle=linecolor;
    			ctx.lineWidth=linw;
    			ctx.lineCap="round";
    			ctx.stroke();
    			
    			oldx=newx;
    			oldy=newy;
    		};
    	};
    	
    </script>
    

    我们稍微改一改还可以做一个完美画板。

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>c0</title>
    </head>
    
    <body>
    <canvas id="myCanvas" width="600" height="300">
    	你的浏览器不支持HTML5
    </canvas><br>
    <button style="80px;background-color:yellow;" 		   onClick='linecolor="yellow";linw=4;'>yellow</button>
    <button style="80px;background-color:red;" 			   onClick='linecolor="red";   linw=4;'>red</button>
    <button style="80px;background-color:blue;" 			   onClick='linecolor="blue";  linw=4;'>blue</button>
    <button style="80px;background-color:green;" 			   onClick='linecolor="green"; linw=4;'>green</button>
    <button style="80px;background-color:white;" 			   onClick='linecolor="white"; linw=4;'>white</button>
    <button style="80px;background-color:black;color:white;" onClick='linecolor="black"; linw=50;'>black</button><br>
    
    
    <script type="text/javascript">
    	var canvas=document.getElementById("myCanvas");
    	var ctx=canvas.getContext("2d");
    	
    	//黑色区域作为画板
    	ctx.fillStyle="black";
    	ctx.fillRect(0,0,600,300);
    	
    	//按下标记
    	var on_off=false;
    	var oldx= -10;
    	var oldy= -10;
    	
    	//线的颜色
    	var linecolor="white";
    	//线宽
    	var linw=4;
    	//鼠标事件,当鼠标按下时会启用XX函数
    	canvas.addEventListener("mousemove",draw,true);
    	canvas.addEventListener("mousedown",down,false);
    	canvas.addEventListener("mouseup",up,false);
    
    	function down(event){
    		on_off=true;
    		oldx=event.pageX-10;
    		oldy=event.pageY-10;
    	}
    	function up(){
    		on_off=false;
    	}
    	function draw(event){
    		if(on_off==true){
    			var newx=event.pageX-10;
    			var newy=event.pageY-10;
    			ctx.beginPath();
    			ctx.moveTo(oldx,oldy);
    			ctx.lineTo(newx,newy);
    			ctx.strokeStyle=linecolor;
    			ctx.lineWidth=linw;
    			ctx.lineCap="round";
    			ctx.stroke();
    			
    			oldx=newx;
    			oldy=newy;
    		};
    	};
    	
    </script>
    
    </body>
    </html>
    

    第四章 lufylegend开源库件

    4.1 lufylegend库件介绍

    lufylengend是本书作者开发的html5库。

    • 封装了Canvas绘图所有的API
    • 利用JavaScript的setInterval函数,对Canvas画板进行周期性重绘。
    • 每次对Canvas画板重绘时,首先使用clearRect方法清空整个画板,然后再调用需要进行重绘的API
  • 相关阅读:
    二叉树的遍历
    Balanced Binary Tree(平衡二叉树)
    Maximum Depth of Binary Tree(二叉树最大深度)
    Binary Tree Level Order Traversal(二叉树广度优先遍历或逐层遍历)
    解决mac下sublime中文乱码
    ubuntu下vi文本后出现不正常的情况
    Linux top命令的用法详细详解
    在Ubuntu 12.04下搭建Cocos2d-x 3.0 生成LuaBindings环境
    iOS7(Xcode5)中隐藏状态栏的方法
    VS2015 打包添加系统必备组件
  • 原文地址:https://www.cnblogs.com/juicebox/p/9648106.html
Copyright © 2020-2023  润新知