XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Периодическое движение
Как организовать) Предположим, что данные по X и Y скорости у меня есть в хэше. Была идея сделать рекурсивную функцию, которая двигает передаваемого ей юнита на прочитанные из хэша X и Y и через 0.04 снова вызывает себя пока юнит не умер. Однако такая функция требует передачи ей параметра (самого юнита-снаряд). А таймеры не позволяют передавать функции параметры. Так как это практично реализовать?
Старый 06.01.2012, 17:25
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
Но ведь на таймер что хочешь можно через тот же хэш повесить.
Или я не так понял задачу? Нужна общая функция для всех двигаемых дами на карте?
Старый 06.01.2012, 18:03
Амбидекстрия
Silenced by ScorpioT1000
offline
Опыт: 8,237
Активность:
MrSigma:
А таймеры не позволяют передавать функции параметры. Так как это практично реализовать?
почему не позволяют? сохраняем в ячейке таймера real X и real Y и потом загружаем.
Старый 06.01.2012, 18:26
Doc

offline
Опыт: 63,163
Активность:
struct Data{
	unit u
	float x
	float y
	float vx
	float vy
	
	static void update(){
		Data this = LoadInteger(Hash, GetHandleId(GetExpiredTimer()), 0)
		.x += .vx
		.y += .vy
		SetUnitX(.u, .x)
		SetUnitY(.u, .y)
	}
}

void launch(float x, float y, float tx, float ty){
	float dx = tx - x
	float dy = ty - y
	float len = SquareRoot(dx * dx + dy * dy)
	dx /= len
	dy /= len
	Data d = Data.create()
	d.u = CreateUnit(Player(0), 'h000', x, y, Acos(dx)) // насчет угла не уверен
	d.x = x
	d.y = y
	d.vx = dx * 10.
	d.vy = dy * 10.
	timer t = CreateTimer()
	SaveInteger(Hash, GetHandleId(t), 0, d)
	TimerStart(t, true, 0.025, function Data.update)
}
Пишу в темноте, могут быть ошибки.

Отредактировано Doc, 08.01.2012 в 22:48.
Старый 06.01.2012, 18:33
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Doc, если честно, я не совсем еще разобрался со структурами на жассе... Насколько я понимаю, в отличии от Сишных структур, в них можно записывать еще и функции?

MrSigma добавил:
И как остановить такое движение? После вызова launch таймер будет каждые 0.025 секунд вызывать апдейт координат моего партикл юнита... Предположим я в update() запишу условия, при которых мое движение остановится. Как мне уничтожить этот таймер из функции update?
Старый 08.01.2012, 00:27
Doc

offline
Опыт: 63,163
Активность:
MrSigma, да. Это скорее классы, чем структуры, см C++ и вообще большинство ООП языков.
Старый 08.01.2012, 00:27
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Точно! Вот же он! getExpiredTimer...

MrSigma добавил:
до чего дошел прогресс... я уж было начал негодовать из-за отсутствия объектной ооринтации jass'а)) Видимо я многое упустил)

MrSigma добавил:
есть какой нибудь гайд по синтаксису этого... объектно ориентированного элемента жасса?) Из всего прочитанного, я понял лишь, что новый объект структуры объявляется посредством метода .allocate)
Старый 08.01.2012, 00:33
Doc

offline
Опыт: 63,163
Активность:
vjass manual в папке JNGP\jasshelper
Старый 08.01.2012, 01:23
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
там, где ты указал, я ничего не нашел.

Попытался разобраться сам, но джассхелпер ругается на строчку

projectile p = projectile.allocate();

говорит, что метод allocate - приватный.
Старый 08.01.2012, 15:59
alexprey
познающий Unity
offline
Опыт: 68,501
Активность:
MrSigma, потому что надо юзать .create() для создания нового экземпляра. allocate можно только внутри структуры использовать
Старый 08.01.2012, 16:33
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Док, ты лжец... T_T
Старый 08.01.2012, 16:34
alexprey
познающий Unity
offline
Опыт: 68,501
Активность:
MrSigma, xgm.ru/forum/showthread.php?t=13118 смотри аттач в первом посту
Старый 08.01.2012, 16:35
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Код:
projectile pr = projectile.create();
pr.initialize(prj, target, movespeed);   //функция для инициализации структуры... 

TimerStart(t, 0.04, true, function pr.tick);   //Вот эта строчка вызывает эррор.


Написано pr is not a struct name.
Старый 08.01.2012, 17:44
J64_

offline
Опыт: 4,724
Активность:
projectile pr = projectile.create();
pr.initialize(prj, target, movespeed);   //функция для инициализации структуры... 

TimerStart(t, 0.04, true, function projectile.tick);   //Вот эта строчка не должна вызывает эррор.
к методам можно обращаться только через имя структуры
Старый 08.01.2012, 20:08
Doc

