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

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

Ответ
 
Extremator

offline
Опыт: 39,403
Активность:
Первые шаги в осваивании Jass'а (by Ex)
Вступление:
Я бы так и не стал разглядывать Jass, так как старый пресловутый GUI позволял мне реализовать все мои задумки.
Я естественно понимаю что он имеет кучу косяков, изъянов и попросту недоработок.
И собственно поэтому я и занялся пока что только изучением и разбором всяких более мелких деталей моего любимого "конструктора" ))).
Я пытался расспрашивать знакомых жассеров, но...
Опытных - раз-два и всё, да и отошли они от дел варкрафтовских уже х))
А прочие - не знакомы с тем о чём я спрашиваю.
В общем помочь простым разъяснением никто не может.
...а читать статьи я никогда не любил, но всё же время от времени иногда приходится это делать
Поясню: я только начал разбираться в строении Jass'а, и крайне не-опытен.
. . .
Ближе к сути:
Для записи всяких данных я всегда использовал глобальные переменные, хоть и знал о существовании локальных аналогов.
Попытавшись воспроизвести свой простенький gui-спелл на jass'е, я понял что передавать данные из функции в функцию я научился,
а вот хранить их n-ное время и потом обращаться за ними - не знаю как... т.е. я хочу обращаться к функции которая
уже будет иметь иметь ряд переменных, которые (в свою очередь) уже были ранее записаны... Глобалки нужны мне).
По сути это не проблема, и я лишь просто хотел немного укомплектовать всё это дело (в своём понимании этих слов).
Я разглядывал всякие коды... коды... да... В общем я наткнулся на некие globals / endglobals и library / endlibrary
Что привело меня к мысли о возможности создания примерно вот такой конструкции (не смейтесь! я серьёзно! я пытался! хД)
(в коде будут комменты с вопросами)
» триггер в общем виде
называется obrs
// условие триггера, на проверку применённого скилла
function orbs_conditions_cast takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction
// действия триггера при срабатывании, в данном случаи тут пока конверт из GUI
function orbs_actions_cast takes nothing returns nothing
    call DisplayTimedTextToPlayer(Player(0), 0., 0., 60., "123") // это для теста
    // =====
    set udg_orbs_Max = ( udg_orbs_Max + 1 )
    // =====
    set udg_orbs_hero[udg_orbs_Max] = GetTriggerUnit()
    set udg_orbs_angle[udg_orbs_Max] = GetRandomDirectionDeg()
    set udg_orbs_range[udg_orbs_Max] = GetRandomReal(128.00, 512.00)
    set udg_orbs_speed[udg_orbs_Max] = GetRandomReal(-16.00, 16.00)
    set udg_orbs_time[udg_orbs_Max] = GetRandomReal(4.00, 20.00)
    // =====
        set udg_orbs_point[0] = GetUnitLoc(GetTriggerUnit())
        set udg_orbs_point[1] = PolarProjectionBJ(udg_orbs_point[0], udg_orbs_range[udg_orbs_Max], udg_orbs_angle[udg_orbs_Max])
    // =====
    call CreateNUnitsAtLoc( 1, 'u000', GetOwningPlayer(GetTriggerUnit()), udg_orbs_point[1], 0.00 )
    set udg_orbs_dummy[udg_orbs_Max] = GetLastCreatedUnit()
    call SetUnitVertexColorBJ( GetLastCreatedUnit(), GetRandomReal(0.00, 100.00), GetRandomReal(0.00, 100.00), GetRandomReal(0.00, 100.00), 0 )
    call SetUnitFlyHeightBJ( GetLastCreatedUnit(), GetRandomReal(30.00, 600.00), 0.00 )
    // =====
        call RemoveLocation(udg_orbs_point[0])
        call RemoveLocation(udg_orbs_point[1])
    // =====
    if ( udg_orbs_Max == 1 ) then
        call StartTimerBJ( udg_orbs_Timer, true, 0.03 )
    endif
endfunction
// вот эта часть - инициализация триггера, его создание, установление ему события, условия и действия
// это чисто для себя, да-да, а то я забуду потом
function InitTrig_orbs takes nothing returns nothing
    local trigger T = CreateTrigger()
    call TriggerAddEventUnitCast(T) // моя функция, прикреплена ниже (у мня она находится нестандартном коде)
    call TriggerAddCondition( T, Condition( function orbs_conditions_cast ) )
    call TriggerAddAction( T, function orbs_actions_cast )
    set T = null
