トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   迷える子羊の部屋【初心者専用】
     自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
矢口マサムネ
Åê¹ÆNo.48459
投稿日時: 2011-12-23 2:28
新米
居住地: 東京
投稿: 21
使用環境:
Windows 7 Professional SP1 / 64bit
Flash CC 2014
Flash CS6
オンライン
自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
とりあえず入門用書籍を読み終わり、練習作としてゲームっぽい動作をするものを1から作ってみていたのですが、
途中不可解な動作が起きてしまい原因に見当が付かないので、どなたかご指南願えますでしょうか。

作成していたのは、シューティングゲームの基本動作部の様なモノで、
自機と自弾、敵に見立てたブロックをそれぞれカスタムクラスとして作成し、
ブロックのみをオーサリングで配置しました。
http://csf.artisania.net/stg_00.html
※クリックで自弾の発射を開始、20HITでブロック消去
※音が出ます


自弾とブロックの接触でブロック内の変数を減らし、
0になった時点でブロックが自身でremoveChildを行い、消去したいのですが、
その時に見た目上は消えるのですがその場に判定が残ってしまっています。
タイムラインのアクションからブロックをtraceしてみても、見た目が消えた後も[object Block]のままなので、消えていないようです。

おそらく問題があるのが、自弾かブロックのどちらかの記述だと思うのですが…

自弾のクラス
package CLSs {
	
	import flash.events.*;
	import flash.display.*; 

	public class Shot_P1 extends MovieClip {
		private var TimeLine_mc:MovieClip;
		var MP3_Kin:Kin_mp3 = new Kin_mp3();
		var kin_d:Boolean = true;
		public function Shot_P1(Get_mc:MovieClip) {
			TimeLine_mc = Get_mc;
			addEventListener(Event.ENTER_FRAME, Shoot);
		}
				
		private function Shoot(e:Event):void{
			if (this.hitTestObject(TimeLine_mc.BLOCK)){
				if(kin_d){MP3_Kin.play(0,1); kin_d = false; TimeLine_mc.BLOCK.$durability--;}
				this.scaleX = this.scaleY += 0.15;
				this.alpha -= 0.1;
				if(this.scaleX > 3){
					stage.removeChild(this);
					removeEventListener(Event.ENTER_FRAME, Shoot);
				}
			}
			else if (this.y > stage.y){
				this.y -=  15;
			}
			else if (this.y < stage.y + 1){
				stage.removeChild(this);
				removeEventListener(Event.ENTER_FRAME, Shoot);
			}
		}
	}
}


ブロックのクラス
package CLSs {
	
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.geom.ColorTransform;
	
	public class Block extends MovieClip {
		public var $durability:int = 20;
		private var _$durability:int = $durability;
		public var $c:int = 0;
		
		public function Block() {
			addEventListener(Event.ENTER_FRAME, Hit);
		}
		private function Hit(e:Event):void{
			if($durability < 1){
//				ここがとても怪しげ?
				this.parent.removeChild(this);
				removeEventListener(Event.ENTER_FRAME, Hit);
			}
			else if($durability < _$durability){
				$c = 100;
				_$durability = $durability;
			}
			else if($c > 0){
				var color:ColorTransform = new ColorTransform( 1, 1, 1, 1, $c, $c, $c, 0);
				this.transform.colorTransform = color;
				$c -= 5;
			}
		}
	}
}


なんとなく怪しげなのがremoveChild時に
this.parent.
と指定している事だと思うのですが、このままではstage.で指定する事が出来ないようで、
オーサリングで配置したので位置の参照を渡す方法もわからず、(配置したものについては基本的に必要無い…と思っていたのですが)
また、見た目だけ消えるという動作が意味不明で、混乱しています。

解決方法と、出来ればなぜ見た目だけが消えるという動作になったのかをお教え下さいませんでしょうか。
よろしくお願い致します。
vader
Åê¹ÆNo.48460
投稿日時: 2011-12-23 15:29
常連
居住地: 東京
投稿: 76
使用環境:
MacOS10.8,FlashCS6
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
Masamune_Yさん、こんにちわ。

残念ながら提示されているコードだけでは原因を特定するのは難しいかと思います。
自弾やブロックをaddChildする親のクラスも重要だと思います。

私が1点気になるのは、Shot_P1クラスShootメソッド内のstage.removeChild(this);の箇所です。
よく混同されがちですが、stage == メインタイムライン(ドキュメントクラス)ではありません。

Stageに個々のMCをaddChildするのではなく、

stage - メインタイムライン - 子MC

のような構成にするべきだと思います。
以上、頑張って下さい。

