FLASHで円の描画 - 複数の円を重ねる方法について

このQ&Aのポイント
  • FLASHのフレーム内で複数の円を重ねて描画したい場合、Depthを設定する必要があります。しかし、現在のコードでは両方の円が同じDepthになってしまっています。
  • 解決策として、mc2のDepthを設定してあげることで、円を別々に表示することができます。
  • 具体的な実装方法としては、change2関数内でmc2のDepthを設定する部分を修正する必要があります。
回答を見る
  • ベストアンサー

flashで円の描画。

長文失礼します。 FLASH,CS3でActionScript2.0で作業しています。 FLASHで複数の円を重ねて円グラフの様な描画をしたくて、ネット上にあったソースを自分で少しいじりました。 しかし複数の円を描画しようとすると他の円が消えてしまいます。 外部に円を描画するスクリプト(DrawArc.as)がおいてあります。 //DrawArc.as class DrawArc { var mc:MovieClip; function DrawArc(target:MovieClip) { mc = target; } function drawLine(x:Number, y:Number, radius:Number, arc:Number, startAngle:Number, thickness:Number, color:Number, alpha:Number, yRadius:Number) { mc.clear(); mc.lineStyle(thickness,color,alpha,false,"none","none"); mc.moveTo(x,y); if (arguments.length<8) { return; } if (yRadius == undefined) { yRadius = radius; } if (Math.abs(arc)>360) { arc = 360; } var segs = Math.ceil(Math.abs(arc)/45); var segAngle = arc/segs; var theta = -(segAngle/180)*Math.PI; var angle = -(startAngle/180)*Math.PI; var ax = x-Math.cos(angle)*radius; var ay = y-Math.sin(angle)*yRadius; if (segs>0) { for (var i = 0; i<segs; i++) { angle += theta; var angleMid = angle-(theta/2); var bx = ax+Math.cos(angle)*radius; var by = ay+Math.sin(angle)*yRadius; var cx = ax+Math.cos(angleMid)*(radius/Math.cos(theta/2)); var cy = ay+Math.sin(angleMid)*(yRadius/Math.cos(theta/2)); mc.curveTo(cx,cy,bx,by); } } } } そしてFLASHのフレーム内に import DrawArc; mc = new DrawArc(this); targetNum = 0; onEnterFrame = function () { if (targetNum<=220) { targetNum += 2; change(); } else { delete this.onEnterFrame; } }; function change() { mc.drawLine(Stage.width/2,65,40,-targetNum,90,30,0x69f203,100); } とかいてあります。 これで円を描画してくれるんですが、 さらにもう一つの円を重ねて表示させたいので FLASHのフレーム内に import DrawArc; mc = new DrawArc(this); mc2 = new DrawArc(this);//新しい用 targetNum = 0; targetNum2 = 0;//新しい用 onEnterFrame = function () { if (targetNum<=220) { targetNum += 2; change(); } if (targetNum2<=210) { targetNum2 += 2; change2(); } }; function change() { mc.drawLine(Stage.width/2,65,40,-targetNum,90,30,0x002503,100); mc.mc.swapDepths(10); trace(mc.mc.getDepth()); } function change2() { mc2.drawLine(Stage.width/2,65,40,-targetNum2,90,30,0x69f203,100); mc2.mc.swapDepths(11); trace(mc2.mc.getDepth()); } と書いたのですがDepthが両方とも10になってしまいます。このDepthが別々になれば両方ちゃんと表示されると思うのですが、手詰まりになってしまいました。 どなたか解決策が分かる方教えてください。

  • jsqrm
  • お礼率45% (16/35)
  • Flash
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • DPE
  • ベストアンサー率85% (666/776)
回答No.1

