PDA

Просмотр полной версии : Преобразование глобальных координат в локальные


Dip52
22.09.2013, 18:45
Здравствуйте.

Цель:

Определить какие противники находятся в области прицела. +
Поместить этих противников в специальный массив. +
Определить какой противник в специальном массиве самый слабый. +
Присвоить координаты самого слабого противника мушке. ?

Положение:

Прицел A.
Мушка B.
Противник C.

Мушка находится в том же контейнере, что и прицел. Противник снаружи.

Перед проверкой "какие противники находятся в области прицела" я перевожу координаты прицела с локальных в глобальные. Чтобы убедиться в том, что проверка действительно работает я присваивал определённую прозрачность тем противникам, которые находятся в области прицела.

Когда я определил самого слабого противника я перевёл его глобальные координаты в локальные и присвоил их мушке. Я получил в итоге: то движение мушки вокруг прицела, то противник стоит в одном месте, а мушка совсем в другом.

package madness.operation
{
import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Point;
import flash.display.Sprite;
import madness.*;
import flash.display.Shape;

import madness.background.Fields;

public class Aiming
{
private var enemies:Array = [];
private var range:Number = 40;
private var limit:Number = 20;

public function Aiming()
{
//Создаю прицел:
var wings:MovieClip = new Wings();
wings.name = 'sight';
wings.y = -200;
Settings.wings.addChild(wings);
Fields.FIELDFORWINGS.addChild(Settings.wings);
//Создаю прицел:

//Создаю мушку:
var foresight:MovieClip = new Foresight();
foresight.name = 'foresight';
wings.addChild(foresight);
//Создаю мушку:

Settings.stage.addEventListener(Event.ENTER_FRAME,work);
}
public function work(event:Event):void
{
wingsMove();
drawLimitAiming();
const LENGTHENEMIES:int = Settings.rangers.length;
const WINGS:MovieClip = MovieClip(Settings.wings.getChildByName('sight'));
var clickPoint:Point=new Point(0, 0);
var wingsPoint:Point = WINGS.localToGlobal(clickPoint);
const FORESIGHT:MovieClip = MovieClip(WINGS.getChildByName('foresight'));

for(var e:int = 0; e < LENGTHENEMIES; e++)
{
const ENEMY:MovieClip = Settings.rangers[e];
var onePoint:Point = new Point();
var twoPoint:Point = new Point();
var r:Number = Settings.wings.rotation*Math.PI/180;

onePoint.x = ENEMY.x - wingsPoint.x;
onePoint.y = ENEMY.y - wingsPoint.y;

twoPoint.x = onePoint.x*Math.cos(r) - onePoint.y*Math.sin(r);
twoPoint.y = onePoint.y*Math.sin(r) + onePoint.y*Math.cos(r);

if(range >= getDistanceForesightAndTarget(twoPoint,new Point()) && limit > Math.abs(twoPoint.y))
{
enemies.push(ENEMY);
ENEMY.alpha = .5;
}
else
{
ENEMY.alpha = 1;
}
}
const L:int = enemies.length;
if(L == 0)
{
FORESIGHT.x = 0;
FORESIGHT.y = 0;
return;
}
var id:int = int.MAX_VALUE;
var l:int = int.MAX_VALUE;
for(var feeble:int = 0; feeble < enemies.length; feeble++)
{
const life:int = enemies[feeble].life;

if(l > life)
{
l = life;
id = feeble;
}
}
if(id != int.MAX_VALUE)
{
var enemy:MovieClip = enemies[id];
enemies.splice(0,enemies.length);
var cp:Point = new Point(0,0);
var fPoint:Point = enemy.globalToLocal(cp);
FORESIGHT.x = fPoint.x;
FORESIGHT.y = fPoint.y;
}
}
//Метод рисования границ прицеливания:
private function drawLimitAiming():void
{
var sight:MovieClip = MovieClip(Settings.wings.getChildByName('sight'));
sight.graphics.clear();
sight.graphics.lineStyle(1,0x00FFFF);
//Верхняя линия:
sight.graphics.moveTo(-range, -limit);
sight.graphics.lineTo(range, -limit);
//Нижняя линия:
sight.graphics.moveTo(-range, limit);
sight.graphics.lineTo(range, limit);
}
//Метод определения дистанции между мишенью и мушкой:
private function getDistanceForesightAndTarget(foresight:Point,target:Point):Number
{
return Math.sqrt(Math.pow(foresight.x-target.x,2)+Math.pow(foresight.y-target.y,2));
}
//Движение крыльев:
private function wingsMove():void
{
var wings:MovieClip = Settings.wings;
var mainPersona:MovieClip = Settings.mainPersona;
wings.x = mainPersona.x;
wings.y = mainPersona.y;
wings.rotation = mainPersona.rotation;
}
}
}