endfunction
function TriggerAddEventUnitCast takes trigger t returns nothing
    local integer i = 16
    loop
        set i = i - 1
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        exitwhen i == 0
    endloop
endfunction
вот эта часть, которую я хочу как-то... я общем я не придумал как заставить её работать
а как она работает на самом деле - я попросту не знаю...
в не я просто хочу объявлять все свои глобальные переменные для данного скилла
мне кажется так было бы удобнее... хотя... хз в общем
» globals
globals orbs
    global integer udg_orbs_Max = 0
    global integer udg_orbs_Loop = 0
    global integer udg_orbs_Index = 0
    global unit array udg_orbs_hero
    global unit array udg_orbs_dummy
    global real array udg_orbs_angle
    global real array udg_orbs_range
    global real array udg_orbs_speed
    global real array udg_orbs_time
    global timer udg_orbs_Timer = CreateTimer()
    global timer udg_orbs_Group = CreateGroup()
endglobals
в итоге я представляю себе триггер в общем виде примерно такой (распишу блоками)
globals orbs
function orbs_conditions_cast
function orbs_actions_cast
function InitTrig_orbs
. . .
Теперь мои основные вопросы:
  1. Можно ли использовать что-либо в роли изображённого мною блока "глобалс" ? (и что это?)
  2. Где мне можно вкрадце прочитать о том как и зачем использовать "глобалс" ? (или это мне пока рано?)
  3. Вопрос аналогичный 2-му, только просто библиотеки (library).
. . .
P.S.: я задаюсь вопросом как сохранить данные, но при этом не упоминаю про хэш...
Да, я сделал это умышленно, я пока не хочу обращаться к изучению хэша... (его я тоже пока не знаю).
Старый 09.05.2014, 11:33
Msey
????
offline
Опыт: 67,346
Активность:
1 чтобы работало нормально, делай через вжас
2 вжас мануал
3 ответ аналогичен второму
советую сразу с вжаса начинать
Старый 09.05.2014, 12:35
Borodach

offline
Опыт: 5,767
Активность:
Начни изучать хеш, он сложный без толкового объяснения.
Пример сохранения юниту предметов доступных ему для использования, глобальной переменной.
Юнит[1] = паладин
Юнит[2] = ассасин
Предмет[1] = молот
Предмет[2] = нож
При условии что поднимает предмет
Юнит[1] и тип предмета[1] выполняются действия.
Хеш имеет "2 массива".
Тот же пример на хеше
Записать в хеш типа логическая
call SaveBoolean(название глобальной хеша,1,1,true)
call SaveBoolean(название глобальной хеша,2,2,true)
При проверке с загруженого хеша call LoadBoolean(название,1,1) = true делаем действия
Но это только по очевидности идет номер сохранения. А в игре все объекты имеют свой номер и
его можно узнать с помощью GetHandleId(объект).
Так более функциональный пнимер
call SaveBoolean(название хеша,GetHandleId(юнит применившый способность),1,true)
Дальше в любом триггере можно загрузить эту логическую и если номер юнита совпадет с тем что сохранили, у тебя выполнятся действия.
Хоть и не внятно объяснил, но хотя б показал преимущество хеша в простоте использования. Лучше
удели время для его изучения.
Borodach добавил:
Начни изучать хеш, он сложный без толкового объяснения.
Пример сохранения юниту предметов доступных ему для использования, глобальной переменной.
Юнит[1] = паладин
Юнит[2] = ассасин
Предмет[1] = молот
Предмет[2] = нож
При условии что поднимает предмет
Юнит[1] и тип предмета[1] выполняются действия.
Хеш имеет "2 массива".
Тот же пример на хеше
Записать в хеш типа логическая
call SaveBoolean(название глобальной хеша,1,1,true)
call SaveBoolean(название глобальной хеша,2,2,true)
При проверке с загруженого хеша call LoadBoolean(название,1,1) = true делаем действия
Но это только по очевидности идет номер сохранения. А в игре все объекты имеют свой номер и
его можно узнать с помощью GetHandleId(объект).
Так более функциональный пнимер
call SaveBoolean(название хеша,GetHandleId(юнит применившый способность),1,true)
Дальше в любом триггере можно загрузить эту логическую и если номер юнита совпадет с тем что сохранили, у тебя выполнятся действия.
Хоть и не внятно объяснил, но хотя б показал преимущество хеша в простоте использования. Лучше
удели время для его изучения.
Старый 09.05.2014, 13:06
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
столько лет на сайте ._.
хранить данные можно в глобалках абсолютно спокойно, ничего с ними не будет
пример объявления в джнгп
    globals
        real data = 316.
    endglobals
