ActionScriptのブログ記事
2月5日のblogにて、ActionScript2.0でのダブルクリックについて書きました(3.0よりダブルクリックをイベントとして受け取れるようです)。
その際に書いたものは、ダブルクリックを検知する前に必ず、普通のクリックも検知してしまうというものでした。
今回紹介するのは、普通のクリックとダブルクリックを分けて検知するスクリプトの紹介です。
ある一定時間以内に二度クリックされた場合はダブルクリック、一度だった場合は普通のクリックと判断します。
クリック検出関数内にて、setInterval関数を使用し、ある一定時間後に別の関数を呼び出す定義をします。この際、クリック回数を1としておきます。
一定時間内に再度クリックがあった場合には、クリック回数を増やします。
setInterval関数にて呼び出しを定義された関数内で、クリック回数を元に処理を分岐します。
以下、そのスクリプトです。
//スクリプトここから(ダブルクリック検知2)
var duration:Number=100;//ダブルクリック時間定数msec
var clickN:Number=0;//クリック回数
clickA.onPress=clickSD;//clickAはクリックを検出したいインスタンス名
var intervalId:Number;
function clickSD2():Void{
if(clickN==1){
//一回だけのクリック処理
}
else if(clickN>1){
//ダブルクリック処理
}
clearInterval(intervalId);//間隔をクリアする
clickN=0;//クリック回数を0に戻す
}
function clickSD():Void{
//durationにて設定した時間後にclickSD2関数呼び出し
if(clickN==0)intervalId = setInterval(_root, "clickSD2", duration);
//クリック回数を増やす
clickN+=1;
}
//スクリプトここまで(ダブルクリック検知2)
もしももっと簡易なスクリプトがございましたら、ぜひ教えていただきたいです。
質問がありましたら質問掲示板にどうぞ。素材のスクリプトについての質問も技術的な指摘もお待ちしています。
Flashではマウスクリックをイベントとしてキャッチことができます。
ただし、ダブルクリックを受け取るというイベントが用意されていません(ActionScript3.0では新たに加わるようです)。
つい先日アップしたFlash素材image10ではダブルクリックと普通のクリックで動作を変えています。
その仕組みについてお話いたします。
まず、ダブルクリックのイベントキャッチを実現する際、最初に思いつくのは、以下のようなアルゴリズムです。
1.クリック時に現在時間を取得する
2.クリック時、取得済みの時間と現在時間との差異によって条件分岐する
たとえば、差異が100ms未満ならダブルクリック、100ms以上なら普通のクリックと判断する。
スクリプトは以下のようになります。
//スクリプトここから(ダブルクリック検知)
var duration:Number=100;//ダブルクリック時間定数msec
var countN:Number=0;//時間取得
clickA.onPress=clickSD;//clickAはクリックを検出したいインスタンス名
//クリック検知用の関数。
function clickSD():Void{
if(getTimer()-countN<duration){
//ダブルクリック処理
}
else{
//一回だけのクリック処理
}
countN=getTimer();
}
//スクリプトここまで(ダブルクリック検知)
これで確かにダブルクリックを検知できますが、一つ欠点がございます。
それは「ダブルクリックの処理をする前に必ず普通のクリックの処理を行ってしまう」というものです。
ということで、その欠点を解消するスクリプトを考えました。配布した素材には解消後のスクリプトを使用しています。
そのスクリプトについてはまた近日中に掲載します。
質問がありましたら質問掲示板にどうぞ。素材のスクリプトについての質問も技術的な指摘もお待ちしています。
今回は文字列からの文字の抽出です。
すでに多くの場所で紹介されているスクリプトでしょうが、それでも紹介して損があるわけではないかと思いますので。
たとえば、外部テキストに格納した文字列をロードして一文字ずつ別々の効果やフォントで表示したいときなどに使用します。
以下のスクリプトは抽出した文字をそれぞれ配列に格納しています。
//スクリプトここから(使用可能文字チェック)
var arr:Array = new Array();//文字列格納
var str:String = "あいうえおかきくけこ";//文字列
var len:Number = 0;//文字列長
len = str.length;//文字列長を取得
for(var i:Number = 0 ; i < len ; i++){
arr[i] = str.charAt(i);//文字の抽出
}
//スクリプトここまで
質問がありましたら質問掲示板にどうぞ。素材のスクリプトについての質問も技術的な指摘もお待ちしています。
今回は外部htmlファイルのロードについて紹介いたします。
正確には「ダイナミックテキストにて外部テキストファイルの記述内容をhtmlとして表示する」ですね。
ただし、Flashはhtml形式に完全に対応しているわけではないので、そのままブラウザで表示するのと同じようには見えません。
使用できるタグが代表的なもの(a,b,br,font,i,img,li,p,span,textformat,u)に限られる上に、画像に対するテキストの回り込みの解除が困難である等の問題があります。
以下、サンプルスクリプトです。
//スクリプトここから(外部htmlロード)
//テキストファイル「textarea.txt」がimgフォルダ内に格納されている場合
//html文書についてはtextarea.txt内の変数text1に記述されている場合
//つまり「&text1=htmlの内容&」という形式
//textAはダイナミックテキストのインスタンス名
System.useCodepage = true;//外部テキスト文字化け防止
var wordA = new LoadVars();//文字列格納用
wordA.load("img/textarea.txt");//テキストファイルロード
wordA.onLoad = function():Void{//ロード完了時
textA.html = true;
textA.htmlText = eval("wordA.text1");
}
//スクリプトここまで
質問がありましたら質問掲示板にどうぞ。素材のスクリプトについての質問も技術的な指摘もお待ちしています。
青春BではFlash素材を配布しています。
その関係もあってか、Flash関係の知識を目的として訪れる人も少なからずいるみたいです。
Flash本に執筆したことも影響しているのでしょう。
なので、今後はActionScript関係の記事をblogに頻繁に掲載しようかと思っています。
ActionScriptのコンテンツを始めようとも考えました。
ですが、ActionScriptを深く語るほどには詳しくないです。
それに、青春BはFlashサイトではないですので、blogでの記事掲載のみに留めるつもりです。もしも数が増えたら別コンテンツ化も考えます。
当面はblog上でのみ掲載とします。Flashの特定のスクリプトについて検索した方に向けてというところですね。
今回はメールアドレスチェックを紹介します(すでに多くの場所で紹介されているスクリプトであるかとは思いますが)。
つまり、来訪者がメールアドレスを入力したとき、入力したアドレスがメールアドレスとして適切なフォーマットかどうかを確認するスクリプトです。
半角英数と一部記号以外を使っていないかとか、@が使われているかとかですね。
ActionScript3.0は正規表現をサポートしているので簡単にできるのでしょうが、現在の主である2.0はサポートしていないのでちょっとややこしいソースになりました。
簡単に説明すると、入力された文字を一つずつ抜き出して、利用可能な文字一つ一つとマッチングを行います。
以下、使用可能な文字以外が使われている場合にfalseを返すスクリプトです。
//スクリプトここから(使用可能文字チェック)
//文字列を受け取って利用可能か否かをtrueかfalseで返します
//mailtextが入力されたメールアドレス、ccharが使用可能な文字となります
function mcheck(mailtext:String):Boolean{
var mchar:String = "";
var cchar:String = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.@";
for (var i=0 ; i < mailtext.length ; i++){
mchar = mailtext.charAt(i);
if (cchar.indexOf(mchar,0) == -1)return false;
}
return true;
}
//スクリプトここまで
charAtは指定した位置の文字を抽出するメソッド、indexOfは文字列検索メソッドで指定の文字が見つからなかった場合は-1を返します。
つまり一文字ずつメールアドレスを取得して、それをindexOfと比較して指定の文字が見つからないときにはfalseを返します。
すべての文字が見つかった際にはtrueを返しています。
さらに、@が使用されているかもチェックしているスクリプトは以下の通りです。
//スクリプトここから(使用可能文字チェック+@使用チェック)
function mcheck(mailtext:String):Boolean{
var mchar:String = "";
var cchar:String = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.@";
for (var i=0 ; i < mailtext.length ; i++){
mchar = mailtext.charAt(i);
if (cchar.indexOf(mchar,0) == -1)return false;
}
for (var i = 0 ; i < mailtext.length ; i++){
if(mailtext.charAt(i) == "@")return true;
}
return false;
}
//スクリプトここまで
応用すれば特定のドメインのメールアドレスを拒むとかも可能にできます。
質問がありましたら質問掲示板に書き込んでくだされば(乏しい)実力の範囲でお答えいたします。
青春B内の素材のスクリプトについての質問にも答えます。
間違いの指摘もお待ちしています。
一昨日、コンポーネントの拡大と縮小の説明の際に、拡大と縮小の一定ではない変化を実現するコードを記載しました。
その点についてちょっと詳しい説明です。
別にわたしが思いついたわけではないアイディアなので、わたしが偉そうに説明するものではないですが、応用が色々とききそうな考え方ですのでご紹介です。
たとえば、nowxという変数値が最初100で、それを0に近づけたいとします。
以下のコードはnowxを10ずつ0に近づけていきます。
実際はif文の処理はこのコードではちょうど0で止まるため必要ないです。
//コードここから
var nowx:Number = 100;//変数nowx
var nextx:Number = 0;//nowxの終値
var diffx:Number = 10;//nowxの変化値
//nowxをdiffxずつnextxに近づけるループ
for( ; nowx > nextx ; nowx -= diffx){
if(nowx < nextx)nowx = nextx;//nowxがnextxより小さくなった際にnextxに戻す
}
//コードここまで
前回の拡大縮小のコードでは、一定間隔の変化ではなく、変化値を減らしていきたかったため、以下のようなコードを使用しました。
if文の条件でnxtxに1をプラスしているのは、最後の方の細かい変化はただの負荷にしかならない場合が多いかと思ったからです(細かい変化を求める場合には不要かもしれないですね)。
//コードここから
var nowx:Number = 100;//変数nowx
var nextx:Number = 0;//nowxの終値
var diffx:Number = 2;//nowxの変化分
//nowxとnextxの差を1/diffxずつ狭めるループ
for( ; nowx > nextx ; nowx -= (nowx - nextx) / diffx){
if(nowx < nextx + 1)nowx = nextx;//nowxがnextx+1より小さくなった際にnextxに戻す
}
//コードここまで
上記のコードではnowxが
100
50
25
12.5
6.25
3.125
1.5625
0
というように変化します。nowxとnextxの差が半分ずつ(つまり1/diffxずつ)に縮まっていっているということです。
diffxの値を3にするとnowxの変化が
100
66.6666666666667
44.4444444444444
29.6296296296296
19.7530864197531
13.1687242798354
8.77914951989026
5.8527663465935
3.90184423106234
2.60122948737489
1.73415299158326
1.15610199438884
0
というように緩やかになります。差が1/3ずつになっているからです。
ありがちなのかどうかわからないですが、個人的によく使用するアルゴリズムです。
スクロールを表現するとき、見た目的に自然な減速になるので。
スクリプトなりプログラムなり、言語経験のある人には誰だって「会心のソース」みたいなものがあると思います。
美しい数式を見たときのような感動を覚える自らの生み出したソースです(過去に他の人がすでに思いついていることがほとんどだとしても)。
わたしはこれまでにいくつかの言語に触れてきました。Basic、VisualBasic、C、C++、Visual C++、Java、HTML、CSS、JavaScript……。
そんな学習の中で心震えたソースについて書いていってみようかななんて思いました。
自己満足が大半だとしても、人の役に立つことがけっこうあるかなとも考えましたので。
このblogにも書きましたが、ことしの夏~秋、MdN出版の「プロとして恥ずかしくないFlashの大原則」の執筆を行いました。全体の9ページではありますが。
自分の書いたソースが人の注目を集める形で世に出るということは、恐くて、でも、同時にすごく嬉しかったです。
その中でコンポーネントの拡大と縮小を取り上げました。
Flashではインスタンスにマウスカーソルが乗ったときにそれを察知するメソッドが用意されていますが、すべてのコンポーネントに対応しているわけではありません(わたしが知る限りはですが、そういう前提でソースを書きました)。
そこで、あらかじめコンポーネントのx座標とy座標を取得して、その位置にマウスカーソルが来たら拡大するというソースを書いてみました。
以下、そのソース(省略版)です。
form1というムービークリップ上にコンポーネントを乗せています。
各コンポーネントはcomp1~comp4というインスタンス名です。
//ソースここから
var compArray:Array = new Array();//コンポーネント格納配列
var compNumber:Number = 4;//コンポーネント数
var bigScale:Number = 150;//コンポーネント拡大時スケール(%)
var mcx:Number = form1._x;//ステージから見たformのx座標
var mcy:Number = form1._y;//ステージから見たformのy座標
//全コンポーネントの配列への格納とx座標y座標の取得
for(var i =1 ; i <= compNumber ; i++){
if(i <= compNumber1) compArray[i] = eval("form1.comp" + i);//配列への格納
compArray[i].nextScale = 100;//通常時は100、拡大時は150
compArray[i].x1 = compArray[i].x + mcx;
compArray[i].x2 = compArray[i].x + mcx + compArray[i].width * bigScale / 100;
compArray[i].y1 = compArray[i].y + mcy;
compArray[i].y2 = compArray[i].y + mcy + compArray[i].height * bigScale / 100;
}
//コンポーネント上にマウスが乗った際の拡大表示
_root.onEnterFrame = function():Void{
for(var i = 1 ; i <= compNumber ; i++){
if(_root._xmouse>compArray[i].x1 && _root._xmouse
compArray[i].nextScale = bigScale;//上にマウスがある場合はnextScaleを150にする
}
else{
compArray[i].nextScale = 100;//上にマウスがない場合はnextScaleを100にする
}
//表示スケールをnextScaleに近づけていく。差を2で割ることによって一定ではない拡大縮小を実現する
compArray[i].scaleX += (compArray[i].nextScale-compArray[i].scaleX) / 2;
compArray[i].scaleY += (compArray[i].nextScale-compArray[i].scaleY) / 2;
}
}
//ソースここまで
ソースは以上です。
自分では良いと思っていても人からすれば欠点だらけのソースかもしれないので、意見等いただけると嬉しいです。
Wikipedia ActionScript
Wikipedia プログラム言語
プロとして恥ずかしくないFlashの大原則 MdN出版該当ページ
プロとして恥ずかしくないFlashの大原則 Amazon該当ページ