蛤?你要用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);
\begin{matrix}
a & c & e\\
b & d & f\\
0 & 0 & 1\\
\end{matrix}
\right)
\]
缩放:translate(a,0,0,d,0,0);
平移:translate(1,0,0,1,e,f);
旋转:\(translate(cos\theta,sin\theta,-sin\theta,cos\theta,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 画板的建立-.-
很有趣
<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="width:80px;background-color:yellow;" onClick='linecolor="yellow";linw=4;'>yellow</button>
<button style="width:80px;background-color:red;" onClick='linecolor="red"; linw=4;'>red</button>
<button style="width:80px;background-color:blue;" onClick='linecolor="blue"; linw=4;'>blue</button>
<button style="width:80px;background-color:green;" onClick='linecolor="green"; linw=4;'>green</button>
<button style="width:80px;background-color:white;" onClick='linecolor="white"; linw=4;'>white</button>
<button style="width: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
蛤?你要用html做游戏?(笔记版)的更多相关文章
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- C语言程序设计做题笔记之C语言基础知识(上)
C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- cocos2d-x 3.0学习游戏笔记的例子《卡塔防》第五步---开始建立游戏界面
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码.第二能够说 ...
- unity零基础开始学习做游戏(一)为了实现你的游戏,你需要提前做的准备工作
-------小基原创,转载请给我一个面子 正所谓,工欲善其事,必现准备好电脑.接下来跟着小基一步一步来搭建你的开发环境吧 1.下载安装unity 上面的那个是破解软件,下面是unity5.5.6的安 ...
- SDOI2017 R1做题笔记
SDOI2017 R1做题笔记 梦想还是要有的,万一哪天就做完了呢? 也就是说现在还没做完. 哈哈哈我竟然做完了-2019.3.29 20:30
- SDOI2014 R1做题笔记
SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(
- 根据学习廖雪峰老师的git教程做的笔记
根据学习廖雪峰老师的git教程做的笔记 安装git 进行git的配置 配置您的用户名和邮箱地址,使用--global 这个参数表明了在此台机器上的所有仓库都会使用该配置 $ git config -- ...
- Web前端可以转行做游戏吗?
作者:ManfredHu 链接:http://www.manfredhu.com/2018/03/15/31-laya-game-tips/index.html 声明:版权所有,转载请保留本段信息,谢 ...
随机推荐
- 【ShaderToy】画一个球体
嗯,其实渲染球体,可以看做就是一个2d圆形图案+渲染光泽的函数. 定义球体结构——半径,球心坐标 struct Sphere { vec3 center; float radius; };edzx- ...
- Webpack友好的错误提示插件friendly-errors-webpack-plugin
Friendly-errors-webpack-plugin 介绍 Friendly-errors-webpack-plugin识别某些类别的webpack错误,并清理,聚合和优先级,以提供更好的开发 ...
- 机器学习用Pandas实现数据库的读取
#读取数据库数据#import pandas as pd 导入模块#import pymysql 导入数据库模块#con = pymysql.connect(host='localhost',po ...
- C# - 学习总目录
C# - 基础 C# - 操作符 C# - 值类型和引用类型 C# - 表达式与语句 C# - 数组 C# - 引用类型 C# - 常用类 C# - 常用接口 C# - LINQ 语言集成查询 C# ...
- 前端使用moment.js 获取当前时间往前的时间
moment().format("YYYY-MM-DD HH:mm:ss"); //当前时间 moment().subtract(, "days").forma ...
- 服务器 隐藏php版本,nginx版本号等
隐藏php版本号: 打开php.ini配置文件 找到 expose_php 关键修改为 off 即可 重启后 web头部就不会有了 隐藏 nginx 服务器版本号: 打开nginx配置文件,在htt ...
- Git开发工作流
1.1 master分支 主分支,产品的功能全部实现后,最终在master分支对外发布. 1.2 develop分支 开发分支,基于master分支克隆,产品的编码工作在此分支进行. 1.3 rele ...
- Python2.7与3.6的一些区别
2.7实现了一部分3的功能, 更早版本可能会稍稍涉及一点 首先是关键字的差别 python3.6 import keyword print(keyword.kwlist) ['False', 'Non ...
- Gitlab_ansible_jenkins三剑客④jenkins安装图解及freestyle的简单使用
java环境准备 # 安装jdk1.8 [root@node02 ~]# rpm -ivh jdk-8u181-linux-x64.rpm vim /etc/profile export JAVA_H ...
- Light OJ 1085 - All Possible Increasing Subsequences
题目 link 给定一个序列, 求出上升子序列的总数. 分析 Dp[i] 表示序列 以 i 结尾的数目. 可知 Dp[i]=∑Dp[x]+1 这是一个前缀和, 用树状数组维护. Code #inclu ...