PDA

Просмотр полной версии : Как ограничить изменение угла у объекта?


Dip52
06.09.2013, 22:33
Добрый вечер.

Цель: Сделать так, чтобы прицел двигался только внутри крыльев: когда противник находится внутри крыльев, то на него автоматически наводится прицел.

Положение:
Есть три объекта:
Летающий корабль.
Прицел.
Крылья прицела.

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

29976

Проблема: Не могу понять, как можно сделать так, чтобы прицел "прыгал" в области ширины и высоты крыльев (то есть, между крыльев, как по высоте, так и по ширине.
Прицел.swf

in4core
07.09.2013, 04:21
а) сделать так, что крылья и прицел это одни СИМВОЛ ( клип, или кастомкласс - не важно ). Смысл в том, чтобы поворачивая крылья внутри оставлась та же система координат.
б) Если говорить о том, чтобы прицел распологался ТОЧНО внутри крыльев, взяв за основу то, что это не прямоугольник, а сложная фигура ( ЛЮБАЯ ) , то я бы отрисовал эту фигуру, как шейп или спрайт и проверял по положению курсора, типа while(x < tx && y < tx ) x += y+= 1
Это вариант на всикду - , а так надо думать

Akopalipsis
07.09.2013, 14:30
я могу ошибаться, но мне кажется что тут всё гораздо проще, но с оговоркой - что это КАЖЕТСЯ.
Если прицел появляется в центре конструкции на рисунке, то мы создаём точку с координатами А(0,0).
Сам прицел мы представляем точкой В(x,y). И теперь у нас получается вектор ab(x,y). Теперь мы можем найти его угол и контролировать его. Но тут для меня не все так просто. Можно просто проверять катеты прямоугольного треугольника на максимальную ширину и высоту, но это грубо. А вот как выразить соотношение косинуса к синусу, чтобы ограничить угол, я пока не придумал. Сижу думаю.

Добавлено через 27 минут
Вот самый банальный пример, но я бы его не стал использовать и показываю для того, что может кто то покажет как только по углу и гипотенузе узнавать. я не могу придумать как соотношение записать.
И особо мне хочется подчеркнуть НЕ ДЛЯ ИНВАЛИДОВ КОТОРЫЕ ЛЮДЕЙ ОСКОРБЛЯЮТ А САМИ НЕ ЗНАЮТ ЧТО ТАКОЕ ТРЕУГОЛЬНИК, чтобы эти не инвалиды не комментировали мой код, который создан для наглядности!
package geom
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;

public class Target extends Sprite
{

public function Target()
{
var a:Sprite = new Sprite();
a.graphics.beginFill(0xffffff);
a.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, 150);
a.graphics.endFill();
addChild(a);
var target:Sprite = new Sprite();
target.graphics.beginFill(0xDF1322);
target.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, 30);
target.graphics.endFill();
addChild(target);
target.addEventListener(Event.ENTER_FRAME, target_enterFrameHandler);

}

private function target_enterFrameHandler(event:Event):void
{

event.target.x = mouseX-stage.stageWidth/2;
event.target.y = mouseY - stage.stageHeight / 2;
var width:int = 150;
var hieght:int = 50;
var O:Point = new Point(0, 0);
var A:Point = new Point(mouseX - stage.stageWidth / 2, mouseY - stage.stageHeight / 2);
var target:Point = A.subtract(O);
if (target.x > width - 30 || target.x < 30 - width)
{
trace('width');
}
if (target.y > hieght - 30 || target.y < 30 - hieght)
{
trace('hieght');
}

}

}

}

AlexCooper
08.09.2013, 19:10
Я бы сделал:
1. а) сделать так, что крылья и прицел это одни СИМВОЛ ( клип, или кастомкласс - не важно ). Смысл в том, чтобы поворачивая крылья внутри оставлась та же система координат.

2. Если делать реализацию только под данный вид прицела, то явно видно внутренний круг который описывает крылья, соответственно
2.1. Точка регистрации "точки прицела" по центру
2.2. От центра всего клипа считать расстояние до новой точкой, минус радиус круглого прицела.
2.3. Верхние границы ограничивать по Y