offline
Опыт: 63,163
Активность:
Аааааа, .allocate можно использовать только когда .create занят да.
Doc добавил:
и да, пост 14 вообще лол, т.к.
projectile pr = projectile.create();
pr.initialize(prj, target, movespeed);
Почему не
projectile pr = projectile.create(prj, target, movespeed);
Doc добавил:
Читай основные принципы ООП, про статик методы.
Старый 08.01.2012, 20:21
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
потому как писал этот стракт до того как ознакомился с синтаксисом и не знал как объявить нестандартый конструктор или деструктор)

MrSigma добавил:
Judycaster64, и как же тогда этот код выберет нужную структуру? Положим у меня есть с десяток разных projectile'ов. Если я буду использовать статичный метод, это ведь повлияет на все стракты типа projectile =\ Мне нужно изменять координаты только для одного объекта этого стракта.

MrSigma добавил:
Doc, я имею некоторые знания в области ООП. На том же си шарпе я использовал нестатичные методы и обращался к ним через конкретный экземпляр, а не через весь класс целиком. Почему я не могу здесь обратиться к нему таким же образом?

MrSigma добавил:
В предыдущей строчке этого кода, кстати, я именно так и сделал. Там я воспользовался методом initialize для одно лишь объекта: pr. Ну и кто мне теперь скажет, что к методам можно обратиться только через имя стракта?

MrSigma добавил:
Я понял почему я не могу использовать методы с таймерами таким образом... Все таки jass - не объектно ориентированный язык. И запись pr.move() в данном случае примерно равна projectile.move(pr).
У меня появилась идея. Несколько тормозная по сравнению со страктами, однако должна работать. Сейчас попробую.
Старый 08.01.2012, 22:07
Doc

offline
Опыт: 63,163
Активность:
MrSigma, ну так лол вот затем и надо сохранять структуру. смотри мой код еще раз. из таймера можно обратиться только к статичным функциям.
Да, последний абзац твой все объясняет.
Старый 08.01.2012, 22:48
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
Я придумал (то есть не придумал, а переперепридумал) метод без использования страктов, а с помощью хэша (потому более тормозной) и одного таймера.

В общем вот код:

Код:
nothing move() {
timer t = GetExpiredTimer();

unit projectile = LoadUnitHandle(hash, HASHDATA_PROJECTILES, GetHandleId(t));
unit target = LoadUnitHandle(hash, HASHDATA_UNITS, GetHandleId(t));
if ((GetUnitState(target, UNIT_STATE_LIFE) <= 0) or (GetUnitState(projectile, UNIT_STATE_LIFE) <= 0)) { DestroyTimer(t); t = null; return; }  //Остановить работу цикла
real velocity = LoadReal(hash, HASHDATA_VARIABLES, GetHandleId(t))/40;

real angle = Atan2(GetUnitY(target) - GetUnitY(projectile), GetUnitX(target) - GetUnitX(projectile))
real Vx = velocity * Cos(angle);
real Vy = velocity * Sin(angle);

SetUnitX(projectile, GetUnitX(projectile) + Vx);
SetUnitY(projectile, GetUnitY(projectile) + Vy);

projectile = null;
target = null;
t = null;
}

nothing RegisterProjectile(unit prj, unit target, real movespeed)
{
trigger trg = CreateTrigger();
timer t = CreateTimer();

TriggerRegisterUnitInRange(trg, prj, 60, null);  //Это для обработки столкновения с целью
TriggerAddCondition(trg, Condition(function projectileHit));  //Это тоже
SaveUnitHandle(hash, HASHDATA_PROJECTILES, GetHandleId(trg), prj); //И это
SaveUnitHandle(hash, HASHDATA_PROJECTILES, GetHandleId(t), prj);
SaveUnitHandle(hash, HASHDATA_UNITS, GetHandleId(trg), target);  //И это
SaveUnitHandle(hash, HASHDATA_UNITS, GetHandleId(t), target);

SaveReal(hash, HASHDATA_VARIABLES, GetHandleId(t), movespeed);

TimerStart(t, 0.04, true, function move);


trg = null;
t = null;
}


MrSigma добавил:
Nerevar, это ваш метод, если не ошибаюсь. Я просто совсем забыл про GetExpiredTimer, и не принял во внимание, что можно навешать по его Id чего угодно...)
Старый 08.01.2012, 23:05
Doc

offline
Опыт: 63,163
Активность:
Старый 08.01.2012, 23:08
MrSigma
愛 - XGM
offline
Опыт: 2,429
Активность:
безусловно. Потому я и пояснил, что пере-пере-пере придумал) Словом, простота этого метода радует) Однако более подробным изучением страктов все же заняться стоит...
Старый 08.01.2012, 23:10
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 13:36.