Просмотр полной версии : В классе задать условие на hitTest экземпляров
Волгоградец
24.01.2008, 17:22
Здравсвуйте, уважаемые участники форума. Если у кого найдется минутка, объясните, почему не работает это:
class Ball extends MovieClip {
private var ball_speed:Number = 1;
private var s:Number = 0;
private var speed:Number;
function Ball (){
_x = Math.round(Math.random()*500);
_y = 30;
_xscale = _yscale = Math.round((Math.random()*(1.2 - 0.8) + 0.8) * 100);
speed = ball_speed * (Math.random()*(3 - 0.1) + 0.1);
}
function onEnterFrame (){
_y += speed;
if (this.hitTest(square)){
trace ("kkk");
}
}
}
Клипы передвигаются как надо, но вот hitTest не срабатывает. Чую, что оператор this всю кашу портит, никак не могу понять - когда его использовать, когда нет.
class Ball extends MovieClip {
private var ball_speed:Number = 1;
private var s:Number = 0;
private var speed:Number;
function Ball (){
this._x = Math.round(Math.random()*500);
this._y = 30;
this._xscale = this._yscale = Math.round((Math.random()*(1.2 - 0.8) + 0.8) * 100);
speed = ball_speed * (Math.random()*(3 - 0.1) + 0.1);
}
function onEnterFrame (){
this._y += speed;
if (this.hitTest(square)){
trace ("kkk");
}
}
}
попробуйте так, правда не уверен, что будет работать, но попытка - не пытка ведь...
Fernando Costa
24.01.2008, 20:23
здается мне что square трейсит андефайнед
Волгоградец
25.01.2008, 12:34
Фернандо прав, неверно ссылку на клип square я дал. Спасибо что подсказал.
class Ball extends MovieClip {
private var ball_speed:Number = 1;
private var speed:Number;
private function Ball (){
this._x = 275;
this._y = 30;
}
function onEnterFrame (){
this._y += speed;
collision ();
}
function collision (){
if (this.hitTest(_root["square"])){
trace ("hhh");
}
}
}
Поискав похожие темы на форуме, сделал вывод, что _root не стоит использовать в классах. Как в моем случае следует переписать строчку _root["square"]? Подскажите, где прочитать можно про это?
1. Мувиклипы класса Ball аттачаться на сцену или их ручками клали?
2. Глубина вложенность мувиклипов класса Ball какая? Всегда в _root или может быть вложены в другие клипы. Если могут быть вложены, то хитТест вся равно с _root["square"] проверяется?
Волгоградец
25.01.2008, 12:54
Мне бы просто разобраться с классами...
1. Ручками клал.
2. В том то и проблема - когда на _root - все работает. А если, допустим, клип будет вложен и уровень вложенности заранее неизвестен, естественно _root["square"] не сработает. Относительные ссылки тоже не прокатят. Как же тогда быть?
Да и вообще чем можно заменить слово _root в классах, есть ли какой-нибудь универсальный способ?
Сделать свойство для экземпляра класса, которое будет ссылаться на нужный клип.
Волгоградец
25.01.2008, 13:12
Я не подумал, что так можно. Буду копать дальше. Спасибо, iNils, я тебе уже наверное вагон пива должен.
Волгоградец
26.01.2008, 15:34
Попробовал использовать targetPath, но все не то... При попытке ввести явно имя клипа square в класс Ball, компилятор ругается - мол нет методов, связанных с этим именем. Неужели надо создавать специальный класс, расширяющий класс MovieClip, специально для того, чтобы узнать где лежит этот square???
CrazyFlasher
26.01.2008, 17:21
import mx.utils.Delegate;
class Ball {
private var ball_speed:Number = 1;
private var speed:Number;
private var ballMc:MovieClip;
private var squareMc:MovieClip;
public function Ball(ballMc:MovieClip, squareMc:MovieClip){
this.ballMc = ballMc;
this.squareMc = squareMc;
this.ballMc._x = 275;
this.ballMc._y = 30;
this.ballMc.onEnterFrame = Delegate.create(this, collision);
}
private function collision (){
ballMc._y += speed;
if (ballMc.hitTest(squareMc)){
trace("hhh");
}
}
}
во фла
var ball:Ball = new Ball(ball, square);
не проверял, но должно работать.
Из личного опыта:
в АС2 не стоит привязывать классы к клипам...теряется ООП модель (имхо)
Волгоградец
26.01.2008, 17:52
Спаисбо, Crazy, буду разбираться. Я согласен с твоим имхом по поводу того, что не не стоит привязывать классы к клипам, буду учиться делать именно так.
А как здесь работает Delegate.create(this, collision)? В хэлпе пример только с компонентами и с какими-то compInstance.addEventListener - я не разобрался. Зачем здесь слово this?
Апд.: полазил по форуму, вот что понял - Delegate.create(this, collision) - первое значение - это место, где читаем функцию, в данном случае читаю ее из самого класса. Поправьте меня, пожалуйста, если я ошибаюсь.
Из личного опыта:
в АС2 не стоит привязывать классы к клипам...теряется ООП модель (имхо)А вот это зря. Композиция хороша лишь в определнных случая.
iNils, если классы, наследуемые от MC, реализуют интерфейс, то да, композиция тут не к месту :)
Да ради бога.
2 Волгоградец:
Кстати, каким образом теряется модель?
Апд.: полазил по форуму, вот что понял - Delegate.create(this, collision) - первое значение - это место, где читаем функцию, в данном случае читаю ее из самого класса. Поправьте меня, пожалуйста, если я ошибаюсь.
Нет, первый аргумент - scope, честно, не знаю, как по-русски %) В смысле, что будет выступать в качестве this для функции. По-этому класс и назывется Delegate, в смысле, делегировать - передать, в этом случае -- передать функцию другому объекту.
import mx.utils.Delegate;
//
var a_obj:Object = {someFunc:function(){trace('I\'m someFunc called on: '+this)}, toString:function(){return '[a_obj]'}};
var b_obj:Object = {toString:function(){return '[b_obj]'}};
a_obj.someFunc();
Delegate.create(b_obj, a_obj.someFunc)();
// or
var d:Delegate = new Delegate(a_obj.someFunc);
d.createDelegate(b_obj)();
ЗЫ. Не стоит привязывать классы к элементам в библиотеке, ИМХО, по другой причине, гораздо более прозаичной.
Может глючить при наследовании.
Просто неудобно работать с непрограмно созданными клипами: невозможно очистить графику с помощью clear(), да и похоже, что разница этим не ограничивается, есть такое чувство, что програмно созданный клип это скорее Sprite из АС3, а не MovieClip. Т.е. должен быть полегче...
Ну и естественно, все прелести отношений родитель-наследник от MovieClip тоже далеко не всегда желанны =) Т.е. если в классе предполагается динамически изменять родителей, создавать новых наследников у других родителей -- то это попросту невозможно.
2 wvxvw:
А. Хочу пример.
Б. А в композиции clear значит работает?
а: http://flasher.ru/forum/showthread.php?t=103055
млин, форум почему-то по ключу "наследование" эту тему не нашел =/
Про clear я говорил в том смысле, что просто удобнее всегда, когда это возможно создавать клипы програмно. Непрограмно - только когда это критически необходимо и по-другому никак.
А. Сделал пример - работает.
А то что в пример не работает, так флеш порой глючит необъяснимо в конкретных примерах. Но стоит все сделать с нулю, как начинает работать.
В смысле все содержимое клипа рисуется программно?
Я тогда тоже сделал. У меня тоже глючило. Вот я и говорю, что может глючить, а не утверждаю, что будет глючить 100%.
Именно, все содержимое =) Нинаю, я каким-то образом живу без того, чтобы пользоваться библиотечными клипами, максимум -- храню в библиотеке битмапы/звук...
Т.е. принцип такой: если графика бизхитростная -- ее лучше нарисовать програмно, если сложная -- тогда все равно лучше битмапом. Исключения только если нужно маштабировать, ну или покадровая анимация.
Это к классам в библиотеке никакого отношения не имеет.
Я тоже не знаю. Как можно игнорировать возможности флеша я не представляю. Ничего хорошего в этом нет. Вместо того что нарисовать трехугольник во флеше, сидеть и мучать вырисовывая его программно.
Т.е. принцип такой: если графика бизхитростная -- ее лучше нарисовать програмноПочему лучше?
Чтобы стирать можно было с помочью clear?
А зачем стирать?
Нет, этой проблемы не было бы если бы классы не были привязаны к элементам библиотеки. Глюк воспроизводимый и имеет тенденцию повторятся. Кроме того, дурацкая система нахождения и определения клипов через их путь соооовсем не добавляет радости при такой разработке. Т.е. если путь к клипу оказывается не валидным с точки зрения ВМ (например, в нем присутствуют символы типа /, ", > и т.д.) то там неразбериха та еще получается.
Это единственный пример на форуме, но если нужно -- могу на заказ его воспроизвести =)
А я не мучаюсь с треугольниками, 1 раз полгода назад написал функцию, которая рисует полигоны с заданным количеством углов и забыл %)
Я всегда считал, что на форуме только один чудак, это D12, но он чудит от незнания, а ты знаешь, но все равно чудишь :)
Скоро буду на тебя ссылки давать для примеров "как делать не надо":)
Ну, это уже делают %))) я не обижаюсь =)
Волгоградец
28.01.2008, 12:25
:eek: Представьте мое состояние - на вопрос получил столько ответов, причем совершенно разных - iNils говорит делай так, wvxvw говорит делай по другому. Голова кругом идет...
Ребята, вы оказываете очень большую честь, что помогаете разобраться. Я признателен вам, если могу как-то отблагодарить - обращайтесь.
P.S.: со своим вопросом так и не разобрался - код CrazyFlasher'а в 10-м посте не видит столкновение. Я не вижу других вариантов кроме как использовать _root.
В коде CrazyFlasher'а speed не определен.
А так класс работает.
Волгоградец
28.01.2008, 13:11
Ну это да, и одна переменная лишняя - это исправил. Может я конечно очень сильно туплю, но у меня он не не трейсит ничего при столкновении клипов. Я руками клипы вытащил, с классом связал оба клипа...
Волгоградец
29.01.2008, 12:38
Прошу прощения, все работает. Я привязал ВСЕ клипы на сцене к одному классу, даже тот квадрат с которым проверяю пересечение (хотя по идее он должен проверить на пересечение самого с собой и выдать сообщение). В общем, будьте внимательны!
Волгоградец
29.01.2008, 19:10
Не сочтите за дерзкость, просто это желание получше разобраться в классах... Вобщем теперь, благодаря форуму, я знаю как создавать классы и заставить клип передвигаться и обнаруживать пересечение с клипом на сцене. Но не получается следующая вещь: как определить что экземпляр одного класса хиттестит экземпляр другого класса (т.е. не конкретно какой-то клип с именем, допустим, "mc", а любой экземпляр)?
CrazyFlasher
29.01.2008, 19:45
Я привязал ВСЕ клипы на сцене
ни один клип не надо было "привязывать" к классу.
(т.е. не конкретно какой-то клип с именем, допустим, "mc", а любой экземпляр)?
//если всё клипы в _root, то надо дописать:
//var myMc:MovieClip = _root; ну или тупо проверять в руте
for (var i in myMc){
if(myMc[i] instanceof MovieClip){
//тут делаем что надо
}
}
import mx.utils.Delegate;
//
class Game {
private var __base:MovieClip;
private var s_n:Number = 4;
private var b_n:Number = 4;
private var s_arr:Array = [];
private var n_arr:Array = [];
function Game(mc:MovieClip) {
__base = mc.createEmptyMovieClip('game_base'+mc.getNextHighestDepth(), mc.getNextHighestDepth());
Bullet.addListener(this);
s_arr = [];
n_arr = [];
__draw();
__base.onEnterFrame = Delegate.create(this, oeFrame);
}
function __draw():Void {
var sl:Soldier;
var bl:Bullet;
for (var i:Number = 0; i<s_n; i++) {
sl = new Soldier(__base);
sl.x = i*110;
n_arr.push(sl);
}
for (var j:Number = 0; j<s_n; j++) {
bl = new Bullet(__base);
bl.x = j*110;
bl.y = 200;
bl.speed = Math.random()*20;
s_arr.push(bl);
}
}
function oeFrame():Void {
for (var i:Number = 0; i<s_arr.length; i++) {
if (s_arr[i].y>0) {
s_arr[i].y -= s_arr[i].speed;
} else {
s_arr[i].y = 200;
}
}
}
function soldierHit(xx:Number, yy:Number):Void {
trace('Boom! '+xx+' : '+yy);
}
}
class Soldier {
private var w:Number = 100;
private var h:Number = 100;
private var a:Number = 100;
private var c:Number = 0xffff;
private var __base:MovieClip = null;
private static var __bases:Array = [];
public static function hit(mc:MovieClip):Boolean {
for(var i:Number=0; i<Soldier.__bases.length; i++){
if(mc.hitTest(Soldier.__bases[i])){
return true;
}
}
return false;
}
private static function register(mc:MovieClip):Void {
Soldier.__bases.push(mc);
}
function Soldier(mc:MovieClip){
__base = mc.createEmptyMovieClip('soldier_base'+mc.getNextHighestDepth(), mc.getNextHighestDepth());
__draw();
Soldier.register(__base);
}
private function __draw():Void {
__base.beginFill(c,a);
__base.moveTo(0,0);
__base.lineTo(w,0);
__base.lineTo(w,h);
__base.lineTo(0,h);
__base.lineTo(0,0);
__base.endFill();
}
public function set x(n:Number):Void {
__base._x = n;
}
public function get x():Number {
return __base._x;
}
public function set y(n:Number):Void {
__base._y = n;
}
public function get y():Number {
return __base._y;
}
}
import mx.utils.Delegate;
//
class Bullet {
private var __base:MovieClip;
private static function __buletInit(){
if(!__initializer){
_global.AsBroadcaster.initialize(Bullet)
return true;
} else {
return true;
}
};
private static var __initializer:Boolean = __buletInit();
public static var addListener:Function;
public static var removeListener:Function;
public static var broadcastMessage:Function;
private var r:Number = 5;
private var c:Number = 0xff;
private var a:Number = 100;
private var __speed:Number = 0;
function Bullet(mc:MovieClip) {
__base = mc.createEmptyMovieClip('bullet_base'+mc.getNextHighestDepth(), mc.getNextHighestDepth());
__buletInit();
__draw();
__base.onEnterFrame = Delegate.create(this,bulletHit)
}
private function __draw():Void {
var c1:Number = r*(Math.SQRT2-1);
var c2:Number = r*Math.SQRT2/2;
var d:Number = r*2;
__base.clear();
__base.beginFill(c,a);
__base.moveTo(d,r);
__base.curveTo(d,r+c1,r+c2,r+c2);
__base.curveTo(r+c1,d,r,d);
__base.curveTo(r-c1,d,r-c2,r+c2);
__base.curveTo(0,r+c1,0,r);
__base.curveTo(0,r-c1,r-c2,r-c2);
__base.curveTo(r-c1,0,r,0);
__base.curveTo(r+c1,0,r+c2,r-c2);
__base.curveTo(d,r-c1,d,r);
__base.endFill();
}
private function bulletHit():Void {
if(Soldier.hit(__base)){
Bullet.broadcastMessage('soldierHit',__base._x,__base._y);
}
}
public function set x(n:Number):Void {
__base._x = n;
}
public function get x():Number {
return __base._x;
}
public function set y(n:Number):Void {
__base._y = n;
}
public function get y():Number {
return __base._y;
}
public function set speed(n:Number):Void {
__speed = n;
}
public function get speed():Number {
return __speed;
}
}
FLA
var gm:Game = new Game(this);
Волгоградец
29.01.2008, 20:35
Спасибо. Получается, если у меня есть класс ClassA, расширяющий класс MovieClip, я смогу просто написать так:
for (var i in ClassA){
if(myMc[i] instanceof ClassA){
//тут делаем что надо
}
}
Спасибо большое!
Upd: :eek: :eek: Олег, мой мозг столько строчек кода не выдержит. Я не умею чужие коды читать к сожалению (надеюсь пока). Но я обязательно буду разбиаться. Спасибо!
Ну там как бы ничего такого...
В двух словах: 3 класса, 1 -- пули, 2 -- солдаты, 3 -- игра. Каждая пуля в онЕнтерФрейме проверяет не натолкнулась ли она на одного из солдат и вещает об этом. Игра слушает и соответсвенно выводит об этом сообщение.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.