PDA

Просмотр полной версии : Проблема в размерах подгружаемых MovieClip'ов


s3dworld
09.03.2012, 15:42
Всем доброго дня!

У нас в игре бродят монстры, которые мы подгружаем как swf файлы. Вот один кадр из жизни монстра в fla файле:

http://xmages.net/storage/10/1/0/a/e/upload/291e6fa2.png

Как видите, картинка монстра png имеет размер 280x280 пикселей (на рисунке она видна синим квадратом). Просто там прозрачные пиксели. Этот fla файл компилируется в swf с размерами 140x120 (хотя мне больше кажется что это влияет только на просмотр этого ролика, а не на его реальный размер). Вот уже в игре я его вывожу и решил проверить его размеры:


sprite.graphics.beginFill(0xFF0000);
sprite.graphics.drawRect(obj.x,obj.y,obj.width,2);
sprite.graphics.drawRect(obj.x+obj.width,obj.y,2,obj.height);
sprite.graphics.drawRect(obj.x,obj.y,2,obj.height);
sprite.graphics.drawRect(obj.x,obj.y+obj.height,obj.width,2);
sprite.graphics.endFill();


И получаю вот такое:

http://xmages.net/storage/10/1/0/4/0/upload/bf108233.png

Почему так получается? А главное он не в центре то почему?

Deimos747
09.03.2012, 15:47
Чтобы был в центре сделайте во fla точку привязки в нужном месте

s3dworld
09.03.2012, 16:07
Deimos747
Чтобы был в центре сделайте во fla точку привязки в нужном месте
А как это сделать?

Deimos747
09.03.2012, 16:11
При редактировании мувиклипа в Flash IDE отображается точка привязки (выглядит как крест) - это начало координат для мувиклипа, относительного него и равняешь.

Zebestov
09.03.2012, 16:35
А такой код как рамочку нарисует?

var rect:Rectangle = obj.getRect(sprite);
sprite.graphics.lineStyle(2, 0xff0000);
sprite.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);

s3dworld
09.03.2012, 18:56
Zebestov
А такой код как рамочку нарисует?
А такой рисует рамочку размером 280x280, где монстр по центру.

Вообще я хочу сделать так, чтобы те объекты, которые перекрывают игрока (то есть игрока не видно за ними) были прозрачными. Определяю стоит ли объект 1 делать прозрачным относительно объекта 2 следующим образом:


// Нужно ли делать объект _obj1 прозрачным относительно объекта _obj2
private function TestTransparency(_obj1:RenderObject,_obj2:RenderObject):Boolean
{
if(_obj1.type!=RenderObject.STATIC_OBJECT && _obj1.type!=RenderObject.DYNAMIC_OBJECT) return false;
if(_obj1.type==RenderObject.STATIC_OBJECT && (_obj1.desc as MapStaticObject).notTransparent) return false;
if(_obj1.type==RenderObject.DYNAMIC_OBJECT && (_obj1.desc as MapDynamicObject).notTransparent) return false;

if(_obj2.desc.row>_obj1.desc.row+_obj1.desc.sizeY-1) return false;
if(_obj2.desc.column>_obj1.desc.column+_obj1.desc.sizeX-1) return false;

if(IntersectBoxs(_obj1.x,_obj1.y,_obj1.width,_obj1.height,_obj2.x,_obj2.y,_obj2.width,_obj2.height))
{
if(TestPixelCollided(_obj1,_obj2)) return true;
}

return false;
}


Здесь у меня идёт проверка того, является ли этот объект статическим либо динамическим (остальные объекты не участвуют). Ещё проверка идёт на то, разрешено ли объекту становиться прозрачным. Получается что если игрок находится ниже или правее, то сортировать объект не надо. А если другое условие, то проверяю пересекаются ли их ограничивающие поверхности:


// Пересечение коробок
private function IntersectBoxs(_b1x:Number,_b1y:Number,_b1w:Number,_b1h:Number,_b2x:Number,_b2y:Number,_b2w:Number,_b2h:Number):Boolean
{
if(_b1x>_b2x+_b2w || _b1x+_b1w<_b2x || _b1y>_b2y+_b2h || _b1y+_b1h<_b2y) return false;
return true;
}


И если пересекаются, то попиксельно сравниваю:


// Пересекается ли объект _obj1 с объектов _obj2 на уровне пикселей
private function TestPixelCollided(_obj1:RenderObject,_obj2:RenderObject):Boolean
{
var i:uint=0;
var j:uint=0;
var bitmapData1:BitmapData=null;
var bitmapData2:BitmapData=null;
var colorAlpha1:uint=0;
var colorAlpha2:uint=0;

if(_obj1.graphType==RenderObject.BITMAP)
{
bitmapData1=_obj1.bitmap.bitmapData;
}
else
{
bitmapData1=new BitmapData(_obj1.movieClip.width,_obj1.movieClip.height,true,0x000000);
bitmapData1.draw(_obj1.movieClip);
}

if(_obj2.graphType==RenderObject.BITMAP)
{
bitmapData2=_obj2.bitmap.bitmapData;
}
else
{
bitmapData2=new BitmapData(_obj2.movieClip.width,_obj2.movieClip.height,true,0x000000);
bitmapData2.draw(_obj2.movieClip);
}

var rect:Rectangle=(new Rectangle(_obj1.x,_obj1.y,_obj1.width,_obj1.height)).intersection(new Rectangle(_obj2.x,_obj2.y,_obj2.width,_obj2.height));
var b1X:Number=_obj1.x-rect.x;
var b1Y:Number=_obj1.y-rect.y;
var b2X:Number=_obj2.x-rect.x;
var b2Y:Number=_obj2.y-rect.y;
var point1:Point=new Point(0,0);
var point2:Point=new Point(0,0);

for(j=0;j<rect.height;j++)
{
point1.y=b1Y+j;
point2.y=b2Y+j;

for(i=0;i<rect.width;i++)
{
point1.x=b1X+i;
point2.x=b2X+i;

colorAlpha1=bitmapData1.getPixel32(point1.x,point1.y)>>>24;
colorAlpha2=bitmapData2.getPixel32(point2.x,point2.y)>>>24;

if(colorAlpha1>0 && colorAlpha2>0) return true;
}
}

return false;
}


В общем если оба пикселя по альфа больше нуля, то пересеклись. Но на практике получилось вот что:

http://xmages.net/storage/10/1/0/f/e/upload/a94a01fa.png

На рисунке человек является параметром _obj2 в функции TestTransparency(). То есть получается что он стоит на той же строке с пугалом, но его колонка меньше, следовательно с успехом не выполнятся эти условия:


if(_obj2.desc.row>_obj1.desc.row+_obj1.desc.sizeY-1) return false;
if(_obj2.desc.column>_obj1.desc.column+_obj1.desc.sizeX-1) return false;


А дальше идёт проверка на пересечение ограничивающих поверхностей. Они пересекаются и тут проблем нет. Следом идёт проверка попиксельного пересечения. И вот как Вы видите, пугало не подсвечивается (а должно бы). Следовательно я допустил ошибку в функции TestPixelCollided(). Пока я буду её искать сам, прошу Вас помочь найти её мне. Всё таки может быть Вы сделаете это быстрее.

Спасибо за помощь!

s3dworld
09.03.2012, 19:22
Не понимаю как использовать BitmapData::hitTest() (http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#hitTest()).