Wolsh
22.09.2013, 18:56
var fPoint:Point = enemy.globalToLocal(cp);То есть Вы перевели точку стейджа (0, 0) в локальные координаты рейнджера. Ну, а мушка то тут при чем? Вам то нужно было глобальные координаты рейнджера перевести в локальные прицела. Видимо (не силен в Вашей архитектуре)
var fPoint:Point = WINGS.globalToLocal(new Point(enemy.x, enemy.y));

Dip52
22.09.2013, 19:15
То есть Вы перевели точку стейджа (0, 0) в локальные координаты рейнджера. Ну, а мушка то тут при чем? Вам то нужно было глобальные координаты рейнджера перевести в локальные прицела. Видимо (не силен в Вашей архитектуре)
var fPoint:Point = WINGS.globalToLocal(new Point(enemy.x, enemy.y));

Я понял. Я просто не задал какие координаты нужно переводить. Спасибо.

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

MikroAcse
22.09.2013, 19:36
Слишком большие вложенности DO приводят к плохим последствиям.
Самой большой проблемой является поддержка этого всего.

Dip52
22.09.2013, 19:51
Слишком большие вложенности DO приводят к плохим последствиям.
Самой большой проблемой является поддержка этого всего.

Что такое "вложенность DO"?

MikroAcse
22.09.2013, 20:09
Что такое "вложенность DO"?
Вложенные MovieClip/Sprite (DisplayObjectContainer = DOC)

AlexCooper
22.09.2013, 20:57
Dip52 Вы всегда создаете такое количество циклов, констант и временных переменных? Особенно циклов. В прошлый раз было три... Я считаю оптимальным подходом, при работе с группой объектов, получать ссылки на них единожды и делать все вычисления на ходу пока не закончатся все преобразования и исчисления. Вы постоянно создаете "временные" массивы куда складываете результаты одной составной итерации всего действия.

Добавлено через 15 минут
package madness.operation
{
import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Point;
import flash.display.Sprite;
import madness.*;
import flash.display.Shape;

import madness.background.Fields;

public class Aiming
{
private var enemies:Array = [];
private var range:Number = 40;
private var limit:Number = 20;

public function Aiming()
{
//Создаю прицел:
var wings:MovieClip = new Wings();
wings.name = 'sight';
wings.y = -200;
Settings.wings.addChild(wings);
Fields.FIELDFORWINGS.addChild(Settings.wings);
//Создаю прицел:

//Создаю мушку:
var foresight:MovieClip = new Foresight();
foresight.name = 'foresight';
wings.addChild(foresight);
//Создаю мушку:

Settings.stage.addEventListener(Event.ENTER_FRAME,work);
}
public function work(event:Event):void
{
wingsMove();
drawLimitAiming();
const LENGTHENEMIES:int = Settings.rangers.length;
const WINGS:MovieClip = MovieClip(Settings.wings.getChildByName('sight'));
var clickPoint:Point=new Point(0, 0);
var wingsPoint:Point = WINGS.localToGlobal(clickPoint);
const FORESIGHT:MovieClip = MovieClip(WINGS.getChildByName('foresight'));

var weakTarget:MovieClip;

for(var e:int = 0; e < LENGTHENEMIES; e++)
{
const ENEMY:MovieClip = Settings.rangers[e];
var onePoint:Point = new Point();
var twoPoint:Point = new Point();
var r:Number = Settings.wings.rotation*Math.PI/180;

onePoint.x = ENEMY.x - wingsPoint.x;
onePoint.y = ENEMY.y - wingsPoint.y;

twoPoint.x = onePoint.x*Math.cos(r) - onePoint.y*Math.sin(r);
twoPoint.y = onePoint.y*Math.sin(r) + onePoint.y*Math.cos(r);

if(range >= getDistanceForesightAndTarget(twoPoint,new Point()) && limit > Math.abs(twoPoint.y))
{
if (!weakTarget || weakTarget.life<ENEMY.life) {
weakTarget = ENEMY;
}

ENEMY.alpha = .5;
}
else
{
ENEMY.alpha = 1;
}
}

if (weakTarget) {

// странная пляска с бубном над globalToLocal

var cp:Point = new Point(0,0);
var fPoint:Point = weakTarget.globalToLocal(cp);

FORESIGHT.x = fPoint.x;
FORESIGHT.y = fPoint.y;

) else {

FORESIGHT.x =
FORESIGHT.y = 0;
}

}
//Метод рисования границ прицеливания:
private function drawLimitAiming():void
{
var sight:MovieClip = MovieClip(Settings.wings.getChildByName('sight'));
sight.graphics.clear();
sight.graphics.lineStyle(1,0x00FFFF);
//Верхняя линия:
sight.graphics.moveTo(-range, -limit);
sight.graphics.lineTo(range, -limit);
//Нижняя линия:
sight.graphics.moveTo(-range, limit);
sight.graphics.lineTo(range, limit);
}
//Метод определения дистанции между мишенью и мушкой:
private function getDistanceForesightAndTarget(foresight:Point,target:Point):Number
{
return Math.sqrt(Math.pow(foresight.x-target.x,2)+Math.pow(foresight.y-target.y,2));
}
//Движение крыльев:
private function wingsMove():void
{
var wings:MovieClip = Settings.wings;
var mainPersona:MovieClip = Settings.mainPersona;
wings.x = mainPersona.x;
wings.y = mainPersona.y;
wings.rotation = mainPersona.rotation;
}
}
}