ひろゆき
Åê¹ÆNo.48461
投稿日時: 2011-12-23 15:31
ちょんまげら
居住地: 東京砂漠
投稿: 4403
使用環境:
10.8.5

Flash Professional CS4/CS6/CC

Safari 6.1
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
まず、投稿に際しての注意点をお読みください。
引用:
市販の書籍や、Web上で公開されている作例などから、ソースコード・解説文などを、作者の許可無く転載・引用することは、権利者の利益を侵害する恐れがありますので、当フォーラムでは禁止します。


次に、学習をされているとおっしゃるのであれば、
基礎的なことから学習されることをお勧めします。
既存の作例で練習をしても、つまずいた部分が基礎的な部分であれば、
そこに原因があるのか、複雑な作例であるが故の問題なのか、明確になりません。

また、仮に、作例中に問題がある場合でも、
ソースコードの一部分だけでは判断しかねる部分もあるでしょう。
# vaderさんも、そのようにお書きになっておられますね。

したがって、addChild(), removeChild() がそもそも何なんかが不明であるのであれば、
その点を確認するような質問を心がけるべきだと思います。
できれば、シューティングゲームの作例自体、一旦棚上げして
addChild(), removeChild() が何をしているのかを確認できるような
シンプルなものを作った上で、質問されるべきでしょう。

そうした点はさておき、本題に触れますと、
removeChild()したところで、表示リストから外れるだけで、
インスタンス自体がなくなるわけではありませんから、
trace()しても、[object Block] と出力されるのは、当然の結果です。


例えば、タイムライン上で、
var block:Block = new Block();
trace(block);
としているのであれば、
block = null;
としてやればよいはずです。

ただし、そのような処理のしかたをすることで、
別の問題も引き起こされる可能性もあります。
# あるべきインスタンスが存在しないことによるエラーが発生するなど。

なので、やはり、学習をされるというのであれば、
もっと基礎的なことを学ばれるべきでしょう。


ドキュメントクラス Main.as
package {

	import flash.display.Sprite;
 	import test.Item;

	[SWF(backgroundColor="#FFFFFF", width="600", height="400", frameRate="30")]

	public class Main extends Sprite {
		private var item:Item;

		public function Main() {
			init();
		}

		private function init():void {
			item = new Item();
			item.x = 300;
			item.y = 200;
			trace(item);
			addChild(item);
			trace(item);
			removeChild(item);
			trace(item);
			item = null;
			trace(item);
		}

	}

}

test.Item.as
package test {

	import flash.display.Sprite;

	public class Item extends Sprite {
		private static var color:uint = 0xCC0000;
		private static var _width:uint = 80;
		private static var _height:uint = 60;

		public function Item() {
			init();
		}

		private function init():void {
			draw();
		}
		private function draw():void {
			graphics.beginFill(color);
			graphics.drawRect(-_width/2, -_height/2, _width, _height);
			graphics.endFill();
		}

	}

}


----------------
質問する際は、回答者に具体的な情報を与えてください。

矢口マサムネ
Åê¹ÆNo.48462
投稿日時: 2011-12-23 17:45
新米
居住地: 東京
投稿: 21
使用環境:
Windows 7 Professional SP1 / 64bit
Flash CC 2014
Flash CS6
オンライン
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
vader 様 はじめまして。

前記の通り作成したクラスは3つで、全て提示するのも冗長になると思い割愛してしまったのですが、
ご指摘の通り、疑問の原因がどの部分から来ているのか確信出来ない以上、最低限ファイルを添付するなりしておくべきでした。申し訳ありません。
それでも目を通して戴き、ありがとうございます。

引用:

vaderさんは書きました:

よく混同されがちですが、stage == メインタイムライン(ドキュメントクラス)ではありません。

Stageに個々のMCをaddChildするのではなく、

stage - メインタイムライン - 子MC

のような構成にするべきだと思います。



今回、これが直接の原因では無かった様ですが、
自分自身、なんとなく良い事かどうか気になりつつも、
とりあえず動くので深く調べずスルーしてしまっていた事でした。
今後、常に気に留めておこうと思います。

アドバイス、ありがとうございました!
矢口マサムネ
Åê¹ÆNo.48463
投稿日時: 2011-12-23 17:46
新米
居住地: 東京
投稿: 21
使用環境:
Windows 7 Professional SP1 / 64bit
Flash CC 2014
Flash CS6
オンライン
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
ひろゆき 様 はじめまして。

とりあえず、こちらの言葉足らずからか誤解を与えてしまっているかも知れませんので、訂正させて下さい
今回提示したソースとグラフィックは、全て自身で手探りで書いたものであり、書籍やWebから引用/コピーしたものではありません。
効果音のみWebのフリー素材を加工したものを使用しましたが、クレジット表記なしでの個人利用を許可されています。

