官术网_书友最值得收藏!

2.4 為組件添加行為

下一步將定義組件的行為。編寫一個(gè)繪畫程序的難度似乎是難以想象的,但App Inventor已經(jīng)承擔(dān)了大部分繁重的工作:借助簡單易用的塊語言,不僅可以處理用戶的觸摸及拖動事件,也可以實(shí)現(xiàn)繪畫及拍照功能。

在設(shè)計(jì)視圖中,已經(jīng)添加了叫作“畫布”的畫布組件。畫布組件可以偵測到觸摸及拖動事件。對觸摸事件編程,實(shí)現(xiàn)畫圓功能,這樣當(dāng)用戶的手指觸摸到畫布時(shí),將在被觸摸的位置畫出一個(gè)圓形;對拖動事件編程,可以實(shí)現(xiàn)畫線功能,即當(dāng)用戶的手指在畫布上劃過時(shí),沿途會畫出一條線。還可以通過對按鈕的點(diǎn)擊事件編程,以改變畫筆的顏色,清除畫布,將畫布的背景圖片修改為相機(jī)拍攝到的照片。

2.4.1 在觸摸事件中畫圓

首先處理觸摸事件:當(dāng)用戶觸摸畫布時(shí),在接觸點(diǎn)繪制一個(gè)圓形。

(1)在編程視圖中,打開畫布的代碼塊抽屜,拖出“當(dāng)畫布被觸摸時(shí)”塊。該代碼塊有三個(gè)參數(shù):x坐標(biāo)、y坐標(biāo)及碰到任意精靈,如圖2-6所示。其中的xy坐標(biāo)提供了接觸點(diǎn)的位置信息。

圖2-6 事件中攜帶了觸碰點(diǎn)的位置信息

提示:在第1章“你好貓咪”應(yīng)用中,我們已經(jīng)熟悉了按鈕點(diǎn)擊事件,但對于畫布組件的事件還很陌生。按鈕點(diǎn)擊事件很簡單,不附帶任何其他信息;但有些事件則不然,它們附帶了與事件有關(guān)的“參數(shù)”信息。在畫布的觸摸事件中,提供了觸摸點(diǎn)在畫布上的xy坐標(biāo),以及是否碰到了位于畫布中的對象(在App Inventor中被稱作“精靈”),但是在第3章之前我們還不需要使用碰到任意精靈參數(shù)。本章我們只用到了觸碰點(diǎn)的坐標(biāo),利用坐標(biāo)來繪制圓形。

(2)從畫布的代碼塊抽屜中拖出“讓畫布畫圓”塊,放在畫布的觸摸事件處理程序中,如圖2-7所示。

圖2-7 當(dāng)用戶點(diǎn)擊畫布時(shí)畫一個(gè)圓

在“讓畫布畫圓”塊的右側(cè)有四個(gè)插槽,前三個(gè)插槽需要填入?yún)?shù):圓心x坐標(biāo)、圓心y坐標(biāo)、半徑,其中圓心xy坐標(biāo)用于指定繪制圓形的位置,半徑用于指定圓的大小。圖中的代碼有些令人困惑,有兩組xy坐標(biāo),這里要區(qū)分清楚:觸摸事件中的xy坐標(biāo)表示接觸點(diǎn)的位置(已知);而畫圓命令塊中的xy坐標(biāo)插槽,用于設(shè)定繪制圓形的圓心位置(待定)。我們恰好要以用戶的觸摸點(diǎn)為圓心繪制圓形,因此可以從觸摸事件中取得xy坐標(biāo)的值,作為畫圓命令的參數(shù),填充到代碼塊的插槽中。“讓畫布畫圓”塊中的第四個(gè)插槽是最近的版本中新增加的參數(shù)——實(shí)心。它的默認(rèn)值是“真”,表示將繪制實(shí)心圓。如果設(shè)為假,將繪制空心圓。——譯者注

提示:可以從觸摸事件塊中提取事件的參數(shù),方法是將鼠標(biāo)懸停在參數(shù)上,如圖2-8所示。

圖2-8 鼠標(biāo)懸停在事件參數(shù)上,可以取得事件的參數(shù)值

(3)從事件中拖出“x坐標(biāo)”“y坐標(biāo)”塊,并將它們填充到畫圓命令塊的插槽中,如圖2-9所示。

圖2-9 圓心的位置已經(jīng)確定,但還需要設(shè)定半徑的大小

(4)現(xiàn)在需要設(shè)定圓的半徑。半徑的單位為像素,像素是顯示屏幕上所能繪制的最小的點(diǎn)。此時(shí)設(shè)半徑為5像素:在編程視圖工作區(qū)的空白處輸入數(shù)字5,按回車,將會自動創(chuàng)建一個(gè)數(shù)字塊,然后將數(shù)字塊5拖入半徑插槽。當(dāng)數(shù)字塊5填入到半徑插槽后,屏幕左下角的黃色三角形處的數(shù)字變?yōu)?,因?yàn)榇藭r(shí)所有的插槽都已經(jīng)被填滿。圖2-10就是完整的觸摸事件處理程序。

