- Сообщений: 683
- Спасибо получено: 351
Правила раздела:
1 Задавайте конкретные вопросы. Для болтовни есть свободный раздел.
2 По возможности давайте конкретные ответы.
3 Один вопрос=одна тема. Если хотите задать ещё вопрос, то начинайте новую тему.
4 Название темы должно составлять сам вопрос, и быть максимально конкретным. Рекомендуется начинать тему словами "Как", "Что", "Почему". А первый пост повторяет вопрос и даёт расширенные сведения.
5 Рекомендуется указывать версию мейкера (2000, 2003, RMXP, RMVX, ACE, IGM, и.т.д.. Это важно, и всё равно ведь спросят.
6 Темы "Пара вопросов", "Помогите", и подобные им - самый лёгкий путь к бану.
7 Поиск находится вверху справа.
А. Названия подразделов этого раздела уточняются. Советы принимаются.
1 Задавайте конкретные вопросы. Для болтовни есть свободный раздел.
2 По возможности давайте конкретные ответы.
3 Один вопрос=одна тема. Если хотите задать ещё вопрос, то начинайте новую тему.
4 Название темы должно составлять сам вопрос, и быть максимально конкретным. Рекомендуется начинать тему словами "Как", "Что", "Почему". А первый пост повторяет вопрос и даёт расширенные сведения.
5 Рекомендуется указывать версию мейкера (2000, 2003, RMXP, RMVX, ACE, IGM, и.т.д.. Это важно, и всё равно ведь спросят.
6 Темы "Пара вопросов", "Помогите", и подобные им - самый лёгкий путь к бану.
7 Поиск находится вверху справа.
А. Названия подразделов этого раздела уточняются. Советы принимаются.
Копия скрипта
8 года 4 мес. назад #101490
от Paranoid
Paranoid создал тему: Копия скрипта
Помогите плез. Нужно размножить один скрипт, то бишь запихнуть его копию в один проект. Но как вы наверное догадались возникает "stack level too deep". Как это побороть? Что конкретно надо переименовать? Скрипт конечно прилагаю.
Ace если что.
Ace если что.
Скрипт
Code:
module Hand_setting
Win_w = 110
Win_h = 50
Win_vis = 255
end
include Hand_setting
class Window_Hand < Window_Base
def initialize
super(Graphics.width-Win_w*4.93, Graphics.height-Win_h, Win_w, Win_h)
create_contents
self.visible = Win_vis
refresh
end
def refresh
self.contents.clear
contents.clear
draw_window_content
end
# Рисуем текст
def draw_window_content
var = $game_variables[1]
if var == 0
var = 20
end
$game_variables[2] = $data_items[var].icon_index
@last_icon = $game_variables[2]
draw_text_ex(0, 0, 'Hand1: \I[\V[2]]')
end
# Обновить
def update
super
return if @last_icon != $game_variables[2]
refresh
end
end
# Scene_Map Class, For keeping it on the map
class Scene_Map < Scene_Base
alias start_window start
alias term_window terminate
alias update_window update
def start
start_window
@winhand = Window_Hand.new
update
end
def terminate
@winhand.dispose
term_window
end
def update
update_window
@winhand.update
end
end
Спасибо сказали: Dmy
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
8 года 4 мес. назад #101493
от Mur
Эммм,… а можно по шагам расписать, что ты хочешь сделать? Вот честно никак не могу понять что значит «размножить» и «запихнуть»?
Или имеется ввиду «один проект» = «этот же самый проект?»
Mur ответил в теме Копия скрипта
Paranoid пишет: Нужно размножить один скрипт, то бишь запихнуть его копию в один проект.
Эммм,… а можно по шагам расписать, что ты хочешь сделать? Вот честно никак не могу понять что значит «размножить» и «запихнуть»?
Или имеется ввиду «один проект» = «этот же самый проект?»
Спасибо сказали: Dmy
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
8 года 4 мес. назад #101496
от Paranoid
Paranoid ответил в теме Копия скрипта
Вот есть у меня скрипт, он показывает окошко с иконкой. А мне нужно еще одно окошко с иконкой. Но этот же самый скрипт нельзя просто скопировать, иначе ничего не работает. А вот мне надо чтобы работало.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
8 года 4 мес. назад - 8 года 4 мес. назад #101498
от Dmy
Dmy ответил в теме Копия скрипта
Я сначала опишу то, о чём просили, а потом опишу правильный способ. 
Переполнение стека вызывается из-за алиасов:
Нужно, чтобы первое название было разным во всех скриптах. То есть лучше заменить start_window на что-то типа start_hand_window_2 и так далее (а также в других местах).
alias создаёт новое имя для старой функции. А потом код переписывает старую функцию и обращается к ней через alias.
Для примера рассмотрим вот этот кусочек кода:
До работы этого кода у нас есть код для отображения экрана карты (Scene_Map), у которого есть функция start. Она вызывается, когда начинается показ экрана карты.
Наш код создаёт псевдоним для старой функции начала экрана карты (alias start_window start). Теперь к ней можно обращаться и как start, и как start_window.
Дальше наш код заменяет функцию start на свою функцию (def start ... end). Это совсем другой код, в котором вызывается исходная start и добавляется окно.
Следующий скрипт уже работает с изменённой функцией start. И alias start_window start сделает, что start_window будет вызывать изменённую функцию start. А так как изменённая функция start вызывает start_window, то получится бесконечный цикл: функция будет вызывать сама себя.
Информация про вызов функции хранится в специальной памяти, в стеке, и эта память не безгранична. Поэтому, когда функция вызывается слишком много раз, возникает ошибка про уровень стека.
Дальше. Другие вещи, которые надо поменять.
Нужно поменять название класса Window_Hand (например, на Window_Hand2).
Окно хранится в переменной @winhand. Нужно поменять её на что-то другое (например, на @winhand2), чтобы одно окно не переписывало второе.
Если второе окно должно иметь другие размеры, не совпадающие с первым окном, то тогда надо переименовать Hand_setting во что-то другое. Если оба окна должны быть одного размера, то тогда можно просто удалить module Hand_setting ... end и настройки будут браться из первого скрипта. (При этом важно, чтобы он был добавлен в списке скриптов выше, чем второй.)
Ну и, вероятно, нужно менять координаты X и Y окон, чтобы они не налезали одно на другое. Это делается в команде инициализации. Вот эту строчку:
super(Graphics.width-Win_w*4.93, Graphics.height-Win_h, Win_w, Win_h)
можно заменить на что-то другое... Если честно, эта строчка очень странная, я бы её сделал вот такой:
Ну и в draw_window_content нужно поменять номера переменных, из которых берётся номер предмета.
И ещё у меня возникала ошибка из-за порядка вызова update’ов, поэтому я заменил
на:
В результате код принимает такой вид:
И это работает, всё хорошо, но проблема в том, что код класса Window_Hand2 почти полностью дублирует код класса Window_Hand. Поэтому вот...
ПРАВИЛЬНЫЙ СПОСОБ.
Правильным способом будет переделать код Window_Hand, чтобы его можно было использовать и для правой, и для левой руки. Тогда это будет не дубликат скрипта, а один скрипт для двух рук. Так делать правильно, потому что:
Для этого нужно передавать параметры в функцию initialize. Мы будем передавать те параметры, которыми руки отличаются друг от друга:
Переполнение стека вызывается из-за алиасов:
Code:
alias start_window start
alias term_window terminate
alias update_window update
Нужно, чтобы первое название было разным во всех скриптах. То есть лучше заменить start_window на что-то типа start_hand_window_2 и так далее (а также в других местах).
Пояснение, почему так происходит и как работает alias
alias создаёт новое имя для старой функции. А потом код переписывает старую функцию и обращается к ней через alias.
Для примера рассмотрим вот этот кусочек кода:
Code:
class Scene_Map < Scene_Base
alias start_window start
# часть кода пропущена...
def start
start_window
@winhand = Window_Hand.new
update
end
#часть кода пропущена
end
До работы этого кода у нас есть код для отображения экрана карты (Scene_Map), у которого есть функция start. Она вызывается, когда начинается показ экрана карты.
Наш код создаёт псевдоним для старой функции начала экрана карты (alias start_window start). Теперь к ней можно обращаться и как start, и как start_window.
Дальше наш код заменяет функцию start на свою функцию (def start ... end). Это совсем другой код, в котором вызывается исходная start и добавляется окно.
Следующий скрипт уже работает с изменённой функцией start. И alias start_window start сделает, что start_window будет вызывать изменённую функцию start. А так как изменённая функция start вызывает start_window, то получится бесконечный цикл: функция будет вызывать сама себя.
Информация про вызов функции хранится в специальной памяти, в стеке, и эта память не безгранична. Поэтому, когда функция вызывается слишком много раз, возникает ошибка про уровень стека.
Дальше. Другие вещи, которые надо поменять.
Список вещей, которые надо поменять в скрипте, чтобы его размножить
Нужно поменять название класса Window_Hand (например, на Window_Hand2).
Окно хранится в переменной @winhand. Нужно поменять её на что-то другое (например, на @winhand2), чтобы одно окно не переписывало второе.
Если второе окно должно иметь другие размеры, не совпадающие с первым окном, то тогда надо переименовать Hand_setting во что-то другое. Если оба окна должны быть одного размера, то тогда можно просто удалить module Hand_setting ... end и настройки будут браться из первого скрипта. (При этом важно, чтобы он был добавлен в списке скриптов выше, чем второй.)
Ну и, вероятно, нужно менять координаты X и Y окон, чтобы они не налезали одно на другое. Это делается в команде инициализации. Вот эту строчку:
super(Graphics.width-Win_w*4.93, Graphics.height-Win_h, Win_w, Win_h)
можно заменить на что-то другое... Если честно, эта строчка очень странная, я бы её сделал вот такой:
Code:
# для первого окна (0, т.е. как можно левее)
super(0, Graphics.height-Win_h, Win_w, Win_h)
# для второго окна (Win_w, т.е. на расстоянии окна)
super(Win_w, Graphics.height-Win_h, Win_w, Win_h)
Ну и в draw_window_content нужно поменять номера переменных, из которых берётся номер предмета.
И ещё у меня возникала ошибка из-за порядка вызова update’ов, поэтому я заменил
Code:
@winhand2.update
Code:
@winhand2.update if @winhand2
В результате код принимает такой вид:
Рабочий скрипт, но с дублированием классов
Code:
include Hand_setting
class Window_Hand2 < Window_Base
def initialize
super(Win_w, Graphics.height-Win_h, Win_w, Win_h)
create_contents
self.visible = Win_vis
refresh
end
def refresh
self.contents.clear
contents.clear
draw_window_content
end
# Рисуем текст
def draw_window_content
### ПОМЕНЯЙТЕ ЧИСЛО В СКОБКАХ НИЖЕ НА НОМЕР ПЕРЕМЕННОЙ
var = $game_variables[1]
if var == 0
var = 20
end
if var < $data_items.length then
$game_variables[2] = $data_items[var].icon_index
@last_icon = $game_variables[2]
draw_text_ex(0, 0, 'Hand2: \I[\V[2]]')
else
draw_text_ex(0, 0, 'Hand2:')
end
end
# Обновить
def update
super
return if @last_icon != $game_variables[2]
refresh
end
end
# Scene_Map Class, For keeping it on the map
class Scene_Map < Scene_Base
alias start_second_hand start
alias term_second_hand terminate
alias update_second_hand update
def start
start_second_hand
@winhand2 = Window_Hand2.new
update
end
def terminate
@winhand2.dispose
term_second_hand
end
def update
update_second_hand
@winhand2.update if @winhand2
end
end
И это работает, всё хорошо, но проблема в том, что код класса Window_Hand2 почти полностью дублирует код класса Window_Hand. Поэтому вот...
ПРАВИЛЬНЫЙ СПОСОБ.
Правильным способом будет переделать код Window_Hand, чтобы его можно было использовать и для правой, и для левой руки. Тогда это будет не дубликат скрипта, а один скрипт для двух рук. Так делать правильно, потому что:
- Его можно будет легко адаптировать и для трёх рук, и для пяти
,
- Если нужно будет поменять механизм работы, можно поменять его сразу для обеих рук.
Для этого нужно передавать параметры в функцию initialize. Мы будем передавать те параметры, которыми руки отличаются друг от друга:
- item_var_id — номер переменной, из которой мы будем брать предмет,
- icon_var_id — номер переменной, в которую мы будем записывать индекс значка,
- x — количество пикселей от края экрана (у первой руки это 0 — ну, или Graphics.width-Win_w*4.93; у второй руки это Win_w)
- window_text — текст в окне ('Hand1:', 'Hand2:', etc.)
Параметры передаются в скобках, так что допишем после функции initialize скобки:
Code:def initialize(x, item_var_id, icon_var_id, window_text) # код пропущен end
x используется прямо здесь — он передаётся в функцию initialize верхнего уровня (суперкласса) с помощью super, поэтому первая строчка примет такой вид:
Code:super(x, Graphics.height-Win_h, Win_w, Win_h)
Другие параметры (item_var_id, icon_var_id, window_text) используются не в функции initialize, а в другой функции, draw_window_content. Чтобы они там были доступны, сохраним их как переменные объекта (перед переменными объекта пишется знак @):
Code:@item_var_id = item_var_id @icon_var_id = icon_var_id @window_text = window_text
В результате функция initalize примет такой вид:
Code:def initialize(x, item_var_id, icon_var_id, window_text) super(x, Graphics.height-Win_h, Win_w, Win_h) @item_var_id = item_var_id @icon_var_id = icon_var_id @window_text = window_text create_contents self.visible = Win_vis refresh end
Так как в функции initialize теперь есть параметры, эти параметры нужно передавать при создании Window_Hand — не
Code:@winhand = Window_Hand.new
аCode:@winhand = Window_Hand.new(0, 1, 2, 'Hand1:')
Это будет в функции start класса Scene_Map, внизу. Ну и, так как рук у нас теперь 2, создадим сразу два окна:
Code:@winhand1 = Window_Hand.new(0, 1, 2, 'Hand1:') @winhand2 = Window_Hand.new(Win_w, 1, 2, 'Hand2:')
Во второй руке нужно заменить 1 и 2 на номера других переменных, иначе оба окна будут показывать одно и то же.
В других местах @winhand.dispose и @winhand.update тоже нужно заменить на две строчки, одну с @winhand1, вторую с @winhand2.
Ну и нужно поменять саму функцию draw_window_content в классе Window_Hand, чтобы она учитывала @item_var_id, @icon_var_id, @window_text:
Code:def draw_window_content var = $game_variables[@item_var_id] if var == 0 var = 20 end if var < $data_items.length then $game_variables[@icon_var_id] = $data_items[var].icon_index @last_icon = $game_variables[@icon_var_id] draw_text_ex(0, 0, @window_text + '\I[\V[' + @icon_var_id.to_s + ']]') else draw_text_ex(0, 0, @window_text) end end
Так как @icon_var_id — это число, а не строка, превратим его в строку с помощью to_s.
Результат получается таким:
Рабочий скрипт без дублирования классовCode:module Hand_setting Win_w = 120 Win_h = 50 Win_vis = 255 end include Hand_setting class Window_Hand < Window_Base def initialize(x, item_var_id, icon_var_id, window_text) super(x, Graphics.height-Win_h, Win_w, Win_h) @item_var_id = item_var_id @icon_var_id = icon_var_id @window_text = window_text create_contents self.visible = Win_vis refresh end def refresh self.contents.clear contents.clear draw_window_content end # Рисуем текст def draw_window_content var = $game_variables[@item_var_id] if var == 0 var = 20 end if var < $data_items.length then $game_variables[@icon_var_id] = $data_items[var].icon_index @last_icon = $game_variables[@icon_var_id] draw_text_ex(0, 0, @window_text + '\I[\V[' + @icon_var_id.to_s + ']]') else draw_text_ex(0, 0, @window_text) end end # Обновить def update super return if @last_icon != $game_variables[@icon_var_id] refresh end end # Scene_Map Class, For keeping it on the map class Scene_Map < Scene_Base alias start_window start alias term_window terminate alias update_window update def start start_window #замените 1 на номер переменной, из которой будет браться предмет #замените 2 на номер переменной, в которую запишется номер последнего значка @winhand1 = Window_Hand.new(0, 1, 2, 'Hand1: ') @winhand2 = Window_Hand.new(Win_w, 1, 2, 'Hand2: ') update end def terminate @winhand1.dispose @winhand2.dispose term_window end def update update_window @winhand1.update if @winhand1 @winhand2.update if @winhand2 end end
Всё бы хорошо, но чтобы настроить скрипт, придётся редактировать строчкив середине кода. Считается дурным тоном заставлять людей редактировать строчки в середине кода. Лучше вынести их наверх — тем более, что у нас уже есть module Hand_setting ... end для хранения настроек.Code:@winhand1 = Window_Hand.new(0, 1, 2, 'Hand1: ') @winhand2 = Window_Hand.new(Win_w, 1, 2, 'Hand2: ')
В результате код получается таким:Code:module Hand_setting # ширина окона Win_w = 120 # высота окон Win_h = 50 # непрозрачность окон Win_vis = 255 # Номер переменной, где хранится предмет правой руки Right_hand_var_id = 1 # Номер переменной, куда запишется значок предмета из правой руки Right_hand_icon_id = 2 # Текст перед значком предмета левой руки: Right_hand_window_text = 'Hand1: ' # Номер переменной, где хранится предмет левой руки Left_hand_var_id = 3 # Номер переменной, куда запишется значок предмета из левой руки Left_hand_icon_id = 4 # Текст перед значком предмета левой руки: Left_hand_window_text = 'Hand2: ' # Номер предмета, который будет показан, если рука пустая Hand_empty_item_id = 20 end include Hand_setting class Window_Hand < Window_Base def initialize(x, item_var_id, icon_var_id, window_text) super(x, Graphics.height-Win_h, Win_w, Win_h) @item_var_id = item_var_id @icon_var_id = icon_var_id @window_text = window_text create_contents self.visible = Win_vis refresh end def refresh self.contents.clear contents.clear draw_window_content end # Рисуем текст def draw_window_content var = $game_variables[@item_var_id] if var == 0 var = Hand_empty_item_id end if var < $data_items.length then $game_variables[@icon_var_id] = $data_items[var].icon_index @last_icon = $game_variables[@icon_var_id] draw_text_ex(0, 0, @window_text + '\I[\V[' + @icon_var_id.to_s + ']]') else draw_text_ex(0, 0, @window_text) end end # Обновить def update super return if @last_icon != $game_variables[@icon_var_id] refresh end end # Scene_Map Class, For keeping it on the map class Scene_Map < Scene_Base alias start_window start alias term_window terminate alias update_window update def start start_window @winhand1 = Window_Hand.new(0, Right_hand_var_id, Right_hand_icon_id, Right_hand_window_text) @winhand2 = Window_Hand.new(Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text) update end def terminate @winhand1.dispose @winhand2.dispose term_window end def update update_window @winhand1.update if @winhand1 @winhand2.update if @winhand2 end end
Я проверял и у меня всё работает, но если что-то не работает — пиши, исправлю. Или если что-то непонятно. Удачи!
Последнее редактирование: 8 года 4 мес. назад пользователем Dmy.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
8 года 4 мес. назад #101499
от Paranoid
Paranoid ответил в теме Копия скрипта
О, спасибо большое, все как мне надо. Только строчку
@winhand2 = Window_Hand.new(Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text)
Заменил на
@winhand2 = Window_Hand.new(Graphics.width-Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text)
Так как на разных частях экрана должны быть.
Ну и раз уж вы такой умелец, может прикрутите возможность прятать этот худ свитчом №1. А то я так и не добился с этим приемлемых результатов.
@winhand2 = Window_Hand.new(Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text)
Заменил на
@winhand2 = Window_Hand.new(Graphics.width-Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text)
Так как на разных частях экрана должны быть.
Ну и раз уж вы такой умелец, может прикрутите возможность прятать этот худ свитчом №1. А то я так и не добился с этим приемлемых результатов.
Спасибо сказали: Dmy
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
8 года 4 мес. назад #101512
от Dmy
Если нужно, можно сделать для разных рук разные свитчи, поменяв Left_hand_enabler_switch и Right_hand_enabler_switch.
Dmy ответил в теме Копия скрипта
Не уверен, что у меня оптимальный вариант, но вот такой код работает:Paranoid пишет: возможность прятать этот худ свитчом №1. А то я так и не добился с этим приемлемых результатов.
Code:
module Hand_setting
# ширина окона
Win_w = 120
# высота окон
Win_h = 50
# непрозрачность окон
Win_vis = 255
# Номер переменной, где хранится предмет правой руки
Right_hand_var_id = 1
# Номер переменной, куда запишется значок предмета из правой руки
Right_hand_icon_id = 2
# Текст перед значком предмета правой руки:
Right_hand_window_text = 'Hand1: '
# Свитч, который включает показ окна для правой руки (или false, если показывать всегда)
Right_hand_enabler_switch = 1
# Номер переменной, где хранится предмет левой руки
Left_hand_var_id = 3
# Номер переменной, куда запишется значок предмета из левой руки
Left_hand_icon_id = 4
# Текст перед значком предмета левой руки:
Left_hand_window_text = 'Hand2: '
# Свитч, который включает показ окна для левой руки (или false, если показывать всегда)
Left_hand_enabler_switch = 1
# Номер предмета, который будет показан, если рука пустая
Hand_empty_item_id = 20
end
include Hand_setting
class Window_Hand < Window_Base
def initialize(x, item_var_id, icon_var_id, window_text, enabler_switch_id)
super(x, Graphics.height-Win_h, Win_w, Win_h)
@item_var_id = item_var_id
@icon_var_id = icon_var_id
@window_text = window_text
@enabler_switch_id = enabler_switch_id
create_contents
self.visible = Win_vis
refresh
end
def refresh
self.contents.clear
contents.clear
draw_window_content
end
# Рисуем текст
def draw_window_content
var = $game_variables[@item_var_id]
if var == 0
var = Hand_empty_item_id
end
if var < $data_items.length then
$game_variables[@icon_var_id] = $data_items[var].icon_index
@last_icon = $game_variables[@icon_var_id]
draw_text_ex(0, 0, @window_text + '\I[\V[' + @icon_var_id.to_s + ']]')
else
draw_text_ex(0, 0, @window_text)
end
end
# Обновить
def update
super
if @enabler_switch_id then
if $game_switches[@enabler_switch_id] then
show
else
hide
end
end
return if @last_icon != $game_variables[@icon_var_id]
refresh
end
end
# Scene_Map Class, For keeping it on the map
class Scene_Map < Scene_Base
alias start_window start
alias term_window terminate
alias update_window update
def start
start_window
@winhand1 = Window_Hand.new(0, Right_hand_var_id, Right_hand_icon_id, Right_hand_window_text, Right_hand_enabler_switch)
@winhand2 = Window_Hand.new(Win_w, Left_hand_var_id, Left_hand_icon_id, Left_hand_window_text, Left_hand_enabler_switch)
update
end
def terminate
@winhand1.dispose
@winhand2.dispose
term_window
end
def update
update_window
@winhand1.update if @winhand1
@winhand2.update if @winhand2
end
end
Если нужно, можно сделать для разных рук разные свитчи, поменяв Left_hand_enabler_switch и Right_hand_enabler_switch.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Время создания страницы: 0.099 секунд
