-
4,果实的born方法: /* 当前的这个果实要生长在哪里呢?我们直接写一个born函数。这个方法就是随机 找一个海葵,海葵总共有50个,我们要记录一下当前的位置。我们为什么需要 海葵的位置呢?因为果实是长在海葵上面的,要知道海葵顶端的坐标是多少, 然后果实才能到这个位置。需要知道这个位置的xy值。好,我们找一个数值, 在海葵的这50个数量中,随机找一个,并且这个aneId需要是整数值,那么用 Math.floor(),那么aneId就是从0到49的这样一个值,ok,就随机给果实找到了 一个对应的海葵。要容易辨认,找到了之后呢,我们就知道了x值, var x=ane.x[aneId]; y值就是整个canvas的高度减去海葵的高度。 var y=canHeight-ane.len[aneId]; x,y这两个属性是果实所对应的x值和y值。这两个值需要记录下来。 所以在fruitObj类定义的时候添加两个属性x和y。 var fruitObj=function() { this.alive=[];//bool this.x=[]; this.y=[]; //果实的图片资源 this.orange=new Image(); this.blue=new Image(); } 然后我们在初始化的时候,也给x和y初始化一下。给0值。 fruitObj.prototype.init=function() { for(var i=0;i<this.num;i++){ this.alive[i]=true; this.x[i]=0; this.y[i]=0; } this.orange.src="./src/fruit.png"; this.blue.src="./src/blue.png"; } 在果实出生的时候赋值一下正确的值。我们把这个i值传进来。这样子,对应的i的果实 的x值和y值我们就得到了。ok,这样子我们在draw的时候呢,就有了依据,因为我们 在画果实的时候要用到果实的坐标,首先我们来看一下果实是画在哪一个画布上的? 是画在第二个canvas上面的, 并且born这个方法必须放在果实类的init方法中 */查看全部
-
3,果实的update方法: 接下来我们再考虑一个问题:我们什么时候告诉其中的一个果实,你要去执行任务了。也就是说我们要一个判断 这里我们需要一个基本的规则,我们需要给果实定义一个规则。比方说:在整个屏幕上,只允许有15个果实,那么当 一个果实出去之后,那么屏幕上还剩下14个,这个时候我们就要执行一个命令,就是告诉那些闲着的果实,要有一个 需要出生了,就是这个规则,我们来写一下, 这是一个规则,与代码实现没有关系: 果实允许范围=15,一旦小于15个,那就要出生了, 哦,我们回到代码。也就是每一帧的时候,都要去判断一下果实的状态,是不是当期屏幕上少了,少了的话,就要 新生果实,这时候我们在fruit类里面写一个方法:更新。 /* 我们把所有的数据计算都放到里面来。我们需要检测当前屏幕上,有多少个果实, 我们需要检测所有的果实状态。如果他的alive状态为真,那么num++ 好,在循环完了之后呢 我们的整个逻辑在这里有点小小的复杂,首先我们要给它设计一个池,在这个池子里,又有 不同的状态,即便是屏幕上的海葵呢,而又分为两种状态。这些东西混合到一起,没有办法 说从头到尾地把这个功能完整的流畅的写出来。这比较困难,我们一定要学会拆捡, 这样子我们就自然而然的,浑然不觉的就把一个复杂的东西做好了,好,首先我们 来这样子规划,我们认为所有的果实,这个池子里面的,所有的都是在执行任务的, 我们先把执行任务的这块写好,也就是从长大到成熟,飘出去,漂出屏幕外,ok,这样我们 在初始化的时候,就把它初始化为真,this.alive[i]=true;每一个都是活着的,那么 我们这边就要画每一个果实了。 */ fruitObj.prototype.update=function(){ var num=0; for(var i=0;i<this.num;i++){ if(this.alive[i]) num++; } }查看全部
-
2.在main.js中定义并初始化果实类,同时将果实的图片设置为果实类的属性并初始化 好,这个类的结构我们就搭出来了。那我们在main.js中给果实定义一个对象,对象叫fruit,并且要在 init方法中初始化一下, /new一个新的fruit类并且初始化一下。 fruit=new fruitObj(); fruit.init(); 另外在gameloop循环中呢,需要绘制果实,ok,这样我们对象就定义好了。那我们来刷新浏览器看有没有问题, 好,没有问题。这个池子我们已经建好了,另外果实是需要图片资源来绘制的,一种是黄色的,一种是蓝色的, 我们要把这个资源加载进去,我们把它放在fruit的类里面,我们把那个黄色的叫做orange当然你可以给它任意一个 名字,那个蓝色的呢,我们叫它blue,这是两个图片资源: this.orange=new Image(); this.blue=new Image(); 在fruit类的初始化函数init中呢,我们希望把这个图片资源加载进来。orange的叫fruit,蓝色的叫blue。 同样的蓝色加载进来: this.orange.src="./src/fruit.png"; this.blue.src="./src/blue.png"; 那么初始化的时候,这两张图片就可以加载进来了。查看全部
-
绘画果实分析2: /* 那果实都有哪些属性呢?是否活着————这是一个布尔值,是真还是假,我们目前只给它一个属性, 其他的属性和框架我们慢慢的搭。 */ var fruitObj=function(){ this.alive=[];//bool } /* 首先给它定义一个数量,池子,数量是30 */ fruitObj.prototype.num=30; /* 另外还要初始化一下。初始化的时候还要给池子里面的每一个果实,要告诉它,它是什么状态。 我们首先初始化的时候,给它是否活着的属性一种任务状态,即初始化为真。 */ fruitObj.prototype.init=function(){ for(var i=0;i<this.num;i++){ this.alive[i]=true; } } /* 哦,另外我们还要画果实。 */ fruitObj.prototype.draw=function(){ } 好,这个类的结构我们就搭出来了。查看全部
-
三,那么海葵就做完了。接下来我们要绘制果实。 1.绘制果实的分析: 一个一个的果实漂上去,首先它长大,漂上去,那么API非常简单,就一个drawImage(). 复杂的地方在这里:首先它要在海葵上面慢慢的长大,从无到有长大。长大成熟之后就离开海葵,就开始往 上漂,一直往上漂。直到漂出了屏幕。我们来看一下海葵果实的过程。首先它会从无到有,长出来,长出来之后 呢,就往上漂,而且漂的速度各有不同,像这样的机制怎么样实现呢?首先这么多海葵果实怎么来控制?一般我们 会设立一个池子,这些池子里面有足够数量的果实。每次我们只需要挑选出需要出生的果实,让它出生,开始长大, 长大完之后,开始往上漂,漂出屏幕之后呢,它就死了。我们到时候要做一个判断。所以果实首先它会有两种主要的 状态,它是活跃还是不活跃。那我们怎么区分活跃还是不活跃呢?是什么意思呢?比方说:如果我们的屏幕上大概有 15个果实,我们的整个果实池会设到足够的大,比方说我们会设到30个。这样子呢,只要有需要,有需求,有果实的 需求,那么池子里面肯定有闲着的果实,我们可以拿来用,所以这个池子里面果实数量要足够的多,这个一般是估算 一下有多少个,我们这里有三十个就足够了。这三十个果实有两种状态,一种是闲着,它在排队等着,还有一种状态是 它被指定的一个任务说:你要开始在海葵上生长了,长长长,长大了之后,然后往上漂。漂出了屏幕之后,就告诉它 你的任务完成了,请你回去排队,排队的概念其实就是把它的状态设置到一个闲着的状态。那么对于已经有任务的 海葵,它又分为两种状态,一种就是它长在海葵上面,正在长大,另外一种过程就是漂的过程,ok,这样分析完了之后呢 我们就开始逐步的把整个任务一点一点的剥离开来,我们首先把大的内容写好,然后逐步去写里面的细节,ok,我们 回到浏览器中,我们首先新建一个文件,Ctrl+N,Ctrl+S,叫做fruit.js 好,保存一下,那果实呢,还是和海葵一样 给它定义一个类,然后在类里边设立数组,来控制着很多数量的海葵,查看全部
-
问:为何用prototype扩充属性和方法,不直接在aneObj=function中定义呢? 答:如果直接调用不能反复使用,把属性和方法放在原型中可以随时使用查看全部
-
这样子海葵就绘制完毕了,到浏览器中刷新一下,海葵已经出现了,但是数值上还需要调整一下<br> 让它看起来更好看一点。线宽度改成20。刷新一下,再把它的间距调一下,间距是在这里的<br> this.x[i]=i*10+Math.random()*20;改成:this.x[i]=i*20+Math.random()*20;试一下,<br> 到浏览器刷新一下,看起来可以了,是不是已经出去了(超出canvas的宽度了)。我们再<br> 试一个值17,差不多,再试一下16,也是可以的,这样还是可以充满的(超出了canvas的宽)<br> 试一下15,15又太小了,出现了一个间隙(海葵虽然离canvas的右边框有个空隙),那么就用16<br> 这样子看起来可以的,海葵这样子并不漂亮,之前调好的颜色#3b154e,把这个颜色赋值给<br> strokeStyle。另外我们希望它有一个透明度。看起来会非常的漂亮,那我们把它放到外面来<br> 在for循环前后加上两个APIctx2.save();和ctx2.restore();这一对API是什么用处呢?<br> 意思就是告诉画布,告诉场景,在这两个API之间的样式定义只在这两个API之间起作用。<br> 一旦出去这个restore呢,其他的样式还是会被恢复的,查看全部
-
for(var i=0;i<this.num;i++){ //首先告诉ctx2要开始绘制一个路径了。 ctx2.beginPath(); /* 然后要去到一个位置,那这个绘制的起始位置在哪里呢?这个最底下,对于一个海葵来说, 最底下这个点,它的x坐标,就是它自身定义的x坐标。它的高度就是它定义的自己的独特的高度。 它顶上的x值和底下的x值是一样的,moveTo的第一个参数x值是this.x[i],第二个参数y值是: 整个canvas的高度。因为它的x轴是向下为正,我们之前获取过canvas的高度canHeight ctx2.moveTo(this.x[i],canHeight)意思是场景ctx2到达了起始点。 */ ctx2.moveTo(this.x[i],canHeight) /* 那要绘制的线段的路径是到哪里呢?lineTo。x轴坐标仍然是this.x[i],y轴坐标就是 canHeight-this.len[i]。 */ ctx2.lineTo(this.x[i],canHeight-this.len[i]); /* 另外我们还需要定义一个线宽度lineWidth,告诉它海葵宽度是多少。 ctx2.lineWidth=20; 在线段结束的时候,我们要告诉它结束的样式。round圆点型。 ctx2.lineCap="round"; lineTo完了之后呢?我们开始给它一个样式。我们要首先给它一个样式,然后stroke 这里要注意:strokeStyle要定义在stroke()之前。这样才能绘制的上去。也就是说 你首先告诉它刷什么颜色,然后拿起刷子stroke,把它刷上去。 ctx2.strokeStyle="#3b154e"; */ ctx2.stroke(); } ctx2.restore();查看全部
-
aneObj.prototype.draw=function(){ ctx2.save(); /* 我们把globalAlpha定义在这里。给值0.6,到浏览器中看一下。ok,看起来还可以。这样我们 海葵就绘制好了。那我们再看一下我们的代码。我们在绘制海葵的时候做了一个循环,做了 50次循环,这个num值还是非常大的,50次循环,这些for循环里的命令都要执行,那么我们再看一 下,除了一些对每一个海葵,对它自己来说,个性化的命令,比如说哪一个点moveTo, 要绘制啊stroke等等,除了这些以外,其中呢,这一部分: ctx2.lineWidth=20; ctx2.lineCap="round"; ctx2.strokeStyle="#3b154e"; 我们把它放到外面来,就是不需要在每一次绘制的时候每一个海葵都要去定义它, 就跟globalAlpha一样,对每一个海葵都是一样的,我们来刷新一下看一下。 仍然是跟之前一样的效果。现在我们代码会更简洁一点。OK。好。 */ ctx2.globalAlpha=0.6; ctx2.lineWidth=20; ctx2.lineCap="round"; ctx2.strokeStyle="#3b154e"; for(var i=0;i<this.num;i++){ //首先告诉ctx2要开始绘制一个路径了。 ctx2.beginPath();查看全部
-
5,我们怎么样来绘制海葵?也就是draw方法该怎么写 /* 你要绘制,这个draw也要放到循环gameloop里面,希望每一帧都会去绘制海葵。 我们怎么样来绘制海葵?绘制海葵的时候就是要把每一条线画出来。前面我们已经介绍了那些API, 我们将会用beginPath,首先告诉场景,我们要开始一个路径,路径开始之后要告诉它一个起始点, moveTo到达某一个点,lineTo是指路径从这个起始点到另外一个点,到这个点之后呢就出现了一个线段, 我们需要把这个线段绘制一下stroke,给它一个颜色,给它颜色用strokeStyle,另外绘制的海葵要有 一定的宽度,也就是我们在绘制图这个颜色的时候,线段是有宽度的lineWidth。另外在这个线段结尾 的时候,会有一个样式lineCap,另外我们还会用到另外一个API————globalAlpha,这个是干嘛的呢? 这个是给我们绘制的物体一定的透明度。Alpha就是透明度的意思。 globalAlpha就是全局透明度。 那我们先来绘制一个海葵。在循环里面,绘制一个海葵, */ aneObj.prototype.draw=function(){查看全部
-
2. 在main.js的前面定义一个变量var ane; 在main.js的init方法中: //我们把ane定义为aneObj类型。并且把它初始化一下, ane=new aneObj(); ane.init(); 3.然后把ane.js这个脚本引入到 html中。好,我们来测试一下吧。看这个init有没有执行,我们要养成经常习惯, 否则bug嵌入太深,到后面找起来非常麻烦, 在ane.js脚本里的aneObj类的init方法里加入console.log("a");这句代码,在浏览器中刷新,在console选项卡中看到有a。 aneObj.prototype.init=function(){ for(var i=0;i<this.num;i++){ this.x[i]=i*10+Math.random()*20; this.len[i]=200+Math.random()*50; } console.log("a"); } 4, /* 这个draw也要放到循环gameloop里面,希望每一帧都会去绘制海葵。大家想一下,海葵不需要 动画,它看起来是一个死的,固定的一个,它不需要每一帧都去刷新的是吧。这个我们后面再说。 我们先不管它。 */ ane.draw();查看全部
-
/* 初始化,初始化的时候做什么工作呢?确定每一个海葵的位置,我们先来想一下这个海葵该怎么画吧? 画一个海葵的原理就是画一条线,从顶端画下来,或者从底端画上去,那我们从底端画上去吧。也就是 说beginPath在底端,先把moveTo到底端的这个点,然后取一个长度,然后画上来,到这里结束。结束 之后呢我们把这条线绘制一下,ok,那这样呢,我们不一定要知道它的y值,我们需要它的一个高度len。 然后做一个循环:把每一个海葵都初始化一下,this.x[i]= 我们给它随机初始化一个位置,我们让 海葵每隔一段距离就长一个海葵,我们要它看起来比较随机一点,给它一个随机值,Math.random() 返回的是0到1之间的一个值[0,1),并且1是开区间,不包括1,但是包括0,给它乘上一个20,暂且先这样 等会我们再回过头来调整,然后我们给海葵的高度一个随机值。高度定义一个基准,200,再加上一个 随机调整,乘以50 这样海葵这个类基本的东西就定义好了。那我们回到main.js中,我们刚才只是定义了一个类,但是我们 的对象还没有创建, */ aneObj.prototype.init=function(){ for(var i=0;i<this.num;i++){ this.x[i]=i*10+Math.random()*20; this.len[i]=200+Math.random()*50; } } //你要绘制 aneObj.prototype.draw=function(){ }查看全部
-
好,看完这些API呢,我们就来绘制海葵了。 我们绘制的海葵是一个摆动的动画,在前面我们讲到这个课程分两个阶段,我们在第二个阶段再做海葵的动画,第一阶段呢,仅仅 绘制一个静态的海葵。绘制一条笔直的直线,这个就非常简单了。我们就绘制一条直线来描绘一下这个路径,然后给它一个颜色, 那么这么多海葵,我们如何来画?我们定义一个类,类里面呢,设置一个数组,海葵的数组,每一条海葵都是数组的成员, 那这个数组,除了海葵的属性,包括海葵的位置,这些信息,包括x值,y值等等,我们先建立一个新的文件,Ctrl+N,Ctrl+S 我们把不同的内容放在不同的脚本里面会比较清晰,ane.js ane是海葵的英文的前面三个字母。 1.我们先来定义一个海葵对象的类, 我们先来定义海葵对象的一个类,aneObj,海葵对象是一个function,这个对象里面有很多的海葵,海葵有 哪些属性呢?我们把这些属性定义为数组类型,它们有一个x值,等于一个数组,它的高度len等于一个数组。 我们想一下还有哪些属性,我们先把想到的写出来。 //它的数量有多少个,我们先定义50个吧。有50条海葵 aneObj.prototype.num=50;查看全部
-
好,另外strokeStyle strokeStyle 属性设置或返回用于笔触的颜色、渐变或模式。 这个就是样式啊,我们主要看一下它需要的参数,ctx.strokeStyle="#0000ff"; strokeStyle后面是一个颜色值 stroke()是干嘛的?绘制已定义的路径。前面定义style之后并没有绘制,只有给一个stroke()命令的时候,它才会绘制, lineWidth 设置或返回当前的线条宽度 ctx.lineWidth=10;单位是像素 lineCap 设置或返回线条的结束端点样式,它有哪一些参数呢? 属性值 值 描述 butt 默认。向线条的每个末端添加平直的边缘。 round 向线条的每个末端添加圆形线帽。 square 向线条的每个末端添加正方形线帽。 等一下我们就用到了round的这种 好,看完这些API呢,我们就来绘制海葵了。查看全部
-
第二个closePath。 定义和用法 closePath() 方法创建从当前点到开始点的路径。 提示:请使用 stroke() 方法在画布上绘制确切的路径。 提示:请使用 fill() 方法来填充图像(默认是黑色)。请使用 fillStyle 属性来填充另一个颜色/渐变。 var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.beginPath(); ctx.moveTo(20,20); ctx.lineTo(20,100); ctx.lineTo(70,100); ctx.closePath(); ctx.stroke(); beginPath()告诉场景要开始跳路径了。然后moveTo到哪一个点,然后lineTo到哪一个点,再lineTo到哪一个点,最后closePath,那么 形成一个闭合的路径,查看全部
举报
0/150
提交
取消