实例1:留言板的制作
我们的这个留言板由服务器端和客户端两部分构成。其工作过程是这样的:用户在Flash电影的第1帧中的输入文本中输入“姓名”、“留言内容”等,然后单击“发送”按钮发送留言,随后,在服务器端的CGI程序完成向数据库中追加;留言的处理后,用户会被带入到Flash电影的第2帧,在该帧中Flash会调用另一个CGI程序显示用户本次的留言和之前所有其它人的留言。
下面我们分别完成服务器端CGI程序和客户端Flash的开发。
1. 服务器端CGI程序的编写
服务器端有3个文件:一个用于把有Flash发来的留言内容写入文本数据库的CGI程序-----leaveword.pl,一个用于把文本数据库中的所有留言发送回Flash的CGI程序----leaveworddisplay.pl,以及一个用于保存留言的文本数据库文件----leaveword.log。
在这个留言板中,我们将收集用户的“姓名”、“来自地区”、“电子邮箱”、“个人网址”、“留言内容”5个信息。这些信息文本在文本数据库中的存储格式如下所示:
陈胜::吴广::http://www.::这是一个测试。
我们将用::分割每个字段。因此,我们应该在把用户的留言内容提交的数据库之前,从所有5个信息中剔除可能存在的“::”以免让用户无意的输入给我们的数据库造成破坏。
首先,我们来看leaveword.pl的代码:
#!/usr/local/bin/perl
#调用readparse子程序对由Flash发送来的URL编码数据进行解码。
&readparse;
print "Content-type: text/html\n\n";
open(LOGFILE, "<cgi-bin/leaveword.log");
#把所有留言读取到entries数组中。
#数组中的每个元素就是数据库中的一条记录,即一次留言信息。
@entries=<LOGFILE>;
close LOGFILE;
$arraylength=@entries;
#以追加方式打开leaveword.log,为把新的留言写入数据库做好准备。
open (LOGFILE, ">>cgi-bin/leaveword.log");
#因为在我们的文本数据库中是用::来作为字段分隔符的,因此需要将留言中所有的:都剔除。
#value数组中保存着已被解码的可用数据。
$value[0]=~ s/://g;
$value[0]=~ s/|//g;
#如果用户的某项信息没有输入内容,就用默认的“未填写”来代替。
if ($value[0] eq "") {
$value[0]="未填写";
}
$value[1]=~ s/://g;
$value[1]=~ s/|//g;
if ($value[1] eq "") {
$value[1]="未填写";
}
$value[2]=~ s/://g;
$value[2]=~ s/|//g;
if ($value[2] eq "") {
$value[2]="未填写";
}
$value[3]=~ s/http:\/\///g;
$value[3]=~ s/://g;
$value[3]=~ s/|//g;
if ($value[3] eq "") {
$value[3]="未填写";
}
else {
$value[3]="http://$value[3]";
}
$value[4]=~ s/://g;
$value[4]=~ s/\n//g;
$value[4]=~ s/|//g;
#如果有人恶意(或无意中)输入了大量的连续的英文、数字或符号,以致会破坏留言系统的格式化,那么就将这些东西剔除。
#这种[!-~][!-~][!-~]……处理机制主要是用于在HTML页面中显示内容时防止数据库格式被恶意破坏的。
$value[4]=~ s/[!-~][!-~]~~//g;
if ($value[4] eq "") {
$value[4]="未填写";
}
#用::来把数组中所有元素连接成一个字符串,再把这个字符串赋给变量newline。
$newline=join('::',@value);
#得到用户提交留言的时间。
($sec, $min, $hour, $mday, $mon, $year, $wday, $ydat, $isdst) = gmtime();
$mon++;
#处理千年问题。
$year=$year+1900;
#从gmtime()函数中得到的是格林威治时间,因此需要计算出北京时间(北京在时区上位于东八区)。
if ($hour>=0 && $hour<=15) {
$hour=$hour+8;
}
else {
$hour=($hour+8)-24;
$mday=$mday+1;
}
if ($mon<10) {
$mon="0$mon";
}
if ($mday<10) {
$mday="0$mday";
}
#将用户提交留言的时间以追加方式写入数据库中。
print LOGFILE ("$year$mon$mday");
print LOGFILE ("::$hour时$min分::");
#将用户的留言信息以追加方式写入数据库中。
print LOGFILE ("$newline");
#为能够用哈希方式处理数据库提供一个关键字hashkeyN,使用哈希方式能够极大的提高搜索数据库时的速度。
if ($arraylength == 0) {
print LOGFILE ("||hashkey1\n");
}
else {
$lastentries = $entries[$arraylength-1];
$hashkeynext = substr($lastentries,length($lastentries)-2,1);
$hashkeynext++;
print LOGFILE ("||hashkey$hashkeynext\n");
}
#关闭数据库。
close LOGFILE;
#向客户端发送回一点数据,以便客户端的LoadVar对象有点东西可装载。
#从而可以判断出向数据库中写入数据的工作是否已经完成。
print "finish=1";
#readparse子程序的作用是对从QUERY_STRING环境变量或标准输入中获取的URL编码数据进行解码。
#解码后的数据被存放在value数组中。
sub readparse {
read(STDIN,$user_string,$ENV{'CONTENT_LENGTH'});
if (length($ENV{'QUERY_STRING'})>0) {$user_string=$ENV{'QUERY_STRING'}};
$user_string =~ s/\+/ /g;
@name_value_pairs = split(/&/,$user_string);
foreach $name_value_pair (@name_value_pairs) {
($keyword,$value) = split(/=/,$name_value_pair);
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/ge;
push(@value, "$value");
$user_data{$keyword} = $value;
if ($value=~/<!--\#exec/) {
print "Content-type: text/html\n\nNo SSI permitted";
exit;
};
};
};
再来看看leaveworddisplay.pl的内容:
#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
open(LOGFILE, "<cgi-bin/leaveword.log");
#把所有留言都读取到entries数组中。
@entries=<LOGFILE>;
close LOGFILE;
$arraylength=@entries;
#颠倒entries数组,以便最新的留言能够显示在最前面。
@reverseentries=reverse(@entries);
$content="";
foreach $line(@reverseentries){
@fields=split(/\|\|/,$line);
#以哈希方式处理留言。
$fieldshash{$fields[1]}=$fields[0];
@eachitem=split(/::/,$fieldshash{$fields[1]});
#对读取到的时间分别提取出年、月、日。
$thisyear=int($eachitem[0]/10000);
$thismonth=int(($eachitem[0]-$thisyear*10000)/100);
$thisday=$eachitem[0]-$thisyear*10000-$thismonth*100;
#把所有的留言连接成一个长长的字符串。
$content="$content $thisyear年$thismonth月$thisday日$eachitem[1] $eachitem[2] $eachitem[3] $eachitem[4] $eachitem[5] $eachitem[6]\n";
}
#把这个长长的字符串以变量/值对的形式返回给客户端的Flash。
print "LWcontent=$content";
你不需要创建文本数据库――leaveword.log,它会由leaveword.pl程序自动创建的,现在把leaveword.pl和leaveworddisplay.pl保存到cgi-bin文件夹中。至此,我们的服务器端的工作就完成了。下面,我们继续完成客户端Flash的开发。
2.客户端Flash程序的编写
在客户端的Flash中,这里是通过一个LoadVar对象来发送数据的。用LoadVar对象来发送数据时实际上发送的是LoadVar对象的自定义属性的值。因此,必须把要发送的数据先赋值给LoadVar对象的一些自定义的属性,然后在调用LoadVar对象的sendAndLoad()方法来发送这些数据。sendAndLoad()方法不仅会发送数据,而且还期待着把服务器端脚本返回的数据装入一个事先准备好的LoadVar对象,因此,需要事先创建另外一个LoadVar对象来装载调用sendAndLoad()方法时由CGI程序返回的数据。
下面是制作过程:
【步骤1】新建一个Flash文档,在时间线第1帧的舞台中,布局留言板的表单,如图13-3-2所示。
图13-3-2布局留言板的表单
输入5个文本的实例名,从上到下分别为:username,userArea,userEmail,userWebsite,userLeaveword。
【步骤2】在时间线的第1帧中捆绑下面的脚本:
//创建两个LoadVar对象—myLVS用来发送数据,myLVL用来接收数据。
myLVS=new LoadVars();
myLVL=new LoadVars();
//因为服务器端的Perl CGI程序默认会以操作系统的传统代码页来编码字符,
//这会导致保存到文本数据库文件中的字符是以操作系统的传统代码页来编码的,
//因此,在Flash程序中读取时也必须以操作系统的传统代码页来进行解释。
System.useCodepage=true;
//点击“发送”按钮前始终停留在第1帧。
stop();
【步骤3】为“发送”按钮捆绑下面的脚本:
on(release){
//把各个输入文本中的内容依次赋给myLVS的各个自定义属性。
myLVS.userLeaveword=userLeaveword.text;
myLVS.userWebsite=userWebsite.text;
myLVS.userEmail=userEmail.text;
myLVS.userArea=userArea.text;
myLVS.userName=userName.text;
//把数据发送给leaveword.pl程序。
myLVS.sendAndLoad("cgi-bin/leaveword.pl",myLVL,"POST");
myLVL.onLoad=function(){
//前进到第2帧。
gotoAndPlay(2);
}
}
【步骤4】这里,将使用一个TextArea组件来显示leaveworddisplay.pl程序返回的留言。
在时间线的第2帧处,插入一个关键帧,从 “组件”面板中把一个TextArea组件的实例拖入到舞台中,用“自由”变形工具适当地所放它,在属性面板中为该实例赋予实例名myTextArea,如图13-3-3所示。
图13-3-3为实例赋予实例名
【步骤5】在根时间线的第2帧中绑定下面的脚本:
//指定TextArea组件myTextArea有能够自动出现的垂直滚动条。
myTextArea.vScrollPolicy="auto";
//调用leaveworddisplay.pl程序,
//返回的数据会被作为myLVL对象的自定义属性装载到myLVL对象中。
myLVL.load("cgi-bin/leaveworddisplay.pl");
//在数据完全装载后在myTextArea中显示留言。
myLVL.onLoad=function(){
myTextArea.text=myLVL.LWcontent;
}
stop();
【步骤6】将该文档保存在MyWeb文件夹中,命名为leaveword.fla,并发布为leaveword.swf。
开发工作完成!现在,让我们测试一下这个留言板的效果。在浏览器中访问http://127.0.0/ leaveword.swf,将看到发送页面。输入一些信息,单击“发送”按钮,你将看到你的留言在TextArea组件中得到显示。
实例2:MP3播放器的制作
如今多媒体的应用越来越普及,热门经常在网上享受更多的视听效果。Flash本身就是为了多媒体开发的,因此使用Flash可以制作出丰富的多媒体作品,例如网站上的MP3播放器,聊天室中视频聊天等。
【步骤1】新建一个fla文件,命名为Mp3player.fla。
【步骤2】设置播放器外观:在设计播放器外观时,可以参照下面的设计图样,如图13-3-4所示。
图13-3-4播放器外观
下面依照图1讲解一下播放器的功能。在声音没有导入前,除了Load按钮,所有的部件都是无法使用的。按下Load按钮,载入“光良-第一次.mp3”,载入的同时,按钮右边的进度条和文本框会报告载入的进度。在100%载入以后,3个按钮和拖动条才能使用,Volume用来控制音量,Pan控制左右声道的播放,transform下面的4个拖动条用来实现声音特效,mp3 progress显示音乐播放的进度。具体的界面请读者自己制作。
【步骤3】编写代码:在主舞台(_root)的“Action”中编写如下代码,以实现上述功能。
function set Enable(disenabled) {
llHead_mc.enabled = disenabled;
lrHead_mc.enabled = disenabled;
rlHead_mc.enabled = disenabled;
rrHead_mc.enabled = disenabled;
volumeHead_mc.enabled = disenabled;
panHead_mc.enabled = disenabled;
playHead_mc.enabled = disenabled;
play_btn.enabled = disenabled;
stop_btn.enabled = disenabled;
pause_btn.enabled = disenabled;
}
_root.onLoad = function() {
play_sound = new Sound();
soundTransformObj = new Object();
soundTransformObj.ll = 100;
volumeHead_mc._x += 200;
llHead_mc._x += 200;
soundTransformObj.lr = 0;
soundTransformObj.rl = 0;
soundTransformObj.rr = 100;
rrHead_mc._x += 200;
play_sound.setTransform(soundTransformObj);
play_sound.setPan(0);
panHead_mc._x += 100;
sound Playing = false;
set Enable(false);
playedPos = 0;
soundLoading = false;
progressBar_mc._visible = false;
};
this.load_btn.onRelease = function() {
play_sound.loadSound("光良 - 第一次.mp3", false);
soundLoading = true;
progressBar_mc._visible = true;
load_btn.enabled = false;
};
this.play_btn.onRelease = function() {
play_sound.start(playedPos);
sound Playing = true;
};
this.pause_btn.onRelease = function() {
playedPos = play_sound.position/1000;
play_sound.stop();
};
this.stop_btn.onRelease = function() {
playedPos = 0;
play_sound.stop();
playHead_mc._x = playHead_mc.orgPos;
sound Playing = false;
};
_root.onEnterFrame = function() {
if (soundLoading) {
var per:Number = play_sound.getBytesLoaded()/play_sound.getBytesTotal();
if (isFinite(per)) {
percent_txt.text = Math. Floor (per*100) +"%";
progressBar_mc._width = per*100;
}
If (per == 1) {
Set Enable (true);
SoundLoading = false;
}
}
};
以上是该实例的主代码。从这些代码基本上就可以知道声音控制是如何实现的,在每个拖动块上都有代码,其内容是基本相似的,在这里只介绍volumeHead_mc._x上的代码:
onClipEvent(load){
Dragged=false;
Sorgos=this’d;
}
on(presss){
Dragged=true;
}
onClipEvent(mouseMove){
if(Dragged){
if(_parent.xmouse<sorgos){
this._x=orgpos;
}else if(_parent._mouse>orgPos+200){
this._x=orgPos+200;
}else{
this._x=parent._xmouse;
}
_parent.player_sound.setVolume((this._x-sorgos)/2;
}
}
on(release,releaseOutside){
Dragged=false;
}
本文只是转载了制作的一部分,如有兴趣学习请自行寻找另一部分。