про либы почитай в вжасс мануале... у меня в подписи ссыль на англ.
на форуме можешь найти перевод адольфа...
столько времени на сайте проведено, поиска не знаем, статьи не любим, яснопонятно
Старый 09.05.2014, 13:24
nvc123
new status
offline
Опыт: 59,284
Активность:
nvc123 добавил:
globals это объявление глобальных переменных
после globals ничего не пишется
а вообще сиджасс позволяет объявлять глобалки намного проще
и функции писать тоже проще
void abc(int a){ //function abc takes integer a returns nothing

} // endfunction

int b // глобальная переменная b типа целочисленная

void abcd(){ // function abcd takes nothing returns nothing

} // endfunction
nvc123 добавил:
для того чтобы хранить данные в глобалках для муи спелла нужно юзать атач
nvc123 добавил:
library это библиотека
Старый 09.05.2014, 14:43
Tobi123

offline
Опыт: 7,826
Активность:
Extremator:
P.S.: я задаюсь вопросом как сохранить данные, но при этом не упоминаю про хэш...
Да, я сделал это умышленно, я пока не хочу обращаться к изучению хэша... (его я тоже пока не знаю).
Хэш рулит. Вот небольшой пример.
Tobi123 добавил:
И кстати локалки позволяют не запариваться насчет муи. И еще лучше не юзать точки(locations), координаты рулят. В примере на координатах написано.
Прикрепленные файлы
Тип файла: w3x Hash(for Extremator).w3x (17.4 Кбайт, 14 просмотров )
Старый 09.05.2014, 20:54
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Tobi123, рулят структуры
Buulichkaa добавил:
в быстродействии, читабельности и логике кода, да и скорости его написания в конце концов.
Buulichkaa добавил:
но с другой стороны и про хэш таблицу тоже надо знать, так что попрактиковаться с ней стоит, она может быть полезна во многих случаях, как огромная БД или же БД с труднодоступными индексами, которые не влазят в диапазон 8192, может быть полезна при каких-нибудь "в теории" бесконечных, динамических спеллов, которые требуют поочередного сохранения координат (например) (прим. это психбольница будет) да и ещё в хренольёне случаев...
Старый 09.05.2014, 21:02
Extremator

offline
Опыт: 39,403
Активность:
Borodach:
Начни изучать хеш, он сложный без толкового объяснения.
Пример сохранения юниту предметов доступных ему для использования, глобальной переменной.
Нее, хеш потом...
сейчас меня интересовал конкретно блок globals
Buulichkaa:
пример объявления в джнгп
    globals
        real data = 316.
    endglobals
