此示例通过处理鼠标事件来说明用户交互。用户在一个由随机字母组成的网格上构造尽可能多的词,拼写方法是:在网格中进行水平或垂直移动,但同一个字母只允许使用一次。此示例演示了 ActionScript 3.0 的下列功能:
-
动态构造组件网格
-
响应鼠标事件
-
根据用户交互维护分数
若要获取此范例的应用程序文件,请参阅
www.adobe.com/go/learn_programmingAS3samples_flash_cn
。可以在 Samples/WordSearch 文件夹中找到 WordSearch 应用程序文件。该应用程序包含以下文件:
文件
|
说明
|
WordSearch.as
|
此类提供了应用程序的主要功能。
|
WordSearch.fla
或
WordSearch.mxml
|
Flex 或 Flash 的主应用程序文件(分别为 MXML 和 FLA 格式)。
|
dictionary.txt
|
此文件用于确定拼写的词能否得分以及拼写是否正确。
|
加载字典
要创建一个涉及查找词的游戏,您需要使用字典。本示例包含一个名为 dictionary.txt 的文本文件,该文件包含以回车符分隔的词列表。创建名为
words
的数组后,
loadDictionary()
函数将请求加载此文件,成功加载后,此文件将变成一个很长的字符串。通过使用
split()
方法,在回车符(字符代码 10)或换行符(字符代码 13)的每个实例处断开,可以将该字符串分析为词的数组。这种分析是在
dictionaryLoaded()
函数中实现的:
words = dictionaryText.split(String.fromCharCode(13, 10));
创建用户界面
在存储这些词后,您就可以设置用户界面了。请创建两个 Button 实例:一个用于提交词,另一个用于清除当前拼写的词。在每种情况下,您必须通过侦听该按钮所广播的
MouseEvent.CLICK
事件并随后调用一个函数来响应用户输入。在
setupUI()
函数中,此代码在两个按钮上创建侦听器:
submitWordButton.addEventListener(MouseEvent.CLICK,submitWord);
clearWordButton.addEventListener(MouseEvent.CLICK,clearWord);
生成游戏板
游戏板是由随机字母组成的网格。在
generateBoard()
函数中,二维网格是通过将一个循环嵌套到另一个循环中创建的。第一个循环增加行数,第二个循环增加每行的总列数。由这些行和列创建的每个单元格包含一个按钮,它表示游戏板上的一个字母。
private function generateBoard(startX:Number, startY:Number, totalRows:Number, totalCols:Number, buttonSize:Number):void
{
buttons = new Array();
var colCounter:uint;
var rowCounter:uint;
for (rowCounter = 0; rowCounter < totalRows; rowCounter++)
{
for (colCounter = 0; colCounter < totalCols; colCounter++)
{
var b:Button = new Button();
b.x = startX + (colCounter*buttonSize);
b.y = startY + (rowCounter*buttonSize);
b.addEventListener(MouseEvent.CLICK, letterClicked);
b.label = getRandomLetter().toUpperCase();
b.setSize(buttonSize,buttonSize);
b.name = "buttonRow"+rowCounter+"Col"+colCounter;
addChild(b);
buttons.push(b);
}
}
}
虽然仅在一行中添加了
MouseEvent.CLICK
事件的侦听器,但由于该侦听器位于
for
循环中,因此会将其分配给每个 Button 实例。此外,还会为每个按钮分配一个从其行和列位置派生的名称,这为以后在代码中引用每个按钮的行和列提供了一种简便的方法。
通过用户输入来构造词
拼词规则是:选择垂直或水平相邻的字母,但每个字母只允许使用一次。每次单击时将生成一个鼠标事件,此时必须检查用户正在拼写的词,以确保该词正确地从以前单击的字母继续进行拼写。否则,将删除以前的词并开始拼写一个新词。此检查在
isLegalContinuation()
方法中执行。
private function isLegalContinuation(prevButton:Button, currButton:Button):Boolean
{
var currButtonRow:Number = Number(currButton.name.charAt(currButton.name. indexOf("Row") + 3));
var currButtonCol:Number = Number(currButton.name.charAt(currButton.name.indexOf("Col") + 3));
var prevButtonRow:Number = Number(prevButton.name.charAt(prevButton.name.indexOf("Row") + 3));
var prevButtonCol:Number = Number(prevButton.name.charAt(prevButton.name.indexOf("Col") + 3));
return ((prevButtonCol == currButtonCol && Math.abs(prevButtonRow - currButtonRow) <= 1) ||
(prevButtonRow == currButtonRow && Math.abs(prevButtonCol - currButtonCol) <= 1));
}
String 类的
charAt()
和
indexOf()
方法从当前单击的按钮和上次单击的按钮中检索相应的行和列。如果行或列未改变,或者行或列已改变但与上次单击位置的行或列之间相差不超过一行或一列,
isLegalContinuation()
方法将返回
true
。如果要更改游戏规则并允许斜向拼写,您可以删除对未改变的行或列的检查,最后一行将如下所示:
return (Math.abs(prevButtonRow - currButtonRow) <= 1) && Math.abs(prevButtonCol - currButtonCol) <= 1));
检查词的提交
要完成游戏的代码,您需要提供检查词的提交和计算分数的机制。
searchForWord()
方法包含这两项功能:
private function searchForWord(str:String):Number
{
if (words && str)
{
var i:uint = 0
for (i = 0; i < words.length; i++)
{
var thisWord:String = words[i];
if (str == words[i])
{
return i;
}
}
return -1;
}
else
{
trace("WARNING: cannot find words, or string supplied is null");
}
return -1;
}
此函数循环访问字典中所有的词。如果用户的词与字典中的词匹配,则返回该词在字典中的位置。如果该位置有效,
submitWord()
方法随后将检查响应并更新分数。
自定义
类的开头是几个常量。可通过修改这些变量来修改此游戏。例如,您可以通过增大
TOTAL_TIME
变量的值来更改可用于玩该游戏的时间。还可以稍微增大
PERCENT_VOWELS
变量的值来增大找到词的可能性。
|
|
|