Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 04.11.2015, 01:19
EndoCrinologist вне форума Посмотреть профиль Отправить личное сообщение для EndoCrinologist Найти все сообщения от EndoCrinologist
  № 1  
Ответить с цитированием
EndoCrinologist
 
Аватар для EndoCrinologist

блогер
Регистрация: Feb 2011
Адрес: Россия, Тольятти
Сообщений: 301
Записей в блоге: 10
По умолчанию Проблема с доступом к объекту при вызове removeChild

Изучаю AS3. Пытаюсь перевести игру Atary Asteroids из AS2 на AS3.
Вот класс Asteroids:
Код AS3:
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.setTimeout;
	/**
	 * ...
	 * @author Volodin Alexandr Sergeevich
	 */
	public class Asteroid extends Sprite
	{
		public static var THIS:Asteroid = null;
 
		public var velX:Number = Math.random() * 6 - 3;
		public var velY:Number = Math.random() * 6 - 3;
		public var rotSpeed:Number = Math.random() * 3;
		public var rotDir:Number = chooseDir();
		public var frame:Number = 0;
 
		public function Asteroid() 
		{
			graphics.beginFill(0xabc098);
			graphics.lineStyle(1);
			graphics.moveTo(-50, -50);
			graphics.lineTo(50, -50);
			graphics.lineTo(50, 50);
			graphics.lineTo(-50, 50);
			graphics.lineTo(-50, -50);
			graphics.endFill();
 
			addEventListener(Event.ENTER_FRAME, onAstMove);
		}
 
		private function onAstMove(e:Event = null):void
		{
			this.x += this.velX;
			this.y += this.velY;
 
			if (this.x > Main.THIS.StageX + this.width) this.x = 0 - this.width;
			if (this.y > Main.THIS.StageY + this.width) this.y = 0 - this.width;
			if (this.x < 0 - this.width) this.x = Main.THIS.StageX + this.width;
			if (this.y < 0 - this.width) this.y = Main.THIS.StageY + this.width;
 
			this.rotation += this.rotDir * this.rotSpeed;
 
			frame++;
 
			if (frame % 10 == 0)
			{
				//Main.THIS.graphics.beginFill(0x00ffaa);
				//Main.THIS.graphics.drawCircle(this.x, this.y, 3);
				//Main.THIS.graphics.endFill();
			}
 
			if (this.hitTestPoint(Main.THIS.ship.x, Main.THIS.ship.y, true))
			{
				Main.THIS.isDead = true;
				Main.THIS.shipDestroy();
			}
		}
 
		private function chooseDir():Number
		{
			var rnd:Number = Math.random();
			if (rnd > 0.5){return 1;} else return -1;
		}
 
	}
 
}
Вот класс Main:
Код AS3:
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
 
 
	/**
	 * ...
	 * @author Volodin Alexandr Sergeevich
	 */
	public class Main extends Sprite 
	{
		public static var THIS:Main = null;
 
		public var rotate:Number = 0;
		public var thrust:Number = 0;
 
		public var StageX:Number = 800;
		public var StageY:Number = 600;
 
		public var frame:Number = 0;
 
		public var isDead:Boolean = false;
 
		public function Main() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		public var ship:Ship = new Ship();
		private var ast_sprite:Sprite = new Sprite();
 
		private function init(e:Event = null):void 
		{
			THIS = this;
 
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			ship.x = StageX / 2;
			ship.y = StageY / 2;
 
			addChild(ship);
 
			stage.addEventListener(KeyboardEvent.KEY_DOWN, shipControl);
			stage.addEventListener(KeyboardEvent.KEY_UP, shipDecontrol);
			ship.addEventListener(Event.ENTER_FRAME, onShipMove);
 
			addChild(ast_sprite);
 
			frame++;
 
			for (var i:int = 0; i < 5; i++ )
			{
				var ast:Asteroid = new Asteroid();
				addChild(ast);
			}
 
		}
 
		private function shipDecontrol(e:KeyboardEvent):void
		{
			rotate = 0;
			thrust = 0;
		}
 
		private function shipControl(e:KeyboardEvent):void
		{
			switch(e.keyCode)
			{
				case 37:
					rotate = -1;
					break;
				case 38:
					thrust = 0.3;
					break;
				case 39:
					rotate = 1;
					break;
				case 40:
					thrust = -0.3;
					break;
			}
		}
 
		private function onShipMove(e:Event = null):void
		{
			if (rotate) ship.rotation += rotate * 5;
			if (Math.abs(thrust) > 0)
			{
				var rad:Number = ship.rotation * Math.PI / 180;
				ship.thrustX = Math.cos(rad) * thrust;
				ship.thrustY = Math.sin(rad) * thrust;
 
				ship.velX += ship.thrustX;
				ship.velY += ship.thrustY;
			}
 
			ship.x += ship.velX;
			ship.y += ship.velY;
 
			if (ship.x > StageX + ship.width) ship.x = 0 - ship.width;
			if (ship.x < 0 - ship.width) ship.x = StageX + ship.width;
 
			if (ship.y > StageY + ship.width) ship.y = 0 - ship.width;
			if (ship.y < 0 - ship.width) ship.y = StageY + ship.width;
		}
 
		public function shipDestroy()
		{
			removeChild(ship);
		}
 
	}
 
}
Вот класс Ship:
Код AS3:
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
 
	/**
	 * ...
	 * @author Volodin Alexandr Sergeevich
	 */
	public class Ship extends Sprite
	{
		//private var spr : Sprite = new Sprite();
 
		public var velX : Number = 0;
		public var velY : Number = 0;
		public var thrustX : Number = 0;
		public var thrustY : Number = 0;
 
		public function Ship() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, onStageShip);
		}
 
		private function onStageShip(e:Event = null):void
		{
			/*spr.graphics.beginFill(0x00ff00);
			spr.graphics.lineStyle(1);
			spr.graphics.moveTo(-20,-20);
			spr.graphics.lineTo(20, 0);
			spr.graphics.lineTo(-20, 20);
			spr.graphics.endFill();*/
 
			graphics.beginFill(0x00ff00);
			graphics.lineStyle(1);
			graphics.moveTo(-20,-20);
			graphics.lineTo(20, 0);
			graphics.lineTo(-20, 20);
			graphics.endFill();
 
			//addChild(spr);
		}
 
		public function shipDead():void
		{
			removeChild(this);
		}
	}
 
}
При соприкосновении астероида и корабля возникает такая ошибка:
Цитата:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display:isplayObjectContainer/removeChild()
at Main/shipDestroy()[Main.as:113]
at Asteroid/onAstMove()[Asteroid.as:58]
Что не так?
__________________
Надо сменить подпись...