実際に円弧を描画する drawLine メソッドの冒頭に  > mc.clear(); という一文がありますよね。 MovieClip クラスの clear メソッドは、ムービークリップ内にある lineTo や curveTo などのメソッド(描画メソッド)で描いた描画オブジェクトを全て消去する命令です。 つまりこの drawLine メソッドは、”今まで描いた線を全て消してから”次の線を描画する設計になっているため、先に描いた円弧を残したまま他の円弧を描画することができません。 従って、1つのムービークリップ内に描画できるのは常に1つの円弧だけ、ということになります。 深度の指定に誤りがあって1つしか表示されないのはよくある話ですが、今回の件は深度の衝突が原因ではないと思います。 解決策は2通り考えられます。  1) DrawArc.as ファイル内の mc.clear(); を削除、またはコメントにする  2) new DrawArc の引数に、それぞれ違うムービークリップを指定する 1) は、要するに前に描画した線が clear メソッドにより消されてしまうことが原因なのですから、これをなくすということです。 ただし、古い線がいつまでも残ることになるため、drawLine メソッドを呼び出すたびに余計な線の描画処理も行われ、場合によっては、処理が重くなったり線が汚く見える可能性も考えられます。 2) は、円弧を描画する数だけムービークリップを用意する方法です。 1つのムービークリップにつき1つの円弧しか描けないのなら、必要な分だけムービークリップを用意すれば、いくつでも円弧を同時に表示することができると言えます。 DrawArc クラスでは、new DrawArc の引数で指定されたムービークリップに描画する設計になっています。 クラスのオブジェクトを2つ作っても、new DrawArc に渡す引数が同じでは円弧が1つだけになってしまいますので、それぞれに違うムービークリップを指定します。 ムービークリップはステージに予め配置しておいても構いませんし、createEmptyMovieClip で作成しても構いません。 このクラスで円弧が1種類しか描けない件は深度の衝突が直接の原因ではないと思われますが、createEmptyMovieClip でムービークリップを作成する際は深度の衝突にご注意ください。 1つの円弧につき1つのムービークリップを用意すると、swapDepths メソッドで深度を変更して重ね順を変える演出も作りやすく、クラスファイルを編集する必要もありません。 また、ムービークリップであるということは、グラフ内の特定の項目をクリックして何かを表示するといった機能も簡単に作れますから、2) の方法がオススメです。 ご提示のスクリプトでは、new DrawArc にいずれも this を渡していますが、この部分を例えば、 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)  import DrawArc;  //円弧を描画するムービークリップを作成  clip1 = this.createEmptyMovieClip( "arc1" ,  this.getNextHighestDepth() );  clip2 = this.createEmptyMovieClip( "arc2" , this.getNextHighestDepth() );  mc = new DrawArc( clip1 );  mc2 = new DrawArc( clip2 );//新しい用 このように、それぞれ違うムービークリップに変更してみてください。 DrawArc.as ファイルを編集しなくても、2つの円弧を同時に表示することができます。 円弧の重なり順はムービークリップの深度の順序に従います。 上記の例では、createEmptyMovieClip でそれぞれの円弧を描くムービークリップを作る際に、黄緑の円弧( DrawArc オブジェクト” mc2 ”で描画する円弧)が上に重なるように深度を指定していますので、change およびchange2 関数内の swapDepths は不要です。

jsqrm
質問者

お礼

できました!!ありがとうございます! 深度が問題ではなかったんですね。恥ずかしい限りです。。。

