其实聊天区的内容非常简单,就是一些与聊天有关的内容:聊天内容显示框、滚动条、文字输入框及几个功能控制按钮。
让我们先看看聊天内容显示框。先制作一个适当大小的文本框,然后给它命名chat_display,如图7-9所示。
图7-9
然后再引入一个滚动条组件(ScrollBar),调整它的大小、宽度到你喜欢的样式,将它的目标文本框的名字指向刚才定义的文件框chat_display,如图7-10所示。
图7-10
这样就把滚动条与文本框联系起来了。如果文本的长度超出时,滚动条就会自动出现滑块,让用户自行操纵。滚动条是Flash MX中新加入的功能,MX不但有滚动条组件,还有其他组件。MX中用户不但可以方便地使用系统提供的组件,还可以自行制作自己需要的组件,这些组件功能让Flash MX的功能变得无比强大,而现在网上已经出现了大量各种功能强大的组件可以下载,极大地方便了使用者。
制作完成,这个聊天显示框的效果如图7-11所示。
图7-11
将之加入主场景中,命名为objChatDisplay,如图7-12所示。
图7-12
下面请看前面提到的init_play函数,这个函数其实就是在聊天显示框内给下棋者一个功能说明,程序如下:
function init_play() {
objChatDisplay.chat_display.html = true;
objChatDisplay.chat_display.htmlText = "";
objChatDisplay.chat_display.htmlText += "<font color = \"#ff0000\" size = \"+4\">【帮助】:把鼠标移到棋盘的最上方,将出现箭头按钮,在自"+newline;
objChatDisplay.chat_display.htmlText += "<font color = \"#ff0000\" size = \"+4\"> 在需要的位置按下箭头按钮,棋子便会在对应格中"+newline;
objChatDisplay.chat_display.htmlText += "<font color = \"#ff0000\" size = \"+4\"> 最低的无棋子位置落子。双方轮流走棋,首先在横、"+newline;
objChatDisplay.chat_display.htmlText += "<font color = \"#ff0000\" size = \"+4\"> 竖、斜任一种方式上形成四子相连局面的一方算胜。<br>";
}
很显然,这里对objChatDisplay.中文字对象chat_display的文本(htmlText)内容进行了控制,直接往文本框中填写内容。这些内容不但可以是普通文本,还可以使用简单的html超文本,而且可以控制字体的颜色与大小。细心的读者可能已经发现了一个问题,就是这里每行都没有颜色结束标志,而每行的开始都有颜色开始的标志。其实这个是Flash MX控制上的问题,就算没有结束它的颜色与字体大小,它的控制内容也不会传递到下一行,也就是每次控制的范围只有一行。
有了聊天显示区,接下来请看通信部分是如何使用它的:
function onXML_Receive(x) {
……
} else if (e.nodeName == "TXT") {
//普通文本框
trace(objChatDisplay.chat_display);
objChatDisplay.chat_display.htmlText += e.attributes.Value+newline;
} else if (e.nodeName == "PRI") {
// 私聊,支持html语言
objChatDisplay.chat_display.htmlText += e.attributes.Value+newline;
} else if (e.nodeName == "SYS") {
//系统信息
objChatDisplay.chat_display.htmlText += sys+e.attributes.Value+newline;
} else if
……
其实,使用起来非常简单,只需不断往文本框的尾部加入新的聊天内容便可。聊天显示框有这个功能便已足够,滚动文本的功能交给系统的ScrollBar组件自动完成,不需再进行专门的编程控制。
在聊天显示框的下面是聊天文字输入框,这是一个供用户输入文本的地方,它又分成下面三个部分
Ö 控制按钮
Ö 文本输入框text
Ö 信息发送按钮
控制按钮
控制按钮从左到右分别是斜体、字体加粗、加超级链接,如图7-13所示。
图7-13
其相关程序如下:
on (release) {
//斜体字
text = text+" ";
Selection.setFocus("text");
Selection.setSelection(text.length-1,text.length-1);
}
on (release) {
//字体加粗
text = text+" ";
Selection.setFocus("text");
Selection.setSelection(text.length-1,text.length-1);
}
on (release) {
//字体加超级链接
text = text+">http://[/url]";
Selection.setFocus("text");
Selection.setSelection(text.length-1,text.length-1);
}
信息发送按钮
这些都比较容易,让我们把精力放在发送按钮上吧,程序如下:
on (release, keyPress "<Enter>") {
//文本输入框为空就什么都不做
if (text == null || trim(text) == "") {
return;
}
text = trim(text);
//如果是在下棋状态,则所有聊天的内容只发给下棋的对手,采用私聊方式发送
if (_root.now_play_table != 0) {
text = "/p "+_root.rival+" "+text;
} else {
if (text.charAt(0) != "/" && trim(target) != null && trim(target) != "") {
text = "/target "+target+" "+text;
}
}
//对输入串进行特别字符变换
text = _root.encode(text);
var chatXML;
var m_Message;
chatXML = new XML();
if (text.charAt(0) == "/") {
// cmds
if (text.charAt(1) == "/") {
//双斜杠命令,可以完成一些系统管理方面的功能
if (trim(target) != null && trim(target) != "") {
text += " "+target;
}
m_Message = chatXML.createElement("CMD");
m_Message.attributes.VALUE = "ACT";
m_Message.attributes.PARAM = text.substring(2);
chatXML.appendChild(m_Message);
} else {
// 单斜杠命令,有一些系统的简单功能
m_Message = chatXML.createElement("CMD");
var cmdEnd = text.indexOf(" ");
if (cmdEnd != -1) {
m_Message.attributes.VALUE = text.substring(1, cmdEnd);
m_Message.attributes.PARAM = text.substring(cmdEnd+1);
} else {
m_Message.attributes.VALUE = text.substring(1);
}
chatXML.appendChild(m_Message);
}
} else {
// 正常的聊天语句
m_Message = chatXML.createElement("TXT");
m_Message.attributes.VALUE = text;
chatXML.appendChild(m_Message);
}
trace(chatXML.toString());
// 发送聊天内容
_root.chatSocket.send(chatXML);
text = "";
Selection.setFocus("text");
function trim(strin) {
var i, j;
for (i=0; i<strin.length; i++) {
if (strin.charAt(i) != ' ') {
break;
}
}
if (i == strin.length) {
return strin;
}
for (j=strin.length-1; j>=i; j--) {
if (strin.charAt(j) != ' ') {
break;
}
}
return strin.substring(i, j+1);
}
}
上面的程序从某种意义上讲是一个简单的命令解释器,根据用户输入的内容来决定是普通的聊天语言还是系统管理方面的命令。如果是双斜杠系统命令//kick就以下面的形式来发送:
<CMD PARAM="kick" VALUE="ACT" />
单斜杠命令/p发出的内容如下:
<CMD VALUE="ver" />
正常的聊天语句“这是一个游戏测试”发送的内容如下:
<TXT VALUE="这是一个游戏测试" />
与其对应在服务器端也有一个处理文本的Java程序段,完成将用户发来的聊天内容广播给其他的人,程序如下:
……
if(this.m_TXT.equals(root.nodeName)) {
// only have text node
if(user.status == this.usr_ST_ON) {
String txt = (String)root.attributes.get(this.ma_VALUE);
if(txt!= null && !txt.equals("")) {
//encode ucc code
txt = this.uccEncode(txt);
//encode special character
txt = this.scEncode(txt);
txt = user.nickname + " : " + txt;
root.attributes.remove(this.ma_VALUE);
root.attributes.put(this.ma_VALUE, txt);
user.manager.notifyAllExcept(root.toString());
}
}
else {
//no a valid user!!!!
user.onKill();
}
}
……
下面是Flash的通信响应程序:
function onXML_Receive(x) {
……
} else if (e.nodeName == "TXT") {
trace(objChatDisplay.chat_display);
objChatDisplay.chat_display.htmlText += e.attributes.Value+newline;
接收到服务器传来的信息,把它加到聊天记录的尾部,这样一句聊天工作就完成了。你可能觉得这样太麻烦,是的,实时聊天就是这样麻烦的,目前还没有其他更好的办法。