windows版FlashCS6で、ActionScript3を使用しております。
どうぞ、よろしくお願いいたします。
最初に、前提をご説明します。
埋め込みアセットクラスBoxをライブラリに準備します。
Boxの中には、50px × 50pxのビットマップが、基準点を中央で配置してあります。
埋め込みアセットクラスWallをライブラリに準備します。
Wallの中には、550px×400pxのビットマップが、基準点を中央で配置してあります。
ステージサイズは550px×400pxです。
タイムラインに、下記のActionScript3を書きます。
var myWall:Wall = new Wall();
myWall.x = 275;
myWall.y = 200;
addChild(myWall);
var myBox:Array = new Array(10);
for(var i:int=0 ; i<10 ; i++){
myBox[i] = new Box();
myBox[i].x = Math.random() * 550;
myBox[i].y = Math.random() * 400;
addChild(myBox[i]);
}
パブリッシュすると、ステージ上にはmyWallのインスタンスが1個と、myBoxのインスタンスが10個配置されます。
myBoxのインスタンスいずれかをクリックすると、クリックされたmyBoxが削除される(クリックされたmyBoxをremoveChild()し、それの参照を保存していた変数にnullを代入する)ようにするには、どのようにスクリプトを組めば良いでしょうか?
背景のmyWallは、クリックされても削除されないようにしたいです。
ご教示のほど、どうぞ、よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
スクリプトとしてはとりあえず
次のような感じ↓で良いのではないでしょうか。
//====================================
var myWall:Wall = new Wall();
myWall.x = 275;
myWall.y = 200;
addChild(myWall);
var myBox:Array = new Array(10);
for (var i:int=0; i<10; i++) {
myBox[i] = new Box();
myBox[i].x = Math.random() * 550;
myBox[i].y = Math.random() * 400;
addChild(myBox[i]);
//------↓以降を追加変更↓------
//(各Boxマウスオーバーでハンドカーソルにする(要る?))
myBox[i].buttonMode = true;
//各Boxクリック時に関数 removeBox を実行
myBox[i].addEventListener(MouseEvent.CLICK,removeBox);
}
//関数 removeBox の定義
function removeBox(e:MouseEvent):void {
//クリックされたターゲットをこの階層の表示リストから削除
removeChild(DisplayObject(e.currentTarget));
}
//====================================
上記スクリプトの最後の部分↓ですが
//クリックされたターゲットをこの階層の表示リストから削除
removeChild(DisplayObject(e.currentTarget));
以下ではこの行についてのみの説明を書きます。
この最後の行は
次↓のように変更してもかまいません。
removeChild(Box(e.currentTarget));
または
Box クラスが MovieClip クラスを継承している場合は
次↓のように変更してもかまいません。
removeChild(MovieClip(e.currentTarget));
もし removeChild(e.currentTarget); のように
引数を「e.currentTarget」だけにした場合,
その「e.currentTarget」は
単なる「Object」クラスのインスタンスとして認識されてしまうため
removeChild(=表示リストから削除する) という命令を使うことができなくなります。
(「Object」クラスのインスタンスには,例えば「配列」や「関数」や「音」など "表示されないオブジェクト" も含まれるため「表示リストから削除する」という命令が通用しない。)
したがって少なくとも
クリックされたターゲットを "表示オブジェクト(DisplayObject)" として認識させる必要があります。
そのために
DisplayObject(e.currentTarget) のように書いて
イベントターゲットを「DisplayObject」に変換しているわけです。
MovieClipクラスも,Boxクラスも,
少なくとも DisplayObjectクラス は継承しているはずですから,
Box(e.currentTarget) や MovieClip(e.currentTarget) などにしてもかまわないということになります。
もし Box クラスが MovieClip クラスを継承していれば
クラスの継承関係は次のようになります。
Object > EventDispatcher > DisplayObject > InteractiveObject > DisplayObjectContainer > Sprite > MovieClip > Box
これらクラスのうち
DisplayObject 以下のクラスとして認識させれば removeChild できるという意味です。
認識させるクラスは作者の都合で適当に決めれば良いです。
ちなみに,
Array(配列) クラスであれば継承関係は次のようになります。
Object > Array
Function(関数/メソッド) クラスであれば継承関係は次のようになります。
Object > Function
Sound(音) クラスであれば継承関係は次のようになります。
Object > EventDispatcher > Sound
これら3つはどれも DisplayObject を継承していませんよね?
したがって
これらはどれも元から表示リストに加える(addChild する)ことができないので
表示リストから削除する(removeChild する)こともできないわけです。
(他にも DisplayObject でないオブジェクトはたくさん存在します。)
または,
別の書き方として次のように変更しても良いでしょう。
removeChild(e.currentTarget as DisplayObject);
removeChild(e.currentTarget as Box);
removeChild(e.currentTarget as MovieClip);
この「as」は ActionScript の略(=AS)ではなく,
英語の前置詞である「as (…として)」が語源でしょうね。
【英文例】I looked up to him as an engineer.
【和訳文】私は技術者として彼を尊敬している。
【Script】removeChild(e.currentTarget as DisplayObject);
【和訳文】表示オブジェクトとしてのイベントターゲットを表示リストから削除
この回答への補足
改めてネットで調べたところ、クロージャを利用することでも、必要な情報を受け渡せることが解かりました。
※恥ずかしながら、クロージャというモノを、初めて知りました。
お陰様で、今回の質問は解決しました。
ありがとうございました!!
ご教示ありがとうございます!
とても丁寧なご説明に、感激しました。
質問させていただいた後、少し考えて
removeChild(e.currentTarget);
と書いてみて、(当然ですが)コンパイルエラーが出て、理由が解からず困っていました。
>少なくとも
>クリックされたターゲットを "表示オブジェクト(DisplayObject)" として認識させる必要があります。
お教えいただき、ようやくコンパイルエラーの理由が解かりました。
ありがとうございます。
removeChildすることで、表示リストから「クリックされたBoxのインスタンス」を外すことが出来ました。
さらに「クリックされたBoxのインスタンス」への参照を保存している変数myBox[i]にnullを代入すれば、「クリックされたBoxのインスタンス」はガベージコレクションの対象になると思います(この考えは、間違えていないでしょうか。。。?)。
ガベージコレクションの対象とするために、setNullという関数を追加してみました。
//ここから上のスクリプトは省略しています。
//各Boxクリック時に関数 removeBox を実行
myBox[i].addEventListener(MouseEvent.CLICK,removeBox);
myBox[i].addEventListener(MouseEvent.CLICK,setNull);
}
function setNull(e:MouseEvent):void{
for(var k:int=0 ; k<10 ; k++){
if(myBox[k] != null){
if(myBox[k].root == null){
myBox[k] = null;
}
}
}
}
Boxのインスタンスをクリックした際に、myBoxの何番に「クリックされたBoxのインスタンスへの参照」が入っているか判らないため、setNullではmyBoxを全てチェックしています。
myBoxを全てチェックせずとも、「クリックされたBoxのインスタンスへの参照」を見つけることは可能でしょうか?
※上記のsetNullよりも、もっと効率の良い方法はないのでしょうか?
重ねての質問とはなりますが、お教えいただけませんでしょうか。。。?
何卒、よろしくお願い申し上げます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- その他(ソフトウェア) Figma 1 2023/06/23 14:22
- Windows 8 動画の再生とタイトルの変更方法を教えてください。 3 2022/08/01 14:51
- C言語・C++・C# クラスのメンバ変数を基準に並べ替えをしたい 5 2022/12/25 17:40
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- JavaScript gasについて 1 2022/05/31 21:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミング、アーキテクチ...
-
【VB.NET】別Formのボタンが押...
-
ウインドウハンドルとインスタ...
-
Python でシャットダウンのコマ...
-
CreateDialogについて
-
YOASOBI
-
マウス自体の移動量の取得
-
FLASHでの色変更
-
PYTHONのtkinterについて
-
マスクにグラデーションをかけ...
-
外部ファイルを読み込んでロス...
-
UWSCのBTN関数について。
-
AS3.0 読み込んだ外部テキスト...
-
下記のサイトのTOPページにある...
-
PythonでSetWindowPosを使うに...
-
オブジェクトのランダムな位置表示
-
Photoshopの基本的な参考書を...
-
複数mcのランダム再生とmc指定...
-
ボタンの背景を透過させたいです!
-
FLASHで「かるた」を作りたいの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミング、アーキテクチ...
-
VB6.0で、フォームから、別のフ...
-
【VB.NET】別Formのボタンが押...
-
フォームの生成と破棄
-
VB6.0のHideのバグ?
-
DataTableの件数を取得したい
-
インスタンスとポインタ
-
ダミーウインドウ
-
Python でシャットダウンのコマ...
-
画像を一定時間ごとに切り替え...
-
CreateDialogについて
-
「Me」を「Form1」にするとエラ...
-
ウインドウハンドルとインスタ...
-
背景画像が拡大縮小しつつ、大...
-
EXEからDLLへ移植
-
Flashの画面をJPEG画像にしてメ...
-
携帯Lite1.1用のプログラム
-
new演算子について教えていただ...
-
getURLでの変数の渡し方
-
【ActionScript】コンボボック...
おすすめ情報