圖2-10 當(dāng)用戶觸摸屏幕時(shí),將以觸摸點(diǎn)為圓心繪制一個(gè)半徑為5的實(shí)心圓

提示:在編程視圖的工作區(qū)中輸入5,然后回車,這種操作叫作輸入塊(typeblocking)。系統(tǒng)會根據(jù)你輸入的字符,顯示與該字符相匹配的一系列塊;如果輸入的是數(shù)字,那么將創(chuàng)建一個(gè)數(shù)字塊。

測試:看看測試設(shè)備上都有什么。觸碰畫布,手指碰過的地方會留下一個(gè)圓點(diǎn)。如果在設(shè)計(jì)視圖中將畫布的畫筆顏色屬性設(shè)置為紅色,那么圓點(diǎn)也是紅色(否則應(yīng)該是默認(rèn)的黑色)。

2.4.2 在拖動事件中畫線

下面添加拖動事件處理程序。先看一下觸摸事件與拖動事件之間的區(qū)別。

· 觸摸事件:手指在畫布上放下再抬起,其間手指沒有移動。

· 拖動事件:手指在畫布上放下,手指與屏幕保持接觸并移動。

在繪畫程序中,手指在屏幕上拖動,將沿著手指移動的路徑繪制出一條線。這條線實(shí)際上是由無數(shù)個(gè)微小的直線(線段)構(gòu)成的:手指每次微小的移動,都將從手指所在的最后一個(gè)位置開始,到手指的當(dāng)前位置為止,繪制一個(gè)微小的線段。

(1)從畫布的代碼塊抽屜中拖出拖動事件處理程序塊,如圖2-11所示。拖動事件攜帶了以下參數(shù)。

圖2-11 比起觸摸事件,拖動事件攜帶了更多的參數(shù)

· 起點(diǎn)X坐標(biāo)、起點(diǎn)Y坐標(biāo):手指開始拖動時(shí)所在的位置(整條線的起點(diǎn))。

· 鄰點(diǎn)X坐標(biāo)、鄰點(diǎn)Y坐標(biāo):手指的上一個(gè)位置(微小線段的起點(diǎn))。

· 當(dāng)前X坐標(biāo)、當(dāng)前Y坐標(biāo):手指的當(dāng)前位置(微小線段的終點(diǎn))。

· 拖到任意精靈:布爾值,如果用戶拖動過程中碰到過精靈,則其值為真。本章不會用到這個(gè)參數(shù)。

(2)從畫布的代碼塊抽屜中拖出“讓畫布畫線”塊,填充到拖動事件塊中,如圖2-12所示。

圖2-12 添加畫線功能

畫線命令塊有四個(gè)參數(shù),分別確定微小線段的起點(diǎn)及終點(diǎn)坐標(biāo),其中起點(diǎn)為(第一點(diǎn)x坐標(biāo),第一點(diǎn)y坐標(biāo)),終點(diǎn)為(第二點(diǎn)x坐標(biāo),第二點(diǎn)y坐標(biāo))。你能確定每個(gè)參數(shù)中需要填入什么值嗎?記住,當(dāng)手指在畫布上拖動時(shí),拖動事件將被調(diào)用很多次:在應(yīng)用中,手指的每次微小的移動都會繪制出一個(gè)微小線段,從(鄰點(diǎn)X坐標(biāo),鄰點(diǎn)Y坐標(biāo))到(當(dāng)前X坐標(biāo),當(dāng)前Y坐標(biāo))。

(3)從拖動事件中拖出你需要的參數(shù)。將鄰點(diǎn)X坐標(biāo)、鄰點(diǎn)Y坐標(biāo)分別填充到第一點(diǎn)x坐標(biāo)、第一點(diǎn)y坐標(biāo)中,然后,將當(dāng)前X坐標(biāo)、當(dāng)前Y坐標(biāo)分別填充到第二點(diǎn)x坐標(biāo)、第二點(diǎn)y坐標(biāo)中,如圖2-13所示。

圖2-13 當(dāng)用戶在屏幕上拖動時(shí),從上一點(diǎn)到當(dāng)前點(diǎn)繪制線段

測試:在設(shè)備上測試一下剛剛設(shè)定的行為。在屏幕上隨意拖動手指,畫出直線及曲線。觸碰屏幕畫圓。

2.4.3 改變顏色

應(yīng)用已經(jīng)實(shí)現(xiàn)了畫線功能,但現(xiàn)在只能畫紅線。下面編寫顏色按鈕的事件處理程序,以便用戶可以改變畫筆的顏色。同樣設(shè)置擦除按鈕程序,以便用戶可以清除畫布并重新開始。