пробовал - запускалось главное меню игры))
сейчас на другом компе - работает... (буду сверять конфиги)
Buulichkaa:
столько времени на сайте проведено, поиска не знаем, статьи не любим, яснопонятно
да я пробовал в поиске искать - ни на что даже просто касающееся темы я не натыкался(
я всё привык делать методом тыка/личного эксперимента...
чужие труды для меня крайне мало понятны... не знаю в честь чего так(
разберусь потихоньку
nvc123:
вот за это спасибо!
много всего интересного написано
хотя мне и первых пары абзацев хватило)) дальше как-то пока не понятно для меня
(в тексте много ошибок, в слове library первая буква отсутствует, вместо твёрдого знака стоит мягкий, и т.п.)
nvc123:
для того чтобы хранить данные в глобалках для муи спелла нужно юзать атач
Да не, у меня с муи и глобалками всё норм... но это на GUI
а так как я пока только изучаю Jass, то появляются непонятны ситуации х)
nvc123:
library это библиотека
Я понимаю что ты хочешь помочь, но это слишком капитанский ответ :DD
Tobi123:
И кстати локалки позволяют не запариваться насчет муи.
И еще лучше не юзать точки(locations), координаты рулят. В примере на координатах написано.
Про локалки то я понимаю, но существуют они только в пределах одной функции...
Но мне нужно в одной функции записывать данные на глобалки, а в другой считывать, при этом это происходит не сразу, может происходит многократно с разным интервалом и с различной величиной массива на момент обращения в ним...
Я видел в мануале примеры всяких струкрут, библиотек, приватных переменных - но мне пока это рано, обычных глобалок вполне хватает.
Extremator добавил:
Хмм... так, я тут поковырялся... с редактором
кароч у меня на ноуте всё норм пашет
а на компе - нифига
Я наверняка какие-то настройки менял, галочки ставил/убирал...
кароч что где поставить нужно что бы норм было? х)
ещё у меня кстати на ноуте при сохранении постоянно писались ошибки мол, и я их убирал
а на компе - пиши в коде всё что хошь, он те слова не скажет, просто потом менюшку покажет вместо экрана загрузки карты хД
как сделать так что бы он тревогу поднимал???
Extremator добавил:
Так, вот эту карта на ноуте работала, а на компе - нет.
код разумеется кину и так
» abc
function abc_actions_periodic takes nothing returns nothing
    local integer L
    local real x
    local real y
    
    set L = 0
    loop
        set L = L + 1
        // =====
        set abc_distance[L] = abc_distance[L] - 30.
        set x = Polar_X(GetUnitX(abc_unit[L]), 30., abc_angle[L])
        set y = Polar_Y(GetUnitY(abc_unit[L]), 30., abc_angle[L])
        // =====
        call SetUnitPosition(abc_unit[L], x, y)
        // =====
        if abc_distance[L] < 30. then
            call KillUnit(abc_unit[L])
            // =====
            set abc_unit[L] = abc_unit[abc_Max]
                set abc_unit[abc_Max] = null
            set abc_angle[L] = abc_angle[abc_Max]
            set abc_distance[L] = abc_distance[abc_Max]
            // =====
            set L = L - 1
            set abc_Max = abc_Max - 1
            // =====
            if abc_Max == 0 then
                call PauseTimer(abc_Timer)
            endif
        endif
        // =====
        exitwhen L == abc_Max
    endloop
    
endfunction


// действия триггера "abc"
function abc_actions_start takes nothing returns nothing
    set abc_Max = abc_Max + 1
    if ( abc_Max == 1 ) then
        call TimerStart(abc_Timer, .03, true, null)
    endif
    // =====
    set abc_unit[abc_Max] = CreateUnit(Player(0), 'ewsp', 0., 0., 0.)
    set abc_angle[abc_Max] = GetRandomReal(0., 360.)
    set abc_distance[abc_Max] = 600.
    // =====
    call UnitAddAbility(abc_unit[abc_Max], 'Aloc')
endfunction

// инициализация триггера "abc"
function InitTrig_abc takes nothing returns nothing
    local trigger t1 = CreateTrigger() // триггер-старт
    local trigger t2 = CreateTrigger() // триггер-период
    // =====
    call TriggerAddEventPlayerESC_ALL(t1) // событие старта
    call TriggerRegisterTimerExpireEvent(t2, abc_Timer) // событие периодп
    // =====
    // condition
    // =====
    call TriggerAddAction(t1, function abc_actions_start)
    call TriggerAddAction(t2, function abc_actions_periodic)
    // =====
    set t1 = null
    set t2 = null
endfunction

globals
    integer abc_Max = 0
    integer abc_Loop = 0
    integer abc_Index = 0
    unit array abc_unit
    real array abc_angle
    real array abc_distance
    timer abc_Timer = CreateTimer()
endglobals
» CustomCode
function TriggerAddEventPlayerESC_ALL takes trigger t returns nothing
    local integer i = 16
    loop
        set i = i - 1
        call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_END_CINEMATIC)
        exitwhen i == 0
    endloop
endfunction

function Polar_X takes real x, real d, real a returns real
    return x + d * Cos(a * bj_DEGTORAD)
endfunction

function Polar_Y takes real y, real d, real a returns real
    return y + d * Sin(a * bj_DEGTORAD)
endfunction
    