Старый 04.11.2015, 10:52
alexandrratush вне форума Посмотреть профиль Отправить личное сообщение для alexandrratush Найти все сообщения от alexandrratush
  № 2  
Ответить с цитированием
alexandrratush
 
Аватар для alexandrratush

Регистрация: Jul 2013
Адрес: Днепр
Сообщений: 529
Отправить сообщение для alexandrratush с помощью ICQ Отправить сообщение для alexandrratush с помощью Skype™
Может быть в этом проблема: The supplied DisplayObject must be a child of the caller.

Старый 04.11.2015, 11:30
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 3  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Код AS3:
removeChild(this);
Эта запись эквивалентна такой:
Код AS3:
this.removeChild(this);
Не может объект удалить самого себя из себя

Старый 04.11.2015, 12:08
EndoCrinologist вне форума Посмотреть профиль Отправить личное сообщение для EndoCrinologist Найти все сообщения от EndoCrinologist
  № 4  
Ответить с цитированием
EndoCrinologist
 
Аватар для EndoCrinologist

блогер
Регистрация: Feb 2011
Адрес: Россия, Тольятти
Сообщений: 301
Записей в блоге: 10
Я понял, что что-то не так с родителями/детьми. Я также пробовал способ удаления самой ship, когда в Main создавал функцию, удаляющую ship, но она вызывала такую же ошибку..
Класс Main:
Код AS3:
public function shipDestroy()
		{
			removeChild(ship);
		}
Вызов из Asteroids:
Код AS3:
if (this.hitTestPoint(Main.THIS.ship.x, Main.THIS.ship.y, true))
			{
				Main.THIS.isDead = true;
				Main.THIS.shipDestroy();
			}
Или, я так понимаю, он всё равно из себя не сможет вызвать какую-то стороннюю функцию для удаления себя?
__________________
Надо сменить подпись...

Старый 04.11.2015, 19:22
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 5  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Не буду говорить на сколько сам код плохо написан, для новичка простительно. Поэтому сразу скажу по делу. Чтобы он мог удалиться из дисплей листа сам, можно сделать так:
Код AS3:
if (parent) parent.removeChild(this);
Собственно делаем проверку на то есть ли у него родитель, и если есть, удаляем. Проверка нужна, чтобы он не падал с ошибкой, если он не находится в дисплей листе во время попытки удаления.

п.с. Таким образом объект никуда не удаляется, и продолжает и висеть в памяти и жрать ресурсы процессора (пока на него сохраняются ссылки). Он просто перестает отображаться

Создать новую тему Ответ Часовой пояс GMT +4, время: 10:57.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 10:57.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.