在編程視圖中完成以下操作。

(1)打開RedButton的代碼塊抽屜,拖出“當(dāng)RedButton被點(diǎn)擊時(shí)”塊。

(2)打開畫布的代碼塊抽屜。拖出“設(shè)畫布的畫筆顏色”塊(可能需要滾動代碼塊列表以便在列表的后面找到它),并把它放在點(diǎn)擊事件塊中“執(zhí)行”的位置。

(3)打開內(nèi)置塊分組中的顏色抽屜,拖出紅色塊,將其填入到設(shè)置畫筆顏色塊的插槽中。

(4)重復(fù)步驟1~3,設(shè)置藍(lán)色及綠色按鈕。

(5)最后設(shè)置擦除按鈕。從擦除按鈕的抽屜中拖出“當(dāng)擦除按鈕被點(diǎn)擊時(shí)”塊。再從畫布抽屜里拖出“清除畫布”塊,并將其放在擦除按鈕點(diǎn)擊事件塊中。確認(rèn)所有塊顯示如圖2-14所示。

圖2-14 點(diǎn)擊顏色按鈕改變畫筆顏色,單擊擦除按鈕清空畫布

測試:點(diǎn)擊每個(gè)顏色按鈕,看看是否能夠畫出不同顏色的圓點(diǎn);點(diǎn)擊擦除按鈕,看看畫布是否被清空。

2.4.4 讓用戶拍照片

App Inventor應(yīng)用可以調(diào)用安卓設(shè)備的強(qiáng)大功能,包括相機(jī)功能。為了增加應(yīng)用的趣味性,用戶可以打開相機(jī)拍攝照片,并將照片設(shè)置為畫布的背景。

照相機(jī)組件有兩個(gè)關(guān)鍵的代碼塊:“讓照相機(jī)拍攝照片”塊用來啟動設(shè)備上的拍照程序;拍照完成時(shí)將觸發(fā)“照相機(jī)完成拍攝”事件。在完成拍攝事件處理程序中,可以將剛剛拍攝的照片設(shè)置為畫布的背景圖片。

(1)打開拍照按鈕的代碼塊抽屜并拖出按鈕點(diǎn)擊事件塊。

(2)從照相機(jī)1的抽屜中拖出“讓照相機(jī)1拍攝照片”塊,放在拍照按鈕的點(diǎn)擊事件處理程序中。

(3)從照相機(jī)1的抽屜中拖出完成拍攝事件塊。

(4)從畫布抽屜中拖出“設(shè)畫布的背景圖片”塊,放在照相機(jī)1拍攝完成事件處理程序中。

(5)照相機(jī)1拍攝完成事件中有一個(gè)名為“圖片地址”的參數(shù),代表剛剛拍攝完成的照片。從事件塊中取出“圖片地址”塊,并填充到“設(shè)畫布的背景圖片”塊的插槽中。

所有的代碼塊如圖2-15所示。

圖2-15 將拍好的照片設(shè)置為畫布的背景圖片

測試:在設(shè)備上點(diǎn)擊拍照按鈕并拍攝照片,貓的圖片會變成你拍的照片。你可以在照片上進(jìn)行繪畫。(在Wolber教授的照片上繪畫是學(xué)生們的一大樂事,如圖2-16所示。)

圖2-16 帶有Wolber教授涂鴉照片的“油漆桶”應(yīng)用

2.4.5 改變畫筆的大小

在畫布上畫圓時(shí),圓的大小取決于畫圓命令中的半徑參數(shù);現(xiàn)在半徑的值是5。如果想改變圓的大小,需要為半徑設(shè)置不同的值。試試看將此前的5改為10,然后在測試設(shè)備上觀察結(jié)果。

但問題是,應(yīng)用的用戶只能用開發(fā)者設(shè)置的半徑參數(shù)畫圓。如何讓用戶來改變圓的大小呢?為此我們來修改程序,這樣不只是程序員,用戶也能改變圓的大小:當(dāng)用戶點(diǎn)擊大圓按鈕時(shí),圓的半徑設(shè)為8;當(dāng)點(diǎn)擊小圓按鈕時(shí),半徑設(shè)為2。

我們要用不同的半徑畫圓,但應(yīng)用如何知道我們要用哪個(gè)值呢?必須通知應(yīng)用我們選定的值,而應(yīng)用必須以某種方式記住或保存這個(gè)值,這樣才能在需要的時(shí)候使用這個(gè)值。之前我們所使用的值,要么設(shè)定為組件的屬性(如畫布的畫筆顏色),要么用固定的數(shù)字塊(如數(shù)字5),而現(xiàn)在應(yīng)用需要記住一些屬性之外的、不是固定不變的東西,這就需要定義一個(gè)變量。變量是一個(gè)存儲單元,可以把它想象成一個(gè)容器,里面存儲著可變的數(shù)據(jù),如畫筆的大小(有關(guān)變量的詳細(xì)信息,請參見第16章)。

讓我們先來定義“畫筆寬度”這個(gè)變量。

(1)在編程視圖的內(nèi)置塊分組中,從變量抽屜中拖出一個(gè)“聲明全局變量”塊。將“我的變量”改為“畫筆寬度”。

(2)注意,這個(gè)“聲明全局變量畫筆寬度”塊有一個(gè)開放的插槽,可以在這里設(shè)定變量的初始值。初始值指的是應(yīng)用啟動時(shí)變量的默認(rèn)值(編程術(shù)語也叫“變量初始化”)。在本應(yīng)用中,用數(shù)字塊2來初始化變量畫筆寬度(創(chuàng)建塊“2”的方法有兩種:在工作區(qū)直接輸入“2”,然后回車;或從數(shù)學(xué)抽屜中拖出“0”塊,將0改為2),將其填充到“聲明全局變量”塊的插槽中,如圖2-17所示。

圖2-17 將全局變量畫筆寬度的初始值設(shè)為2

2.4.6 使用變量

下一步,我們要修改畫布的觸摸事件處理程序,將其中畫圓命令中的半徑參數(shù)由原來的固定值替換為變量畫筆寬度。(乍一看我們使用的半徑參數(shù)還是預(yù)先設(shè)定的固定值2,并非一個(gè)可變值,不過別急,稍后我們將改變畫筆寬度的值,因此也就改變了所畫圓的大小。)

(1)從“聲明全局變量畫筆寬度”塊中拖出一個(gè)“畫筆寬度”塊,它提供了變量的值。

(2)來看“讓畫布畫圓”塊,將數(shù)字塊“5”拖出插槽并扔進(jìn)垃圾桶,用“畫筆寬度”塊來替換(見圖2-18)。當(dāng)用戶觸摸畫布時(shí),應(yīng)用將根據(jù)畫筆寬度的大小來確定圓的半徑。

圖2-18 圓的半徑取決于變量“畫筆寬度”中保存的值

2.4.7 修改變量的值

現(xiàn)在,應(yīng)用將根據(jù)畫筆寬度的值來決定繪制圓的大小。不過,畫筆寬度既然是變量,就要依據(jù)用戶的選擇進(jìn)行改變。通過編寫小圓按鈕及大圓按鈕的點(diǎn)擊事件處理程序來實(shí)現(xiàn)此功能。

(1)從小圓按鈕的抽屜中拖出點(diǎn)擊事件處理程序。再從變量抽屜中拖出第三個(gè)塊——“設(shè)……為”塊,點(diǎn)擊小倒三角形周圍區(qū)域打開下拉列表(此時(shí)只有一項(xiàng)),選擇“global畫筆寬度”,并將其填充到小圓按鈕點(diǎn)擊事件中。最后,創(chuàng)建一個(gè)數(shù)字塊“2”,并將其填充到“設(shè)global畫筆寬度”塊中。

(2)創(chuàng)建另一個(gè)類似的大圓按鈕點(diǎn)擊事件處理程序,設(shè)置畫筆寬度為8。這兩個(gè)事件處理程序顯示在編程視圖中,如圖2-19所示。

圖2-19 點(diǎn)擊按鈕改變畫筆寬度,畫圓的大小也將隨之改變

提示:“設(shè)global畫筆寬度”中的“global”(全局)指的是該變量適用于程序中所有的事件處理程序,因此被稱為全局變量。與全局變量相對應(yīng)的是局部變量,適用于程序的特定部分(詳見第21章)。

測試:嘗試單擊大圓按鈕、小圓按鈕,然后在畫布上觸碰,所繪圓點(diǎn)的大小是否不同?畫線呢?線沒有變化,因?yàn)橹挥挟媹A命令塊使用了變量畫筆寬度。在此基礎(chǔ)上,能否考慮修改代碼塊,以使畫筆寬度對畫線也同樣有效?(提示:畫布有一個(gè)畫筆線寬屬性。)

主站蜘蛛池模板: 襄垣县| 共和县| 新龙县| 东兰县| 海口市| 济南市| 彰武县| 丹凤县| 崇州市| 文成县| 沅江市| 呼伦贝尔市| 隆化县| 佛山市| 平泉县| 临沭县| 青铜峡市| 恩施市| 页游| 巫溪县| 加查县| 林口县| 太康县| 精河县| 洮南市| 中西区| 龙南县| 冕宁县| 沙湾县| 海晏县| 大安市| 琼结县| 涟源市| 东源县| 凤凰县| 婺源县| 肇州县| 彩票| 城市| 连平县| 元阳县|