関連するQ&A

  • javascriptによる複数の円の描画

    http://okwave.jp/qa/q8255766.htmlの質問のつづきになります。 回答いただいた以下の円を複数(3つ以上)描きたいとき、 //ここに追加 の部分に単純に たとえば ctxt.arc(150, 100, radius, 0, Math.PI*2, false); ctxt.arc(0, 0, radius, 0, Math.PI*2, false); と足しても円は綺麗にならず添付した画像のように不思議な図形になります。 すみません。回答いただけたらと思います。 何卒よろしくお願いいたします。 var canvas = document.getElementById('test'), ctxt = canvas.getContext('2d'); var rmin = 1, rmax = 25, diff = 1, radius = rmin; var r = 0, g = 255, b = 0; var dc = Math.floor(255/rmax), dr = dc, dg = -dc, db = 0; var timer = setInterval(function(){ canvas.width = 255;//canvas clear ctxt.fillStyle = 'rgb(' + r +',' + g + ',' + b + ')'; ctxt.arc(100, 80, radius, 0, Math.PI*2, false); //ここに追加 ctxt.fill(); radius += diff; if(radius >= rmax){ diff = -1; db = dc; dr = -dc; r = 255; b = 0; g = 0; } if(radius <= rmin){ diff = 0; db = 0; dr = 0; r = 0; b = 255; g = 0; } r += dr; g += dg; b += db; }, 200);

  • classを作ったのに動きません。

    現在classについて勉強中なのですが、自分の書いたスクリプトで実行すると「classを読み込めませんでした」とのエラーが帰ってきます。 何が原因なのか探してみたのですが、いまだにわかりません。 わかる方は教えていただけないでしょうか? ちなみに下に書いてあるスクリプトはclassとそれを動かす新規ファイル「rotation.fla」の1フレーム目に記述したものです。 ステージにはムービークリップ「bar_mc」と「center_mc」が置かれています。 //MyClass01クラス class MyClass01 { var mc:MovieClip; function MyClass01(target:MovieClip) { mc = target; } function circle(x:Number, y:Number, r:Number, d:Number):Void { mc._rotation += d; var rad = mc._rotation * Math.PI / 180; mc._x = x + r * Math.cos(rad); mc._y = y + r * Math.sin(rad); } } rotation.flaの1フレーム目 var barObj:MyClass01 = new MyClass01(bar_mc); bar_mc.onEnterFrame = function() { var x = center_mc._x; var y = center_mc._y; var r = 100; var d = 10; barObj.circle(x, y, r, d); };

    • ベストアンサー
    • Flash
  • 円をランダムで描画していき、最初の円から徐々に透明になる

    現在AS3.0にてランダムで永遠と円を描きながらも、描画した円から順番に透明になっていくスクリプトを書いているのですが、以下のスクリプトですと全体が透明になっていき、最終的に何も残らなくなってしまいます。 常に透明度1の円を描画しつつも、先に描画した円から徐々に透明になっていくスクリプトにするにはどうすればよいのでしょうか?ご教授お願いできればと思います。 addEventListener(Event.ENTER_FRAME, rain); import flash.display.Sprite; import flash.display.MovieClip; var mySprite:Sprite = new Sprite(); var myClip:Sprite = new Sprite(); addChild(myClip); function rain(event:Event):void { with(mySprite.graphics) { var circle:int = Math.floor(Math.random()*100); var stageX:int = Math.floor(Math.random()*stage.stageWidth); var stageY:int = Math.floor(Math.random()*stage.stageHeight); beginFill(0x000000); drawCircle(stageX, stageY , circle); endFill; myClip.addChild(mySprite); var diff:Number = 0.01; myClip.alpha -= diff; } }

    • ベストアンサー
    • Flash
  • flashのムービークリップにリンクを複数張る方法

    flash初心者です。質問します。 ムービークリップのMATRIXと円運動関数を使用して、3Dに回転するナビゲーションを作成したいのですが、ムービークリップ毎に個別にリンクを貼る方法が分からず、行き詰っています。 スクリプトは後記に記述しますが、this.onRelease=function() と getURL(url, "_blank");で 指定URLに飛んでくれるのですが、全てのムービークリップに1つのURLが適用されてしまい ナビゲーションとしての意味がなくなってしまいます。 var url = ("http://www.yahoo.co.jp/");の部分にURLを付け足してみたり色々試したのですが、 うまくいきません。 緊急なので、早めにお返事いただけるとありがたいです。何卒、よろしくお願いします。 ▼ 以下が問題のスクリプトです ▼ import flash.geom.Matrix; import flash.filters.BlurFilter; var composer:Array=new Array("a","b","c", "d","e","f","g","h", "i","j"); var url = ("http://www.yahoo.co.jp/"); var num = 10; var speed:Number; var diff:Number = 0; var rd:Number; var a:Number; var depth:Number; var v:Number; this.createEmptyMovieClip("composerNameBox",100); composerNameBox.createTextField("tf",120,0,0,220,25); composerNameBox._x = -10; composerNameBox._y = 145; for (i=1; i<=num; i++) { var mc = this.attachMovie("sp"+i, "sp"+i, i); mc.n = i; mc.onEnterFrame = circulating; } function circulating() { speed = (Stage.width/2-_xmouse)*0.005*0.001*Math.PI; diff += speed; rd = diff+this.n/num*2*Math.PI; a = Math.sin(rd) b = 0.3*Math.cos(rd); c = 0; d = 1; mcx = 100-200*Math.cos(rd); mcy = 40+40*Math.sin(rd); var myMatrix:Matrix = new Matrix(a, b, c, d, mcx, mcy); this.transform.matrix = myMatrix; depth = Math.floor((3+Math.sin(rd))*2500); this.swapDepths(depth); if (this.rollover) { v = 5; } else { v = Math.floor((1-Math.sin(rd))*5.5); } blurChange(this); this.onRollOver=function() { this.rollover = true; composerNameBox.tf.text = composer[this.n-1]; txtFormat(composerNameBox); } this.onRollOut=function() { this.rollover = false; composerNameBox.tf.text = ""; } this.onRelease=function() { getURL(url, "_blank"); } } function blurChange(this_mc) { var myBlur:BlurFilter = new BlurFilter(v, v, -5); this_mc.filters = [myBlur]; } function txtFormat(mc) { var format = new TextFormat(); with (format) { size = 12; color = 0x000000; align = "center"; bold = true; } mc.tf.setTextFormat(format); }

    • ベストアンサー
    • Flash
  • ASで降らせた雪のマスクの掛け方について。

    下記のサイトのASを使用させていただき、雪の降るFlashを作成したのですが、 参照サイト : http://www.webdesignlibrary.jp/2006/06/flash_snow.php このスクリプトで降らせた雪を、例えば星型の図形をマスクにして、 その範囲内で雪が降るようにしたいと思い、 色々と丸一日掛けて調べたのですが、全く上手く行きません。 とりあえず、色々と調べてみた結果、 【 xxx.setMask 】 を使えば良いのだろうか・・?、、、と言う所までは 行き着いたのですが、スクリプトを、どう改造?してみても、全く思う結果が得られません。 【 _root.setMask 】 で、ステージ全体を、目的の図形MCでマスクする事で、 思う結果に近しいカタチは出来たのですが、_root.setMask でステージをマスクしてしまうと、 例えば、マスク外に何か画像処理を施したくても、マスク外の画像は全て消えてしまいますし、 その画像の大きさ込みでマスクを作成すると、その画像の上にも雪が降ってしまうので、 完全に行き詰ってしまっています。 ASで降らせた雪だけをマスクする方法はありますでしょうか? どなたか、ご存知の方がいらっしゃいましたらば、 是非にご教示願えますと、大変ありがたいです。  何卒よろしくお願い申し上げますm(_ _)m 以下、使用AS ------------------------------------------------ width = 550; height = 400; total = 200; for (var t = 0; t != total; t++) { var mc = _root.attachMovie("snowflake", "snowflake"+t, _root.getNextHighestDepth()); mc._x = (Math.random()*(width+20))-10; mc._y = (Math.random()*(height+20))-10; mc.yspeed = (Math.random()*1.75)+0.25; mc.speed = (Math.random()*3)+2; mc._xscale = mc._yscale=(mc.speed+mc.yspeed)*10; mc.onEnterFrame = function() { var angle = Math.atan2(_root._xmouse-(width/2), _root._ymouse)+1.5707963267949; this._y += Math.sin(angle)*this.speed+this.yspeed; this._x += Math.cos(angle)*this.speed; if (this._x>width+10) { this._x = -10; } else if (this._x<0-10) { this._x = width+10; } if (this._y>height+10) { this._y = -10; } else if (this._y<0-10) { this._y = height+10; } }; } ------------------------------------------------ 【 AS使用環境 】 Adobe Flash CS3, アクションスクリプト2.0

    • ベストアンサー
    • Flash
  • HTML5のcanvasで描画がされない

    HTML5のcanvas要素を使って描画をしようとしたのですが、図形が表示されません。 コードは以下の通りです。 ・index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>canvasで図形を描く</title> <script type="text/javascript" src="paint.js"></script> </head> <body onLoad="draw()"> <canvas id="mycanvas"width="800" height"800"> </canvas> </body> </html> ・paint.js function draw() { //描画コンテキストの取得 var canvas = document.getElementById('mycanvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.arc(180,150,20,Math.PI*1,Math.PI*2,true); } } このコードでは(180,150)の位置に半径20の円が描画されるはずなのですが、何も表示されませんでした。 どこかコードに誤りがあるのでしょうか? よろしくお願いします。

  • ActionScript3.0について…

    ある課題で下記の条件を満たしたものを制作するというものがありまして、 制作してみたんですが、回答例と異なっていました。 私が制作したものでは、なにか間違っているのか分かりませんので質問させていただきました。よろしくお願いいたします。 ☆☆☆ 条件 ☆☆☆ ★ _mcの移動幅を5~10もしくは-10~-5の範囲になるようにします。 ★ 縦方向、横方向ともにステージの端まで移動したら反転するようにします。 ※ステージ幅は400px、高さは300pxとします。 ※条件ではありませんが、この問題を解くヒントとして、 「移動幅は2分の1の確率で-1を掛ける」と 「2分の1を表す条件式の例としては[ Math.random < 0.5 ]が考えられます。」とあります。 ☆☆☆ 回答例 ☆☆☆ var stepX:int = Math.floor(Math.random() * 6) + 5; var stepY:int = Math.floor(Math.random() * 6) + 5; if (Math.random() < 0.5){ stepX *= -1; } if (Math.random() < 0.5){ stepY *= -1; } _mc.addEventListener(Event.ENTER_FRAME, xEnterFrame); function xEnterFrame(evt) { _mc.x += stepX; _mc.y += stepY; if (_mc.x >= 400 || _mc.x <= 0){ stepX *= -1; } if (_mc.y >= 300 || _mc.y <= 0){ stepY *= -1; } } ☆☆☆ 私が書いたもの ☆☆☆ var stepX:int = Math.floor(Math.random() * 6) + 5; var stepY:int = Math.floor(Math.random() * 6) + 5; _mc.addEventListener(Event.ENTER_FRAME, xEnterFrame); function xEnterFrame(evt) { _mc.x += stepX; _mc.y += stepY; if(_mc.x > 400 || _mc.x < 0){ stepX *= -1; } if(_mc.y > 300 || _mc.y < 0){ stepY *= -1; } } あくまでもヒントでしたので、私が書く際にはヒントを見ずに書きました。

    • ベストアンサー
    • Flash
  • [Flash]actionscript2.0を用いて歯車を作りたいのですが

    Adobe FLASH CS2を使い2つのかみ合った歯車を制作しています。 ドラッグで片方の歯車を回転させると もう片方の方は逆回転になるはずですが、 うまいことactionscriptをかくことができません。 片方はこのようなactionscriptを使っているのですが うまい作り方はないでしょうか。 よろしくおねがいします。 on (press) { //このMCの基準点からのマウス座標を取得 rx0 = _root._xmouse-this._x; ry0 = _root._ymouse-this._y; //このMCの基準点とマウスとの距離を算出 td0 = Math.sqrt(rx0*rx0+ry0*ry0); //マウスによる回転の差分を算出 tr0 = (Math.PI/2+Math.atan2(ry0, rx0))*180/Math.PI-this._rotation; //onEnterFrame を定義 this.onEnterFrame = function() { //現在のMCの基準点からのマウス座標を取得 rx1 = _root._xmouse-this._x; ry1 = _root._ymouse-this._y; //このMCの回転を計算 this._rotation = (Math.PI/2+Math.atan2(ry1, rx1))*180/Math.PI-tr0; //このMCの移動を計算 }; } on (release, releaseOutside) { //この onEnterFrame を削除 delete this.onEnterFrame; }

  • フェードインから反転のアニメーション:actionscript

    ActionScriptでランダムに画像を読み込んだ状態でランダムフェードインして、ランダム秒数後に反転する。 反転すると違う画像がランダムに読み込まれていて、そしてまたランダム秒数後にまた反転してひっくり返るとまたランダムに画像が読み込まれているという、変わったアニメーションを作りたいのですが。(下の図を参照してください。) 現在ここまで↓できていて、xscaleを使えばできそうな感じなのですが、どうスクリプトを組めばよいかわかりません、どなたか教えてください。 環境;Flash 8,ActionScript2.0 ------------------------------------------------------------------- 回転させるparent_mcの1フレームに記述: // フェードイン設定 var load_time:Number = getTimer(); var wait_time:Number = Math.random()*1000; this._alpha = 0; // 反転タイマー関数 function InversionTimer() { flg++; } // ランダム秒設定 var max_sec:Number = 9; var min_sec:Number = 4; var random_sec:Number = Math.floor(Math.random()*(max_sec-min_sec+1))+min_sec; // フラグ変数 var flg:Number = 0; // MCのスケール関係 var scale:Number = 100; var scale_spd:Number = 8; this.onEnterFrame = function() { if (load_time+wait_time<getTimer()&&flg==0) { this._alpha += 2; if (this._alpha>99) { this._alpha = 100; flg = 1; setTimeout(InversionTimer, random_sec*1000); } } if (flg==2) { this.loader._xscale = scale; scale -= scale_spd; if (scale<=0) { scale = 0; this.child_mc.unloadMovie(IMG); flg = 3; } } else if (flg==3) { ???????????? } };

    • ベストアンサー
    • Flash
  • 線の描画

    使用ソフトはFlashMX2004でMacOSXを使用しています。 線の描画なんですが、他の動きとの関係で マウス位置より85上に線を描画→描画の度に新しいMCを作る→最初に作られたMCから透明になって消える という流れを目指して制作しています。 表現の関係上、btとリンケージ名をつけたボタンを1度押し、離した時に描画位置を指定し、再びボタンを押した時に描画終了という動きをさせたいと思い、以前頂いたサンプルに手を加え var osi = 0; canvases = 0; bt.onPress = function() { canNum++; if (osi == 1 &&_root._xmouse>=28 && _root._xmouse<=470 && _root._ymouse>=22 && _root._ymouse<=500) { _root.createEmptyMovieClip("can"+canvases, canvases); _root["can"+canvases]._alpha = 50; _root["can"+canvases].lineStyle(4, 0xffffff); _root["can"+canvases].lineTo(_root._xmouse, _root._ymouse-85); _root["can"+canvases].onEnterFrame = function() { this._alpha--; if (this._alpha<1) { this.removeMovieClip(); } }; updateAfterEvent(); canvases++; osi = 0; }; bt.onRelease = function() { if (osi == 1 &&_root._xmouse>=28 && _root._xmouse<=470 && _root._ymouse>=22 && _root._ymouse<=500) { _root["can"+canvases].moveTo(_root._xmouse, _root._ymouse-85); } } }; というスクリプトをくみましたが描画されません。 私が手を加えた箇所が間違っているのでしょうか。 一応試行錯誤はしてみたんですが解決策が見当たらず・・・。 間違っていましたらご指摘お願いします。 また、解決策がありましたらご教授お願いします。 このスクリプトがてを加える前の状態です。 this.stop(); canNum = 0; var osi = 0; canvases = 0; bt.onPress = function() { canNum++; if (_root._xmouse>=28 && _root._xmouse<=470 && _root._ymouse>=22 && _root._ymouse<=500) { mX = _root._xmouse; mY = _root._ymouse; osi = 1; } else { osi = 0; } }; bt.onRelease = function() { if (_root._xmouse>=28 && _root._xmouse<=470 && _root._ymouse>=22 && _root._ymouse<=500) { if (osi>0) { _root.createEmptyMovieClip("can"+canvases, canvases); _root["can"+canvases]._alpha = 50; _root["can"+canvases].lineStyle(4, 0xffffff); _root["can"+canvases].moveTo(mX, mY); _root["can"+canvases].lineTo(_root._xmouse, _root._ymouse-85); _root["can"+canvases].onEnterFrame = function() { this._alpha--; if (this._alpha<1) { this.removeMovieClip(); } }; updateAfterEvent(); canvases++; osi = 0; } } }; 長くなってしまい申し訳ありません。

専門家に質問してみよう