-
4,果實(shí)的born方法: /* 當(dāng)前的這個(gè)果實(shí)要生長(zhǎng)在哪里呢?我們直接寫一個(gè)born函數(shù)。這個(gè)方法就是隨機(jī) 找一個(gè)海葵,??偣灿?0個(gè),我們要記錄一下當(dāng)前的位置。我們?yōu)槭裁葱枰? ??奈恢媚??因?yàn)楣麑?shí)是長(zhǎng)在海葵上面的,要知道??敹说淖鴺?biāo)是多少, 然后果實(shí)才能到這個(gè)位置。需要知道這個(gè)位置的xy值。好,我們找一個(gè)數(shù)值, 在海葵的這50個(gè)數(shù)量中,隨機(jī)找一個(gè),并且這個(gè)aneId需要是整數(shù)值,那么用 Math.floor(),那么aneId就是從0到49的這樣一個(gè)值,ok,就隨機(jī)給果實(shí)找到了 一個(gè)對(duì)應(yīng)的海葵。要容易辨認(rèn),找到了之后呢,我們就知道了x值, var x=ane.x[aneId]; y值就是整個(gè)canvas的高度減去海葵的高度。 var y=canHeight-ane.len[aneId]; x,y這兩個(gè)屬性是果實(shí)所對(duì)應(yīng)的x值和y值。這兩個(gè)值需要記錄下來。 所以在fruitObj類定義的時(shí)候添加兩個(gè)屬性x和y。 var fruitObj=function() { this.alive=[];//bool this.x=[]; this.y=[]; //果實(shí)的圖片資源 this.orange=new Image(); this.blue=new Image(); } 然后我們?cè)诔跏蓟臅r(shí)候,也給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"; } 在果實(shí)出生的時(shí)候賦值一下正確的值。我們把這個(gè)i值傳進(jìn)來。這樣子,對(duì)應(yīng)的i的果實(shí) 的x值和y值我們就得到了。ok,這樣子我們?cè)赿raw的時(shí)候呢,就有了依據(jù),因?yàn)槲覀? 在畫果實(shí)的時(shí)候要用到果實(shí)的坐標(biāo),首先我們來看一下果實(shí)是畫在哪一個(gè)畫布上的? 是畫在第二個(gè)canvas上面的, 并且born這個(gè)方法必須放在果實(shí)類的init方法中 */查看全部
-
3,果實(shí)的update方法: 接下來我們?cè)倏紤]一個(gè)問題:我們什么時(shí)候告訴其中的一個(gè)果實(shí),你要去執(zhí)行任務(wù)了。也就是說我們要一個(gè)判斷 這里我們需要一個(gè)基本的規(guī)則,我們需要給果實(shí)定義一個(gè)規(guī)則。比方說:在整個(gè)屏幕上,只允許有15個(gè)果實(shí),那么當(dāng) 一個(gè)果實(shí)出去之后,那么屏幕上還剩下14個(gè),這個(gè)時(shí)候我們就要執(zhí)行一個(gè)命令,就是告訴那些閑著的果實(shí),要有一個(gè) 需要出生了,就是這個(gè)規(guī)則,我們來寫一下, 這是一個(gè)規(guī)則,與代碼實(shí)現(xiàn)沒有關(guān)系: 果實(shí)允許范圍=15,一旦小于15個(gè),那就要出生了, 哦,我們回到代碼。也就是每一幀的時(shí)候,都要去判斷一下果實(shí)的狀態(tài),是不是當(dāng)期屏幕上少了,少了的話,就要 新生果實(shí),這時(shí)候我們?cè)趂ruit類里面寫一個(gè)方法:更新。 /* 我們把所有的數(shù)據(jù)計(jì)算都放到里面來。我們需要檢測(cè)當(dāng)前屏幕上,有多少個(gè)果實(shí), 我們需要檢測(cè)所有的果實(shí)狀態(tài)。如果他的alive狀態(tài)為真,那么num++ 好,在循環(huán)完了之后呢 我們的整個(gè)邏輯在這里有點(diǎn)小小的復(fù)雜,首先我們要給它設(shè)計(jì)一個(gè)池,在這個(gè)池子里,又有 不同的狀態(tài),即便是屏幕上的海葵呢,而又分為兩種狀態(tài)。這些東西混合到一起,沒有辦法 說從頭到尾地把這個(gè)功能完整的流暢的寫出來。這比較困難,我們一定要學(xué)會(huì)拆撿, 這樣子我們就自然而然的,渾然不覺的就把一個(gè)復(fù)雜的東西做好了,好,首先我們 來這樣子規(guī)劃,我們認(rèn)為所有的果實(shí),這個(gè)池子里面的,所有的都是在執(zhí)行任務(wù)的, 我們先把執(zhí)行任務(wù)的這塊寫好,也就是從長(zhǎng)大到成熟,飄出去,漂出屏幕外,ok,這樣我們 在初始化的時(shí)候,就把它初始化為真,this.alive[i]=true;每一個(gè)都是活著的,那么 我們這邊就要畫每一個(gè)果實(shí)了。 */ fruitObj.prototype.update=function(){ var num=0; for(var i=0;i<this.num;i++){ if(this.alive[i]) num++; } }查看全部
-
2.在main.js中定義并初始化果實(shí)類,同時(shí)將果實(shí)的圖片設(shè)置為果實(shí)類的屬性并初始化 好,這個(gè)類的結(jié)構(gòu)我們就搭出來了。那我們?cè)趍ain.js中給果實(shí)定義一個(gè)對(duì)象,對(duì)象叫fruit,并且要在 init方法中初始化一下, /new一個(gè)新的fruit類并且初始化一下。 fruit=new fruitObj(); fruit.init(); 另外在gameloop循環(huán)中呢,需要繪制果實(shí),ok,這樣我們對(duì)象就定義好了。那我們來刷新瀏覽器看有沒有問題, 好,沒有問題。這個(gè)池子我們已經(jīng)建好了,另外果實(shí)是需要圖片資源來繪制的,一種是黃色的,一種是藍(lán)色的, 我們要把這個(gè)資源加載進(jìn)去,我們把它放在fruit的類里面,我們把那個(gè)黃色的叫做orange當(dāng)然你可以給它任意一個(gè) 名字,那個(gè)藍(lán)色的呢,我們叫它blue,這是兩個(gè)圖片資源: this.orange=new Image(); this.blue=new Image(); 在fruit類的初始化函數(shù)init中呢,我們希望把這個(gè)圖片資源加載進(jìn)來。orange的叫fruit,藍(lán)色的叫blue。 同樣的藍(lán)色加載進(jìn)來: this.orange.src="./src/fruit.png"; this.blue.src="./src/blue.png"; 那么初始化的時(shí)候,這兩張圖片就可以加載進(jìn)來了。查看全部
-
繪畫果實(shí)分析2: /* 那果實(shí)都有哪些屬性呢?是否活著————這是一個(gè)布爾值,是真還是假,我們目前只給它一個(gè)屬性, 其他的屬性和框架我們慢慢的搭。 */ var fruitObj=function(){ this.alive=[];//bool } /* 首先給它定義一個(gè)數(shù)量,池子,數(shù)量是30 */ fruitObj.prototype.num=30; /* 另外還要初始化一下。初始化的時(shí)候還要給池子里面的每一個(gè)果實(shí),要告訴它,它是什么狀態(tài)。 我們首先初始化的時(shí)候,給它是否活著的屬性一種任務(wù)狀態(tài),即初始化為真。 */ fruitObj.prototype.init=function(){ for(var i=0;i<this.num;i++){ this.alive[i]=true; } } /* 哦,另外我們還要畫果實(shí)。 */ fruitObj.prototype.draw=function(){ } 好,這個(gè)類的結(jié)構(gòu)我們就搭出來了。查看全部
-
三,那么??妥鐾炅?。接下來我們要繪制果實(shí)。 1.繪制果實(shí)的分析: 一個(gè)一個(gè)的果實(shí)漂上去,首先它長(zhǎng)大,漂上去,那么API非常簡(jiǎn)單,就一個(gè)drawImage(). 復(fù)雜的地方在這里:首先它要在??厦媛拈L(zhǎng)大,從無到有長(zhǎng)大。長(zhǎng)大成熟之后就離開海葵,就開始往 上漂,一直往上漂。直到漂出了屏幕。我們來看一下??麑?shí)的過程。首先它會(huì)從無到有,長(zhǎng)出來,長(zhǎng)出來之后 呢,就往上漂,而且漂的速度各有不同,像這樣的機(jī)制怎么樣實(shí)現(xiàn)呢?首先這么多??麑?shí)怎么來控制?一般我們 會(huì)設(shè)立一個(gè)池子,這些池子里面有足夠數(shù)量的果實(shí)。每次我們只需要挑選出需要出生的果實(shí),讓它出生,開始長(zhǎng)大, 長(zhǎng)大完之后,開始往上漂,漂出屏幕之后呢,它就死了。我們到時(shí)候要做一個(gè)判斷。所以果實(shí)首先它會(huì)有兩種主要的 狀態(tài),它是活躍還是不活躍。那我們?cè)趺磪^(qū)分活躍還是不活躍呢?是什么意思呢?比方說:如果我們的屏幕上大概有 15個(gè)果實(shí),我們的整個(gè)果實(shí)池會(huì)設(shè)到足夠的大,比方說我們會(huì)設(shè)到30個(gè)。這樣子呢,只要有需要,有需求,有果實(shí)的 需求,那么池子里面肯定有閑著的果實(shí),我們可以拿來用,所以這個(gè)池子里面果實(shí)數(shù)量要足夠的多,這個(gè)一般是估算 一下有多少個(gè),我們這里有三十個(gè)就足夠了。這三十個(gè)果實(shí)有兩種狀態(tài),一種是閑著,它在排隊(duì)等著,還有一種狀態(tài)是 它被指定的一個(gè)任務(wù)說:你要開始在海葵上生長(zhǎng)了,長(zhǎng)長(zhǎng)長(zhǎng),長(zhǎng)大了之后,然后往上漂。漂出了屏幕之后,就告訴它 你的任務(wù)完成了,請(qǐng)你回去排隊(duì),排隊(duì)的概念其實(shí)就是把它的狀態(tài)設(shè)置到一個(gè)閑著的狀態(tài)。那么對(duì)于已經(jīng)有任務(wù)的 ???,它又分為兩種狀態(tài),一種就是它長(zhǎng)在??厦妫陂L(zhǎng)大,另外一種過程就是漂的過程,ok,這樣分析完了之后呢 我們就開始逐步的把整個(gè)任務(wù)一點(diǎn)一點(diǎn)的剝離開來,我們首先把大的內(nèi)容寫好,然后逐步去寫里面的細(xì)節(jié),ok,我們 回到瀏覽器中,我們首先新建一個(gè)文件,Ctrl+N,Ctrl+S,叫做fruit.js 好,保存一下,那果實(shí)呢,還是和??粯? 給它定義一個(gè)類,然后在類里邊設(shè)立數(shù)組,來控制著很多數(shù)量的???,查看全部
-
問:為何用prototype擴(kuò)充屬性和方法,不直接在aneObj=function中定義呢? 答:如果直接調(diào)用不能反復(fù)使用,把屬性和方法放在原型中可以隨時(shí)使用查看全部
-
這樣子??屠L制完畢了,到瀏覽器中刷新一下,??呀?jīng)出現(xiàn)了,但是數(shù)值上還需要調(diào)整一下<br> 讓它看起來更好看一點(diǎn)。線寬度改成20。刷新一下,再把它的間距調(diào)一下,間距是在這里的<br> this.x[i]=i*10+Math.random()*20;改成:this.x[i]=i*20+Math.random()*20;試一下,<br> 到瀏覽器刷新一下,看起來可以了,是不是已經(jīng)出去了(超出canvas的寬度了)。我們?cè)?lt;br> 試一個(gè)值17,差不多,再試一下16,也是可以的,這樣還是可以充滿的(超出了canvas的寬)<br> 試一下15,15又太小了,出現(xiàn)了一個(gè)間隙(??m然離canvas的右邊框有個(gè)空隙),那么就用16<br> 這樣子看起來可以的,??@樣子并不漂亮,之前調(diào)好的顏色#3b154e,把這個(gè)顏色賦值給<br> strokeStyle。另外我們希望它有一個(gè)透明度??雌饋頃?huì)非常的漂亮,那我們把它放到外面來<br> 在for循環(huán)前后加上兩個(gè)APIctx2.save();和ctx2.restore();這一對(duì)API是什么用處呢?<br> 意思就是告訴畫布,告訴場(chǎng)景,在這兩個(gè)API之間的樣式定義只在這兩個(gè)API之間起作用。<br> 一旦出去這個(gè)restore呢,其他的樣式還是會(huì)被恢復(fù)的,查看全部
-
for(var i=0;i<this.num;i++){ //首先告訴ctx2要開始繪制一個(gè)路徑了。 ctx2.beginPath(); /* 然后要去到一個(gè)位置,那這個(gè)繪制的起始位置在哪里呢?這個(gè)最底下,對(duì)于一個(gè)海葵來說, 最底下這個(gè)點(diǎn),它的x坐標(biāo),就是它自身定義的x坐標(biāo)。它的高度就是它定義的自己的獨(dú)特的高度。 它頂上的x值和底下的x值是一樣的,moveTo的第一個(gè)參數(shù)x值是this.x[i],第二個(gè)參數(shù)y值是: 整個(gè)canvas的高度。因?yàn)樗膞軸是向下為正,我們之前獲取過canvas的高度canHeight ctx2.moveTo(this.x[i],canHeight)意思是場(chǎng)景ctx2到達(dá)了起始點(diǎn)。 */ ctx2.moveTo(this.x[i],canHeight) /* 那要繪制的線段的路徑是到哪里呢?lineTo。x軸坐標(biāo)仍然是this.x[i],y軸坐標(biāo)就是 canHeight-this.len[i]。 */ ctx2.lineTo(this.x[i],canHeight-this.len[i]); /* 另外我們還需要定義一個(gè)線寬度lineWidth,告訴它??麑挾仁嵌嗌?。 ctx2.lineWidth=20; 在線段結(jié)束的時(shí)候,我們要告訴它結(jié)束的樣式。round圓點(diǎn)型。 ctx2.lineCap="round"; lineTo完了之后呢?我們開始給它一個(gè)樣式。我們要首先給它一個(gè)樣式,然后stroke 這里要注意:strokeStyle要定義在stroke()之前。這樣才能繪制的上去。也就是說 你首先告訴它刷什么顏色,然后拿起刷子stroke,把它刷上去。 ctx2.strokeStyle="#3b154e"; */ ctx2.stroke(); } ctx2.restore();查看全部
-
aneObj.prototype.draw=function(){ ctx2.save(); /* 我們把globalAlpha定義在這里。給值0.6,到瀏覽器中看一下。ok,看起來還可以。這樣我們 ??屠L制好了。那我們?cè)倏匆幌挛覀兊拇a。我們?cè)诶L制??臅r(shí)候做了一個(gè)循環(huán),做了 50次循環(huán),這個(gè)num值還是非常大的,50次循環(huán),這些for循環(huán)里的命令都要執(zhí)行,那么我們?cè)倏匆? 下,除了一些對(duì)每一個(gè)??瑢?duì)它自己來說,個(gè)性化的命令,比如說哪一個(gè)點(diǎn)moveTo, 要繪制啊stroke等等,除了這些以外,其中呢,這一部分: ctx2.lineWidth=20; ctx2.lineCap="round"; ctx2.strokeStyle="#3b154e"; 我們把它放到外面來,就是不需要在每一次繪制的時(shí)候每一個(gè)??家ザx它, 就跟globalAlpha一樣,對(duì)每一個(gè)??际且粯拥?,我們來刷新一下看一下。 仍然是跟之前一樣的效果。現(xiàn)在我們代碼會(huì)更簡(jiǎn)潔一點(diǎn)。OK。好。 */ ctx2.globalAlpha=0.6; ctx2.lineWidth=20; ctx2.lineCap="round"; ctx2.strokeStyle="#3b154e"; for(var i=0;i<this.num;i++){ //首先告訴ctx2要開始繪制一個(gè)路徑了。 ctx2.beginPath();查看全部
-
5,我們?cè)趺礃觼砝L制????也就是draw方法該怎么寫 /* 你要繪制,這個(gè)draw也要放到循環(huán)gameloop里面,希望每一幀都會(huì)去繪制???。 我們?cè)趺礃觼砝L制??坷L制??臅r(shí)候就是要把每一條線畫出來。前面我們已經(jīng)介紹了那些API, 我們將會(huì)用beginPath,首先告訴場(chǎng)景,我們要開始一個(gè)路徑,路徑開始之后要告訴它一個(gè)起始點(diǎn), moveTo到達(dá)某一個(gè)點(diǎn),lineTo是指路徑從這個(gè)起始點(diǎn)到另外一個(gè)點(diǎn),到這個(gè)點(diǎn)之后呢就出現(xiàn)了一個(gè)線段, 我們需要把這個(gè)線段繪制一下stroke,給它一個(gè)顏色,給它顏色用strokeStyle,另外繪制的??? 一定的寬度,也就是我們?cè)诶L制圖這個(gè)顏色的時(shí)候,線段是有寬度的lineWidth。另外在這個(gè)線段結(jié)尾 的時(shí)候,會(huì)有一個(gè)樣式lineCap,另外我們還會(huì)用到另外一個(gè)API————globalAlpha,這個(gè)是干嘛的呢? 這個(gè)是給我們繪制的物體一定的透明度。Alpha就是透明度的意思。 globalAlpha就是全局透明度。 那我們先來繪制一個(gè)??T谘h(huán)里面,繪制一個(gè)海葵, */ aneObj.prototype.draw=function(){查看全部
-
2. 在main.js的前面定義一個(gè)變量var ane; 在main.js的init方法中: //我們把a(bǔ)ne定義為aneObj類型。并且把它初始化一下, ane=new aneObj(); ane.init(); 3.然后把a(bǔ)ne.js這個(gè)腳本引入到 html中。好,我們來測(cè)試一下吧??催@個(gè)init有沒有執(zhí)行,我們要養(yǎng)成經(jīng)常習(xí)慣, 否則bug嵌入太深,到后面找起來非常麻煩, 在ane.js腳本里的aneObj類的init方法里加入console.log("a");這句代碼,在瀏覽器中刷新,在console選項(xiàng)卡中看到有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, /* 這個(gè)draw也要放到循環(huán)gameloop里面,希望每一幀都會(huì)去繪制海葵。大家想一下,??恍枰? 動(dòng)畫,它看起來是一個(gè)死的,固定的一個(gè),它不需要每一幀都去刷新的是吧。這個(gè)我們后面再說。 我們先不管它。 */ ane.draw();查看全部
-
/* 初始化,初始化的時(shí)候做什么工作呢?確定每一個(gè)??奈恢?,我們先來想一下這個(gè)海葵該怎么畫吧? 畫一個(gè)海葵的原理就是畫一條線,從頂端畫下來,或者從底端畫上去,那我們從底端畫上去吧。也就是 說beginPath在底端,先把moveTo到底端的這個(gè)點(diǎn),然后取一個(gè)長(zhǎng)度,然后畫上來,到這里結(jié)束。結(jié)束 之后呢我們把這條線繪制一下,ok,那這樣呢,我們不一定要知道它的y值,我們需要它的一個(gè)高度len。 然后做一個(gè)循環(huán):把每一個(gè)??汲跏蓟幌?,this.x[i]= 我們給它隨機(jī)初始化一個(gè)位置,我們讓 ??扛粢欢尉嚯x就長(zhǎng)一個(gè)海葵,我們要它看起來比較隨機(jī)一點(diǎn),給它一個(gè)隨機(jī)值,Math.random() 返回的是0到1之間的一個(gè)值[0,1),并且1是開區(qū)間,不包括1,但是包括0,給它乘上一個(gè)20,暫且先這樣 等會(huì)我們?cè)倩剡^頭來調(diào)整,然后我們給??母叨纫粋€(gè)隨機(jī)值。高度定義一個(gè)基準(zhǔn),200,再加上一個(gè) 隨機(jī)調(diào)整,乘以50 這樣海葵這個(gè)類基本的東西就定義好了。那我們回到main.js中,我們剛才只是定義了一個(gè)類,但是我們 的對(duì)象還沒有創(chuàng)建, */ 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呢,我們就來繪制海葵了。 我們繪制的海葵是一個(gè)擺動(dòng)的動(dòng)畫,在前面我們講到這個(gè)課程分兩個(gè)階段,我們?cè)诘诙€(gè)階段再做??膭?dòng)畫,第一階段呢,僅僅 繪制一個(gè)靜態(tài)的海葵。繪制一條筆直的直線,這個(gè)就非常簡(jiǎn)單了。我們就繪制一條直線來描繪一下這個(gè)路徑,然后給它一個(gè)顏色, 那么這么多???,我們?nèi)绾蝸懋??我們定義一個(gè)類,類里面呢,設(shè)置一個(gè)數(shù)組,??臄?shù)組,每一條??际菙?shù)組的成員, 那這個(gè)數(shù)組,除了??膶傩?,包括海葵的位置,這些信息,包括x值,y值等等,我們先建立一個(gè)新的文件,Ctrl+N,Ctrl+S 我們把不同的內(nèi)容放在不同的腳本里面會(huì)比較清晰,ane.js ane是??挠⑽牡那懊嫒齻€(gè)字母。 1.我們先來定義一個(gè)海葵對(duì)象的類, 我們先來定義??麑?duì)象的一個(gè)類,aneObj,??麑?duì)象是一個(gè)function,這個(gè)對(duì)象里面有很多的???? 哪些屬性呢?我們把這些屬性定義為數(shù)組類型,它們有一個(gè)x值,等于一個(gè)數(shù)組,它的高度len等于一個(gè)數(shù)組。 我們想一下還有哪些屬性,我們先把想到的寫出來。 //它的數(shù)量有多少個(gè),我們先定義50個(gè)吧。有50條???aneObj.prototype.num=50;查看全部
-
好,另外strokeStyle strokeStyle 屬性設(shè)置或返回用于筆觸的顏色、漸變或模式。 這個(gè)就是樣式啊,我們主要看一下它需要的參數(shù),ctx.strokeStyle="#0000ff"; strokeStyle后面是一個(gè)顏色值 stroke()是干嘛的?繪制已定義的路徑。前面定義style之后并沒有繪制,只有給一個(gè)stroke()命令的時(shí)候,它才會(huì)繪制, lineWidth 設(shè)置或返回當(dāng)前的線條寬度 ctx.lineWidth=10;單位是像素 lineCap 設(shè)置或返回線條的結(jié)束端點(diǎn)樣式,它有哪一些參數(shù)呢? 屬性值 值 描述 butt 默認(rèn)。向線條的每個(gè)末端添加平直的邊緣。 round 向線條的每個(gè)末端添加圓形線帽。 square 向線條的每個(gè)末端添加正方形線帽。 等一下我們就用到了round的這種 好,看完這些API呢,我們就來繪制海葵了。查看全部
-
第二個(gè)closePath。 定義和用法 closePath() 方法創(chuàng)建從當(dāng)前點(diǎn)到開始點(diǎn)的路徑。 提示:請(qǐng)使用 stroke() 方法在畫布上繪制確切的路徑。 提示:請(qǐng)使用 fill() 方法來填充圖像(默認(rèn)是黑色)。請(qǐng)使用 fillStyle 屬性來填充另一個(gè)顏色/漸變。 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()告訴場(chǎng)景要開始跳路徑了。然后moveTo到哪一個(gè)點(diǎn),然后lineTo到哪一個(gè)點(diǎn),再lineTo到哪一個(gè)點(diǎn),最后closePath,那么 形成一個(gè)閉合的路徑,查看全部
舉報(bào)
0/150
提交
取消