《The Essential Guide to HTML5》学习笔记(一)
一、Dice Game
【游戏说明】
掷两枚骰子,骰子的点数由1到6,这个游戏是自己跟系统玩,略显无聊,但是稍微改进也可以变成两个人玩的。游戏规则是这样的:1.如果两个骰子点数之和为7或者11,那么你赢了。2.如果你扔出了2、3、12,那么就输了。3.如果是(4、5、6、8、9、10),那么把该值记录下来,叫做player's point,然后再扔一次,扔出了与上次相同的点数就赢,扔出了7就输了,扔到其他点数还要继续扔,就是说继续做player's point和7判定,而这时候规则1和规则2无效。
真心觉得这个游戏的作者定义的规则略无聊,不过抱着学习html5的心态还是继续看下去,一步一步跟着做。
【学习重点】
1.在canvas上画矩形、圆
2.模拟扔骰子的过程,就是用Math.random()实现1-6的随机数
【细节】
在canvas上画图形的简单示例:
function init()
{
var ctx=document.getElementById("canvas").getContext('2d'); //得到一个canvas的上下文,用它对canvas进行操作
ctx.beginPath(); //开启路径
ctx.arc(200,200,50,0,Math.PI,false);//(200,200):圆心 50:半径 0、pi:开始角度和结束角度 false:逆时针
ctx.fillStyle="rgb(200,0,200)";//填充颜色
ctx.closePath(); //关闭路径之后,半圆的两个端点会被连接起来
ctx.fill(); //用填充色填充
ctx.strokeStyle="rgb(255,0,0)"; //描边颜色
ctx.lineWidth=5; //描边宽度
ctx.stroke(); //描边
}
产生1-6的随机数:
1+Math.floor(Math.random()*6) ;
random得到的是一个0到1的小数
骰子的画法:
1-6六种点数可以拆成由4种基本形状组成,其函数分别为draw1(画中间一点)、draw2(左上+右下)、draw4(四个角)、draw2mid(中间两点)
页面载入后由onload=init()调用init函数,画骰子分边框和点数两部分
矩形的绘制:
ctx.strokeRect(dx,dy,dicewidth,diceheight) ; //(x,y)为矩形的左上角,接下来两个参数是矩形的宽和高
ctx.clearRect(x,y,width,height); //清除原先画的矩形
二、Bouncing Ball
【游戏说明】
有一个矩形的盒子,里面有一个球在运动,球的水平速度和垂直速度可以手动输入改变,当球碰到盒子的边界时,球会被反弹回来,反弹的路线类似于光的反射,模拟真实的物理碰撞反弹。在第一个版本中,盒子边界只是纯色的描边,球也一样。在这个基础上的版本中,使用了一个图像来代表球,盒子的边界也可以用渐变填充来代替纯色。另一个改进是在速度输入框中加入了输入合法性验证,如果输入了无效的输入值,输入框会变为红色,如果是合法的值则是绿色,这用到了html5的表单控制新功能。
【学习重点】
1.用setInterval函数控制动画的产生
2.form输入框的合法性验证
3.渐变的产生
【细节】
创建一个Image对象:
var img = new Image();
img.src="pearl.jpg";
将一个图像画到canvas上面:
ctx.drawImage(img,ballx-ballrad,bally-ballrad,2*ballrad,2*ballrad);
渐变分为线性渐变和径向渐变两种,这里使用的是线性渐变,创建一个渐变:
var grad;
grad=ctx.createLinearGradient(boxx,boxy,boxx+boxwidth,boxy+boxheight);
//定义了一个数组,存放了六种将要应用于渐变中的颜色
var hue = [
[255, 0, 0 ],
[255, 255, 0 ],
[ 0, 255, 0 ],
[ 0, 255, 255 ],
[ 0, 0, 255 ],
[255, 0, 255 ]
] ;
绘制一个渐变的过程:
var h;
ctx = document.getElementById('canvas').getContext('2d');
grad = ctx.createLinearGradient(boxx,boxy,boxx+boxwidth,boxy+boxheight);
for (h=0;h<hue.length;h++)
{
color = 'rgb('+hue[h][0]+','+hue[h][1]+','+hue[h][2]+')';
grad.addColorStop(h*1/6,color); //可以在0-1之间放置渐变的中间色
}
ctx.fillStyle = grad;
ctx.lineWidth = ballrad;
……
ctx.fillRect(boxx,boxy+boxheight-ballrad,boxwidth,ballrad);
注意绘制的渐变如上图,因为创建渐变的时候是从左上角到右下角,而四条边是分四次填充的,这说明填充的部分只是让已经画好的渐变显示出来。
实现定时调用函数:
setInterval(moveball,100); //每100ms调用函数moveball一次
setInterval("moveball();",100); //和上面一句的作用相同
setInterval("positionx += speed;",100); //每100ms执行引号内的语句一次
在输入框<input type="text" name="secs" value="0"/> 中,输入一个数字不是真正的数字,要使用它要把它转化为真正的数字:
var num = Number(document.f.secs.value);
假如要把输入框中的数字加1再显示回去,应该这样做:
document.f.secs.value = String(1+Number(document.f.secs.value));
停止setInterval定时,使用clearInterval函数:
tev = setInterval(moveball,100);
clearInterval(tev);
与setInterval不同,setTimeout所调用的函数只发生一次
实现球反弹的函数,其实挺简单,就是判断有没有出界,如果出界了,就把被阻挡方向的速度变为相反
function moveandcheck()
{
var nballx = ballx + ballvx;
var nbally = bally +ballvy;
if (nballx > boxboundx)
{
ballvx =-ballvx;
nballx = boxboundx;
}
if (nballx < inboxboundx)
{
nballx = inboxboundx
ballvx = -ballvx;
}
if (nbally > boxboundy)
{
nbally = boxboundy;
ballvy =-ballvy;
}
if (nbally < inboxboundy)
{
nbally = inboxboundy;
ballvy = -ballvy;
}
ballx = nballx;
bally = nbally;
}
表单的验证:
输入框所使用的表单
<form name="f" id="f" onSubmit="return change();">
Horizontal velocity <input name="hv" id="hv" value="4" type="number" min="-10" <!-- min和max限定了输入的最大值最小值,超过就属于不合法,input:invalid生效-->
max="10" />
<br>
Vertical velocity <input name="vv" id="vv" value="8" type="number" min="-10"
max="10"/>
<input type="submit" value="CHANGE"/>
</form>
只需要在css中加入以下两条,就可以让合法的输入与不合法的输入出现不一样的效果:
input:valid {background:green;}
input:invalid {background:red;}
三、Cannonball and Slingshot
【游戏说明】
有一个弹弓,用鼠标拖拽弹弓上的球能够让球发射出去打击目标,弹弓的速度与拖拽的距离相关,拉得越长,发射出去的水平速度越快。球飞出去之后,能够模拟在重力的作用下下落的抛物线效果。如果球击中了目标,目标会有所反应,比如破碎了之类,书中用了一只鸡做目标,打中了之后鸡就只剩下羽毛了。这就是简单版的愤怒的小鸟吧!
【学习目标】
1.将一个表中的物体画到canvas上,并维护这个表
2.实现物体的旋转
3.实现用鼠标的拖放物体
4.模拟小球在重力下的飞行和碰撞
【细节】
模拟重力:
verticalvel2 = verticalvel1 + gravity;
dy = (verticalvel1 + verticalvel2)*.5;
构造一个对象Ball代表小球:
function Ball(sx,sy,rad,stylestring) {
this.sx = sx;
this.sy = sy;
this.rad = rad;
this.draw = drawball;
this.moveit = moveball;
this.fillstyle = stylestring;
}
图像的旋转:
function init(){
ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = "rgb(250,0,0)";
ctx.save(); //保存当前的绘图状态
ctx.translate(50,50); //变换坐标原点
ctx.rotate(-Math.PI/6); //逆时针旋转π/6
ctx.translate(-50,-50);
ctx.fillRect(50,50,100,200);
ctx.restore();
ctx.fillStyle = "rgb(0,0,250)";
ctx.fillRect(50,50,5,5);
}
画直线:
moveTo(x,y); //移动到直线的起点
lineTo(x,y); //画到直线的终点
实现拖放动作:
canvas1 = document.getElementById('canvas');
canvas1.addEventListener('mousedown',findball,false); //鼠标按下触发findball函数
canvas1.addEventListener('mousemove',moveit,false);
canvas1.addEventListener('mouseup',finish,false);
击中之后的图像替换:
everything.splice(targetindex,1,[htarget,false]);
everything.splice(ballindex,1);
计算拉开的弹弓距离:两点距离公式
四、The Memory (aka Concentration) Game
【游戏说明】
卡片记忆游戏,页面上有好多张卡片,它们是两两配对的,先把它们的正面翻过来给你看,然后翻过反面,凭着记忆点击两张卡片,如果这两张卡片是配对的,那么它们将从屏幕上消失,如果不配对就重新来过。卡片配对的规则可以自定义,可以是相同形状的几何图形,可以是同一个人的不同角度的照片。当游戏结束时,给出完成游戏的时间。
【学习目标】
1.多边形的画法
2.在canvas上放置文字
3.实现暂停
4.计算总共花费的时间
5.洗牌的方法
【细节】
显示文字:
function init(){
ctx = document.getElementById('canvas').getContext('2d');
ctx.font="15px Lucida Handwriting"; //字体,字号
ctx.fillText("this is Lucida Handwriting", 10, 20); //要显示的文字
ctx.font="italic 30px HarlemNights";
ctx.fillText("italic HarlemNights",40,80);
ctx.font="bold 40px HarlemNights"
ctx.fillText("HarlemNights",100,200);
ctx.font="30px Accent";
ctx.fillText("Accent", 200,300);
}
显示当前匹配数目:
ctx.fillText ("Number of matches so far: "+String(count),10,360);
多边形的画法:
使用lineTo和moveTo,用三角函数计算出各个点
总共花费时间的计算:
//开始时间
starttime = new Date();
starttime = Number(starttime.getTime());
//当前时间-开始时间
var now = new Date(); //创建一个Date对象
var nt = Number(now.getTime());
var seconds = Math.floor(.5+(nt-starttime)/1000); //为了抵消直接卸去小数部分产生的误差,取floor之前先加上0.5
暂停:
setTimeout(flipback,1000); //每1s执行一次回调函数flipback