Прикрепленные файлы
Тип файла: w3x Test Map.w3x (7.3 Кбайт, 5 просмотров )
Старый 10.05.2014, 07:20
Tobi123

offline
Опыт: 7,826
Активность:
Extremator, объяви глобалки в топе Custom кода.
Я скомпилировал твой код. В нем есть некоторое приемущество, что все сделано на одном глобальном таймере. Но для этого приходится использовать глобальные переменные(кстати можно обойтись и без глобалок, используя тот же самый хэш). Я считаю, что использование подобных глобалок приводит к некоторому неудобству, если их много. И ввиду этого, я считаю, что хэш с локальными переменными - наилучший вариант для использования в подобных случаях.
Прикрепленные файлы
Тип файла: w3x Hash(for Extremator).w3x (20.3 Кбайт, 4 просмотров )
Старый 10.05.2014, 08:12
Extremator

offline
Опыт: 39,403
Активность:
Не, говорю же - хэш потом, в своё время.
Я не понимаю почему в одном редакторе карта запускается нормально, а в другом - нет.
Я тут пробую всякие галочки тыкать - не выходит ничего. (посмотреть как галки расставлены на ноуте пока не могу)
Старый 10.05.2014, 08:33
Tobi123

offline
Опыт: 7,826
Активность:
За проверку кода отвечает JassHelper и AcidOptimizer
Старый 10.05.2014, 09:22
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Extremator, на том компе, на котором не работает переустанови джнгп, делов-то...
Старый 10.05.2014, 09:35
Extremator

offline
Опыт: 39,403
Активность:
Buulichkaa:
Extremator, на том компе, на котором не работает переустанови джнгп, делов-то...
хотел скачать заново
залез вот сюда - xgm.guru/p/wc3/jngp
скачал вот тут - xgm.guru/p/wc3/jassnewgenpack-exp
всё казалось бы просто
но архив требует пароль :DD что за шутки?
Старый 10.05.2014, 10:24
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Extremator, xgm.ru был по-моему... попробуй или xgm.guru
Старый 10.05.2014, 10:26
Extremator

offline
Опыт: 39,403
Активность:
я тут всё с галочками мучаюсь
У меня вот так втыкнуто (AcidOptimizer вырубать пробовал - не помогает)
Миниатюры
Кликните на картинку для увеличения
Название:  J1.PNG
Просмотров: 5
Размер:  73.5 Кбайт  Кликните на картинку для увеличения
Название:  J2.PNG
Просмотров: 4
Размер:  5.1 Кбайт  Кликните на картинку для увеличения
Название:  J3.PNG
Просмотров: 3
Размер:  10.4 Кбайт  Кликните на картинку для увеличения
Название:  J4.PNG
Просмотров: 2
Размер:  2.0 Кбайт  Кликните на картинку для увеличения
Название:  J5.PNG
Просмотров: 2
Размер:  4.4 Кбайт  

Кликните на картинку для увеличения
Название:  J6.PNG
Просмотров: 3
Размер:  5.7 Кбайт  
Старый 10.05.2014, 10:32
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Extremator, переустановил и не работает?
Старый 10.05.2014, 10:39
Extremator

offline
Опыт: 39,403
Активность:
Buulichkaa:
xgm.ru был по-моему...
да, подошло
Buulichkaa:
переустановил и не работает?
вот только распаковал, сейчас посмотрим......
Extremator добавил:
пароль подошёл
установил
запустил
(чё-то в карта вся чёрная, ночь)
запускаю - гл.меню (
Старый 10.05.2014, 10:50
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Extremator, тогда не знаю, у меня все робит лол :D мб путь к карте русский или т.д. почитай в теме чего нельзя делать...
Старый 10.05.2014, 10:52
Extremator

offline
Опыт: 39,403
Активность:
А ночь то как убрать?! что это за фигня
в настройках стоит "фикс.полдень", а там ночь!!! ><
Старый 10.05.2014, 10:54
Buulichkaa
Делаю спеллы за еду
offline
Опыт: 20,146
Активность:
Extremator, карта которую ты кидал выше (тест мап) у меня спокойно запустилась и скомпилилась без ошибок

Отредактировано Buulichkaa, 10.05.2014 в 11:05.
Старый 10.05.2014, 10:55
Ответ

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

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

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

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



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