Babylon
23.09.2013, 06:18
Слишком большие вложенности DO приводят к плохим последствиям.
Самой большой проблемой является поддержка этого всего.

Не согласен.

AlexCooper
23.09.2013, 13:10
Я бы вообще отказался от реализации объектов ( целей ) унаследованных от MovieClip. Слишком много избыточных методов и свойств.
Это были б какие-то инстансы классов только с характеристиками объекта ( то-есть позиция, угол поворота, жизни, броня, статус, движение ) и свойство вьювер - соответсвено и есть мувиклип, а лучше спрайт. Который при рендере считывался б и обновлялся.

caseyryan
23.09.2013, 13:24
Слишком большие вложенности DO приводят к плохим последствиям.
Самой большой проблемой является поддержка этого всего.

Только в случае если нужно координаты всего этого приводить к какой-то другой системе постоянно. А в целом особой проблемы не вижу.

п.с. Правильнее тогда DOC (DisplayObjectContainer). Bitmap тоже является DO, но в него нельзя ничего вложить.

MikroAcse
23.09.2013, 17:25
Не согласен.
Внимание. Говорю только про Flash IDE.
Программно созданные иерархии объектов - это нормально, хорошо и даже очень.

caseyryan
23.09.2013, 18:32
Внимание. Говорю только про Flash IDE.
Программно созданные иерархии объектов - это нормально, хорошо и даже очень.
В чем разница?

MikroAcse
23.09.2013, 18:40
В чем разница?
Разница в том, что, в основном, в коде ты имеешь готовый список (массив) созданных тобою элементов и ты точно знаешь как они расположены.
А для просмотра этого ужаса в Flash IDE нужен, как минимум, открытый Flash IDE и автор сего чуда.

caseyryan
23.09.2013, 18:44
Не убедительный аргумент, если честно. Во флеш IDE тоже можно все сделать красиво и логично, ровно как и сварганить полную кашу в коде)

MikroAcse
23.09.2013, 18:50
Во флеш IDE тоже можно все сделать красиво и логично
Можно, но посмотрите:
class Basket {
var basketBody:Shape;
var basketGrip:Shape;
var fruits:Array = [];
createFruits();
}
class Apple, Grape {
var body:Shape;
var leaf:Shape;
// etc...
}
Удобство в том, что здесь работает autocomplete, в отличии от "мувиков", созданных во Flash IDE.
Плюс: намного проще изменить структуру.
У подхода с Flash IDE тоже есть свои плюсы. Например, легко переместить, перерисовать или добавить/удалить элемент.
Но не более.