Akopalipsis
08.09.2013, 19:36
AlexCooper Вы очень значит хорошо разбираетесь в геометрии!
я пока не могу такое сделать, но сделал тоже самое, что и описали Вы, но я пока не знаю как вписать в это уравнение поворот самих крыльев. Может покажите?

AlexCooper
08.09.2013, 21:24
Управление:
A / D - поворот корабля
Space - запустить / остановить движение объектов

aim.swf

package {

import flash.display.Sprite;
import com.greensock.TweenLite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;


public class Ship extends Sprite {

public var target:Vector.<Sprite> = new Vector.<Sprite>;
private var range:Number;
private var limit:Number;

public function Ship() {

range = 200; // maximum range length
limit = 100; // up / down range

drawUpDownLimit();

stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init);

}

private function init(event:Event=null):void {

removeEventListener(Event.ADDED_TO_STAGE, init);

addEventListener(Event.ENTER_FRAME, autoaim );
}

private function autoaim(event:Event):void {

graphics.clear();

drawUpDownLimit();

graphics.lineStyle(2,0xFF0000);

var pn:Point ;
var ps:Point = new Point();

var a:Number = - rotation * Math.PI / 180;

for each(var _target:Sprite in target) {

graphics.moveTo(0,0);

pn = new Point();

pn.x = _target.x-x;
pn.y = _target.y-y;

ps.x = pn.x*Math.cos(a) - pn.y*Math.sin(a);
ps.y = pn.x*Math.sin(a) + pn.y*Math.cos(a);

graphics.lineTo( ps.x, ps.y );

if (range >= dist( ps, new Point() ) && limit > Math.abs(ps.y) ) {

aim.x = ps.x;
aim.y = ps.y;

} else aim.x = aim.y = 0;
}
}

private function drawUpDownLimit():void {

graphics.lineStyle(1,0x00FFFF);

graphics.moveTo(-range, -limit);
graphics.lineTo(range, -limit);

graphics.moveTo(-range, limit);
graphics.lineTo(range, limit);
}

private function dist(p0:Point,p1:Point):Number {
return Math.sqrt( Math.pow( p1.x - p0.x , 2 ) + Math.pow( p1.y - p0.y , 2 ) );
}

}

}


Я так понимаю это нужно было?

Akopalipsis
08.09.2013, 21:43
Здорово! И так просто.

AlexCooper
08.09.2013, 21:52
Здорово! И так просто.

Надеюсь это то что хотел ТС

Akopalipsis
08.09.2013, 21:56
я сижу смотрю и понимаю, что нужно в свободное время, хоть немного смотреть видео о создании игр.
Потому что, сколько я не думал о том как сделать это, мне не раз не пришло в голову проверять дистанцию с обьектом))) я даже о нем и не думал.

AlexCooper
08.09.2013, 22:06
я сижу смотрю и понимаю, что нужно в свободное время, хоть немного смотреть видео о создании игр.
Потому что, сколько я не думал о том как сделать это, мне не раз не пришло в голову проверять дистанцию с обьектом))) я даже о нем и не думал.

Надо исходить из того что будет проще просчитывать машине, в этом и заключается наиболее оптимальное решение ( и скорей всего правильное ). В данном случае дистанция между двумя точками может описать зону прицеливания по кругу, а верхние границы просто по Y. Соответственно остается только все свести в одну систему координат + превращения ( определения вектора между точками и его поворот ).

Dip52
10.09.2013, 01:20
Огромное спасибо всем. "stage ? init() : " Красиво.

AlexCooper
11.09.2013, 14:59
Огромное спасибо всем.

Пожалуйста.

Красиво.
не более

KumoKairo
11.09.2013, 15:45
stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init);
Мне тут недавно объяснили что так лучше не делать. (http://www.flasher.ru/forum/showthread.php?t=200541)

AlexCooper
11.09.2013, 16:20
Это я знаю, данная конструкция применяется для переопределения. То-есть
var = (if) ? true : false;
Но я записал так, читабельность при этом не понизилась.