もちろん様々なWeb記事やこちらのフォーラムの過去トピックなどを多分に参考にしながら作成はしましたので、
import flash.events.*;
import flash.display.*;
など、ごく基本的な部分に、行単位で参考元と同じになってしまっている箇所はありますが、
「既存の作品/作例を、知識としてではなく文字列としてコピー」
した箇所は、自らの基準では、部分単位でも無いと言えると判断しています。
こちらのフォーラムの判断基準で「ソースコードの転載・引用」とされるかどうかも、過去トピックなどを見た限りでは大丈夫だと思いました。

アドバイスを戴く立場でありがなら生意気であると思われるかも知れませんが、
真っ先にご指摘されてしまったので、もしやどこかの作例を丸々コピーペーストしたものだと判断されたのかも…と思い、
このトピックを閲覧戴いた他の方にもそう思わせてしまったかもと感じましたので、この点だけ主張させておいて下さい。最初からその点を明記しておかずにすみませんでした。



と、いう訳でさらに続けてご指摘戴いた「既存の作例で練習」している訳でも無いと思うのですが、
提示する例として躓いたファイルそのものでなく、同様の問題が起きるだけの極力シンプルなものに作り直した上で、その全てを提示するべきだ
というのは、全くもっておっしゃられる通りでした。
事実、それはやれば出来たと思いますので、単に私が横着してしまった事です。
大変、申し訳ありませんでした。

学習の要領については、初心者入門用の参考書を読み終え自身で「とりあえず理解した」と思えた部分を組み合わせて練習しているつもりだったのですが、
引用:

addChild(), removeChild() がそもそも何なんかが不明

であるとご指摘されてしまった様に、「理解したつもりになっていた」だけな事が、まだまだ多かった様です。
安易に練習に製作の楽しさを見出してしまう前に、もっともっと基礎的な下積みをする必要があるようですね。
アドバイス、ありがとうございました。



引用:

removeChild()したところで、表示リストから外れるだけで、
インスタンス自体がなくなるわけではありません


結局、見た目に無くなったのに当たり判定が残る…という疑問に関しても、
単に表示リストから消える = 見えなくなるだけ
だったので、当たり前という事だったのですね。

もう一度基礎的な学習を修めた上で、同じ場所まで戻って来たいと思います。
その途中また自力での理解が困難なポイントが発生した際には、よろしければまたアドバイスをお願い致します。

ありがとうございました!


-追記-

上のレスを書いている間に追加でソースコードを書いて戴いた様なので、これからその解析も含めて修正を行ってみようと思います。
重ね重ね、ありがとうございました!
野中文雄
Åê¹ÆNo.48465
投稿日時: 2011-12-23 23:48
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
以下の記事をご参考まで。なお、解説中で「サイズの情報」というのは、表示リストの親を調べたときにそのインスタンスのサイズとして含まれるということです。今回のように、表示リストから外したインスタンスを直接調べれば、位置座標や大きさは保ち続けます。

「ActionScript 3.0におけるパフォーマンス向上のヒント」04「visibleとalphaとremoveChild()
引用:
Masamune_Yさんは書きました:
引用:
removeChild()したところで、表示リストから外れるだけで、
インスタンス自体がなくなるわけではありません


結局、見た目に無くなったのに当たり判定が残る…という疑問に関しても、
単に表示リストから消える = 見えなくなるだけ
だったので、当たり前という事だったのですね。


----------------
 

矢口マサムネ
Åê¹ÆNo.48466
投稿日時: 2011-12-24 2:09
新米
居住地: 東京
投稿: 21
使用環境:
Windows 7 Professional SP1 / 64bit
Flash CC 2014
Flash CS6
オンライン
Re: 自身でremoveChildしたインスタンスの接触判定だけが残ってしまう?
野中文雄 様
前回に続いてのご指導、ありがとうございます。

参考先のページの記事、読ませて戴きました。
「DisplayObject.visibleプロパティで画面から消す場合」の解説の項にて、
その場合はhitTestObject()の判定が残る…という例がちょうど記述されていましたので、少々悩んでしまいましたが、

removeChild()で親の表示リストから消去した場合でも、親の持っている情報には含まれなくなるけれど、
そのインスタンス自身が一度持ったサイズや位置の情報は消えはしていないので、
直接そのインスタンスを指定してhitTestObject()した場合は当たり判定が出る…という事ですね。

だいぶややこしく感じましたが、あやふやに捉えていた部分が少しずつでも固まってきた様に感じます。
一度色々とパターンを変えて試してみて、自分の中で整理してみようと思います。


ありがとうございました!
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops