《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

 

 

 

 

 

 

 

 

 

 

posted @ 2013-04-29 15:32  mrlaker  阅读(369)  评论(0编辑  收藏  举报